diff options
| author | Dedan Kibere <[email protected]> | 2024-10-27 23:05:49 +0300 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-10-27 23:05:49 +0300 |
| commit | 87059fe805d3372263d26b391f8855139f84ad34 (patch) | |
| tree | 7099fbce72e7614c0c689d2f9a62e69f8b2e621a /routes | |
| parent | 041db323e4c23d87663bc29519af604137f3eb42 (diff) | |
| parent | d09712ef8f8ea8218ce229b233fc0013e6c06f7a (diff) | |
| download | coinos-server-87059fe805d3372263d26b391f8855139f84ad34.tar.gz coinos-server-87059fe805d3372263d26b391f8855139f84ad34.zip | |
Merge branch 'coinos:master' into master
Diffstat (limited to 'routes')
| -rw-r--r-- | routes/ecash.ts | 61 | ||||
| -rw-r--r-- | routes/invoices.ts | 6 | ||||
| -rw-r--r-- | routes/payments.ts | 188 | ||||
| -rw-r--r-- | routes/users.ts | 48 |
4 files changed, 157 insertions, 146 deletions
diff --git a/routes/ecash.ts b/routes/ecash.ts index 48b03fd3..cc617138 100644 --- a/routes/ecash.ts +++ b/routes/ecash.ts @@ -1,20 +1,20 @@ -import { g, s, db } from "$lib/db"; -import { get, claim, mint, check } from "$lib/ecash"; +import { db, g, s } from "$lib/db"; +import { check, claim, get, mint } from "$lib/ecash"; +import { err, l } from "$lib/logging"; +import { credit, debit, types } from "$lib/payments"; +import { emit } from "$lib/sockets"; import { bail, fail } from "$lib/utils"; -import { debit, credit, types } from "$lib/payments"; import { v4 } from "uuid"; -import { l, err } from "$lib/logging"; -import { emit } from "$lib/sockets"; -let { ecash: type } = types; +const { ecash: type } = types; export default { async save(req, res) { - let { + const { body: { token }, } = req; try { - let id = v4(); + const id = v4(); await s(`cash:${id}`, token); res.send({ id }); } catch (e) { @@ -24,12 +24,12 @@ export default { }, async get(req, res) { - let { + const { params: { id, version }, } = req; try { - let token = await get(id, version); - let status = await check(token); + const token = await get(id, version); + const status = await check(token); res.send({ token, status }); } catch (e) { err(e.message); @@ -38,17 +38,17 @@ export default { }, async claim(req, res) { - let { + const { body: { token }, user, } = req; try { - let amount = await claim(token); + const amount = await claim(token); let memo; - let hash = v4(); - let { currency, id: uid } = user; - let rates = await g("rates"); + const hash = v4(); + const { currency, id: uid } = user; + const rates = await g("rates"); await s(`invoice:${hash}`, { currency, id: hash, @@ -68,18 +68,17 @@ export default { }, async mint(req, res) { - let { + const { body: { amount }, user, } = req; try { - let id = v4(); - let hash = v4(); + const id = v4(); + const hash = v4(); - let memo, rate; - let p = await debit({ hash, amount, user, type, memo, rate }); - let token = await mint(amount); - p.memo = token; + const p = await debit({ hash, amount, user, type }); + const token = await mint(amount); + p.memo = id; await s(`payment:${p.id}`, p); s(`cash:${id}`, token); @@ -97,11 +96,11 @@ export default { } = req; try { amount = Math.round(amount / 1000); - let ref = preimage; - let { lightning: type } = types; + const ref = preimage; + const { lightning: type } = types; if (user.username !== "mint") fail("unauthorized"); - let { id: uid, currency } = user; - let ourfee = await db.debit( + const { id: uid, currency } = user; + const ourfee = await db.debit( `balance:${uid}`, `credit:${type}:${uid}`, amount || 0, @@ -110,13 +109,13 @@ export default { 0, ); - let rates = await g("rates"); - let rate = rates[currency]; + const rates = await g("rates"); + const rate = rates[currency]; if (ourfee.err) fail(ourfee.err); - let id = v4(); - let p = { + const id = v4(); + const p = { id, amount: -amount, hash, diff --git a/routes/invoices.ts b/routes/invoices.ts index acad5ce7..c571f4de 100644 --- a/routes/invoices.ts +++ b/routes/invoices.ts @@ -1,11 +1,11 @@ import { g } from "$lib/db"; import { generate } from "$lib/invoices"; -import { bail, pick } from "$lib/utils"; import { err } from "$lib/logging"; +import { bail, pick } from "$lib/utils"; export default { async get(req, res) { - let { + const { params: { id }, } = req; let invoice = await g(`invoice:${id}`); @@ -31,7 +31,7 @@ export default { async create(req, res) { let { body, user } = req; if (body.user) user = body.user; - let { invoice } = body; + const { invoice } = body; try { res.send(await generate({ invoice, user })); diff --git a/routes/payments.ts b/routes/payments.ts index 33f66e8d..4573ac4f 100644 --- a/routes/payments.ts +++ b/routes/payments.ts @@ -1,33 +1,33 @@ import config from "$config"; -import { emit } from "$lib/sockets"; -import { v4 } from "uuid"; +import api from "$lib/api"; +import { requirePin } from "$lib/auth"; import { db, g, s, t } from "$lib/db"; -import { l, err, warn } from "$lib/logging"; +import { err, l, warn } from "$lib/logging"; +import mqtt from "$lib/mqtt"; +import { + build, + completePayment, + credit, + debit, + decode, + sendInternal, + sendLightning, + sendOnchain, + types, +} from "$lib/payments"; +import { emit } from "$lib/sockets"; import { + SATS, bail, fail, getInvoice, getPayment, getUser, sats, - SATS, } from "$lib/utils"; -import { requirePin } from "$lib/auth"; -import { - completePayment, - decode, - debit, - credit, - types, - build, - sendInternal, - sendLightning, - sendOnchain, -} from "$lib/payments"; -import { mqtt1, mqtt2 } from "$lib/mqtt"; -import got from "got"; -import api from "$lib/api"; import rpc from "@coinos/rpc"; +import got from "got"; +import { v4 } from "uuid"; import ln from "$lib/ln"; @@ -37,16 +37,16 @@ export default { }, async create(req, res) { - let { body, user } = req; + const { body, user } = req; let { amount, hash, maxfee, fund, memo, payreq } = body; - let balance = await g(`balance:${user.id}`); + const balance = await g(`balance:${user.id}`); try { if (await g("freeze")) fail("Problem sending payment"); if (typeof amount !== "undefined") { amount = parseInt(amount); - if (amount < 0 || amount > SATS || isNaN(amount)) + if (amount < 0 || amount > SATS || Number.isNaN(amount)) fail("Invalid amount"); } @@ -92,7 +92,7 @@ export default { payments = ( await Promise.all( payments.map(async (pid) => { - let p = await g(`payment:${pid}`); + const p = await g(`payment:${pid}`); if (!p) { warn("user", id, "missing payment", pid); await db.lRem(`${aid || id}:payments`, 0, pid); @@ -107,9 +107,9 @@ export default { .filter((p) => p) .sort((a, b) => b.created - a.created); - let count = payments.length; + const count = payments.length; - let fn = (a, b) => ({ + const fn = (a, b) => ({ ...a, [b.currency]: { tips: (a[b.currency] ? a[b.currency].tips : 0) + (b.tip || 0), @@ -135,8 +135,8 @@ export default { }, }); - let incoming = payments.filter((p: any) => p.amount > 0).reduce(fn, {}); - let outgoing = payments.filter((p: any) => p.amount < 0).reduce(fn, {}); + const incoming = payments.filter((p: any) => p.amount > 0).reduce(fn, {}); + const outgoing = payments.filter((p: any) => p.amount < 0).reduce(fn, {}); if (limit) payments = payments.slice(offset, offset + limit); @@ -145,10 +145,10 @@ export default { async get(req, res) { try { - let { + const { params: { hash }, } = req; - let p = await getPayment(hash); + const p = await getPayment(hash); if (p.type === types.internal) p.with = await g(`user:${p.ref}`); res.send(p); } catch (e) { @@ -158,14 +158,14 @@ export default { }, async parse(req, res) { - let { + const { body: { payreq }, user, } = req; try { - let hour = 1000 * 60 * 60; + const hour = 1000 * 60 * 60; let nodes = await g("nodes"); - let { last } = nodes || {}; + const { last } = nodes || {}; if (!last || last > Date.now() - hour) { ({ nodes } = await ln.listnodes()); @@ -173,15 +173,15 @@ export default { await s("nodes", nodes); } - let decoded = await ln.decodepay(payreq); - let { amount_msat, payee } = decoded; - let node = nodes.find((n) => n.nodeid === payee); - let alias = node ? node.alias : payee.substr(0, 12); + const decoded = await ln.decodepay(payreq); + const { amount_msat, payee } = decoded; + const node = nodes.find((n) => n.nodeid === payee); + const alias = node ? node.alias : payee.substr(0, 12); - let amount = Math.round(amount_msat / 1000); + const amount = Math.round(amount_msat / 1000); let ourfee = Math.round(amount * config.fee); - let credit = await g(`credit:lightning:${user.id}`); - let covered = Math.min(credit, ourfee) || 0; + const credit = await g(`credit:lightning:${user.id}`); + const covered = Math.min(credit, ourfee) || 0; ourfee -= covered; res.send({ alias, amount, ourfee }); @@ -191,10 +191,10 @@ export default { }, async fund(req, res) { - let { + const { params: { name }, } = req; - let amount = await g(`fund:${name}`); + const amount = await g(`fund:${name}`); if (typeof amount === "undefined" || amount === null) return bail(res, "fund not found"); let payments = (await db.lRange(`fund:${name}:payments`, 0, -1)) || []; @@ -209,10 +209,10 @@ export default { }, async withdraw(req, res) { - let { + const { params: { name }, } = req; - let maxWithdrawable = await g(`fund:${name}`); + const maxWithdrawable = await g(`fund:${name}`); res.send({ tag: "withdrawRequest", callback: `${URL}/lnurlw/${name}`, @@ -239,8 +239,8 @@ export default { if (!iid) { iid = v4(); - let rates = await g("rates"); - let { currency } = user; + const rates = await g("rates"); + const { currency } = user; await s(`invoice:${iid}`, { currency, id: iid, @@ -251,7 +251,7 @@ export default { }); } - let payment = await credit({ + const payment = await credit({ hash: iid, amount, memo: id, @@ -268,23 +268,23 @@ export default { }, async confirm(req, res) { - let { + const { body: { txid, wallet, type }, } = req; try { - let node = rpc({ ...config[type], wallet }); - let { confirmations, details } = await node.getTransaction(txid); - let hot = wallet === config[type].wallet; + const node = rpc({ ...config[type], wallet }); + const { confirmations, details } = await node.getTransaction(txid); + const hot = wallet === config[type].wallet; let aid; if (!hot) aid = wallet; - for (let { address, amount, asset, category, vout } of details) { + for (const { address, amount, asset, category, vout } of details) { if (!address) continue; if (type === types.liquid && asset !== config.liquid.btc) continue; if (category === "send") { - let p = await getPayment(txid); + const p = await getPayment(txid); if (!p) continue; if (confirmations) { @@ -299,10 +299,10 @@ export default { continue; } - let p = await getPayment(`${txid}:${vout}`); + const p = await getPayment(`${txid}:${vout}`); if (!p) { - let invoice = await getInvoice(address); + const invoice = await getInvoice(address); if (!hot && aid !== invoice?.aid) continue; await credit({ hash: address, @@ -312,13 +312,13 @@ export default { aid, }); } else if (confirmations >= 1) { - let id = `payment:${txid}:${vout}`; - let p = await getPayment(`${txid}:${vout}`); + const id = `payment:${txid}:${vout}`; + const p = await getPayment(`${txid}:${vout}`); if (!p) return db.sAdd("missed", id); if (p.confirmed) return; - let invoice = await getInvoice(address); - let { id: iid } = invoice; + const invoice = await getInvoice(address); + const { id: iid } = invoice; p.confirmed = true; invoice.received += parseInt(invoice.pending); @@ -334,9 +334,8 @@ export default { .incrBy(`balance:${p.aid || p.uid}`, p.amount) .exec(); - emit(p.uid, "payment", p); - let user = await g(`user:${p.uid}`); - await completePayment(p, user); + const user = await g(`user:${p.uid}`); + await completePayment(invoice, p, user); } } res.send({}); @@ -348,7 +347,7 @@ export default { }, async fee(req, res) { - let { body, user } = req; + const { body, user } = req; try { res.send(await build({ ...body, user })); } catch (e) { @@ -366,12 +365,12 @@ export default { }, async send(req, res) { - let { body, user } = req; + const { body, user } = req; try { await requirePin({ body, user }); - let { hash: txid } = await sendOnchain({ ...body, user }); - let pid = await g(`payment:${txid}`); - let p = await g(`payment:${pid}`); + const { hash: txid } = await sendOnchain({ ...body, user }); + const pid = await g(`payment:${txid}`); + const p = await g(`payment:${pid}`); res.send(p); } catch (e) { @@ -382,7 +381,7 @@ export default { }, async freeze(req, res) { - let { + const { body: { secret }, } = req; try { @@ -396,23 +395,18 @@ export default { }, async print(req, res) { - let { + const { body: { id }, user, } = req; try { - let p = await g(`payment:${id}`); + const p = await g(`payment:${id}`); if (p.uid !== user.id) fail("unauthorized"); emit(user.id, "payment", p); - let { username } = user; - - mqtt1.publish( - username, - `pay:${p.amount}:${p.tip}:${p.rate}:${p.created}:${p.id}`, - ); + const { username } = user; - mqtt2.publish( + mqtt.publish( username, `pay:${p.amount}:${p.tip}:${p.rate}:${p.created}:${p.id}`, ); @@ -433,21 +427,21 @@ export default { lnaddress = decodeURIComponent(lnaddress); await requirePin({ body, user }); - let [username, domain] = lnaddress.split("@"); - let { minSendable, maxSendable, callback, metadata } = (await got( + const [username, domain] = lnaddress.split("@"); + const { minSendable, maxSendable, callback, metadata } = (await got( `https://${domain}/.well-known/lnurlp/${username}`, ).json()) as any; - let memo = metadata["text/plain"] || ""; + const memo = metadata["text/plain"] || ""; if (amount * 1000 < minSendable || amount * 1000 > maxSendable) fail("amount out of range"); - let r: any = await got(`${callback}?amount=${amount * 1000}`).json(); + const r: any = await got(`${callback}?amount=${amount * 1000}`).json(); if (r.reason) fail(r.reason); - let { pr } = r; + const { pr } = r; - let { payee } = await ln.decode(pr); - let { id } = await ln.getinfo(); + const { payee } = await ln.decode(pr); + const { id } = await ln.getinfo(); let p; if (payee === id) { @@ -463,7 +457,7 @@ export default { }, async gateway(req, res) { - let { + const { body: { short_channel_id, webhook }, } = req; @@ -472,24 +466,24 @@ export default { }, async replace(req, res) { - let { + const { body: { id }, user, } = req; try { - let p = await g(`payment:${id}`); + const p = await g(`payment:${id}`); if (!p) fail("Payment not found"); if (p.uid !== user.id) fail("unauthorized"); - let { tx, type } = await decode(p.hex); - let node = rpc(config[type]); + const { tx, type } = await decode(p.hex); + const node = rpc(config[type]); - let fees: any = await fetch(`${api[type]}/fees/recommended`).then((r) => + const fees: any = await fetch(`${api[type]}/fees/recommended`).then((r) => r.json(), ); - let outputs = []; - for (let { + const outputs = []; + for (const { scriptPubKey: { address }, value, } of tx.vout) { @@ -497,21 +491,21 @@ export default { outputs.push({ [address]: value }); } - let raw = await node.createRawTransaction(tx.vin, outputs); + const raw = await node.createRawTransaction(tx.vin, outputs); - let newTx = await node.fundRawTransaction(raw, { + const newTx = await node.fundRawTransaction(raw, { fee_rate: fees.fastestFee + 50, replaceable: true, subtractFeeFromOutputs: [], }); - let diff = sats(newTx.fee) - p.fee; + const diff = sats(newTx.fee) - p.fee; if (diff < 0) fail("fee must increase"); if (config[type].walletpass) await node.walletPassphrase(config[type].walletpass, 300); p.hex = (await node.signRawTransactionWithWallet(newTx.hex)).hex; - let r = await node.testMempoolAccept([p.hex]); + const r = await node.testMempoolAccept([p.hex]); if (!r[0].allowed) fail(`transaction rejected ${p.hex}`); warn("bump", user.username, p.hex); @@ -523,12 +517,12 @@ export default { }, async internal(req, res) { - let { + const { body: { username, amount }, user: sender, } = req; - let recipient = await getUser(username); + const recipient = await getUser(username); res.send(await sendInternal({ amount, sender, recipient })); }, }; diff --git a/routes/users.ts b/routes/users.ts index 5f6f0747..25a6a6d2 100644 --- a/routes/users.ts +++ b/routes/users.ts @@ -256,6 +256,7 @@ export default { "prompt", "profile", "pubkey", + "push", "reserve", "salt", "seed", @@ -340,21 +341,38 @@ export default { } }, - async subscribe(req, res) { - let { body, user } = req; - let { subscriptions } = user; - let { subscription } = body; - if (!subscriptions) subscriptions = []; - if ( - !subscriptions.find( - (s) => JSON.stringify(s) === JSON.stringify(subscription), - ) - ) - subscriptions.push(subscription); - user.subscriptions = subscriptions; - l("subscribing", user.username); - await user.save(); - res.sendStatus(201); + async subscriptions(req, res) { + try { + let { user } = req; + let subscriptions = await db.sMembers(`${user.id}:subscriptions`); + res.send(subscriptions); + } catch (e) { + bail(res, e.message); + } + }, + + async subscription(req, res) { + try { + let { subscription } = req.body; + let { id } = req.user; + await db.sAdd(`${id}:subscriptions`, JSON.stringify(subscription)); + res.send(subscription); + } catch (e) { + console.log(e); + bail(res, e.message); + } + }, + + async deleteSubscription(req, res) { + try { + let { subscription } = req.body; + let { id } = req.user; + await db.sRem(`${id}:subscriptions`, JSON.stringify(subscription)); + res.send(subscription); + } catch (e) { + console.log(e); + bail(res, e.message); + } }, async password(req, res) { |
