snort/packages/app/src/Element/CashuNuts.tsx

82 lines
2.3 KiB
TypeScript
Raw Normal View History

2023-05-16 17:54:49 +00:00
import { useEffect, useState } from "react";
2023-05-09 15:25:59 +00:00
import { FormattedMessage } from "react-intl";
import useLogin from "Hooks/useLogin";
2023-06-16 19:31:33 +00:00
import { useUserProfile } from "@snort/system-react";
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 }) {
const login = useLogin();
2023-08-24 14:25:54 +00:00
const profile = useUserProfile(login.publicKey);
2023-05-09 15:25:59 +00:00
async function copyToken(e: React.MouseEvent<HTMLButtonElement>, token: string) {
e.stopPropagation();
await navigator.clipboard.writeText(token);
}
async function redeemToken(e: React.MouseEvent<HTMLButtonElement>, token: string) {
e.stopPropagation();
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}</>;
return (
<div className="note-invoice">
<div className="flex f-between">
<div>
<h4>
<FormattedMessage defaultMessage="Cashu token" />
</h4>
<p>
<FormattedMessage
defaultMessage="Amount: {amount} sats"
values={{
amount: cashu.token[0].proofs.reduce((acc, v) => acc + v.amount, 0),
}}
/>
</p>
<small className="xs">
<FormattedMessage defaultMessage="Mint: {url}" values={{ url: cashu.token[0].mint }} />
</small>
</div>
<div>
<button onClick={e => copyToken(e, token)} className="mr5">
<FormattedMessage defaultMessage="Copy" description="Button: Copy Cashu token" />
</button>
<button onClick={e => redeemToken(e, token)}>
<FormattedMessage defaultMessage="Redeem" description="Button: Redeem Cashu token" />
</button>
</div>
</div>
</div>
);
}