diff options
| author | Adam Soltys <[email protected]> | 2020-05-18 15:37:50 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2020-05-18 15:37:50 -0700 |
| commit | 8ffd969ff2f50af4116edb2050ae5c95e2af6f41 (patch) | |
| tree | ef87b6f4abdbee0ca8e14f43767ae0e7d68ba790 /routes/assets.js | |
| parent | 56f05870ff6cc9100683ba017b6f6b4818a47f7f (diff) | |
| download | coinos-server-8ffd969ff2f50af4116edb2050ae5c95e2af6f41.tar.gz coinos-server-8ffd969ff2f50af4116edb2050ae5c95e2af6f41.zip | |
asset issuance
Diffstat (limited to 'routes/assets.js')
| -rw-r--r-- | routes/assets.js | 109 |
1 files changed, 107 insertions, 2 deletions
diff --git a/routes/assets.js b/routes/assets.js index 350781d7..3e7bd338 100644 --- a/routes/assets.js +++ b/routes/assets.js @@ -1,12 +1,117 @@ const axios = require("axios"); +const crypto = require("crypto"); app.get("/assets", async (req, res) => { let assets; try { assets = await axios.get("https://assets.blockstream.info/"); res.send(assets.data); - } catch(e) { + } catch (e) { l.error("error fetching assets", e); res.status(500).send("error fetching assets"); - } + } +}); + +app.post("/assets", auth, async (req, res) => { + try { + const sha256 = crypto.createHash("sha256"); + const { id: user_id } = req.user; + const token_address = await lq.getNewAddress("", "legacy"); + const asset_address = await lq.getNewAddress("", "legacy"); + const blind = false; + const info = await lq.getAddressInfo(asset_address); + const { pubkey: issuer_pubkey } = info; + + const { name, asset_amount, token_amount, precision, ticker } = req.body; + const domain = "adamsoltys.com"; + const version = 0; + + const contract = { + entity: { domain }, + issuer_pubkey, + name, + precision, + ticker, + version + }; + + 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.00003 }); + const ria = await lq.rawIssueAsset(funded.hex, [ + { + asset_amount, + token_amount, + asset_address, + token_address, + blind, + contract_hash + } + ]); + const { asset, hex } = 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) { + 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 + }, + lock: transaction.LOCK.UPDATE, + transaction + }); + + if (Math.round(funded.fee * SATS) > account.balance) { + l.error("amount exceeds balance", amount, fee, account.balance); + throw new Error("insufficient funds"); + } + + account.balance -= Math.round(funded.fee * SATS); + await account.save({ transaction }); + + account = await db.Account.create( + { + asset, + user_id, + ticker, + precision, + name, + balance: 0, + pending: asset_amount * SATS + }, + { transaction } + ); + + const payment = await db.Payment.create({ + account_id: account.id, + user_id, + hash: txid, + amount: asset_amount * SATS, + received: true, + confirmed: false, + address: asset_address, + network: "LBTC" + }); + + issuances[txid] = { user_id, asset, asset_amount, payment_id: payment.id }; + + let user = await getUserById(user_id, transaction); + emit(user.username, "user", user); + }); + + res.send(issuances[txid]); + } + } catch (e) { + l.error("asset issuance failed", e.message); + res.status(500).send("Failed to issue asset"); + } }); |
