aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/Image.svelte
blob: 4f8b39bb5d8bd22e28064eddab742f4b017cc2fc (plain) (blame)
1
2
3
4
5
6
<script>
  export let image;
  export let style;
</script>

<img src="/images/{image}.webp" alt={image} class={style} />
olor: #B06; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #369 } /* Name.Variable */ .highlight .ow { color: #080 } /* Operator.Word */ .highlight .w { color: #BBB } /* Text.Whitespace */ .highlight .mb { color: #00D; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #00D; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #00D; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #00D; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #00D; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #D20; background-color: #FFF0F0 } /* Literal.String.Affix */ .highlight .sb { color: #D20; background-color: #FFF0F0 } /* Literal.String.Backtick */ .highlight .sc { color: #D20; background-color: #FFF0F0 } /* Literal.String.Char */ .highlight .dl { color: #D20; background-color: #FFF0F0 } /* Literal.String.Delimiter */ .highlight .sd { color: #D20; background-color: #FFF0F0 } /* Literal.String.Doc */ .highlight .s2 { color: #D20; background-color: #FFF0F0 } /* Literal.String.Double */ .highlight .se { color: #04D; background-color: #FFF0F0 } /* Literal.String.Escape */ .highlight .sh { color: #D20; background-color: #FFF0F0 } /* Literal.String.Heredoc */ .highlight .si { color: #33B; background-color: #FFF0F0 } /* Literal.String.Interpol */ .highlight .sx { color: #2B2; background-color: #F0FFF0 } /* Literal.String.Other */ .highlight .sr { color: #080; background-color: #FFF0FF } /* Literal.String.Regex */ .highlight .s1 { color: #D20; background-color: #FFF0F0 } /* Literal.String.Single */ .highlight .ss { color: #A60; background-color: #FFF0F0 } /* Literal.String.Symbol */ .highlight .bp { color: #038 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #06B; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #369 } /* Name.Variable.Class */ .highlight .vg { color: #D70 } /* Name.Variable.Global */ .highlight .vi { color: #33B } /* Name.Variable.Instance */ .highlight .vm { color: #369 } /* Name.Variable.Magic */ .highlight .il { color: #00D; font-weight: bold } /* Literal.Number.Integer.Long */
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");
  }

  let payment;

    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 });

      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);

    });

      return payment;
};