diff options
| author | Adam Soltys <[email protected]> | 2020-05-07 20:15:56 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2020-05-07 20:58:24 -0700 |
| commit | 47aa48402a0d34dd8ab11f0f315393fcc4f5c61b (patch) | |
| tree | 2e907e64628d26c4707660e854e9bc87b332ff08 /routes | |
| parent | 2f0f9e640ead76518f7f8013b16704da89421ee4 (diff) | |
| download | coinos-server-47aa48402a0d34dd8ab11f0f315393fcc4f5c61b.tar.gz coinos-server-47aa48402a0d34dd8ab11f0f315393fcc4f5c61b.zip | |
c-lightning support
Diffstat (limited to 'routes')
| -rw-r--r-- | routes/balances.js | 22 | ||||
| -rw-r--r-- | routes/lightning/invoice.js | 20 | ||||
| -rw-r--r-- | routes/lightning/query.js | 28 | ||||
| -rw-r--r-- | routes/lightning/receive.js | 45 | ||||
| -rw-r--r-- | routes/lightning/send.js | 102 | ||||
| -rw-r--r-- | routes/lightning/user.js | 52 | ||||
| -rw-r--r-- | routes/payments.js | 14 |
7 files changed, 152 insertions, 131 deletions
diff --git a/routes/balances.js b/routes/balances.js index 9e57750b..78567c44 100644 --- a/routes/balances.js +++ b/routes/balances.js @@ -11,19 +11,33 @@ app.get("/info", async (req, res) => { group: ["asset"], }); + let lnchannel; + let lnwallet; + let lninfo; + + if (config.lna.clightning) { + lninfo = await lna.getinfo(); + const funds = await lna.listfunds(); + lnchannel = parseInt(funds.channels.reduce((a, b) => a + b.channel_sat, 0)); + lnwallet = parseInt(funds.outputs.reduce((a, b) => a + b.value, 0)); + } else { + lninfo = await lna.getInfo({}); + lnchannel = parseInt((await lna.channelBalance({})).balance); + lnwallet = parseInt((await lna.walletBalance({})).total_balance); + } + const info = { - lnd: await lna.getInfo({}), bitcoind: await bc.getNetworkInfo(), elementsd: await lq.getNetworkInfo(), accounts, assets, bitcoin: parseInt((await bc.getBalance()) * SATS), liquid: parseInt(assets.bitcoin * SATS), - lnchannel: parseInt((await lna.channelBalance({})).balance), - lnwallet: parseInt((await lna.walletBalance({})).total_balance), + lnchannel, + lnwallet, }; - const { bitcoin, liquid, lnchannel, user, lnwallet } = info; + const { bitcoin, liquid, user } = info; info.total = parseInt(bitcoin) + diff --git a/routes/lightning/invoice.js b/routes/lightning/invoice.js index f19b3484..3f4ab1db 100644 --- a/routes/lightning/invoice.js +++ b/routes/lightning/invoice.js @@ -3,9 +3,25 @@ module.exports = async (req, res) => { l.info("adding lightning invoice", req.user.username, amount, tip); + /* + const exists = await db.Invoice.findOne({ + where: { + [Op.or]: { + address: invoice.address || "undefined", + text: invoice.text + } + } + }); + */ + try { - const invoice = await lnb.addInvoice({ value: amount + tip }); - res.send(invoice.payment_request); + if (config.lna.clightning) { + const invoice = await lnb.invoice(`${amount + tip}sat` || "any", new Date(), "", 360); + res.send(invoice.bolt11); + } else { + const invoice = await lnb.addInvoice({ value: amount + tip }); + res.send(invoice.payment_request); + } } catch (e) { l.error("problem creating invoice", e.message); res.status(500).send(e.message); diff --git a/routes/lightning/query.js b/routes/lightning/query.js deleted file mode 100644 index 6e70f30a..00000000 --- a/routes/lightning/query.js +++ /dev/null @@ -1,28 +0,0 @@ -const bolt11 = require("bolt11"); - -module.exports = async (req, res) => { - let { amount, payreq } = req.body; - - try { - let invoice = await db.Invoice.findOne({ - where: { text: payreq }, - include: { - model: db.User, - as: "user" - } - }); - - if (invoice) emit(req.user.username, "to", invoice.user); - - payreq = bolt11.decode(payreq); - - res.send( - await lna.queryRoutes({ - pub_key: payreq.payeeNodeKey, - amt: amount || payreq.satoshis - }) - ); - } catch (e) { - res.status(500).send(e.message); - } -}; diff --git a/routes/lightning/receive.js b/routes/lightning/receive.js index 286541d2..3082c205 100644 --- a/routes/lightning/receive.js +++ b/routes/lightning/receive.js @@ -21,13 +21,15 @@ const handlePayment = async msg => { } }); + let preimage = msg.r_preimage.toString("hex"); + let payment = await db.Payment.create({ account_id: account.id, user_id, hash, amount, currency, - preimage: msg.r_preimage.toString('hex'), + preimage, rate, received: true, confirmed: true, @@ -54,12 +56,43 @@ const handlePayment = async msg => { "lightning payment received", user.username, payment.amount, - payment.tip, + payment.tip ); }; -const invoices = lna.subscribeInvoices({}); -invoices.on("data", handlePayment); +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); + + let settled = status === "paid"; + let amt_paid_sat = parseInt(msatoshi_received / 1000); + + await handlePayment({ + payment_request, + settled, + amt_paid_sat, + r_preimage + }); + wait(pay_index); + }; + + const { invoices } = await ln.listinvoices(); + wait(Math.max(...invoices.map(i => i.pay_index).filter(n => n))); + }; + + poll(lna); + poll(lnb); +} else { + const invoices = lna.subscribeInvoices({}); + invoices.on("data", handlePayment); -const invoicesb = lnb.subscribeInvoices({}); -invoicesb.on("data", handlePayment); + const invoicesb = lnb.subscribeInvoices({}); + invoicesb.on("data", handlePayment); +} diff --git a/routes/lightning/send.js b/routes/lightning/send.js index 2c17ba1f..e3b5c75a 100644 --- a/routes/lightning/send.js +++ b/routes/lightning/send.js @@ -30,57 +30,90 @@ module.exports = async (req, res) => { throw new Error("Insufficient funds"); } - let m = await lna.sendPaymentSync({ - amt: amount, - payment_request: hash, - max_parts: 10, - }); + let error, fee, total, preimage; + + if (config.lna.clightning) { + let m = await lna.pay(hash); + let sent; + ({ + msatoshi: total, + msatoshi_sent: sent, + payment_preimage: preimage + } = m); + + fee = parseInt((sent - total)/1000); + total = parseInt(total / 1000); + } else { + let m = await lna.sendPaymentSync({ + amt: amount, + payment_request: hash, + max_parts: 10 + }); + + ({ + payment_error: error, + payment_route: { total_fees: fee, total_amt: total }, + payment_preimage: preimage + } = m); + } + + preimage = preimage.toString("hex"); + + + if (payreq.payeeNodeKey === config.lnb.id) { + if (config.lna.clightning) { + let invoice = await lna.invoice(`${amount}sat` || "any", new Date(), "", 360); + let { bolt11: payment_request } = invoice; + await lnb.pay(payment_request); + } else { + let invoice = await lna.addInvoice({ value: amount }) + let { payment_request } = invoice; + await lnb.sendPaymentSync({ payment_request, max_parts: 10 }); + } + l.info("lnb sent back", amount); + } - if (m.payment_error) { - l.error("error sending lightning", m.payment_hash.toString('hex'), m.payment_error); - return res.status(500).send(m.payment_error); - } + if (error) { + l.error("error sending lightning", error); + return res.status(500).send(error); + } - if (seen.includes(m.payment_preimage)) { - l.warn("duplicate payment detected", m.payment_preimage); + if (seen.includes(preimage)) { + l.warn("duplicate payment detected", preimage); throw new Error("Duplicate payment detected"); } - let total = parseInt(m.payment_route.total_amt); - let fee = m.payment_route.total_fees; + total = parseInt(total); + fee = parseInt(fee); account.balance -= total; await account.save({ transaction }); - let payment = await db.Payment.create({ - amount: -total, - account_id: account.id, - user_id: user.id, - hash, - preimage: m.payment_preimage.toString("hex"), - rate: app.get("rates")[user.currency], - currency: user.currency, - confirmed: true, - network: "LNBTC" - }, { transaction }); + let payment = await db.Payment.create( + { + amount: -total, + account_id: account.id, + user_id: user.id, + hash, + preimage, + rate: app.get("rates")[user.currency], + currency: user.currency, + confirmed: true, + network: "LNBTC", + fee + }, + { transaction } + ); payment = payment.get({ plain: true }); payment.account = account.get({ plain: true }); - seen.push(m.payment_preimage); - l.info("sent lightning", user.username, -payment.amount); + seen.push(preimage); + l.info("sent lightning", user.username, total); user = await getUser(user.username, transaction); emit(user.username, "user", user); - l.info(config.lnb.id, payreq.payeeNodeKey); - if (payreq.payeeNodeKey === config.lnb.id) { - let invoice = await lna.addInvoice({ value: amount }) - let { payment_request } = invoice; - await lnb.sendPaymentSync({ payment_request, max_parts: 10 }); - l.info("lnb sending back", amount); - } - seen.push(hash); res.send(payment); }); @@ -88,7 +121,6 @@ module.exports = async (req, res) => { l.error( "problem sending lightning payment", user.username, - user.balance, e.message ); return res.status(500).send(e.message); diff --git a/routes/lightning/user.js b/routes/lightning/user.js deleted file mode 100644 index 41bd507f..00000000 --- a/routes/lightning/user.js +++ /dev/null @@ -1,52 +0,0 @@ -const bolt11 = require("bolt11"); - -module.exports = async (req, res) => { - let { payuser, amount } = req.body; - - let user = await db.User.findOne({ - where: { - username: payuser - } - }); - - const account = await db.Account.findOne({ - where: { - user_id: user.id, - asset: config.liquid.btcasset - } - }); - - l.info("paying user", req.user.username, payuser); - - if (!user) { - return res.status(500).send("Couldn't find the user you're trying to pay"); - } - let err = m => res.status(500).send(m); - - let invoice; - try { - invoice = await lnb.addInvoice({ value: amount }); - } catch (e) { - return err(e.message); - } - - let hash = invoice.payment_request; - - await db.Payment.create({ - user_id: user.id, - account_id: account.id, - hash, - amount, - rate: app.get("rates")[req.user.currency], - currency: req.user.currency, - tip: 0, - confirmed: true, - received: false, - network: "LNBTC" - }); - - req.url = "/lightning/send"; - let payreq = bolt11.decode(hash); - req.body.payreq = hash; - return app._router.handle(req, res); -}; diff --git a/routes/payments.js b/routes/payments.js index 4089ae23..04b5dc51 100644 --- a/routes/payments.js +++ b/routes/payments.js @@ -1,13 +1,21 @@ const BitcoinCore = require("bitcoin-core"); const lnd = require("../lib/lnd"); const { Op } = require("sequelize"); +const { join } = require("path"); (async () => { bc = new BitcoinCore(config.bitcoin); lq = new BitcoinCore(config.liquid); - lna = lnd(config.lna); - lnb = lnd(config.lnb); + if (config.lna.clightning) { + const lnapath = join(require('os').homedir(), '.lightningreg/regtest') + const lnbpath = join(require('os').homedir(), '.lightningregb/regtest') + lna = require('clightning-client')(lnapath); + lnb = require('clightning-client')(lnbpath); + } else { + lna = lnd(config.lna); + lnb = lnd(config.lnb); + } seen = []; addresses = {}; @@ -25,9 +33,7 @@ const { Op } = require("sequelize"); app.post("/send", auth, require("./send")); app.post("/lightning/invoice", auth, require("./lightning/invoice")); - app.post("/lightning/query", auth, require("./lightning/query")); app.post("/lightning/send", auth, require("./lightning/send")); - app.post("/lightning/user", auth, require("./lightning/user")); require("./lightning/receive"); app.post("/bitcoin/send", auth, require("./bitcoin/send")); |
