snort/packages/app/src/Components/Embed/CashuNuts.tsx

83 lines
2.3 KiB
TypeScript
Raw Normal View History

2023-09-22 11:17:02 +00:00
import "./CashuNuts.css";
2024-01-04 17:01:18 +00:00
import { useUserProfile } from "@snort/system-react";
2023-05-16 17:54:49 +00:00
import { useEffect, useState } from "react";
2023-09-22 11:17:02 +00:00
import { FormattedMessage, FormattedNumber } from "react-intl";
2023-05-09 15:25:59 +00:00
import AsyncButton from "@/Components/Button/AsyncButton";
import ECashIcon from "@/Components/Icons/ECash";
import Icon from "@/Components/Icons/Icon";
import { useCopy } from "@/Hooks/useCopy";
2024-01-04 17:01:18 +00:00
import useLogin from "@/Hooks/useLogin";
2023-05-09 15:25:59 +00:00
2023-05-16 17:54:49 +00:00
interface Token {
token: Array<{
mint: string;
proofs: Array<{
amount: number;
}>;
}>;
memo?: string;
}
2023-05-09 15:25:59 +00:00
export default function CashuNuts({ token }: { token: string }) {
2023-09-23 21:21:37 +00:00
const { publicKey } = useLogin(s => ({ publicKey: s.publicKey }));
const profile = useUserProfile(publicKey);
const { copy } = useCopy();
2023-05-09 15:25:59 +00:00
async function redeemToken(token: string) {
2023-05-09 15:25:59 +00:00
const lnurl = profile?.lud16 ?? "";
2023-05-09 15:28:50 +00:00
const url = `https://redeem.cashu.me?token=${encodeURIComponent(token)}&lightning=${encodeURIComponent(
2023-09-12 21:58:37 +00:00
lnurl,
2023-05-09 15:28:50 +00:00
)}&autopay=yes`;
2023-05-09 15:25:59 +00:00
window.open(url, "_blank");
}
2023-05-16 17:54:49 +00:00
const [cashu, setCashu] = useState<Token>();
useEffect(() => {
2023-05-09 15:25:59 +00:00
try {
if (!token.startsWith("cashuA") || token.length < 10) {
return;
}
2023-05-16 17:54:49 +00:00
import("@cashu/cashu-ts").then(({ getDecodedToken }) => {
const tkn = getDecodedToken(token);
setCashu(tkn);
});
2023-05-09 15:25:59 +00:00
} catch {
// ignored
}
}, [token]);
if (!cashu) return <>{token}</>;
2023-09-22 11:17:02 +00:00
const amount = cashu.token[0].proofs.reduce((acc, v) => acc + v.amount, 0);
2023-05-09 15:25:59 +00:00
return (
<div className="cashu flex justify-between p24 br items-center">
<div className="flex flex-col gap-2 f-ellipsis">
<div className="flex items-center gap-4">
<ECashIcon width={30} />
2023-09-22 11:17:02 +00:00
<FormattedMessage
defaultMessage="{n} eSats"
id="yAztTU"
2023-09-22 11:17:02 +00:00
values={{
n: (
<span className="text-3xl">
<FormattedNumber value={amount} />
</span>
),
2023-09-22 11:17:33 +00:00
}}
/>
2023-05-09 15:25:59 +00:00
</div>
2023-09-22 11:17:02 +00:00
</div>
<div className="flex gap-2 items-center">
<AsyncButton onClick={() => copy(token)}>
2023-09-22 11:17:02 +00:00
<Icon name="copy" />
</AsyncButton>
<AsyncButton onClick={() => redeemToken(token)}>
<FormattedMessage defaultMessage="Redeem" />
</AsyncButton>
2023-05-09 15:25:59 +00:00
</div>
</div>
);
}