import { DefaultButton } from "@/element/buttons" import Modal from "@/element/modal" import type { NostrStreamProvider } from "@/providers" import { LNURL } from "@snort/shared" import { useEffect, useState } from "react" import { FormattedMessage, useIntl } from "react-intl" export default function AccountWithdrawl({ provider, onFinish, }: { provider: NostrStreamProvider onFinish: () => void }) { const [topup, setTopup] = useState(false) const [addr, setAddress] = useState("") const [error, setError] = useState("") const [amount, setAmount] = useState() const [withdrawalSupported, setWithdrawalSupported] = useState(null) const { formatMessage } = useIntl() // Check if withdrawal is supported by making a HEAD request useEffect(() => { const checkWithdrawalSupport = async () => { try { const withdrawUrl = `${provider.url}withdraw` const response = await fetch(withdrawUrl, { method: "HEAD", }) // If we get 200, 400, 401, 405, or 403, the endpoint exists // If we get 404, the endpoint doesn't exist (not supported) setWithdrawalSupported(response.status !== 404) } catch (_error) { // On network error, assume it's supported to avoid breaking existing functionality setWithdrawalSupported(false) } } checkWithdrawalSupport() }, [provider.url]) useEffect(() => { if (addr.startsWith("lnbc") && amount !== undefined) { setAmount(undefined) } else if (!addr.startsWith("lnbc") && amount === undefined) { setAmount(0) } }, [addr, amount]) async function withdraw() { setError("") let invoice = addr if (!invoice.startsWith("lnbc") && amount && amount > 1) { const invoiceError = formatMessage({ defaultMessage: "Failed to get invoice", }) try { const lnurl = new LNURL(addr) await lnurl.load() const rsp = await lnurl.getInvoice(amount, "Withdrawal from zap.stream") if (rsp.pr) { invoice = rsp.pr } else { setError(rsp.reason ?? invoiceError) return } } catch (e) { if (e instanceof Error) { setError(e.message) } else { setError(invoiceError) } } } try { const res = await provider.withdraw(invoice) if (res.preimage) { setTopup(false) onFinish() } else if (res.error) { setError(res.error) } } catch (e) { if (e instanceof Error) { setError(e.message) } } } // Don't render if withdrawal is not supported if (!withdrawalSupported) { return null } return ( <> setTopup(true)}> {topup && ( setTopup(false)}>
setAddress(e.target.value)} placeholder={formatMessage({ defaultMessage: "LNURL or invoice", })} />
{amount !== undefined && (
setAmount(e.target.valueAsNumber)} />
)} {error && {error}}
)} ) }