diff options
| author | Adam Soltys <[email protected]> | 2023-01-08 21:05:34 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2023-01-08 21:05:34 -0800 |
| commit | dce07aa93b3c2f47aca0c24cea6adde9ec37f1a7 (patch) | |
| tree | 6c6b8930ebe9c2cc5b8d1f759e61260f509fdd7a /routes/liquid/send.js | |
| parent | f7b844883506a8072213245b9b8a2b988694e4f5 (diff) | |
| download | coinos-server-dce07aa93b3c2f47aca0c24cea6adde9ec37f1a7.tar.gz coinos-server-dce07aa93b3c2f47aca0c24cea6adde9ec37f1a7.zip | |
tech debt jubilee
Diffstat (limited to 'routes/liquid/send.js')
| -rw-r--r-- | routes/liquid/send.js | 276 |
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); - } -}; |
