diff options
| author | Adam Soltys <[email protected]> | 2022-09-06 09:20:25 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2022-09-06 09:20:25 -0700 |
| commit | c2464b2407ee23134732fd67586758dbfe18f9b5 (patch) | |
| tree | 3e2d9f009bb325a9a7c4304ea02f6e64dda85bd1 /routes/assets.js | |
| parent | 8a080ef9a198799e7ee31cf81f92afd5495e4074 (diff) | |
| download | coinos-server-c2464b2407ee23134732fd67586758dbfe18f9b5.tar.gz coinos-server-c2464b2407ee23134732fd67586758dbfe18f9b5.zip | |
prettier
Diffstat (limited to 'routes/assets.js')
| -rw-r--r-- | routes/assets.js | 699 |
1 files changed, 340 insertions, 359 deletions
diff --git a/routes/assets.js b/routes/assets.js index 541c9625..826ff2d9 100644 --- a/routes/assets.js +++ b/routes/assets.js @@ -4,16 +4,14 @@ 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 axios from "axios"; +import crypto from "crypto"; +import fs from "fs"; let fetchAssets; (fetchAssets = async () => { try { - const { data } = await axios.get( - "https://assets.blockstream.info/" - ); + const { data } = await axios.get("https://assets.blockstream.info/"); store.assets = data; } catch (e) { @@ -30,432 +28,415 @@ let fetchAssets; 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 - }; - }); +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"); - } - }) + 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; +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"); + if (!user_id) throw new Error("unauthorized"); - const { - address, - domain, - name, - asset_amount, - filename, - token_amount, - precision, - pubkey, - ticker - } = req.body; + const { + address, + domain, + name, + asset_amount, + filename, + token_amount, + precision, + pubkey, + ticker + } = req.body; - const asset_address = address - ? address - : await lq.getNewAddress("", "legacy"); + const asset_address = address + ? address + : await lq.getNewAddress("", "legacy"); - const token_address = - token_amount && (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; + const issuer_pubkey = pubkey + ? pubkey + : (await lq.getAddressInfo(asset_address)).pubkey; + const version = 0; - let contract = { - entity: { domain }, - issuer_pubkey, - name, - precision, - version - }; + let contract = { + entity: { domain }, + issuer_pubkey, + name, + precision, + version + }; - if (filename) contract.file = filename; - if (ticker) contract.ticker = ticker; + if (filename) contract.file = filename; + if (ticker) contract.ticker = ticker; - contract = Object.keys(contract) - .sort() - .reduce((r, k) => ((r[k] = contract[k]), r), {}); + contract = Object.keys(contract) + .sort() + .reduce((r, k) => ((r[k] = contract[k]), r), {}); - l( - "attempting issuance", - req.user.username, - contract, - "address", - address, - "pubkey", - pubkey - ); + l( + "attempting issuance", + req.user.username, + 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 - }; + 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); + 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); - } + 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); - } + 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); + 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"]], - transaction - }); + 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"]], + transaction + }); - let { user } = account; + 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`); - } + 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); + + account = await db.Account.create( + { + asset, + contract, + domain, + user_id, + ticker, + precision, + name, + balance: 0, + network: "liquid", + pending: address ? 0 : Math.round(params.asset_amount * SATS) + }, + { transaction } + ); - await account.decrement( - { balance: Math.round(funded.fee * SATS) }, + emit(user.username, "account", account); + l( + "issued asset", + user.username, + params.asset_amount, + ticker, + name, + account.id + ); + + if (!address) { + const asset_payment = await db.Payment.create( + { + account_id: account.id, + user_id, + hash: txid, + amount: Math.round(params.asset_amount * SATS), + received: true, + confirmed: false, + address: asset_address, + network: "liquid" + }, { transaction } ); - await account.reload({ transaction }); - emit(user.username, "account", account); + emit(user.username, "payment", asset_payment); + + issuances[txid] = { + user_id, + asset, + asset_amount: params.asset_amount, + asset_payment_id: asset_payment.id + }; + } + if (token_amount) { account = await db.Account.create( { - asset, - contract, - domain, + asset: token, user_id, - ticker, - precision, - name, + domain, + ticker: `${ticker}REISSUANCETOKEN`, + precision: 8, + name: `${name} Reissuance Token`, balance: 0, - network: "liquid", - pending: address ? 0 : Math.round(params.asset_amount * SATS) + pending: address ? 0 : Math.round(token_amount * SATS) }, { transaction } ); - emit(user.username, "account", account); - l( - "issued asset", - user.username, - params.asset_amount, - ticker, - name, - account.id - ); if (!address) { - const asset_payment = await db.Payment.create( + const token_payment = await db.Payment.create( { account_id: account.id, user_id, hash: txid, - amount: Math.round(params.asset_amount * SATS), + amount: Math.round(token_amount * SATS), received: true, confirmed: false, - address: asset_address, + address: token_address, network: "liquid" }, { transaction } ); - emit(user.username, "payment", asset_payment); + emit(user.username, "payment", token_payment); - issuances[txid] = { - user_id, - asset, - asset_amount: params.asset_amount, - asset_payment_id: asset_payment.id - }; + issuances[txid].token = token; + issuances[txid].token_amount = token_amount; + issuances[txid].token_payment_id = token_payment.id; } + } + }); - if (token_amount) { - account = await db.Account.create( - { - asset: token, - user_id, - domain, - ticker: `${ticker}REISSUANCETOKEN`, - precision: 8, - name: `${name} Reissuance Token`, - balance: 0, - pending: address ? 0 : Math.round(token_amount * SATS) - }, - { transaction } - ); - emit(user.username, "account", account); - - if (!address) { - const token_payment = await db.Payment.create( - { - account_id: account.id, - user_id, - hash: txid, - amount: Math.round(token_amount * SATS), - received: true, - confirmed: false, - address: token_address, - network: "liquid" - }, - { transaction } - ); - emit(user.username, "payment", token_payment); - - issuances[txid].token = token; - issuances[txid].token_amount = token_amount; - issuances[txid].token_payment_id = token_payment.id; - } - } - }); + res.send(issuances[txid] ? issuances[txid] : { asset }); + } catch (e) { + err("asset issuance failed", e.message, e.stack); + res.code(500).send(e.message); + } +}); - res.send(issuances[txid] ? 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 } - }) + }); -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); + } +}); - l("registering", asset, account.contract); +app.post("/loadFaucet", auth, async (req, res) => { + return res.code(500).send("Faucet feature temporarily disabled"); - 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); - const { user } = req; - let { asset, amount } = req.body; - amount = parseInt(amount); + try { + if (amount <= 0) throw new Error("Amount to load cannot be negative"); - 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); - 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"); - 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; + let fee = 0; - await account.decrement({ balance: amount }, { transaction }); - await account.reload({ transaction }); + await account.decrement({ balance: amount }, { transaction }); + await account.reload({ transaction }); - let a2; - let acc = { - user_id: null, - asset - }; + let a2; + let acc = { + user_id: null, + asset + }; - a2 = await db.Account.findOne({ - where: acc, - lock: transaction.LOCK.UPDATE, - transaction - }); + 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; + 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; + 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 (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); - } + 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" - }; + acc = { ...acc, ...{ domain, ticker, precision, name } }; + acc.balance = amount; + acc.pending = 0; + acc.network = "liquid"; + a2 = await db.Account.create(acc, { transaction }); + } - let payment = await db.Payment.create(params, { 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" + }; - payment = payment.get({ plain: true }); - payment.account = account.get({ plain: true }); + let payment = await db.Payment.create(params, { transaction }); - l("sent internal", user.username, -payment.amount); + payment = payment.get({ plain: true }); + payment.account = account.get({ plain: true }); - emit(user.username, "payment", payment); - emit(user.username, "account", account); - emit(user.username, "user", user); + l("sent internal", user.username, -payment.amount); - l("loaded faucet", asset, amount); - res.send({}); - }); - } catch (e) { - err("problem loading faucet", user.username, e.message); - return res.code(500).send(e.message); - } - }) + emit(user.username, "payment", payment); + emit(user.username, "account", account); + emit(user.username, "user", user); -app.get( - "/faucet", - auth, - async (req, res) => { - let { asset } = req.query; - let faucet = await db.Account.findOne({ - where: { - asset, - user_id: null - } + l("loaded faucet", asset, amount); + res.send({}); }); + } catch (e) { + err("problem loading faucet", user.username, e.message); + return res.code(500).send(e.message); + } +}); - if (!faucet) - faucet = { - asset, - balance: 0, - ticker: "Unknown" - }; +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); - }) + res.send(faucet); +}); |
