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";
|
|
|
|
import { System } from "index";
|
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-06-16 19:31:33 +00:00
|
|
|
const profile = useUserProfile(System, 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(
|
|
|
|
lnurl
|
|
|
|
)}&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>
|
|
|
|
);
|
|
|
|
}
|