import "./send-zap.css"; import * as Dialog from "@radix-ui/react-dialog"; import { useEffect, useState, type ReactNode } from "react"; import { LNURL } from "@snort/shared"; import { NostrEvent, EventPublisher } from "@snort/system"; import { formatSats } from "../number"; import { Icon } from "./icon"; import AsyncButton from "./async-button"; import { Relays } from "index"; import QrCode from "./qr-code"; export interface LNURLLike { get name(): string; get maxCommentLength(): number; get canZap(): boolean; getInvoice( amountInSats: number, comment?: string, zap?: NostrEvent ): Promise<{ pr?: string }>; } export interface SendZapsProps { lnurl: string | LNURLLike; pubkey?: string; aTag?: string; eTag?: string; targetName?: string; onFinish: () => void; button?: ReactNode; } export function SendZaps({ lnurl, pubkey, aTag, eTag, targetName, onFinish, }: SendZapsProps) { const UsdRate = 30_000; const satsAmounts = [ 100, 1_000, 5_000, 10_000, 50_000, 100_000, 500_000, 1_000_000, ]; const usdAmounts = [0.05, 0.5, 2, 5, 10, 50, 100, 200]; const [isFiat, setIsFiat] = useState(false); const [svc, setSvc] = useState(); const [amount, setAmount] = useState(satsAmounts[0]); const [comment, setComment] = useState(""); const [invoice, setInvoice] = useState(""); const name = targetName ?? svc?.name; async function loadService(lnurl: string) { const s = new LNURL(lnurl); await s.load(); setSvc(s); } useEffect(() => { if (!svc) { if (typeof lnurl === "string") { loadService(lnurl).catch(console.warn); } else { setSvc(lnurl); } } }, [lnurl]); async function send() { if (!svc) return; const pub = await EventPublisher.nip7(); if (!pub) return; const amountInSats = isFiat ? Math.floor((amount / UsdRate) * 1e8) : amount; let zap: NostrEvent | undefined; if (pubkey) { zap = await pub.zap( amountInSats * 1000, pubkey, Relays, undefined, comment, (eb) => { if (aTag) { eb.tag(["a", aTag]); } if (eTag) { eb.tag(["e", eTag]); } return eb; } ); } const invoice = await svc.getInvoice(amountInSats, comment, zap); if (!invoice.pr) return; if (window.webln) { await window.webln.enable(); try { await window.webln.sendPayment(invoice.pr); onFinish(); } catch (error) { setInvoice(invoice.pr); } } else { setInvoice(invoice.pr); } } function input() { if (invoice) return; return ( <>
{ setIsFiat(false); setAmount(satsAmounts[0]); }} > SATS { setIsFiat(true); setAmount(usdAmounts[0]); }} > USD
Zap amount in {isFiat ? "USD" : "sats"}
{(isFiat ? usdAmounts : satsAmounts).map((a) => ( setAmount(a)} > {isFiat ? `$${a.toLocaleString()}` : formatSats(a)} ))}
{svc && (svc.maxCommentLength > 0 || svc.canZap) && (
Your comment for {name}