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/receive.js | |
| parent | f7b844883506a8072213245b9b8a2b988694e4f5 (diff) | |
| download | coinos-server-dce07aa93b3c2f47aca0c24cea6adde9ec37f1a7.tar.gz coinos-server-dce07aa93b3c2f47aca0c24cea6adde9ec37f1a7.zip | |
tech debt jubilee
Diffstat (limited to 'routes/liquid/receive.js')
| -rw-r--r-- | routes/liquid/receive.js | 406 |
1 files changed, 0 insertions, 406 deletions
diff --git a/routes/liquid/receive.js b/routes/liquid/receive.js deleted file mode 100644 index 718feba5..00000000 --- a/routes/liquid/receive.js +++ /dev/null @@ -1,406 +0,0 @@ -import db from "$db"; -import config from "$config"; -import { getBlockHeight, getUser, getUserById, toSats, SATS } from "$lib/utils"; -import { emit } from "$lib/sockets"; -import store from "$lib/store"; -import { sendLiquid } from "$routes/liquid/send"; -import { notify } from "$lib/notifications"; -import { callWebhook } from "$lib/webhooks"; -import reverse from "buffer-reverse"; -import zmq from "zeromq/v5-compat"; -import { Op } from "@sequelize/core"; -import { fromBase58 } from "bip32"; -import bitcoin from "bitcoinjs-lib"; -import liquidJs from "liquidjs-lib"; -import { l, err, warn } from "$lib/logging"; -import lq from "$lib/liquid"; - -const { Block, networks, Transaction } = liquidJs; - -const network = - networks[ - config.liquid.network === "mainnet" ? "liquid" : config.liquid.network - ]; - -import { computeConversionFee } from "./conversionFee"; - -const getAccount = async (params, transaction) => { - let account = await db.Account.findOne({ - where: params, - lock: transaction.LOCK.UPDATE, - transaction - }); - - if (account) { - l("found account", params, account.asset, account.id); - return account; - } - - let { asset, pubkey } = params; - let name = asset.substr(0, 6); - let domain = ""; - let ticker = asset.substr(0, 3).toUpperCase(); - let precision = 8; - - if (pubkey) { - const nc = await db.Account.findOne({ - where: { pubkey }, - order: [["id", "ASC"]], - limit: 1, - lock: transaction.LOCK.UPDATE, - transaction - }); - - params.index = 0; - params.path = nc.path; - params.pubkey = nc.pubkey; - params.privkey = nc.privkey; - params.seed = nc.seed; - } - - if (store.assets[asset]) { - ({ domain, ticker, precision, name } = store.assets[asset]); - } else { - const existing = await db.Account.findOne({ - where: { - asset - }, - order: [["id", "ASC"]], - limit: 1, - lock: transaction.LOCK.UPDATE, - transaction - }); - - if (existing) { - l("existing", existing.id); - ({ domain, ticker, precision, name } = existing); - } - } - - params = { ...params, ...{ domain, ticker, precision, name } }; - params.balance = 0; - params.pending = 0; - params.network = "liquid"; - return db.Account.create(params, { transaction }); -}; - -const zmqRawBlock = zmq.socket("sub"); -zmqRawBlock.connect(config.liquid.zmqrawblock); -zmqRawBlock.subscribe("rawblock"); - -const zmqRawTx = zmq.socket("sub"); -zmqRawTx.connect(config.liquid.zmqrawtx); -zmqRawTx.subscribe("rawtx"); - -const queue = {}; -const seen = []; - -zmqRawTx.on("message", async (topic, message, sequence) => { - try { - const hex = message.toString("hex"); - - let unblinded, tx, blinded, txid; - try { - txid = Transaction.fromHex(hex).getId(); - if (seen.includes(txid)) return; - seen.push(txid); - if (seen.length > 5000) seen.shift(); - - unblinded = await lq.unblindRawTransaction(hex); - tx = await lq.decodeRawTransaction(unblinded.hex); - blinded = await lq.decodeRawTransaction(hex); - } catch (e) { - return err("problem decoding liquid tx", e.message); - } - - for (let o of tx.vout) { - try { - if (!(o.scriptPubKey && o.scriptPubKey.address)) return; - - const { asset } = o; - const value = toSats(o.value); - const { address } = o.scriptPubKey; - - if ( - Object.keys(store.addresses).includes(address) && - !store.change.includes(address) - ) { - await db.transaction(async transaction => { - let user = await getUser(store.addresses[address], transaction); - - let invoice = await db.Invoice.findOne({ - where: { - [Op.or]: { - unconfidential: address, - address - }, - user_id: user.id, - network: "liquid" - }, - order: [["id", "DESC"]], - transaction - }); - - if (!invoice) return; - - let confirmed = 0; - - let account = await db.Account.findOne({ - where: { - id: invoice.account_id, - asset - }, - lock: transaction.LOCK.UPDATE, - transaction - }); - - if (!account) { - let pubkey = account ? account.pubkey : null; - - account = await getAccount( - { - user_id: user.id, - asset, - pubkey - }, - transaction - ); - } - - await account.increment({ pending: value }, { transaction }); - await account.reload({ transaction }); - - if (config.liquid.walletpass) - await lq.walletPassphrase(config.liquid.walletpass, 300); - - await user.save({ transaction }); - - const currency = invoice ? invoice.currency : user.currency; - const rate = invoice ? invoice.rate : store.rates[user.currency]; - const tip = invoice ? invoice.tip : 0; - const memo = invoice ? invoice.memo : ""; - - let payment = await db.Payment.create( - { - account_id: account.id, - user_id: user.id, - hash: blinded.txid, - amount: value - tip, - currency, - memo, - rate, - received: true, - tip, - confirmed, - address, - network: "liquid", - invoice_id: invoice.id - }, - { transaction } - ); - - payment = payment.get({ plain: true }); - payment.account = account.get({ plain: true }); - payment.invoice = invoice.get({ plain: true }); - - emit(user.username, "payment", payment); - emit(user.username, "account", payment.account); - l("liquid detected", address, user.username, asset, value); - notify(user, `${value} SAT payment detected`); - callWebhook(invoice, payment); - }); - } - } catch (e) { - console.log(e); - err("Problem processing transaction", e.message, e.stack); - } - } - } catch (e) { - console.log(e); - } -}); - -zmqRawBlock.on("message", async (topic, message, sequence) => { - try { - const payments = await db.Payment.findAll({ - where: { confirmed: 0 } - }); - - let hash, json; - - hash = await lq.getBlockHash(getBlockHeight(message)); - json = await lq.getBlock(hash, 2); - - for (let tx of json.tx) { - if (store.issuances[tx.txid]) { - await db.transaction(async transaction => { - const { - user_id, - asset, - asset_amount, - asset_payment_id, - token, - token_amount, - token_payment_id - } = store.issuances[tx.txid]; - - const user = await getUserById(user_id); - - let account = await db.Account.findOne({ - where: { user_id, asset }, - lock: transaction.LOCK.UPDATE, - transaction - }); - account.balance = Math.round(asset_amount * SATS); - account.pending = 0; - await account.save({ transaction }); - - let payment = await db.Payment.findOne({ - where: { id: asset_payment_id }, - include: { - model: db.Account, - as: "account" - }, - lock: transaction.LOCK.UPDATE, - transaction - }); - - payment.confirmed = true; - await payment.save({ transaction }); - payment = payment.get({ plain: true }); - payment.account = account.get({ plain: true }); - - emit(user.username, "account", account); - emit(user.username, "payment", payment); - - if (token) { - account = await db.Account.findOne({ - where: { user_id, asset: token }, - lock: transaction.LOCK.UPDATE, - transaction - }); - account.balance = token_amount * SATS; - account.pending = 0; - await account.save({ transaction }); - - payment = await db.Payment.findOne({ - where: { id: token_payment_id }, - include: { - model: db.Account, - as: "account" - }, - lock: transaction.LOCK.UPDATE, - transaction - }); - - payment.confirmed = true; - await payment.save({ transaction }); - - payment = payment.get({ plain: true }); - payment.account = account.get({ plain: true }); - - emit(user.username, "account", account); - emit(user.username, "payment", payment); - } - }); - } else if (payments.find(p => p.hash === tx.txid)) queue[tx.txid] = 1; - } - } catch (e) { - return console.log(e); - } -}); - -setInterval(async () => { - try { - const arr = Object.keys(queue); - - for (let i = 0; i < arr.length; i++) { - const hash = arr[i]; - - let account, invoice, address, user, total, p; - await db.transaction(async transaction => { - p = await db.Payment.findOne({ - where: { hash, confirmed: 0, received: 1 }, - include: [ - { - model: db.Account, - as: "account" - }, - { - model: db.Invoice, - as: "invoice" - }, - { - model: db.User, - as: "user" - } - ], - lock: transaction.LOCK.UPDATE, - transaction - }); - - if (p && p.address) address = p.address; - if (p && p.user) user = p.user; - - if (p && p.account) { - ({ account, invoice } = p); - total = p.amount + p.tip; - p.confirmed = 1; - await account.save({ transaction }); - - await invoice.increment({ received: total }, { transaction }); - await account.increment({ balance: total }, { transaction }); - await account.decrement( - { pending: Math.min(account.pending, total) }, - { transaction } - ); - await account.increment( - { liquid_credits: computeConversionFee(total) }, - { transaction } - ); - await account.reload({ transaction }); - await invoice.reload({ transaction }); - - await p.save({ transaction }); - - p = p.get({ plain: true }); - account = account.get({ plain: true }); - invoice = invoice.get({ plain: true }); - - emit(user.username, "account", account); - emit(user.username, "payment", p); - - l("liquid confirmed", user.username, account.asset, p.amount, p.tip); - - notify(user, `${total} SAT payment confirmed`); - callWebhook(p.invoice, p); - } else { - warn("couldn't find liquid payment", hash); - } - - delete queue[hash]; - }); - - let c = store.convert[address]; - if (address && c && p.account.asset === network.assetHash) { - l( - "liquid detected for conversion request", - address, - c.address, - user.username - ); - - user.account = p.account; - - sendLiquid({ - address: c.address, - amount: total - 100, - user, - limit: total - }); - } - } - } catch (e) { - err("problem processing queued liquid transaction", e.message, e.stack); - } -}, 1000); |
