diff options
| author | Adam Soltys <[email protected]> | 2020-08-16 21:34:13 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2020-08-16 21:34:13 -0700 |
| commit | 7ab3036cb1576fe38ba1fd423a58b7cd97a58579 (patch) | |
| tree | 305b1a0aa321389b60385009876bbdb1fe0a1c68 /routes/liquid | |
| parent | b2208797d3c5559c7e8cc7d35b7a020da0c61193 (diff) | |
| download | coinos-server-7ab3036cb1576fe38ba1fd423a58b7cd97a58579.tar.gz coinos-server-7ab3036cb1576fe38ba1fd423a58b7cd97a58579.zip | |
non-custodial liquid wallets
Diffstat (limited to 'routes/liquid')
| -rw-r--r-- | routes/liquid/broadcast.js | 36 | ||||
| -rw-r--r-- | routes/liquid/fee.js | 19 | ||||
| -rw-r--r-- | routes/liquid/receive.js | 134 | ||||
| -rw-r--r-- | routes/liquid/send.js | 7 |
4 files changed, 134 insertions, 62 deletions
diff --git a/routes/liquid/broadcast.js b/routes/liquid/broadcast.js new file mode 100644 index 00000000..e3709597 --- /dev/null +++ b/routes/liquid/broadcast.js @@ -0,0 +1,36 @@ +module.exports = ah(async (req, res) => { + try { + const { user } = req; + let hash = await lq.sendRawTransaction(req.body.tx); + + if (user) { + let { account } = user; + let payment = await db.Payment.create({ + ...req.body.payment, + hash, + amount: -req.body.payment.amount, + tip: 0, + account_id: account.id, + user_id: user.id, + rate: app.get("rates")[user.currency], + currency: user.currency, + confirmed: true, + received: false, + network: "LBTC", + }); + + account.balance += payment.amount - payment.fee; + await account.save(); + + payment = payment.get({ plain: true }); + payment.account = account.get({ plain: true }); + emit(user.username, "payment", payment); + emit(user.username, "account", payment.account); + res.send(payment); + } else { + res.send(result); + } + } catch (e) { + res.status(500).send(e.message); + } +}); diff --git a/routes/liquid/fee.js b/routes/liquid/fee.js index 77a9ce17..acf28160 100644 --- a/routes/liquid/fee.js +++ b/routes/liquid/fee.js @@ -1,8 +1,20 @@ +const buildTx = require("../../lib/buildliquidtx"); + module.exports = ah(async (req, res) => { let { user } = req; let { address, asset, amount, feeRate } = req.body; let tx, fee; + if (user.account.pubkey) { + try { + let psbt = await buildTx({ address, asset, amount, feeRate, user }); + return res.send(psbt); + } catch(e) { + throw e; + return res.status(500).send(e.message); + } + } + let invoice = await db.Invoice.findOne({ where: { address }, include: { @@ -13,8 +25,11 @@ module.exports = ah(async (req, res) => { }); if (invoice) { - emit(user.username, "to", invoice.user); - return res.end(); + let { ismine } = await lq.getAddressInfo(address); + if (ismine) { + emit(user.username, "to", invoice.user); + return res.end(); + } } try { diff --git a/routes/liquid/receive.js b/routes/liquid/receive.js index 3fe235a6..325e6783 100644 --- a/routes/liquid/receive.js +++ b/routes/liquid/receive.js @@ -1,7 +1,53 @@ const axios = require("axios"); +const reverse = require("buffer-reverse"); const zmq = require("zeromq"); const { Op } = require("sequelize"); +const { fromBase58 } = require("bip32"); +const bitcoin = require("bitcoinjs-lib"); const elements = require("elementsjs-lib"); +const liquid = require("liquidjs-lib"); + +const network = + liquid.networks[ + config.liquid.network === "mainnet" ? "liquid" : config.liquid.network + ]; + +const getAccount = async (params, pending) => { + let account = await db.Account.findOne({ + where: params + }); + + if (account) return account; + + let { asset } = params; + let name = asset.substr(0, 6); + let domain = ""; + let ticker = asset.substr(0, 3).toUpperCase(); + let precision = 8; + + const assets = (await axios.get("https://assets.blockstream.info/")).data; + + if (assets[asset]) { + ({ domain, ticker, precision, name } = assets[asset]); + } else { + const existing = await db.Account.findOne({ + where: { + asset, + }, + order: [["id", "ASC"]], + limit: 1, + }); + + if (existing) { + ({ domain, ticker, precision, name } = existing); + } + } + + params = { ...params, ...{ domain, ticker, precision, name } }; + params.balance = 0; + params.pending = pending; + return db.Account.create(params); +}; const zmqRawBlock = zmq.socket("sub"); zmqRawBlock.connect(config.liquid.zmqrawblock); @@ -26,77 +72,50 @@ zmqRawTx.on("message", async (topic, message, sequence) => { const value = toSats(o.value); const address = o.scriptPubKey.addresses[0]; - if (Object.keys(addresses).includes(address)) { + if ( + Object.keys(addresses).includes(address) && + !change.includes(address) + ) { let user = await getUser(addresses[address]); - let confirmed = 0; + let invoice = await db.Invoice.findOne({ + where: { + address, + user_id: user.id, + network: "LBTC", + }, + order: [["id", "DESC"]], + include: { + model: db.Account, + as: "account", + }, + }); - let params = { - user_id: user.id, - asset, - }; + if (!invoice) return; - let account = await db.Account.findOne({ - where: params, - }); + let confirmed = 0; - if (account) { + let { account } = invoice; + + if (account.asset === asset) { account.pending += value; await account.save(); } else { - let name = asset.substr(0, 6); - let domain = ''; - let ticker = asset.substr(0, 3).toUpperCase(); - let precision = 8; - - const assets = (await axios.get("https://assets.blockstream.info/")) - .data; - - if (assets[asset]) { - ({ domain, ticker, precision, name } = assets[asset]); - } else { - const existing = await db.Account.findOne({ - where: { - asset, - }, - order: [["id", "ASC"]], - limit: 1, - }); - - if (existing) { - ({ domain, ticker, precision, name } = existing); - } - } - - params = { ...params, ...{ domain, ticker, precision, name } }; - params.balance = 0; - params.pending = value; - account = await db.Account.create(params); + if (!account) account = await getAccount( + { + user_id: user.id, + asset, + pubkey: account.pubkey, + }, + value + ); } if (config.liquid.walletpass) await lq.walletPassphrase(config.liquid.walletpass, 300); - user.confidential = await lq.getNewAddress(); - user.liquid = ( - await lq.getAddressInfo(user.confidential) - ).unconfidential; - await user.save(); - addresses[user.liquid] = user.username; - - let invoice; - if (asset === config.liquid.btcasset) { - invoice = await db.Invoice.findOne({ - where: { - user_id: user.id, - network: "LBTC", - }, - order: [["id", "DESC"]], - }); - } - const currency = invoice ? invoice.currency : user.currency; const rate = invoice ? invoice.rate : app.get("rates")[user.currency]; const tip = invoice ? invoice.tip : 0; @@ -123,7 +142,7 @@ zmqRawTx.on("message", async (topic, message, sequence) => { emit(user.username, "payment", payment); emit(user.username, "account", account); - l.info("liquid detected", user.username, asset, value); + l.info("liquid detected", address, user.username, asset, value); notify(user, `${value} SAT payment detected`); } }) @@ -218,6 +237,7 @@ zmqRawBlock.on("message", async (topic, message, sequence) => { }); setInterval(async () => { + // throw new Error("boom"); try { const arr = Object.keys(queue); diff --git a/routes/liquid/send.js b/routes/liquid/send.js index 1d12db30..7f7e1cb5 100644 --- a/routes/liquid/send.js +++ b/routes/liquid/send.js @@ -39,8 +39,9 @@ module.exports = ah(async (req, res) => { await db.transaction(async (transaction) => { for (let i = 0; i < assets.length; i++) { let asset = assets[i]; - let total = totals[asset]; - if (change[asset]) total -= change[asset]; + let amount = totals[asset]; + if (change[asset]) amount -= change[asset]; + let total = amount; if (asset === config.liquid.btcasset) total += fee; l.info("creating liquid payment", user.username, asset, total, fee); @@ -67,7 +68,7 @@ module.exports = ah(async (req, res) => { await account.save({ transaction }); let payment = { - amount: -total, + amount: -amount, account_id: account.id, fee, memo, |
