aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/buildliquidtx.js125
-rw-r--r--lib/buildtx.js2
-rw-r--r--lib/whitelist.js3
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",