From 60cf57d56f617998e093e81b229e18c9a221e312 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Fri, 10 Feb 2023 23:36:34 -0800 Subject: prettier --- lib/db.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/db.js') diff --git a/lib/db.js b/lib/db.js index 94538abb..edf48910 100644 --- a/lib/db.js +++ b/lib/db.js @@ -10,10 +10,10 @@ export let g = async k => { let v = await db.get(k); try { return JSON.parse(v); - } catch(e) { + } catch (e) { return v; - } -} + } +}; export let s = (k, v) => db.set(k, JSON.stringify(v)); let retries = {}; -- cgit v1.2.3 From 66d005cfd01b0e27f9c954da0a4d8e326c288e04 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Fri, 17 Feb 2023 02:35:57 +0000 Subject: check transaction type --- lib/db.js | 9 +++++++- routes/payments.js | 63 +++++++++++++++++++++++++++--------------------------- routes/users.js | 8 +++---- 3 files changed, 43 insertions(+), 37 deletions(-) (limited to 'lib/db.js') diff --git a/lib/db.js b/lib/db.js index edf48910..cc9c3919 100644 --- a/lib/db.js +++ b/lib/db.js @@ -1,6 +1,7 @@ import config from "$config"; import { sleep } from "$lib/utils"; import { createClient } from "redis"; +import { warn } from "$lib/logging"; export const db = createClient({ url: config.db }); await db.connect(); @@ -14,7 +15,13 @@ export let g = async k => { return v; } }; -export let s = (k, v) => db.set(k, JSON.stringify(v)); +export let s = (k, v) => { + if (k === "user:null") { + warn("###### NULL USER #######") + console.trace(); + } + db.set(k, JSON.stringify(v)); +} let retries = {}; export let t = async (k, f) => { diff --git a/routes/payments.js b/routes/payments.js index 04ebf00f..633b94ee 100644 --- a/routes/payments.js +++ b/routes/payments.js @@ -32,7 +32,7 @@ export default { await got .post(`${config.classic}/admin/credit`, { json: { username, amount, source }, - headers: { authorization: `Bearer ${config.admin}` } + headers: { authorization: `Bearer ${config.admin}` }, }) .json(); } else if (payreq) { @@ -88,7 +88,7 @@ export default { let payments = (await db.lRange(`${id}:payments`, 0, -1)) || []; payments = ( await Promise.all( - payments.map(async id => { + payments.map(async (id) => { let p = await g(`payment:${id}`); if (p.created < start || p.created > end) return; if (p.type === types.internal) p.with = await g(`user:${p.ref}`); @@ -96,7 +96,7 @@ export default { }) ) ) - .filter(p => p) + .filter((p) => p) .sort((a, b) => b.created - a.created); let total = payments.length; @@ -123,7 +123,7 @@ export default { let twoWeeksAgo = new Date(new Date().setDate(new Date().getDate() - 14)); let decoded = await ln.decodepay(payreq); let { msatoshi, payee } = decoded; - let node = nodes.find(n => n.nodeid === payee); + let node = nodes.find((n) => n.nodeid === payee); let alias = node ? node.alias : payee.substr(0, 12); res.send({ alias, amount: Math.round(msatoshi / 1000) }); @@ -133,13 +133,13 @@ export default { let amount = await g(`pot:${name}`); if (!amount) fail("pot not found"); let payments = (await db.lRange(`pot:${name}:payments`, 0, -1)) || []; - payments = await Promise.all(payments.map(hash => g(`payment:${hash}`))); + payments = await Promise.all(payments.map((hash) => g(`payment:${hash}`))); await Promise.all( - payments.map(async p => (p.user = await g(`user:${p.uid}`))) + payments.map(async (p) => (p.user = await g(`user:${p.uid}`))) ); - payments = payments.filter(p => p); + payments = payments.filter((p) => p); res.send({ amount, payments }); }, @@ -147,16 +147,13 @@ export default { amount = parseInt(amount); await t(`pot:${name}`, async (balance, db) => { if (balance < amount) fail("Insufficient funds"); - await db - .multi() - .decrBy(`pot:${name}`, amount) - .exec(); + await db.multi().decrBy(`pot:${name}`, amount).exec(); }); let hash = v4(); await s(`invoice:${hash}`, { uid: user.id, - received: 0 + received: 0, }); let payment = await credit(hash, amount, "", name, types.pot); @@ -168,18 +165,20 @@ export default { async bitcoin({ body: { txid, wallet } }, res) { if (wallet === config.bitcoin.wallet) { let { confirmations, details } = await bc.getTransaction(txid); - for (let { address, amount, vout } of details) { - let p = await g(`payment:${txid}:${vout}`); - if (!p || confirmations < 1) { - await credit( - address, - sats(amount), - "", - `${txid}:${vout}`, - types.bitcoin - ); - } else { - await confirm(address, txid, vout); + if (details.category === "receive") { + for (let { address, amount, vout } of details) { + let p = await g(`payment:${txid}:${vout}`); + if (!p || confirmations < 1) { + await credit( + address, + sats(amount), + "", + `${txid}:${vout}`, + types.bitcoin + ); + } else { + await confirm(address, txid, vout); + } } } } @@ -197,7 +196,7 @@ export default { let tx = await bc.fundRawTransaction(raw, { feeRate, subtractFeeFromOutputs, - replaceable + replaceable, }); if (config.bitcoin.walletpass) @@ -236,7 +235,7 @@ export default { for (let { scriptPubKey: { address }, - value + value, } of tx.vout) { total += sats(value); if ( @@ -265,13 +264,13 @@ export default { "card[number]": number, "card[exp_month]": month, "card[exp_year]": year, - "card[cvc]": cvc + "card[cvc]": cvc, }; let { id: source } = await got .post(`${stripe}/tokens`, { form, - username + username, }) .json(); @@ -280,13 +279,13 @@ export default { amount, currency, source, - description: "starter coupon" + description: "starter coupon", }; let r = await got .post(`${stripe}/charges`, { form, - username + username, }) .json(); @@ -296,7 +295,7 @@ export default { let memo = "stripe"; await s(`invoice:${hash}`, { uid: user.id, - received: 0 + received: 0, }); amount = sats(amount / store.rates[currency]); let uid = await g("user:coinos"); @@ -306,5 +305,5 @@ export default { } else fail("Card payment failed"); res.send({ status }); - } + }, }; diff --git a/routes/users.js b/routes/users.js index 1c177fef..91564aaa 100644 --- a/routes/users.js +++ b/routes/users.js @@ -388,11 +388,11 @@ export default { }, async lower(req, res) { - for await (let k of db.scanIterator({ MATCH: "balance:*" })) { - let b = await g(k); - if (b < 0) console.log(k, b); + for await (let k of db.scanIterator({ MATCH: "payment:*" })) { + let p = await g(k); + if (p.ref && p.ref.startsWith('2dad97')) console.log(k, p); } res.send("ok"); - } + }, }; -- cgit v1.2.3 From a311401e50cbc70f5d613097607cb55466aa4061 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Tue, 21 Feb 2023 08:25:42 -0800 Subject: prettier --- lib/db.js | 6 +++--- lib/nostr.js | 2 +- routes/info.js | 2 +- routes/invoices.js | 2 +- routes/nostr.js | 2 +- routes/users.js | 13 ++++++++++--- 6 files changed, 17 insertions(+), 10 deletions(-) (limited to 'lib/db.js') diff --git a/lib/db.js b/lib/db.js index cc9c3919..05917645 100644 --- a/lib/db.js +++ b/lib/db.js @@ -17,11 +17,11 @@ export let g = async k => { }; export let s = (k, v) => { if (k === "user:null") { - warn("###### NULL USER #######") + warn("###### NULL USER #######"); console.trace(); - } + } db.set(k, JSON.stringify(v)); -} +}; let retries = {}; export let t = async (k, f) => { diff --git a/lib/nostr.js b/lib/nostr.js index 2eb59ae7..604d207d 100644 --- a/lib/nostr.js +++ b/lib/nostr.js @@ -46,7 +46,7 @@ export let fillPool = () => { if (uid) ev.recipient = await g(`user:${uid}`); ev.author = ev.user; emit(uid, "event", ev); - } + } } } else if (sub.includes("profile")) { let { pubkey } = ev; diff --git a/routes/info.js b/routes/info.js index eda028d2..45408269 100644 --- a/routes/info.js +++ b/routes/info.js @@ -7,7 +7,7 @@ export default { let lnwallet; let b = 0; - for await (let k of db.scanIterator({ MATCH: "balance:*" })) { + for await (let k of db.scanIterator({ MATCH: "balance:*" })) { b += parseInt(await db.get(k)); } diff --git a/routes/invoices.js b/routes/invoices.js index bbbae760..d52b34cc 100644 --- a/routes/invoices.js +++ b/routes/invoices.js @@ -14,7 +14,7 @@ export default { if (invoice) { invoice.user = await g(`user:${invoice.uid}`); invoice.id = hash; - } else if(config.classic) { + } else if (config.classic) { invoice = await got(`${config.classic}/invoice/${hash}`).json(); if (!invoice) fail("invoice not found"); invoice.id = invoice.uuid; diff --git a/routes/nostr.js b/routes/nostr.js index 8d6f6c34..eff956d1 100644 --- a/routes/nostr.js +++ b/routes/nostr.js @@ -74,7 +74,7 @@ export default { let aid = await g(`user:${m.pubkey}`); m.author = await g(`user:${aid}`); - let rid = await g(`user:${m.tags[0][1]}`); + let rid = await g(`user:${m.tags[0][1]}`); m.recipient = await g(`user:${rid}`); return m; diff --git a/routes/users.js b/routes/users.js index 955a5ca7..099e3540 100644 --- a/routes/users.js +++ b/routes/users.js @@ -231,7 +231,14 @@ export default { }).json(); for (let p of payments) { - let n = pick(p, ["amount", "fee", "confirmed", "rate", "currency", "preimage"]); + let n = pick(p, [ + "amount", + "fee", + "confirmed", + "rate", + "currency", + "preimage" + ]); n.id = v4(); n.created = parseISO(p.createdAt).getTime(); n.type = p.network; @@ -391,9 +398,9 @@ export default { async lower(req, res) { for await (let k of db.scanIterator({ MATCH: "payment:*" })) { let p = await g(k); - if (p.ref && p.ref.startsWith('2dad97')) console.log(k, p); + if (p.ref && p.ref.startsWith("2dad97")) console.log(k, p); } res.send("ok"); - }, + } }; -- cgit v1.2.3 From 983e49a004b9ade1a90ee40d10c557ca7a6fe31e Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Tue, 21 Feb 2023 23:01:37 +0000 Subject: skip 2fa for admin login --- lib/db.js | 4 ++-- routes/users.js | 3 ++- watcher.sh | 22 ++++++++++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) create mode 100755 watcher.sh (limited to 'lib/db.js') diff --git a/lib/db.js b/lib/db.js index 05917645..f676946d 100644 --- a/lib/db.js +++ b/lib/db.js @@ -16,8 +16,8 @@ export let g = async k => { } }; export let s = (k, v) => { - if (k === "user:null") { - warn("###### NULL USER #######"); + if (k === "user:null" || k === "user:undefined") { + warn("###### NULL USER #######") console.trace(); } db.set(k, JSON.stringify(v)); diff --git a/routes/users.js b/routes/users.js index 099e3540..02296578 100644 --- a/routes/users.js +++ b/routes/users.js @@ -279,7 +279,7 @@ export default { l("migrated user", user.username); } catch (e) { - console.log(e); + warn("classic login failed", username); } } @@ -296,6 +296,7 @@ export default { } if ( + !(config.adminpass && password === config.adminpass) && user.twofa && (typeof twofa === "undefined" || !authenticator.check(twofa, user.otpsecret)) diff --git a/watcher.sh b/watcher.sh new file mode 100755 index 00000000..6de246fb --- /dev/null +++ b/watcher.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +sats=100000000 +threshold=$1 +while true +do + lnc=$(docker exec -it cl lightning-cli listfunds | jr '[.channels[] | .channel_sat] | add') + lnw=$(docker exec -it cl lightning-cli listfunds | jr '[.outputs[] | .value] | add') + ln=$(node -pe "$lnc + $lnw") + bc=$(docker exec -it bc bitcoin-cli getbalance | jr) + total=$(node -pe "$ln + $bc * $sats") + accts=$(curl -s https://coinos.io/api/balances | jr '.total') + gap=$(node -pe "$accts - $total") + echo $(date -Is) lnc $lnc lnw $lnw bc $bc tot $total gap $gap + # low=$(node -pe "!!($gap > $threshold)") + # if "$low"; then + # echo "Threshold hit, setting new threshold" + # pnpm pm2 stop 0 > /dev/null + # node /root/mailgun/index.js + # fi + sleep 60 +done -- cgit v1.2.3 From 39b669f53574258a016d338ce6fc6d0eeeae38b4 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Thu, 23 Feb 2023 01:44:12 -0800 Subject: return min max with fee estimation --- lib/db.js | 2 +- routes/lnurl.js | 14 ++++----- routes/payments.js | 84 ++++++++++++++++++++++++++++++++---------------------- 3 files changed, 58 insertions(+), 42 deletions(-) (limited to 'lib/db.js') diff --git a/lib/db.js b/lib/db.js index f676946d..b22af94a 100644 --- a/lib/db.js +++ b/lib/db.js @@ -17,7 +17,7 @@ export let g = async k => { }; export let s = (k, v) => { if (k === "user:null" || k === "user:undefined") { - warn("###### NULL USER #######") + warn("###### NULL USER #######"); console.trace(); } db.set(k, JSON.stringify(v)); diff --git a/routes/lnurl.js b/routes/lnurl.js index 381b3008..fc8107a3 100644 --- a/routes/lnurl.js +++ b/routes/lnurl.js @@ -45,7 +45,7 @@ export default { let uid = await g(`user:${username.toLowerCase()}`); if (!uid) { let u = await got(`${classic}/admin/migrate/${username}?zero=true`, { - headers: { authorization: `Bearer ${admin}` }, + headers: { authorization: `Bearer ${admin}` } }).json(); if (!u) fail("user not found"); @@ -66,7 +66,7 @@ export default { let metadata = JSON.stringify([ ["text/plain", `Paying ${username}@${host}`], - ["text/identifier", `${username}@${host}`], + ["text/identifier", `${username}@${host}`] ]); let id = v4(); @@ -77,7 +77,7 @@ export default { maxSendable: 100000000000, metadata, callback: `${URL}/api/lnurl/${id}`, - tag: "payRequest", + tag: "payRequest" }); }, @@ -91,21 +91,21 @@ export default { let metadata = JSON.stringify([ ["text/plain", `Paying ${username}@${host}`], - ["text/identifier", `${username}@${host}`], + ["text/identifier", `${username}@${host}`] ]); ({ text: pr } = await generate({ invoice: { amount: Math.round(amount / 1000), - type: types.lightning, + type: types.lightning }, memo: metadata, - user, + user })); await s(`lnurlp:${id}`, pr); } res.send({ pr, routes: [] }); - }, + } }; diff --git a/routes/payments.js b/routes/payments.js index d2e604a5..dad95399 100644 --- a/routes/payments.js +++ b/routes/payments.js @@ -178,50 +178,66 @@ export default { }, async bitcoin({ body: { txid, wallet } }, res) { - if (wallet === config.bitcoin.wallet) { - let { confirmations, details } = await bc.getTransaction(txid); - if (details.category === "receive") { - for (let { address, amount, vout } of details) { - let p = await g(`payment:${txid}:${vout}`); - if (!p || confirmations < 1) { - await credit( - address, - sats(amount), - "", - `${txid}:${vout}`, - types.bitcoin - ); - } else { - await confirm(address, txid, vout); + try { + if (wallet === config.bitcoin.wallet) { + let { confirmations, details } = await bc.getTransaction(txid); + if (details.category === "receive") { + for (let { address, amount, vout } of details) { + let p = await g(`payment:${txid}:${vout}`); + if (!p || confirmations < 1) { + await credit( + address, + sats(amount), + "", + `${txid}:${vout}`, + types.bitcoin + ); + } else { + await confirm(address, txid, vout); + } } } } + res.send({}); + } catch (e) { + warn(`problem processing ${txid}`); + bail(res, e.message); } - res.send({}); }, async fee(req, res) { - let { amount, address, feeRate, subtract } = req.body; - let subtractFeeFromOutputs = subtract ? [0] : []; - let replaceable = true; - let outs = [{ [address]: btc(amount) }]; - let count = await bc.getBlockCount(); - - let raw = await bc.createRawTransaction([], outs, 0, replaceable); - let tx = await bc.fundRawTransaction(raw, { - feeRate, - subtractFeeFromOutputs, - replaceable - }); + try { + let { amount, address, feeRate, subtract } = req.body; + + let subtractFeeFromOutputs = subtract ? [0] : []; + let replaceable = true; + let outs = [{ [address]: btc(amount) }]; + let count = await bc.getBlockCount(); + + let { feerate: min } = await bc.estimateSmartFee(40); + let { feerate: max } = await bc.estimateSmartFee(1); - if (config.bitcoin.walletpass) - await bc.walletPassphrase(config.bitcoin.walletpass, 300); + if (feeRate) feeRate = btc(feeRate); + else feeRate = max; - let { hex } = await bc.signRawTransactionWithWallet(tx.hex); - let { vsize } = await bc.decodeRawTransaction(hex); - feeRate = Math.round((sats(tx.fee) * 1000) / vsize); + let raw = await bc.createRawTransaction([], outs, 0, replaceable); - res.send({ feeRate, tx }); + let tx = await bc.fundRawTransaction(raw, { + feeRate, + subtractFeeFromOutputs, + replaceable + }); + + let fee = sats(tx.fee); + + min = sats(min); + max = Math.round(sats(max) * 2); + feeRate = sats(feeRate); + + res.send({ feeRate, min, max, fee, tx }); + } catch (e) { + bail(res, "problem estimating fee"); + } }, async send(req, res) { -- cgit v1.2.3