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/assets.js | |
| parent | f7b844883506a8072213245b9b8a2b988694e4f5 (diff) | |
| download | coinos-server-dce07aa93b3c2f47aca0c24cea6adde9ec37f1a7.tar.gz coinos-server-dce07aa93b3c2f47aca0c24cea6adde9ec37f1a7.zip | |
tech debt jubilee
Diffstat (limited to 'routes/assets.js')
| -rw-r--r-- | routes/assets.js | 536 |
1 files changed, 0 insertions, 536 deletions
diff --git a/routes/assets.js b/routes/assets.js deleted file mode 100644 index ed0d3036..00000000 --- a/routes/assets.js +++ /dev/null @@ -1,536 +0,0 @@ -import { emit } from "$lib/sockets"; -import store from "$lib/store"; -import db from "$db"; -import config from "$config"; -import app from "$app"; -import { auth } from "$lib/passport"; -import axios from "axios"; -import crypto from "crypto"; -import fs from "fs"; -import { err, l } from "$lib/logging"; -import lq from "$lib/liquid"; -import { SATS } from "$lib/utils"; - -let fetchAssets; -(fetchAssets = async () => { - try { - const { data } = await axios.get("https://assets.blockstream.info/"); - - store.assets = data; - } catch (e) { - var liquid_assets = JSON.parse(fs.readFileSync("/app/assets.json")); - if (liquid_assets) { - store.assets = liquid_assets; - console.debug("using static assets..." + e.message); - } else { - err("error fetching assets", e.message); - res.code(500).send("error fetching assets"); - } - } - - setTimeout(fetchAssets, 7200000); -})(); - -app.get("/assets", async (req, res) => { - if (store.assets) { - const accounts = await db.Account.findAll({ - // group: ["asset"] - }); - Object.keys(store.assets).map(a => { - store.assets[a].registered = true; - if (!store.assets[a].asset) - store.assets[a].asset = store.assets[a].asset_id; - if ( - (store.assets[a].ticker === "BTC" && - store.assets[a].asset !== config.liquid.btcasset) || - (store.assets[a].ticker === "EUR" && - store.assets[a].asset !== config.liquid.eurasset) || - (store.assets[a].ticker === "CAD" && - store.assets[a].asset !== config.liquid.cadasset) || - (store.assets[a].ticker === "USDt" && - store.assets[a].asset !== config.liquid.usdtasset) - ) - delete store.assets[a]; - }); - accounts.map(({ asset, name, domain, ticker, precision }) => { - if (!store.assets[asset]) - store.assets[asset] = { - asset, - name, - domain, - ticker, - precision - }; - }); - - res.send(store.assets); - } else { - console.log("error getting blockstream assets"); - res.code(500).send("Problem fetching blockstream asset registry data"); - } -}); - -app.post("/assets", auth, async (req, res) => { - try { - const sha256 = crypto.createHash("sha256"); - const { id: user_id } = req.user; - const blind = false; - - if (!user_id) throw new Error("unauthorized"); - - const { - address, - domain, - name, - asset_amount, - filename, - token_amount, - precision, - pubkey, - ticker - } = req.body; - - const asset_address = address - ? address - : await lq.getNewAddress("", "legacy"); - - const token_address = - token_amount && (await lq.getNewAddress("", "legacy")); - - const issuer_pubkey = pubkey - ? pubkey - : (await lq.getAddressInfo(asset_address)).pubkey; - const version = 0; - - let contract = { - entity: { domain }, - issuer_pubkey, - name, - precision, - version - }; - - if (filename) contract.file = filename; - if (ticker) contract.ticker = ticker; - - contract = Object.keys(contract) - .sort() - .reduce((r, k) => ((r[k] = contract[k]), r), {}); - - l( - "attempting issuance", - req.user.username, - JSON.stringify(contract), - "address", - address, - "pubkey", - pubkey - ); - - sha256.update(JSON.stringify(contract)); - const hash = sha256.digest("hex"); - const contract_hash = hash - .match(/[a-f0-9]{2}/g) - .reverse() - .join(""); - const rawtx = await lq.createRawTransaction([], [{ data: "00" }]); - const funded = await lq.fundRawTransaction(rawtx, { feeRate: 0.000002 }); - const params = { - asset_amount, - asset_address, - blind, - contract_hash - }; - - params.asset_amount = asset_amount / (SATS / 10 ** precision); - - if (token_amount) { - params.token_amount = token_amount; - params.token_address = token_address; - params.token_amount = parseInt(params.token_amount); - } - - let ria; - try { - ria = await lq.rawIssueAsset(funded.hex, [params]); - } catch (e) { - l(asset_amount, token_amount, params); - throw new Error(e.message); - } - - const { asset, hex, token } = ria[0]; - const brt = await lq.blindRawTransaction(hex, true, [], false); - const srt = await lq.signRawTransactionWithWallet(brt); - const allowed = (await lq.testMempoolAccept([srt.hex]))[0].allowed; - if (!allowed) throw new Error("issuance rejected by mempool", srt.hex); - const txid = await lq.sendRawTransaction(srt.hex); - - await db.transaction(async transaction => { - let account = await db.Account.findOne({ - where: { - user_id, - asset: config.liquid.btcasset, - pubkey: null - }, - include: { - model: db.User, - as: "user" - }, - order: [["balance", "DESC"]], - lock: transaction.LOCK.UPDATE, - transaction - }); - - let { user } = account; - - if (Math.round(funded.fee * SATS) > account.balance) { - err( - "amount exceeds balance", - asset_amount, - funded.fee, - account.balance - ); - throw new Error(`Insufficient funds to pay fee of ${funded.fee} BTC`); - } - - await account.decrement( - { balance: Math.round(funded.fee * SATS) }, - { transaction } - ); - await account.reload({ transaction }); - emit(user.username, "account", account); - - let invoice; - let recipient = user; - if (address) { - invoice = await db.Invoice.findOne({ - where: { address }, - include: { - model: db.User, - as: "user" - } - }); - recipient = invoice.user; - } - - if (!invoice) { - invoice = await db.Invoice.create( - { - account_id: account.id, - user_id, - amount: Math.round(params.asset_amount * SATS), - address: asset_address, - currency: user.currency, - rate: store.rates[user.currency], - network: "liquid" - }, - { transaction } - ); - } - - account = await db.Account.create( - { - asset, - contract, - domain, - user_id: invoice.user_id, - ticker, - precision, - name, - balance: 0, - network: "liquid", - pending: Math.round(params.asset_amount * SATS) - }, - { transaction } - ); - - emit(recipient.username, "account", account); - l( - "issued asset", - user.username, - params.asset_amount, - ticker, - name, - account.id - ); - - const asset_payment = await db.Payment.create( - { - account_id: account.id, - user_id: invoice.user_id, - invoice_id: invoice.id, - hash: txid, - amount: Math.round(params.asset_amount * SATS), - received: true, - confirmed: false, - address: asset_address, - network: "liquid" - }, - { transaction } - ); - emit(recipient.username, "payment", asset_payment); - - if (invoice.user_id !== user.id) { - const asset_send = await db.Payment.create( - { - account_id: account.id, - user_id, - hash: txid, - amount: -Math.round(params.asset_amount * SATS), - received: false, - confirmed: false, - address, - network: "liquid" - }, - { transaction } - ); - emit(recipient.username, "payment", asset_send); - } - - store.issuances[txid] = { - user_id, - asset, - asset_amount: params.asset_amount, - asset_payment_id: asset_payment.id - }; - - if (token_amount) { - invoice = null; - recipient = user; - - if (address) { - invoice = await db.Invoice.findOne({ - where: { address }, - include: { - model: db.User, - as: "user" - } - }); - recipient = invoice.user; - } - - if (!invoice) { - invoice = await db.Invoice.create( - { - account_id: account.id, - user_id, - amount: Math.round(params.token_amount * SATS), - address: token_address, - currency: user.currency, - rate: store.rates[user.currency], - network: "liquid" - }, - { transaction } - ); - } - - account = await db.Account.create( - { - asset: token, - user_id: invoice.user_id, - domain, - ticker: `${ticker}REISSUANCETOKEN`, - precision: 8, - name: `${name} Reissuance Token`, - balance: 0, - pending: address ? 0 : Math.round(token_amount * SATS) - }, - { transaction } - ); - emit(recipient.username, "account", account); - - const token_payment = await db.Payment.create( - { - account_id: account.id, - invoice_id: invoice.id, - user_id, - hash: txid, - amount: Math.round(token_amount * SATS), - received: true, - confirmed: false, - address: token_address, - network: "liquid" - }, - { transaction } - ); - emit(recipient.username, "payment", token_payment); - - if (invoice.user_id !== user.id) { - const token_send = await db.Payment.create( - { - account_id: account.id, - invoice_id: invoice.id, - user_id, - hash: txid, - amount: -Math.round(token_amount * SATS), - received: false, - confirmed: false, - address, - network: "liquid" - }, - { transaction } - ); - emit(recipient.username, "payment", token_send); - } - - store.issuances[txid].token = token; - store.issuances[txid].token_amount = token_amount; - store.issuances[txid].token_payment_id = token_payment.id; - } - }); - - res.send(store.issuances[txid] ? store.issuances[txid] : { asset }); - } catch (e) { - err("asset issuance failed", e.message, e.stack); - res.code(500).send(e.message); - } -}); - -app.post("/assets/register", auth, async (req, res) => { - const { asset } = req.body; - const account = await db.Account.findOne({ - where: { - user_id: req.user.id, - asset - } - }); - - l("registering", asset, account.contract); - - try { - const { data: result } = await axios.post( - "https://assets.blockstream.info/", - { - asset_id: asset, - contract: account.contract - } - ); - l("register asset result", req.user.username, result); - res.send(result); - } catch (e) { - err("asset registration failed", e.message); - res.code(500).send(e.message); - } -}); - -app.post("/loadFaucet", auth, async (req, res) => { - return res.code(500).send("Faucet feature temporarily disabled"); - - const { user } = req; - let { asset, amount } = req.body; - amount = parseInt(amount); - - try { - if (amount <= 0) throw new Error("Amount to load cannot be negative"); - - await db.transaction(async transaction => { - let account = await getAccount(config.liquid.btcasset, user, transaction); - - if (account.asset !== config.liquid.btcasset) - throw new Error( - "Faucet has to be funded with bitcoin. Try sending from another wallet." - ); - if (account.balance < amount) throw new Error("Insufficient funds"); - - let fee = 0; - - await account.decrement({ balance: amount }, { transaction }); - await account.reload({ transaction }); - - let a2; - let acc = { - user_id: null, - asset - }; - - a2 = await db.Account.findOne({ - where: acc, - lock: transaction.LOCK.UPDATE, - transaction - }); - - if (a2) { - await a2.increment({ balance: amount }, { transaction }); - await a2.reload({ transaction }); - } else { - let name = asset.substr(0, 6); - let domain; - let ticker = asset.substr(0, 3).toUpperCase(); - let precision = 8; - - const assets = assets; - - if (assets[asset]) { - ({ domain, ticker, precision, name } = assets[asset]); - } else { - const existing = await db.Account.findOne({ - where: { - asset - }, - order: [["id", "ASC"]], - limit: 1, - lock: transaction.LOCK.UPDATE, - transaction - }); - - if (existing) { - ({ domain, ticker, precision, name } = existing); - } - } - - acc = { ...acc, ...{ domain, ticker, precision, name } }; - acc.balance = amount; - acc.pending = 0; - acc.network = "liquid"; - a2 = await db.Account.create(acc, { transaction }); - } - - let params = { - amount: -amount, - account_id: account.id, - user_id: user.id, - rate: store.rates[user.currency], - currency: user.currency, - confirmed: true, - hash: `Loaded Faucet - ${a2.ticker}`, - network: "COINOS" - }; - - let payment = await db.Payment.create(params, { transaction }); - - payment = payment.get({ plain: true }); - payment.account = account.get({ plain: true }); - - l("sent internal", user.username, -payment.amount); - - emit(user.username, "payment", payment); - emit(user.username, "account", account); - emit(user.username, "user", user); - - l("loaded faucet", asset, amount); - res.send({}); - }); - } catch (e) { - err("problem loading faucet", user.username, e.message); - return res.code(500).send(e.message); - } -}); - -app.get("/faucet", auth, async (req, res) => { - let { asset } = req.query; - let faucet = await db.Account.findOne({ - where: { - asset, - user_id: null - } - }); - - if (!faucet) - faucet = { - asset, - balance: 0, - ticker: "Unknown" - }; - - res.send(faucet); -}); |
