From 80ae2ffb356a01da30c8c8d197cfc277a24674ef Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Thu, 5 Sep 2024 20:59:43 -0700 Subject: payments ts --- lib/payments.ts | 60 +++++++++++++++++++++++++++++++++++------------------- lib/rpc.ts | 4 ++-- routes/payments.ts | 3 ++- 3 files changed, 43 insertions(+), 24 deletions(-) diff --git a/lib/payments.ts b/lib/payments.ts index 797b3a97..f46a0a6a 100644 --- a/lib/payments.ts +++ b/lib/payments.ts @@ -21,11 +21,16 @@ import got from "got"; import { mqtt1, mqtt2 } from "$lib/mqtt"; import { mail, templates } from "$lib/mail"; import api from "$lib/api"; +import { bech32 } from "bech32"; +import rpc from "$lib/rpc"; -import lq from "$lib/liquid"; -import bc from "$lib/bitcoin"; +import lq_ from "$lib/liquid"; +import bc_ from "$lib/bitcoin"; import ln from "$lib/ln"; +let bc = bc_ as any; +let lq = lq_ as any; + let { URL } = process.env; export let types = { @@ -41,10 +46,10 @@ export let debit = async ({ hash, amount, fee = 0, - memo, + memo = undefined, user, type = types.internal, - rate, + rate = undefined, }) => { amount = parseInt(amount); if (type !== types.internal && (await g("freeze"))) @@ -53,8 +58,8 @@ export let debit = async ({ // fail(`⚡️${amount} exceeds max withdrawal of ⚡️1,000,000`); let ref; let { id: uid, currency } = user; - - let rates = await g('rates'); + + let rates = await g("rates"); if (!rate) rate = rates[currency]; let invoice = await getInvoice(hash); @@ -81,7 +86,9 @@ export let debit = async ({ if (!amount || amount < 0) fail("Amount must be greater than zero"); - let ourfee = [types.bitcoin, types.liquid, types.lightning].includes(type) + let ourfee: any = [types.bitcoin, types.liquid, types.lightning].includes( + type, + ) ? Math.round((amount + fee + tip) * config.fee) : 0; @@ -102,6 +109,7 @@ export let debit = async ({ amount: -amount, fee, hash, + hex: undefined, ourfee, memo, iid, @@ -145,14 +153,13 @@ export let credit = async (hash, amount, memo, ref, type = types.internal) => { let user = await g(`user:${inv.uid}`); let { id: uid, currency, username } = user; - let rates = await g('rates'); + let rates = await g("rates"); let rate = rates[currency]; if (!rate) await sleep(1000); rate = rates[currency]; - let equivalentRate = - inv.rate * (rates[currency] / rates[inv.currency]); + let equivalentRate = inv.rate * (rates[currency] / rates[inv.currency]); if (Math.abs(inv.rate / rates[inv.currency] - 1) < 0.01) { rate = equivalentRate; @@ -165,7 +172,7 @@ export let credit = async (hash, amount, memo, ref, type = types.internal) => { id, iid: inv.id, hash, - amount: parseInt(amount - tip), + amount: amount - tip, uid, rate, currency, @@ -175,6 +182,7 @@ export let credit = async (hash, amount, memo, ref, type = types.internal) => { type, confirmed: true, created: Date.now(), + items: undefined, }; if ([types.bitcoin, types.liquid].includes(type)) inv.pending += amount; @@ -303,15 +311,15 @@ let pay = async ({ amount, to, user }) => { lnurl = `https://${domain}/.well-known/lnurlp/${name}`; } else if (to.startsWith("lnurl")) { lnurl = Buffer.from( - bech32.fromWords(bech32.decode(text, 20000).words), + bech32.fromWords(bech32.decode(to, 20000).words), ).toString(); } let maxfee = getMaxFee(amount); if (lnurl) { amount -= maxfee; - let { callback } = await got(lnurl).json(); - ({ pr } = await got(`${callback}?amount=${amount * 1000}`).json()); + let { callback } = (await got(lnurl).json()) as any; + ({ pr } = (await got(`${callback}?amount=${amount * 1000}`).json()) as any); } else if (to.startsWith("ln")) { amount -= maxfee; pr = to; @@ -449,7 +457,13 @@ let getMaxFee = (n) => let checking = {}; let inflight = {}; -export let sendLightning = async ({ user, pr, amount, maxfee, memo }) => { +export let sendLightning = async ({ + user, + pr, + amount, + maxfee, + memo = undefined, +}) => { try { if (inflight[user.id]) fail("payment in flight"); inflight[user.id] = true; @@ -463,7 +477,7 @@ export let sendLightning = async ({ user, pr, amount, maxfee, memo }) => { } let total = amount; - let { amount_msat, payment_hash } = await ln.decode(pr); + let { amount_msat } = await ln.decode(pr); if (amount_msat) total = Math.round(amount_msat / 1000); maxfee = parseInt(maxfee) || getMaxFee(total); @@ -566,10 +580,14 @@ export let sendLightning = async ({ user, pr, amount, maxfee, memo }) => { } }; -export let getNode = (type) => { - if (type === types.bitcoin) return bc; - else if (type === types.liquid) return lq; - else fail("unrecognized transaction type"); +export let getNode = (type, wallet = undefined) => { + if (type === types.bitcoin) { + return bc; + } else if (type === types.liquid) { + return lq; + } else if (wallet) { + return rpc({ ...config.bitcoin, wallet }); + } else fail("unrecognized transaction type"); }; let getAddressType = async (a) => { @@ -593,7 +611,7 @@ export let build = async ({ amount, address, feeRate, user, subtract }) => { amount = parseInt(amount); if (amount < 0) fail("invalid amount"); - let fees = await fetch(`${api[type]}/fees/recommended`).then((r) => r.json()); + let fees: any = await fetch(`${api[type]}/fees/recommended`).then((r) => r.json()); if (!feeRate) { feeRate = fees.halfHourFee; diff --git a/lib/rpc.ts b/lib/rpc.ts index bcf695a4..0346a3cd 100644 --- a/lib/rpc.ts +++ b/lib/rpc.ts @@ -1,6 +1,6 @@ import got from "got"; -export default ({ host, port, wallet, username, password })=> +export default ({ host, port, wallet, username, password }) => new Proxy( {}, { @@ -23,6 +23,6 @@ export default ({ host, port, wallet, username, password })=> }) .json() .then(({ result }) => result); - })((prop as string).toLowerCase(), ...params), + })((prop as any).toLowerCase(), ...params), }, ); diff --git a/routes/payments.ts b/routes/payments.ts index 38215832..e7a4b851 100644 --- a/routes/payments.ts +++ b/routes/payments.ts @@ -253,7 +253,8 @@ export default { } = req; try { - let node = getNode(type); + let known = await g(`${wallet}:balance`) !== null + let node = getNode(type, known ? wallet : undefined); if (wallet === config.bitcoin.wallet || wallet === config.liquid.wallet) { let { confirmations, details } = await node.getTransaction(txid); -- cgit v1.2.3