diff options
| author | Adam Soltys <[email protected]> | 2026-03-03 21:40:58 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-03-03 21:40:58 -0800 |
| commit | 55ae58daf23028fa0f647f7bb2b4b0f8cd751de7 (patch) | |
| tree | 49f4031b81352bea5c963d4201250f24ee8bd2dd /routes | |
| parent | 9507e040a03834f7d603c5c13a1f69ae6ef48b3a (diff) | |
| download | coinos-server-55ae58daf23028fa0f647f7bb2b4b0f8cd751de7.tar.gz coinos-server-55ae58daf23028fa0f647f7bb2b4b0f8cd751de7.zip | |
sync vault
Diffstat (limited to 'routes')
| -rw-r--r-- | routes/payments.ts | 69 | ||||
| -rw-r--r-- | routes/users.ts | 2 |
2 files changed, 70 insertions, 1 deletions
diff --git a/routes/payments.ts b/routes/payments.ts index 98581ebd..524f6f4d 100644 --- a/routes/payments.ts +++ b/routes/payments.ts @@ -23,6 +23,7 @@ import { sendInternal, sendLightning, sendOnchain, + syncBitcoinVault, } from "$lib/payments"; import { emit } from "$lib/sockets"; import { @@ -1116,4 +1117,72 @@ export default { return bail(c, e.message); } }, + + async bitcoinSync(c) { + try { + const user = c.get("user"); + const { aid } = await c.req.json(); + const { id: uid } = user; + + const pos = await db.lPos(`${uid}:accounts`, aid); + if (pos === null) return bail(c, "account not found"); + + const account = await g(`account:${aid}`); + if (!account?.pubkey || !account?.fingerprint) return bail(c, "not a bitcoin vault"); + + const lockKey = `btcsynclock:${aid}`; + const gotLock = await db.set(lockKey, "1", { NX: true, EX: 30 }); + if (!gotLock) return c.json({ synced: 0, received: 0, payments: [] }); + + try { + const { pendingTotal, newPayments } = await syncBitcoinVault(account, user); + + let received = 0; + const payments = []; + + for (const p of newPayments) { + if (p.amount > 0) { + received += p.amount; + payments.push(p); + + const invoiceIds = await db.lRange(`${aid}:invoices`, 0, 20); + for (const iid of invoiceIds) { + const inv = await getInvoice(iid); + if (!inv || inv.type !== "bitcoin") continue; + if (inv.received >= inv.amount && inv.amount > 0) continue; + if (inv.amount > 0 && p.amount < inv.amount) continue; + inv.received = (inv.received || 0) + p.amount; + p.iid = iid; + await s(`invoice:${iid}`, inv); + await s(`payment:${p.id}`, p); + emit(uid, "payment", p); + break; + } + } + } + + // Compute balance from payments + const paymentIds = await db.lRange(`${aid}:payments`, 0, -1); + const paymentKeys = paymentIds.map((pid) => `payment:${pid}`); + const allPayments = await gfAll(paymentKeys); + let balance = 0; + for (const pay of allPayments) { + if (pay) balance += pay.amount; + } + balance = Math.max(balance, 0); + + return c.json({ + synced: newPayments.length, + received, + payments, + balance, + pending: pendingTotal, + }); + } finally { + await db.del(lockKey); + } + } catch (e) { + return bail(c, e.message); + } + }, }; diff --git a/routes/users.ts b/routes/users.ts index 6948fb28..027d836e 100644 --- a/routes/users.ts +++ b/routes/users.ts @@ -894,7 +894,7 @@ export default { await importAccountHistory(account); } - if (account.type === PaymentType.ark) { + if (account.type === PaymentType.ark || (account.pubkey && account.fingerprint)) { const paymentIds = (await db.lRange(`${aid}:payments`, 0, -1)) as string[]; const paymentKeys = paymentIds.map((pid) => `payment:${pid}`); const payments = await gfAll(paymentKeys); |
