diff options
| -rwxr-xr-x | bun.lockb | bin | 208922 -> 208929 bytes | |||
| -rw-r--r-- | lib/invoices.ts | 5 | ||||
| -rw-r--r-- | lib/migrate.ts | 21 | ||||
| -rw-r--r-- | lib/payments.ts | 34 | ||||
| -rw-r--r-- | package.json | 2 | ||||
| -rw-r--r-- | routes/users.ts | 29 |
6 files changed, 47 insertions, 44 deletions
| Binary files differ diff --git a/lib/invoices.ts b/lib/invoices.ts index 4626e257..60bcba0f 100644 --- a/lib/invoices.ts +++ b/lib/invoices.ts @@ -30,13 +30,16 @@ export let generate = async ({ invoice, user }) => { secret, } = invoice; - let account = await g(`account:${aid}`); amount = parseInt(amount || 0); tip = parseInt(tip) || null; if (user) user = await getUser(user.username); if (!user) fail("user not provided"); + let account = await g(`account:${aid}`); + if (!account) account = await g(`account:${user.id}`); + if (!account) fail("account not found"); + let rates = await g("rates"); if (!currency) currency = user.currency; if (!rate) rate = rates[currency]; diff --git a/lib/migrate.ts b/lib/migrate.ts index d26c8581..1ff280ea 100644 --- a/lib/migrate.ts +++ b/lib/migrate.ts @@ -12,26 +12,7 @@ async function migrate(id) { let user = await g(`user:${id}`); if (typeof user === "string") user = await g(`user:${user}`); - - if (user) { - let k = `lock:${user.id}:accounts`; - const lock = await db.set(k, "1", { NX: true, PX: 5000 }); - if (!lock) return user; - try { - let accounts = await db.lLen(`${user.id}:accounts`); - - if (!accounts) { - await db.set( - `account:${user.id}`, - JSON.stringify({ id: user.id, name: "Cash", type: types.ecash }), - ); - await db.lPush(`${user.id}:accounts`, user.id); - } - return user; - } finally { - await db.del(k); - } - } + if (user) return user; user = await ga(`user:${id}`); diff --git a/lib/payments.ts b/lib/payments.ts index e2b44ea9..4bec9a93 100644 --- a/lib/payments.ts +++ b/lib/payments.ts @@ -40,6 +40,7 @@ export let types = { fund: "fund", liquid: "liquid", ecash: "ecash", + reconcile: "reconcile", }; export let debit = async ({ @@ -140,8 +141,8 @@ export let debit = async ({ export let credit = async ({ hash, amount, - memo = undefined, - ref = undefined, + memo = "", + ref = "", type = types.internal, aid = undefined, }) => { @@ -369,9 +370,7 @@ export let sendOnchain = async (params) => { let { tx, type } = await decode(hex); let node = - aid === user.id - ? rpc(config[type]) - : rpc({ ...config[type], wallet: aid }); + aid === user.id ? rpc(config[type]) : rpc({ ...config[type], wallet: aid }); let { txid } = tx; try { @@ -428,8 +427,7 @@ export let sendOnchain = async (params) => { } of tx.vout) { total += sats(value); let invoice = await g(`invoice:${address}`); - if (invoice?.aid === aid) - fail("Cannot send to internal address"); + if (invoice?.aid === aid) fail("Cannot send to internal address"); if ((await node.getAddressInfo(address)).ismine) { change += sats(value); @@ -604,12 +602,18 @@ export let sendLightning = async ({ } }; -export let sendInternal = async ({ amount, invoice = undefined, recipient, sender }) => { - if (!invoice) invoice = await generate({ - invoice: { amount, type: "lightning" }, - user: recipient, - sender, - }); +export let sendInternal = async ({ + amount, + invoice = undefined, + recipient, + sender, +}) => { + if (!invoice) + invoice = await generate({ + invoice: { amount, type: "lightning" }, + user: recipient, + sender, + }); let { hash } = invoice; let memo; @@ -644,9 +648,7 @@ export let build = async ({ let type = await getAddressType(address); if (!aid) aid = user.id; let node = - aid === user.id - ? rpc(config[type]) - : rpc({ ...config[type], wallet: aid }); + aid === user.id ? rpc(config[type]) : rpc({ ...config[type], wallet: aid }); amount = parseInt(amount); if (amount < 0) fail("invalid amount"); diff --git a/package.json b/package.json index e61ed771..50c6a0f4 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ }, "dependencies": { "@aws-sdk/client-ses": "^3.449.0", - "@cashu/cashu-ts": "github:cashubtc/cashu-ts#development", + "@cashu/cashu-ts": "^1.1.0", "@coinos/rpc": "^0.0.6", "@fastify/cors": "^8.3.0", "@fastify/http-proxy": "^9.5.0", diff --git a/routes/users.ts b/routes/users.ts index 9746f36a..06e437dd 100644 --- a/routes/users.ts +++ b/routes/users.ts @@ -1,7 +1,7 @@ import { appendFile } from "node:fs/promises"; import { g, s, db } from "$lib/db"; import config from "$config"; -import { pick, bail, fail, getUser } from "$lib/utils"; +import { SATS, pick, bail, fail, getUser } from "$lib/utils"; import jwt from "jsonwebtoken"; import { authenticator } from "otplib"; import whitelist from "$lib/whitelist"; @@ -10,7 +10,7 @@ import { emit } from "$lib/sockets"; import register from "$lib/register"; import { requirePin } from "$lib/auth"; import { v4 } from "uuid"; -import { types } from "$lib/payments"; +import { credit, types } from "$lib/payments"; import { bech32 } from "bech32"; import { mail, templates } from "$lib/mail"; import upload from "$lib/upload"; @@ -613,11 +613,11 @@ export default { async createAccount(req, res) { try { - let { fingerprint, pubkey, type, seed } = req.body; + let { fingerprint, pubkey, name, seed, type } = req.body; let { user } = req; let id = v4(); - let account = { id, seed, type }; + let account = { id, name, seed, type }; let node = rpc(config[type]); @@ -644,13 +644,30 @@ export default { } await node.importDescriptors(descriptors); + let { total_amount } = await node.scanTxOutSet("start", descriptors); + let amount = Math.round(total_amount * SATS); + + if (amount) { + let hash = v4(); + let inv = { + memo: "On-chain balance reconciliation", + type: types.reconcile, + hash, + amount, + uid: user.id, + aid: id, + }; + await s(`invoice:${hash}`, inv); + let { id: pid } = await credit({ hash, amount, type: types.reconcile }); + await db.lPush(`${id}:payments`, pid); + } await s(`account:${id}`, account); - await s(`balance:${id}`, 0); + await s(`balance:${id}`, amount); await s(`pending:${id}`, 0); await db.lPush(`${user.id}:accounts`, id); - await appendFile("/bitcoin.conf", `wallet=${id}`); + await appendFile("/bitcoin.conf", `wallet=${id}\n`); res.send(account); } catch (e) { |
