aboutsummaryrefslogtreecommitdiffstats
path: root/lib/send.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2020-07-08 14:13:01 -0700
committerAdam Soltys <[email protected]>2020-07-08 14:13:01 -0700
commitc405440c832f54c98bae34b3f10506905199d5ce (patch)
tree155ff3e0568a03e943fe47ecd362147bd1aa1bf2 /lib/send.js
parent3dd0d83f3900818344e534681cf13155c210bd22 (diff)
downloadcoinos-server-c405440c832f54c98bae34b3f10506905199d5ce.tar.gz
coinos-server-c405440c832f54c98bae34b3f10506905199d5ce.zip
lnurl pay requests
Diffstat (limited to 'lib/send.js')
-rw-r--r--lib/send.js115
1 files changed, 115 insertions, 0 deletions
diff --git a/lib/send.js b/lib/send.js
new file mode 100644
index 00000000..2e04c5d4
--- /dev/null
+++ b/lib/send.js
@@ -0,0 +1,115 @@
+const bolt11 = require("bolt11");
+
+send = async (amount, hash, user) => {
+ let payreq = bolt11.decode(hash);
+
+ if (!amount) amount = payreq.satoshis;
+
+ l.info("attempting lightning payment", user.username, amount);
+
+ if (seen.includes(hash)) {
+ l.warn("attempted to pay a paid invoice", user.username);
+ throw new Error("Invoice has been paid, can't pay again");
+ }
+
+ await db.transaction(async (transaction) => {
+ let account = await db.Account.findOne({
+ where: {
+ user_id: user.id,
+ asset: config.liquid.btcasset,
+ },
+ lock: transaction.LOCK.UPDATE,
+ transaction,
+ });
+
+ if (account.balance < amount) {
+ throw new Error("Insufficient funds");
+ }
+
+ 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,
+ });
+
+ if (m.payment_error) throw new Error(m.payment_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 (seen.includes(preimage)) {
+ l.warn("duplicate payment detected", preimage);
+ throw new Error("Duplicate payment detected");
+ }
+
+ 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,
+ 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 });
+
+ emit(user.username, "account", payment.account);
+ emit(user.username, "payment", payment);
+
+ seen.push(preimage);
+ seen.push(hash);
+
+ l.info("sent lightning", user.username, total);
+ });
+};