import { useContext, useEffect, useState } from "react"; import { FormattedMessage } from "react-intl"; import { SnortContext } from "@snort/system-react"; import { NostrStreamProvider, StreamProviderEndpoint, StreamProviderInfo } from "@/providers"; import { SendZaps } from "@/element/send-zap"; import { StreamEditor, StreamEditorProps } from "@/element/stream-editor"; import Spinner from "@/element/spinner"; import { useRates } from "@/hooks/rates"; import { DefaultButton } from "@/element/buttons"; import Pill from "@/element/pill"; import { AddForwardInputs } from "./fowards"; import StreamKey from "./stream-key"; import AccountTopup from "./topup"; import AccountWithdrawl from "./withdraw"; import BalanceHistory from "./history"; import StreamKeyList from "./stream-keys"; export default function NostrProviderDialog({ provider, showEndpoints, showEditor, showForwards, showBalanceHistory, showStreamKeys, ...others }: { provider: NostrStreamProvider; showEndpoints: boolean; showEditor: boolean; showForwards: boolean; showBalanceHistory: boolean; showStreamKeys: boolean; } & StreamEditorProps) { const system = useContext(SnortContext); const [topup, setTopup] = useState(false); const [info, setInfo] = useState(); const [ep, setEndpoint] = useState(); const [hrs, setHrs] = useState(25); const [tos, setTos] = useState(false); const rate = useRates("BTCUSD"); function sortEndpoints(arr: Array) { return arr.sort((a, b) => ((a.rate ?? 0) > (b.rate ?? 0) ? -1 : 1)); } async function loadInfo() { const info = await provider.info(); setInfo(info); setTos(info.tosAccepted ?? true); setEndpoint(sortEndpoints(info.endpoints)[0]); } useEffect(() => { loadInfo(); }, [provider]); if (!info) { return ; } if (topup) { return ( { const pr = await provider.topup(amount); return { pr }; }, }} onFinish={() => { provider.info().then(v => { setInfo(v); setTopup(false); }); }} /> ); } function calcEstimate() { if (!ep?.rate || !ep?.unit || !info?.balance || !info.balance) return; const raw = Math.max(0, info.balance / ep.rate); if (ep.unit === "min" && raw > 60) { const pm = hrs * 60 * ep.rate; return ( <> {`${(raw / 60).toFixed(0)} hour @ ${ep.rate} sats/${ep.unit}`}   or
{`${pm.toLocaleString()} sats/month ($${(rate.ask * pm * 1e-8).toFixed(2)}/mo) streaming ${hrs} hrs/month`}
Hrs setHrs(e.target.valueAsNumber)} />
); } return `${raw.toFixed(0)} ${ep.unit} @ ${ep.rate} sats/${ep.unit}`; } function parseCapability(cap: string) { const [tag, ...others] = cap.split(":"); if (tag === "variant") { const [height] = others; return height === "source" ? "source" : `${height.slice(0, -1)}p`; } if (tag === "output") { return others[0]; } return cap; } async function acceptTos() { await provider.acceptTos(); const i = await provider.info(); setInfo(i); } function tosInput() { if (!info) return; return ( <>
setTos(e.target.checked)} />

window.open(info.tosLink, "popup", "width=400,height=800")}> ), }} />

); } function streamEndpoints() { if (!info) return; return ( <> {info.endpoints.length > 1 && (

{sortEndpoints(info.endpoints).map(a => ( setEndpoint(a)}> {a.name} ))}
)} {ep && }

{ep?.capabilities?.map(a => {parseCapability(a)})}
); } function streamEditor() { if (!info || !showEditor) return; if (info.tosAccepted === false) { return tosInput(); } return ( { provider.updateStreamInfo(system, ex); others.onFinish?.(ex); }} ev={others.ev} options={{ canSetStream: false, canSetStatus: false, }} /> ); } function forwardInputs() { if (!info || !showForwards) return; return (

{info.forwards?.map(a => ( <>
{a.name}
{ await provider.removeForward(a.id); await loadInfo(); }}> ))}
); } function balanceHist() { if (!info || !showBalanceHistory) return; return (

); } function streamKeys() { if (!info || !showStreamKeys) return; return ; } return ( <> {showEndpoints && streamEndpoints()} {streamEditor()} {forwardInputs()} {balanceHist()} {streamKeys()} ); }