diff options
| author | Adam Soltys <[email protected]> | 2022-09-20 22:48:18 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2022-09-20 22:48:18 -0700 |
| commit | 4569736bac949bd2b06ce03b11299b11984e8d3c (patch) | |
| tree | d4e7c71c5be97903a43e0e25f816b2a4b9fde0a5 | |
| parent | f2fb6b587bb171101b0f91722c0c29e358b386e0 (diff) | |
| parent | b53875cf6bdf47c359139aa846c6597fa3627c87 (diff) | |
| download | coinos-server-4569736bac949bd2b06ce03b11299b11984e8d3c.tar.gz coinos-server-4569736bac949bd2b06ce03b11299b11984e8d3c.zip | |
Merge branch 'master' into prod
| -rw-r--r-- | Dockerfile | 2 | ||||
| -rw-r--r-- | db/models/users.js | 9 | ||||
| -rw-r--r-- | docker-compose.yml | 1 | ||||
| -rw-r--r-- | lib/binance.js | 3 | ||||
| -rw-r--r-- | lib/ln.js | 3 | ||||
| -rw-r--r-- | lib/send.js | 18 | ||||
| -rw-r--r-- | lib/sync.js | 131 | ||||
| -rw-r--r-- | lib/whitelist.js | 5 | ||||
| -rw-r--r-- | routes/info.js | 3 | ||||
| -rw-r--r-- | routes/lightning/channel.js | 7 | ||||
| -rw-r--r-- | routes/lightning/channelRequest.js | 3 | ||||
| -rw-r--r-- | routes/lightning/invoice.js | 3 | ||||
| -rw-r--r-- | routes/lightning/receive.js | 46 | ||||
| -rw-r--r-- | routes/lnurl.js | 23 | ||||
| -rw-r--r-- | routes/payments.js | 8 | ||||
| -rw-r--r-- | routes/send.js | 1 | ||||
| -rw-r--r-- | sampleconfig/index.js | 2 | ||||
| -rw-r--r-- | sampleconfig/knexfile.js | 2 |
18 files changed, 166 insertions, 104 deletions
@@ -4,7 +4,7 @@ ARG NODE_ENV=production ENV NODE_ENV $NODE_ENV RUN apk update -RUN apk add git inotify-tools +RUN apk add inotify-tools RUN apk add --update npm RUN npm i -g pnpm diff --git a/db/models/users.js b/db/models/users.js index cfd31cb7..7cbaf8e6 100644 --- a/db/models/users.js +++ b/db/models/users.js @@ -20,6 +20,15 @@ const attributes = { comment: null, field: "address" }, + theme: { + type: DataTypes.STRING, + allowNull: true, + defaultValue: false, + primaryKey: false, + autoIncrement: false, + comment: null, + field: "theme" + }, profile: { type: DataTypes.BOOLEAN, allowNull: true, diff --git a/docker-compose.yml b/docker-compose.yml index 4c432f83..d492d56d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -181,3 +181,4 @@ services: networks: default: name: net + external: true diff --git a/lib/binance.js b/lib/binance.js index af8d0b15..5eb2f286 100644 --- a/lib/binance.js +++ b/lib/binance.js @@ -27,7 +27,8 @@ export default () => { }; binance.onerror = async function(error) { - err("binance socket error", error); + console.log(error) + err("binance socket error", error.message); }; return binance; @@ -2,7 +2,8 @@ import config from "$config"; let ln; if (config.lna.clightning) { - ln = (await import("clightning-client"))(config.lna.dir); + let { LightningClient } = (await import("clightning-client")).default; + ln = new LightningClient(config.lna.dir); } else { ln = await import("./lnd"); } diff --git a/lib/send.js b/lib/send.js index 77d954f6..9d70b34e 100644 --- a/lib/send.js +++ b/lib/send.js @@ -9,6 +9,7 @@ import { conversionFeeReceiver } from "../routes/lightning/conversionFee"; import lnd from "$lib/lnd"; +import ln from "$lib/ln"; import { payViaPaymentRequest } from "lightning"; import { l, warn, err } from "$lib/logging"; @@ -89,7 +90,9 @@ export default async (amount, memo, hash, user) => { let tokens; if (!payreq.satoshis) tokens = amount; - let m = await payViaPaymentRequest({ + let m; + if (config.lnd) { + m = await payViaPaymentRequest({ lnd, request: hash, max_fee: Math.min(10000, account.balance) @@ -97,8 +100,19 @@ export default async (amount, memo, hash, user) => { if (!m) throw new Error(`lightning payment failed ${amount} ${hash}`); if (m.payment_error) throw new Error(m.payment_error); - ({ fee, secret: preimage, tokens: total } = m); + } else { + m = await ln.pay(hash, tokens ? `${tokens}sats` : undefined); + let sent; + ({ + msatoshi: total, + msatoshi_sent: sent, + payment_preimage: preimage + } = m); + + fee = parseInt((sent - total) / 1000); + total = parseInt(total / 1000); + } preimage = preimage.toString("hex"); diff --git a/lib/sync.js b/lib/sync.js index 467ce107..95abb99d 100644 --- a/lib/sync.js +++ b/lib/sync.js @@ -75,82 +75,85 @@ const sync = async () => { ] }); - let { invoices } = await getInvoices({ lnd, limit: 1000 }); + let missed, invoices; + if (config.lnd) { + ({ invoices } = await getInvoices({ lnd, limit: 1000 })); - let recent = invoices - .filter( - i => - i.is_confirmed && - differenceInDays(new Date(), new Date(i.created_at)) < 2 - ) - .map(i => ({ - amount: parseInt(i.received), - preimage: i.secret, - pr: i.request, - createdAt: new Date(i.created_at) - })); - - const twoDaysAgo = new Date(new Date().setDate(new Date().getDate() - 2)); - let settled = ( - await db.Payment.findAll({ - where: { network: "lightning", createdAt: { [Op.gt]: twoDaysAgo } }, - attributes: ["preimage"] - }) - ).map(p => p.preimage); + let recent = invoices + .filter( + i => + i.is_confirmed && + differenceInDays(new Date(), new Date(i.created_at)) < 2 + ) + .map(i => ({ + amount: parseInt(i.received), + preimage: i.secret, + pr: i.request, + createdAt: new Date(i.created_at) + })); - let missed = recent.filter(i => !settled.includes(i.preimage)); - for (let i = 0; i < missed.length; i++) { - let { amount, preimage, pr: text, createdAt } = missed[i]; - if (!text || !text.length) continue; + const twoDaysAgo = new Date(new Date().setDate(new Date().getDate() - 2)); + let settled = ( + await db.Payment.findAll({ + where: { network: "lightning", createdAt: { [Op.gt]: twoDaysAgo } }, + attributes: ["preimage"] + }) + ).map(p => p.preimage); - try { - let invoice = await db.Invoice.findOne({ - where: { text }, - include: { - model: db.User, - as: "user" - } - }); + missed = recent.filter(i => !settled.includes(i.preimage)); + for (let i = 0; i < missed.length; i++) { + let { amount, preimage, pr: text, createdAt } = missed[i]; + if (!text || !text.length) continue; - if (invoice && invoice.user_id) { - let account = await db.Account.findOne({ - where: { - user_id: invoice.user_id, - asset: config.liquid.btcasset, - pubkey: null + try { + let invoice = await db.Invoice.findOne({ + where: { text }, + include: { + model: db.User, + as: "user" } }); - if (account) { - let payment = await db.Payment.create({ - account_id: account.id, - user_id: invoice.user_id, - hash: text, - amount, - currency: invoice.currency, - preimage, - rate: invoice.rate, - received: true, - confirmed: true, - network: "lightning", - tip: invoice.tip, - invoice_id: invoice.id, - createdAt, - updatedAt: createdAt + if (invoice && invoice.user_id) { + let account = await db.Account.findOne({ + where: { + user_id: invoice.user_id, + asset: config.liquid.btcasset, + pubkey: null + } }); - await account.increment({ balance: amount }); + if (account) { + let payment = await db.Payment.create({ + account_id: account.id, + user_id: invoice.user_id, + hash: text, + amount, + currency: invoice.currency, + preimage, + rate: invoice.rate, + received: true, + confirmed: true, + network: "lightning", + tip: invoice.tip, + invoice_id: invoice.id, + createdAt, + updatedAt: createdAt + }); + + await account.increment({ balance: amount }); - l("lightning missing from account", account.id, amount); + l("lightning missing from account", account.id, amount); + } } + } catch (e) { + err( + "problem syncing lightning payment", + JSON.stringify(missed[i]), + e.message, + e.stack + ); } - } catch (e) { - err( - "problem syncing lightning payment", - JSON.stringify(missed[i]), - e.message, - e.stack - ); } } diff --git a/lib/whitelist.js b/lib/whitelist.js index a5c7a15f..d3e361d1 100644 --- a/lib/whitelist.js +++ b/lib/whitelist.js @@ -16,5 +16,8 @@ export default [ "keys", "index", "verified", - "email" + "email", + "profile", + "banner", + "theme" ]; diff --git a/routes/info.js b/routes/info.js index 63f353a5..fd77c5d1 100644 --- a/routes/info.js +++ b/routes/info.js @@ -6,6 +6,7 @@ import store from "$lib/store"; import bc from "$lib/bitcoin"; import lq from "$lib/liquid"; import lnd from "$lib/lnd"; +import ln from "$lib/ln"; import { getChannelBalance, getChainBalance } from "lightning"; import sequelize from "@sequelize/core"; @@ -50,7 +51,7 @@ app.get("/balances", async (req, res, next) => { if (config.lna) { if (config.lna.clightning) { - const funds = await lna.listfunds(); + const funds = await ln.listfunds(); lnchannel = parseInt( funds.channels.reduce((a, b) => a + b.channel_sat, 0) ); diff --git a/routes/lightning/channel.js b/routes/lightning/channel.js index 1c7bab10..107896f4 100644 --- a/routes/lightning/channel.js +++ b/routes/lightning/channel.js @@ -1,6 +1,7 @@ import axios from "axios"; import { addPeer, getIdentity } from "lightning"; import lnd from "$lib/lnd"; +import ln from "$lib/ln"; export default async (req, res) => { const { params } = req.body; @@ -24,7 +25,11 @@ export default async (req, res) => { const { callback, k1 } = params; let remoteid; try { - remoteid = (await getIdentity({ lnd })).public_key; + if (config.lna.clightning) { + remoteid = (await ln.getinfo()).id; + } else { + remoteid = (await getIdentity({ lnd })).public_key; + } } catch (e) { err("problem getting lightning node info", e.message); return res.code(500).send(e.message); diff --git a/routes/lightning/channelRequest.js b/routes/lightning/channelRequest.js index 530fad48..74e4cbba 100644 --- a/routes/lightning/channelRequest.js +++ b/routes/lightning/channelRequest.js @@ -1,6 +1,7 @@ import { lnurlServer } from "$routes/lnurl"; +import { err } from "$lib/logging"; -export default async (req, res) => { +export const channelRequest = async (req, res) => { let { localAmt, pushAmt } = req.body; pushAmt = 0; diff --git a/routes/lightning/invoice.js b/routes/lightning/invoice.js index 94aac768..94961b35 100644 --- a/routes/lightning/invoice.js +++ b/routes/lightning/invoice.js @@ -2,6 +2,7 @@ import config from "$config"; import { createInvoice } from "lightning"; import { err } from "$lib/logging"; import lnd from "$lib/lnd"; +import ln from "$lib/ln"; export default async (req, res) => { let { amount, memo, tip } = req.body; @@ -11,7 +12,7 @@ export default async (req, res) => { try { if (config.lna.clightning) { if (!memo) memo = "coinos"; - const invoice = await lna.invoice( + const invoice = await ln.invoice( value ? `${value}sat` : "any", new Date(), memo, diff --git a/routes/lightning/receive.js b/routes/lightning/receive.js index 56714da7..084161b5 100644 --- a/routes/lightning/receive.js +++ b/routes/lightning/receive.js @@ -8,11 +8,11 @@ import { computeConversionFee } from "./conversionFee"; import { sendLiquid } from "$routes/liquid/send"; import { subscribeToInvoices } from "lightning"; import lnd from "$lib/lnd"; +import ln from "$lib/ln"; import { l, err, warn } from "$lib/logging"; const handlePayment = async msg => { try { - console.log(msg) l("incoming lightning payment", msg.received); if (!msg.secret) return; @@ -134,29 +134,33 @@ const handlePayment = async msg => { if (config.lna.clightning) { const poll = async ln => { - const wait = async i => { - const { - bolt11: payment_request, - pay_index, - status, - msatoshi_received, - payment_preimage: r_preimage - } = await ln.waitanyinvoice(i); + try { + const wait = async i => { + const { + bolt11: request, + pay_index, + status, + msatoshi_received, + payment_preimage: secret + } = await ln.waitanyinvoice(i); + console.log("um"); - let settled = status === "paid"; - let amt_paid_sat = parseInt(msatoshi_received / 1000); + let settled = status === "paid"; + let received = parseInt(msatoshi_received / 1000); - await handlePayment({ - payment_request, - settled, - amt_paid_sat, - r_preimage - }); - wait(pay_index); - }; + await handlePayment({ + request, + received, + secret + }); + await wait(pay_index); + }; - const { invoices } = await ln.listinvoices(); - wait(Math.max(...invoices.map(i => i.pay_index).filter(n => n))); + const { invoices } = await ln.listinvoices(); + await wait(Math.max(...invoices.map(i => i.pay_index).filter(n => n))); + } catch (e) { + err("problem waiting for c-lightning invoice", e.message); + } }; poll(ln); diff --git a/routes/lnurl.js b/routes/lnurl.js index 547a41dd..fc2e5a52 100644 --- a/routes/lnurl.js +++ b/routes/lnurl.js @@ -91,7 +91,17 @@ app.post("/withdraw", auth, async (req, res, next) => { amount: value, params: { callback, k1 } } = req.body; - const invoice = await createInvoice({ lnd, value }); + + let invoice; + if (config.lna.clightning) { + let label = new Date(); + let desc = label; + + invoice = await ln.invoice(`${value}sats`, label, desc); + } else { + invoice = await createInvoice({ lnd, value }); + } + const { payment_request: pr } = invoice; const url = `${callback}?k1=${k1}&pr=${pr}`; @@ -260,6 +270,7 @@ app.get("/decode", async (req, res, next) => { } const { data: params } = await axios.get(url); + res.send(params); } catch (e) { err("problem decoding lnurl", e.message); @@ -366,8 +377,14 @@ lnurlServer.bindToHook( } try { - let decoded = await decodePaymentRequest({ lnd, request: pr }); - let amount = decoded.num_satoshis; + let amount; + + if (config.lna.clightning) { + let { msatoshi } = await ln.decodepay(pr); + amount = parseInt(msatoshi/1000); + } else { + ({ num_satoshis: amount } = await decodePaymentRequest({ lnd, request: pr })); + } let conversionFee = computeConversionFee(amount); await db.transaction(async transaction => { diff --git a/routes/payments.js b/routes/payments.js index 4ffeb6b3..fa7da641 100644 --- a/routes/payments.js +++ b/routes/payments.js @@ -62,10 +62,10 @@ app.post("/lightning/invoice", lnRoutes.invoice); app.post("/lightning/query", auth, lnRoutes.query); app.post("/lightning/send", auth, lnRoutes.send); -// if (config.lnurl) { -// let channelRequest = await import("$routes/lightning/channelRequest"); -// app.post("/lightning/channelRequest", channelRequest) -// } +if (config.lnurl) { + let { channelRequest } = await import("$routes/lightning/channelRequest"); + app.post("/lightning/channelRequest", channelRequest) +} app.post("/bitcoin/broadcast", optionalAuth, btcRoutes.broadcast); app.get("/bitcoin/generate", auth, btcRoutes.generate); diff --git a/routes/send.js b/routes/send.js index 360ad5b2..b57d8fc3 100644 --- a/routes/send.js +++ b/routes/send.js @@ -1,3 +1,4 @@ +import { err } from "$lib/logging"; import sendInternal from "$lib/sendInternal"; export default async (req, res, next) => { diff --git a/sampleconfig/index.js b/sampleconfig/index.js index 0896d541..e1478127 100644 --- a/sampleconfig/index.js +++ b/sampleconfig/index.js @@ -2,7 +2,7 @@ const db = { user: "root", password: "password", database: "coinos", - host: "mariadb", + host: "maria", dialect: "mariadb", dialectOptions: { multipleStatements: true, timezone: "Etc/GMT+7" } }; diff --git a/sampleconfig/knexfile.js b/sampleconfig/knexfile.js index 5eab5c09..dafb0d1c 100644 --- a/sampleconfig/knexfile.js +++ b/sampleconfig/knexfile.js @@ -4,7 +4,7 @@ export default { development: { client: "mysql2", connection: { - host: "mariadb", + host: "maria", database: "coinos", user: "root", password: "password" |
