PayLightningInvoice.tsx raw
1 import { Invoice, getFiatValue } from "@getalby/lightning-tools";
2 import { CopyIcon, ExternalLinkIcon } from "lucide-react";
3 import React from "react";
4 import { FixedFloatButton } from "src/components/FixedFloatButton";
5 import { FormattedBitcoinAmount } from "src/components/FormattedBitcoinAmount";
6 import Loading from "src/components/Loading";
7 import QRCode from "src/components/QRCode";
8 import { Button } from "src/components/ui/button";
9 import { copyToClipboard } from "src/lib/clipboard";
10
11 type PayLightningInvoiceProps = {
12 invoice: string;
13 };
14
15 export function PayLightningInvoice({ invoice }: PayLightningInvoiceProps) {
16 const amountSat = new Invoice({
17 pr: invoice,
18 }).satoshi;
19 const [fiatAmount, setFiatAmount] = React.useState(0);
20 React.useEffect(() => {
21 getFiatValue({ satoshi: amountSat, currency: "USD" }).then((fiatAmount) =>
22 setFiatAmount(fiatAmount)
23 );
24 }, [amountSat]);
25 const copy = () => {
26 copyToClipboard(invoice);
27 };
28
29 return (
30 <div className="flex w-full flex-col items-center justify-center gap-6">
31 <div className="flex items-center justify-center gap-2 font-semibold leading-none">
32 <Loading variant="loader" />
33 <p>Waiting for Payment...</p>
34 </div>
35 <div className="relative flex w-full items-center justify-center">
36 <QRCode value={invoice} className="w-full" paymentType="lightning" />
37 </div>
38 <div>
39 <p className="text-lg font-semibold">
40 <FormattedBitcoinAmount amountMsat={amountSat * 1000} />
41 </p>
42 <p className="flex flex-col items-center justify-center">
43 {new Intl.NumberFormat("en-US", {
44 currency: "USD",
45 style: "currency",
46 }).format(fiatAmount)}
47 </p>
48 </div>
49 <div className="flex w-full flex-col gap-3">
50 <Button onClick={copy} variant="secondary" className="w-full">
51 <CopyIcon />
52 Copy Invoice
53 </Button>
54 <FixedFloatButton
55 to="BTCLN"
56 address={invoice}
57 className="w-full"
58 variant="outline"
59 >
60 <ExternalLinkIcon className="size-4" />
61 Pay with Crypto
62 </FixedFloatButton>
63 </div>
64 </div>
65 );
66 }
67