aboutsummaryrefslogtreecommitdiffstats
path: root/routes/liquid/send.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2023-01-08 21:05:34 -0800
committerAdam Soltys <[email protected]>2023-01-08 21:05:34 -0800
commitdce07aa93b3c2f47aca0c24cea6adde9ec37f1a7 (patch)
tree6c6b8930ebe9c2cc5b8d1f759e61260f509fdd7a /routes/liquid/send.js
parentf7b844883506a8072213245b9b8a2b988694e4f5 (diff)
downloadcoinos-server-dce07aa93b3c2f47aca0c24cea6adde9ec37f1a7.tar.gz
coinos-server-dce07aa93b3c2f47aca0c24cea6adde9ec37f1a7.zip
tech debt jubilee
Diffstat (limited to 'routes/liquid/send.js')
-rw-r--r--routes/liquid/send.js276
1 files changed, 0 insertions, 276 deletions
diff --git a/routes/liquid/send.js b/routes/liquid/send.js
deleted file mode 100644
index 83b5d6ca..00000000
--- a/routes/liquid/send.js
+++ /dev/null
@@ -1,276 +0,0 @@
-import db from "$db";
-import lq from "$lib/liquid";
-import { toSats } from "$lib/utils";
-import { emit } from "$lib/sockets";
-import store from "$lib/store";
-import config from "$config";
-import { l, warn, err } from "$lib/logging";
-import { liquidTx } from "$routes/liquid/fee";
-import { Transaction } from 'liquidjs-lib';
-import { requirePin } from "$lib/utils";
-
-import {
- computeConversionFee,
- conversionFeeReceiver
-} from "./conversionFee.js";
-
-const btc = config.liquid.btcasset;
-const lcad = config.liquid.cadasset;
-
-export const sendLiquid = async ({ asset, amount, user, address, memo, tx, limit }) => {
- try {
- l("sending liquid", amount, address);
- if (!tx) {
- ({ tx } = await liquidTx({
- address,
- asset,
- amount,
- feeRate: 200,
- replaceable: false,
- user
- }));
- }
-
- const isChange = async address =>
- (await lq.getAddressInfo(address)).ismine &&
- !Object.keys(store.addresses).includes(address);
-
- let totals = {};
- let change = {};
- let fee = 0;
-
- let { vout } = await lq.decodeRawTransaction(tx.hex);
-
- for (let i = 0; i < vout.length; i++) {
- let {
- asset,
- value,
- scriptPubKey
- } = vout[i];
-
- if (scriptPubKey.type === "fee") fee = toSats(value);
- else {
- if (!totals[asset]) totals[asset] = change[asset] = 0;
- totals[asset] += toSats(value);
-
- if (scriptPubKey.address) {
- if (await isChange(scriptPubKey.address)) {
- change[asset] += toSats(value);
- }
- }
- }
- }
-
- const assets = Object.keys(totals);
- const payments = [];
-
- let main, signed;
- await db.transaction(async transaction => {
- let fee_payment;
- let fee_payment_id = null;
-
- for (let i = 0; i < assets.length; i++) {
- let asset = assets[i];
- let amount = totals[asset];
- if (change[asset]) amount -= change[asset];
- let total = amount;
-
- if (asset === btc) {
- let covered = 0;
- let nonbtc = assets.filter(a => a !== btc);
- if (nonbtc.length === 1) {
- let faucet = await db.Account.findOne({
- where: {
- asset: nonbtc[0],
- user_id: null
- },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- if (faucet) {
- covered = faucet.balance;
- if (covered > fee) covered = fee;
- await faucet.decrement({ balance: covered }, { transaction });
- await faucet.reload({ transaction });
- await faucet.save({ transaction });
- }
- }
-
- total += fee - covered;
- }
-
- var conversionFee = computeConversionFee(amount);
-
- if (limit && total > limit + fee)
- throw new Error("Tx amount exceeds authorized amount");
-
- if (asset !== btc || total) {
- l("creating liquid payment", user.username, asset, total, fee);
-
- let account = await db.Account.findOne({
- where: {
- user_id: user.id,
- asset,
- pubkey: null
- },
- lock: transaction.LOCK.UPDATE,
- order: [["balance", "DESC"]],
- transaction
- });
-
- // use user's credits to reduce fee, if available
- let conversionFeeDeduction = Math.min(
- account.liquid_credits,
- conversionFee
- );
- if (conversionFeeDeduction) {
- await account.decrement(
- { liquid_credits: conversionFeeDeduction },
- { transaction }
- );
- await account.reload({ transaction });
- conversionFee -= conversionFeeDeduction;
- }
-
- if (asset !== btc) conversionFee = 0;
-
- if (total > account.balance) {
- warn("amount exceeds balance", {
- total,
- fee,
- balance: account.balance
- });
- throw new Error(
- `Insufficient funds, need ${total} ${
- account.ticker === "BTC" ? "SAT" : account.ticker
- }, have ${account.balance}`
- );
- } else if (total + conversionFee > account.balance) {
- warn("amount plus conversion fee exceeds balance", {
- total,
- fee,
- conversionFee,
- balance: account.balance
- });
- throw new Error(
- `Insufficient funds, need ${total + conversionFee} ${
- account.ticker === "BTC" ? "SAT" : account.ticker
- }, have ${account.balance}`
- );
- }
-
- await account.decrement(
- { balance: total + conversionFee },
- { transaction }
- );
- await account.reload({ transaction });
-
- let receiverAccount = await db.Account.findOne({
- where: {
- "$user.username$": conversionFeeReceiver
- },
- include: [
- {
- model: db.User,
- as: "user"
- }
- ],
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- if (conversionFee) {
- await receiverAccount.increment(
- { balance: conversionFee },
- { transaction }
- );
- await receiverAccount.reload({ transaction });
- fee_payment = {
- amount: conversionFee,
- fee: 0,
- memo: "Liquid conversion fee",
- account_id: receiverAccount.id,
- user_id: receiverAccount.user_id,
- rate: store.rates[receiverAccount.user.currency],
- currency: receiverAccount.user.currency,
- confirmed: true,
- received: true,
- network: "COINOS"
- };
- fee_payment.account = receiverAccount;
- ({ id: fee_payment_id } = await db.Payment.create(fee_payment, {
- transaction
- }));
- }
-
- let payment = {
- amount: -amount,
- account_id: account.id,
- fee,
- memo,
- user_id: user.id,
- rate: store.rates[user.currency],
- currency: user.currency,
- address,
- confirmed: true,
- received: false,
- network: "liquid",
- fee_payment_id
- };
-
- payment.account = account;
- payments.push(payment);
- }
- }
-
- signed = await lq.signRawTransactionWithWallet(
- await lq.blindRawTransaction(tx.hex)
- );
- let txid = Transaction.fromHex(signed.hex).getId();
-
- for (let i = 0; i < payments.length; i++) {
- let p = payments[i];
- if (p) {
- let { account } = p;
- p.hash = txid;
- p = await db.Payment.create(p, { transaction });
- if (p.user_id === user.id && (account.ticker !== "BTC" || !main)) {
- main = p.get({ plain: true });
- main.fee_payment = fee_payment;
- main.account = account.get({ plain: true });
- }
- }
- }
-
- emit(user.username, "account", main.account);
- emit(user.username, "payment", main);
- });
-
- if (config.liquid.walletpass)
- await lq.walletPassphrase(config.liquid.walletpass, 300);
-
- let txid = await lq.sendRawTransaction(signed.hex);
- l("sent liquid tx", txid, address);
-
- return main;
- } catch (e) {
- err("problem sending liquid", e.message);
- return e;
- }
-};
-
-export default async (req, res) => {
- let { user } = req;
-
- try {
- await requirePin(req);
- let result = await sendLiquid({ ...req.body, user })
- if (result instanceof Error) throw result;
- res.send(result);
- } catch (e) {
- console.log(e)
- err("problem sending liquid", user.username, e.message);
- return res.code(500).send(e);
- }
-};