diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/buildliquidtx.js | 125 | ||||
| -rw-r--r-- | lib/buildtx.js | 2 | ||||
| -rw-r--r-- | lib/whitelist.js | 3 |
3 files changed, 126 insertions, 4 deletions
diff --git a/lib/buildliquidtx.js b/lib/buildliquidtx.js new file mode 100644 index 00000000..d9b14d13 --- /dev/null +++ b/lib/buildliquidtx.js @@ -0,0 +1,125 @@ +const axios = require("axios"); +const liquid = require("liquidjs-lib"); +const coinselect = require("coinselect"); +const split = require("coinselect/split"); +const api = prod ? "https://blockstream.info/api" : "http://localhost:3002"; +const SATS = 100000000; +const network = prod ? liquid.networks["liquid"] : liquid.networks["regtest"]; + +module.exports = async ({ address, asset, amount, feeRate, user }) => { + const { btcasset: btc } = config.liquid; + + if (!feeRate) { + let { feerate } = await lq.estimateSmartFee(6); + if (!feerate) feerate = 0.00002; + feeRate = feerate * SATS; + } + feeRate = Math.round(feeRate / 1000); + if (asset !== btc) feeRate = 0; + + const payments = await db.Payment.findAll({ + where: { + received: true, + account_id: user.account_id, + }, + }); + + let utxos = []; + for (let i = 0; i < payments.length; i++) { + let url = `${api}/address/${payments[i].address}/utxo`; + try { + utxos.push(...(await axios.get(url)).data); + } catch (e) { + l.error("problem fetching utxos", e.message, url); + } + } + + let feeInput = utxos.find((utxo) => utxo.asset === btc && utxo.value > 1000); + if (!feeInput) throw new Error("Couldn't find fee input"); + + utxos = utxos.filter((utxo) => utxo.asset === asset); + + let feeChange = feeInput.value - 1000; + + let targets = [ + { + address, + value: amount, + }, + ]; + + let { inputs, outputs, fee } = coinselect(utxos, targets, feeRate); + + if (!inputs || !outputs) { + l.info( + "utxos", + amount, + feeRate, + utxos.map((u) => u.value), + inputs, + outputs + ); + throw new Error( + "Couldn't find inputs for transaction, check your balance/fee" + ); + } + + let psbt = new liquid.Psbt({ network }); + let total = 0; + + let { address: changeAddress } = payments[payments.length - 1]; + + outputs.map(({ address, value }) => { + total += value; + if (!address) { + address = changeAddress; + change.push(address); + } + + psbt = psbt.addOutput({ + address, + asset, + value, + }); + }); + + for (let i = 0; i < inputs.length; i++) { + let { txid, vout } = inputs[i]; + psbt = psbt.addInput({ + hash: txid, + index: vout, + nonWitnessUtxo: Buffer.from(await lq.getRawTransaction(txid), "hex"), + }); + } + + if (asset !== btc) { + l.info("feeInput", feeInput); + psbt.addInput({ + hash: feeInput.txid, + index: feeInput.vout, + nonWitnessUtxo: Buffer.from( + await lq.getRawTransaction(feeInput.txid), + "hex" + ), + }); + + psbt.addOutput({ + changeAddress, + asset: btc, + value: feeChange, + }); + } + + + psbt.addOutput({ + asset: btc, + script: Buffer.alloc(0), + value: fee, + nonce: Buffer.alloc(1, 0), + }); + + feeRate = Math.round(feeRate * 1000); + psbt = psbt.toBase64(); + + return { tx: psbt, feeRate }; +}; diff --git a/lib/buildtx.js b/lib/buildtx.js index 0da8c456..56b4bbff 100644 --- a/lib/buildtx.js +++ b/lib/buildtx.js @@ -2,7 +2,7 @@ const axios = require("axios"); const bitcoin = require("bitcoinjs-lib"); const coinselect = require("coinselect"); const split = require("coinselect/split"); -const api = prod ? "https://blockstream.info/api" : "http://localhost:3002"; +const api = prod ? "https://blockstream.info/api" : "http://localhost:3001"; const SATS = 100000000; const network = prod ? bitcoin.networks["bitcoin"] diff --git a/lib/whitelist.js b/lib/whitelist.js index 9bacedfd..78369c0e 100644 --- a/lib/whitelist.js +++ b/lib/whitelist.js @@ -5,13 +5,10 @@ whitelist = [ "fiat", "unit", "username", - "address", "symbol", "currency", "currencies", "twofa", - "liquid", - "confidential", "accounts", "payments", "seed", |
