From cf1d8029efc1f9497bcef71b5c959c42794f3566 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Thu, 5 Feb 2026 16:44:55 -0800 Subject: payment forwarding --- src/lib/ark.ts | 29 ++++++++++++++++++++++++++++- src/lib/parse.ts | 2 ++ 2 files changed, 30 insertions(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/ark.ts b/src/lib/ark.ts index 26c16a93..25122a8c 100644 --- a/src/lib/ark.ts +++ b/src/lib/ark.ts @@ -53,11 +53,38 @@ export const syncTransactions = async (aid: string) => { return post("/post/ark/sync", { transactions, aid }); }; +export const vtxoKey = (v: { txid: string; vout: number }) => + `${v.txid}:${v.vout}`; + +export const getProcessedVtxos = (): Set => { + try { + return new Set( + JSON.parse(localStorage.getItem("processedArkVtxos") || "[]"), + ); + } catch { + return new Set(); + } +}; + +export const addProcessedVtxos = (keys: string[]) => { + const processed = getProcessedVtxos(); + for (const k of keys) processed.add(k); + const arr = [...processed].slice(-200); + localStorage.setItem("processedArkVtxos", JSON.stringify(arr)); +}; + export const sendArk = async (address: string, amount: number) => { const wallet = await getWallet(); if (!wallet) throw new Error("Ark wallet not available"); - return wallet.sendBitcoin({ address, amount }); + const txid = await wallet.sendBitcoin({ address, amount }); + + // Mark post-send VTXOs as processed so notifyIncomingFunds + // ignores change VTXOs from this send + const vtxos = await wallet.getVtxos({ spendableOnly: false }); + if (vtxos?.length) addProcessedVtxos(vtxos.map(vtxoKey)); + + return txid; }; export const settle = async () => { diff --git a/src/lib/parse.ts b/src/lib/parse.ts index 8520c27a..3249b9db 100644 --- a/src/lib/parse.ts +++ b/src/lib/parse.ts @@ -72,8 +72,10 @@ export default async (s, host, cookies) => { invoice = { id: iid }; } else if (t.toLowerCase().startsWith("ln")) { try { + const aid = cookies.get("aid"); invoice = await get(`/invoice/${t}`); if (invoice.user.username === "mint") throw new Error("mint payment"); + if (aid && aid !== invoice.aid) throw new Error("cross-account"); } catch (e) { if (t.toLowerCase().startsWith("lno")) { const { offer_amount_msat: a } = await get(`/decode/${t}`); -- cgit v1.2.3