aboutsummaryrefslogtreecommitdiffstats
path: root/routes/lightning/receive.js
blob: 719a8184d156397e669aec404599cfb22741c24f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
const asset = "LNBTC";

const handlePayment = async (msg) => {
  try {
    await db.transaction(async (transaction) => {
      if (!msg.settled) return;

      const invoice = await db.Invoice.findOne({
        where: {
          text: msg.payment_request,
        },
      });

      if (!invoice)
        return l.warn(
          "received lightning with no invoice",
          msg.payment_request
        );

      const { text: hash, currency, memo, rate, tip, user_id } = invoice;
      const amount = parseInt(msg.amt_paid_sat) - tip;

      const account = await db.Account.findOne({
        where: {
          user_id,
          asset: config.liquid.btcasset,
        },
        include: {
          model: db.User,
          as: "user",
        },
        lock: transaction.LOCK.UPDATE,
        transaction,
      });

      const { user } = account;

      let preimage = msg.r_preimage.toString("hex");

      let payment = await db.Payment.create(
        {
          account_id: account.id,
          user_id,
          hash,
          memo,
          amount,
          currency,
          preimage,
          rate,
          received: true,
          confirmed: true,
          network: "LNBTC",
          tip,
        },
        { transaction }
      );

      let total = amount + tip;
      invoice.received += total;
      account.balance += total;

      await account.save({ transaction });
      await invoice.save({ transaction });
      await payment.save({ transaction });
      payments.push(msg.payment_request);

      payment = payment.get({ plain: true });
      payment.account = account.get({ plain: true });

      emit(user.username, "payment", payment);
      emit(user.username, "account", payment.account);
      notify(user, `Received ${total} SAT`);

      l.info(
        "lightning payment received",
        user.username,
        payment.amount,
        payment.tip
      );
    });
  } catch (e) {
    l.error("problem receiving lightning payment", e.message);
  }
};

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);
} else {
  const invoices = lna.subscribeInvoices({});
  invoices.on("data", handlePayment);
}