Update btcOperator.js
- update any fn dependent on btcOperator module that needs fix
This commit is contained in:
parent
470aea4150
commit
25197aaced
@ -1,29 +1,40 @@
|
||||
(function (EXPORTS) { //btcOperator v1.0.13c
|
||||
(function (EXPORTS) { //btcOperator v1.1.1
|
||||
/* BTC Crypto and API Operator */
|
||||
const btcOperator = EXPORTS;
|
||||
|
||||
//This library uses API provided by chain.so (https://chain.so/)
|
||||
const URL = "https://chain.so/api/v2/";
|
||||
const URL = "https://blockchain.info/";
|
||||
|
||||
const fetch_api = btcOperator.fetch = function (api) {
|
||||
const fetch_api = btcOperator.fetch = function (api, json_res = true) {
|
||||
return new Promise((resolve, reject) => {
|
||||
console.debug(URL + api);
|
||||
fetch(URL + api).then(response => {
|
||||
response.json()
|
||||
.then(result => result.status === "success" ? resolve(result) : reject(result))
|
||||
.catch(error => reject(error))
|
||||
if (response.ok) {
|
||||
(json_res ? response.json() : response.text())
|
||||
.then(result => resolve(result))
|
||||
.catch(error => reject(error))
|
||||
} else {
|
||||
response.json()
|
||||
.then(result => reject(result))
|
||||
.catch(error => reject(error))
|
||||
}
|
||||
}).catch(error => reject(error))
|
||||
})
|
||||
};
|
||||
|
||||
const SATOSHI_IN_BTC = 1e8;
|
||||
|
||||
const util = btcOperator.util = {};
|
||||
|
||||
util.Sat_to_BTC = value => parseFloat((value / SATOSHI_IN_BTC).toFixed(8));
|
||||
util.BTC_to_Sat = value => parseInt(value * SATOSHI_IN_BTC);
|
||||
|
||||
function get_fee_rate() {
|
||||
return new Promise((resolve, reject) => {
|
||||
fetch('https://api.blockchain.info/mempool/fees').then(response => {
|
||||
if (response.ok)
|
||||
response.json()
|
||||
.then(result => resolve(parseFloat((result.regular / SATOSHI_IN_BTC).toFixed(8))))
|
||||
.then(result => resolve(util.Sat_to_BTC(result.regular)))
|
||||
.catch(error => reject(error));
|
||||
else
|
||||
reject(response);
|
||||
@ -102,18 +113,21 @@
|
||||
if (!addr)
|
||||
return undefined;
|
||||
let type = coinjs.addressDecode(addr).type;
|
||||
if (["standard", "multisig", "bech32"].includes(type))
|
||||
if (["standard", "multisig", "bech32", "multisigBech32"].includes(type))
|
||||
return type;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
btcOperator.multiSigAddress = function (pubKeys, minRequired) {
|
||||
btcOperator.multiSigAddress = function (pubKeys, minRequired, bech32 = true) {
|
||||
if (!Array.isArray(pubKeys))
|
||||
throw "pubKeys must be an array of public keys";
|
||||
else if (pubKeys.length < minRequired)
|
||||
throw "minimum required should be less than the number of pubKeys";
|
||||
return coinjs.pubkeys2MultisigAddress(pubKeys, minRequired);
|
||||
if (bech32)
|
||||
return coinjs.pubkeys2MultisigAddressBech32(pubKeys, minRequired);
|
||||
else
|
||||
return coinjs.pubkeys2MultisigAddress(pubKeys, minRequired);
|
||||
}
|
||||
|
||||
//convert from one blockchain to another blockchain (target version)
|
||||
@ -213,8 +227,8 @@
|
||||
//BTC blockchain APIs
|
||||
|
||||
btcOperator.getBalance = addr => new Promise((resolve, reject) => {
|
||||
fetch_api(`get_address_balance/BTC/${addr}`)
|
||||
.then(result => resolve(parseFloat(result.data.confirmed_balance)))
|
||||
fetch_api(`q/addressbalance/${addr}`)
|
||||
.then(result => resolve(util.Sat_to_BTC(result)))
|
||||
.catch(error => reject(error))
|
||||
});
|
||||
|
||||
@ -222,11 +236,13 @@
|
||||
BASE_INPUT_SIZE = 41,
|
||||
LEGACY_INPUT_SIZE = 107,
|
||||
BECH32_INPUT_SIZE = 27,
|
||||
BECH32_MULTISIG_INPUT_SIZE = 35,
|
||||
SEGWIT_INPUT_SIZE = 59,
|
||||
MULTISIG_INPUT_SIZE_ES = 351,
|
||||
BASE_OUTPUT_SIZE = 9,
|
||||
LEGACY_OUTPUT_SIZE = 25,
|
||||
BECH32_OUTPUT_SIZE = 23,
|
||||
BECH32_MULTISIG_OUTPUT_SIZE = 34,
|
||||
SEGWIT_OUTPUT_SIZE = 23;
|
||||
|
||||
function _redeemScript(addr, key) {
|
||||
@ -249,6 +265,8 @@
|
||||
return BASE_INPUT_SIZE + LEGACY_INPUT_SIZE;
|
||||
case "bech32":
|
||||
return BASE_INPUT_SIZE + BECH32_INPUT_SIZE;
|
||||
case "multisigBech32":
|
||||
return BASE_INPUT_SIZE + BECH32_MULTISIG_INPUT_SIZE;
|
||||
case "multisig":
|
||||
switch (coinjs.script().decodeRedeemScript(rs).type) {
|
||||
case "segwit__":
|
||||
@ -269,6 +287,8 @@
|
||||
return BASE_OUTPUT_SIZE + LEGACY_OUTPUT_SIZE;
|
||||
case "bech32":
|
||||
return BASE_OUTPUT_SIZE + BECH32_OUTPUT_SIZE;
|
||||
case "multisigBech32":
|
||||
return BASE_OUTPUT_SIZE + BECH32_MULTISIG_OUTPUT_SIZE;
|
||||
case "multisig":
|
||||
return BASE_OUTPUT_SIZE + SEGWIT_OUTPUT_SIZE;
|
||||
default:
|
||||
@ -299,7 +319,7 @@
|
||||
parameters.privkeys[i] = coinjs.privkey2wif(key);
|
||||
});
|
||||
if (invalids.length)
|
||||
throw "Invalid keys:" + invalids;
|
||||
throw "Invalid private key for address:" + invalids;
|
||||
}
|
||||
//receiver-ids (and change-id)
|
||||
if (!Array.isArray(parameters.receivers))
|
||||
@ -329,10 +349,10 @@
|
||||
const tx = coinjs.transaction();
|
||||
let output_size = addOutputs(tx, receivers, amounts, change_address);
|
||||
addInputs(tx, senders, redeemScripts, total_amount, fee, output_size, fee_from_receiver).then(result => {
|
||||
if (result.change_amount > 0) //add change amount if any
|
||||
tx.outs[tx.outs.length - 1].value = parseInt(result.change_amount * SATOSHI_IN_BTC); //values are in satoshi
|
||||
if (result.change_amount > 0 && result.change_amount > result.fee) //add change amount if any (ignore dust change)
|
||||
tx.outs[tx.outs.length - 1].value = util.BTC_to_Sat(result.change_amount); //values are in satoshi
|
||||
if (fee_from_receiver) { //deduce fee from receivers if fee_from_receiver
|
||||
let fee_remaining = parseInt(result.fee * SATOSHI_IN_BTC);
|
||||
let fee_remaining = util.BTC_to_Sat(result.fee);
|
||||
for (let i = 0; i < tx.outs.length - 1 && fee_remaining > 0; i++) {
|
||||
if (fee_remaining < tx.outs[i].value) {
|
||||
tx.outs[i].value -= fee_remaining;
|
||||
@ -398,30 +418,31 @@
|
||||
return reject("Insufficient Balance");
|
||||
let addr = senders[rec_args.n],
|
||||
rs = redeemScripts[rec_args.n];
|
||||
let addr_type = coinjs.addressDecode(addr).type;
|
||||
let size_per_input = _sizePerInput(addr, rs);
|
||||
fetch_api(`get_tx_unspent/BTC/${addr}`).then(result => {
|
||||
let utxos = result.data.txs;
|
||||
fetch_api(`unspent?active=${addr}`).then(result => {
|
||||
let utxos = result.unspent_outputs;
|
||||
console.debug("add-utxo", addr, rs, required_amount, utxos);
|
||||
for (let i = 0; i < utxos.length && required_amount > 0; i++) {
|
||||
if (!utxos[i].confirmations) //ignore unconfirmed utxo
|
||||
continue;
|
||||
var script;
|
||||
if (!rs || !rs.length) //legacy script
|
||||
script = utxos[i].script_hex;
|
||||
else if (((rs.match(/^00/) && rs.length == 44)) || (rs.length == 40 && rs.match(/^[a-f0-9]+$/gi))) {
|
||||
//redeemScript for segwit/bech32
|
||||
script = utxos[i].script;
|
||||
else if (((rs.match(/^00/) && rs.length == 44)) || (rs.length == 40 && rs.match(/^[a-f0-9]+$/gi)) || addr_type === 'multisigBech32') {
|
||||
//redeemScript for segwit/bech32 and multisig (bech32)
|
||||
let s = coinjs.script();
|
||||
s.writeBytes(Crypto.util.hexToBytes(rs));
|
||||
s.writeOp(0);
|
||||
s.writeBytes(coinjs.numToBytes((utxos[i].value * SATOSHI_IN_BTC).toFixed(0), 8));
|
||||
s.writeBytes(coinjs.numToBytes(utxos[i].value.toFixed(0), 8));
|
||||
script = Crypto.util.bytesToHex(s.buffer);
|
||||
} else //redeemScript for multisig
|
||||
} else //redeemScript for multisig (segwit)
|
||||
script = rs;
|
||||
tx.addinput(utxos[i].txid, utxos[i].output_no, script, 0xfffffffd /*sequence*/); //0xfffffffd for Replace-by-fee
|
||||
tx.addinput(utxos[i].tx_hash_big_endian, utxos[i].tx_output_n, script, 0xfffffffd /*sequence*/); //0xfffffffd for Replace-by-fee
|
||||
//update track values
|
||||
rec_args.input_size += size_per_input;
|
||||
rec_args.input_amount += parseFloat(utxos[i].value);
|
||||
required_amount -= parseFloat(utxos[i].value);
|
||||
rec_args.input_amount += util.Sat_to_BTC(utxos[i].value);
|
||||
required_amount -= util.Sat_to_BTC(utxos[i].value);
|
||||
if (fee_rate) //automatic fee calculation (dynamic)
|
||||
required_amount += size_per_input * fee_rate;
|
||||
}
|
||||
@ -563,11 +584,14 @@
|
||||
btcOperator.createMultiSigTx = function (sender, redeemScript, receivers, amounts, fee = null, options = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
//validate tx parameters
|
||||
if (validateAddress(sender) !== "multisig")
|
||||
let addr_type = validateAddress(sender);
|
||||
if (!(["multisig", "multisigBech32"].includes(addr_type)))
|
||||
return reject("Invalid sender (multisig):" + sender);
|
||||
else {
|
||||
let script = coinjs.script();
|
||||
let decode = script.decodeRedeemScript(redeemScript);
|
||||
let decode = (addr_type == "multisig") ?
|
||||
script.decodeRedeemScript(redeemScript) :
|
||||
script.decodeRedeemScriptBech32(redeemScript);
|
||||
if (!decode || decode.address !== sender)
|
||||
return reject("Invalid redeem-script");
|
||||
}
|
||||
@ -622,10 +646,10 @@
|
||||
let n = [];
|
||||
for (let i in tx.ins) {
|
||||
var s = tx.extractScriptKey(i);
|
||||
if (s['type'] !== 'multisig')
|
||||
if (s['type'] !== 'multisig' && s['type'] !== 'multisig_bech32')
|
||||
n.push(s.signed == 'true' || (tx.witness[i] && tx.witness[i].length == 2))
|
||||
else {
|
||||
var rs = coinjs.script().decodeRedeemScript(s.script);
|
||||
var rs = coinjs.script().decodeRedeemScript(s.script); //will work for bech32 too, as only address is diff
|
||||
let x = {
|
||||
s: s['signatures'],
|
||||
r: rs['signaturesRequired'],
|
||||
@ -657,8 +681,8 @@
|
||||
}
|
||||
|
||||
const getTxOutput = (txid, i) => new Promise((resolve, reject) => {
|
||||
fetch_api(`get_tx_outputs/BTC/${txid}/${i}`)
|
||||
.then(result => resolve(result.data.outputs))
|
||||
fetch_api(`rawtx/${txid}`)
|
||||
.then(result => resolve(result.out[i]))
|
||||
.catch(error => reject(error))
|
||||
});
|
||||
|
||||
@ -672,8 +696,8 @@
|
||||
promises.push(getTxOutput(tx.ins[i].outpoint.hash, tx.ins[i].outpoint.index));
|
||||
Promise.all(promises).then(inputs => {
|
||||
result.inputs = inputs.map(inp => Object({
|
||||
address: inp.address,
|
||||
value: parseFloat(inp.value)
|
||||
address: inp.addr,
|
||||
value: util.Sat_to_BTC(inp.value)
|
||||
}));
|
||||
let signed = checkSigned(tx, false);
|
||||
result.inputs.forEach((inp, i) => inp.signed = signed[i]);
|
||||
@ -681,10 +705,10 @@
|
||||
result.outputs = tx.outs.map(out => {
|
||||
var address;
|
||||
switch (out.script.chunks[0]) {
|
||||
case 0: //bech32
|
||||
case 0: //bech32, multisig-bech32
|
||||
address = encodeBech32(Crypto.util.bytesToHex(out.script.chunks[1]), coinjs.bech32.version, coinjs.bech32.hrp);
|
||||
break;
|
||||
case 169: //multisig, segwit
|
||||
case 169: //segwit, multisig-segwit
|
||||
address = encodeLegacy(Crypto.util.bytesToHex(out.script.chunks[1]), coinjs.multisig);
|
||||
break;
|
||||
case 118: //legacy
|
||||
@ -692,7 +716,7 @@
|
||||
}
|
||||
return {
|
||||
address,
|
||||
value: parseFloat(out.value / SATOSHI_IN_BTC)
|
||||
value: util.Sat_to_BTC(out.value)
|
||||
}
|
||||
});
|
||||
//Parse Totals
|
||||
@ -713,22 +737,115 @@
|
||||
return Crypto.util.bytesToHex(txid);
|
||||
}
|
||||
|
||||
btcOperator.getTx = txid => new Promise((resolve, reject) => {
|
||||
fetch_api(`get_tx/BTC/${txid}`)
|
||||
.then(result => resolve(result.data))
|
||||
const getLatestBlock = btcOperator.getLatestBlock = () => new Promise((resolve, reject) => {
|
||||
fetch_api(`q/getblockcount`)
|
||||
.then(result => resolve(result))
|
||||
.catch(error => reject(error))
|
||||
})
|
||||
|
||||
btcOperator.getTx = txid => new Promise((resolve, reject) => {
|
||||
fetch_api(`rawtx/${txid}`).then(result => {
|
||||
getLatestBlock().then(latest_block => resolve({
|
||||
block: result.block_height,
|
||||
txid: result.hash,
|
||||
time: result.time * 1000,
|
||||
confirmations: result.block_height === null ? 0 : latest_block - result.block_height, //calculate confirmations using latest block number as api doesnt relay it
|
||||
size: result.size,
|
||||
fee: util.Sat_to_BTC(result.fee),
|
||||
inputs: result.inputs.map(i => Object({ address: i.prev_out.addr, value: util.Sat_to_BTC(i.prev_out.value) })),
|
||||
total_input_value: util.Sat_to_BTC(result.inputs.reduce((a, i) => a + i.prev_out.value, 0)),
|
||||
outputs: result.out.map(o => Object({ address: o.addr, value: util.Sat_to_BTC(o.value) })),
|
||||
total_output_value: util.Sat_to_BTC(result.out.reduce((a, o) => a += o.value, 0)),
|
||||
}))
|
||||
}).catch(error => reject(error))
|
||||
});
|
||||
|
||||
btcOperator.getAddressData = addr => new Promise((resolve, reject) => {
|
||||
fetch_api(`address/BTC/${addr}`)
|
||||
.then(result => resolve(result.data))
|
||||
btcOperator.getTx.hex = txid => new Promise((resolve, reject) => {
|
||||
fetch_api(`rawtx/${txid}?format=hex`, false)
|
||||
.then(result => resolve(result))
|
||||
.catch(error => reject(error))
|
||||
})
|
||||
|
||||
btcOperator.getAddressData = address => new Promise((resolve, reject) => {
|
||||
fetch_api(`rawaddr/${address}`).then(data => {
|
||||
let details = {};
|
||||
details.balance = util.Sat_to_BTC(data.final_balance);
|
||||
details.address = data.address;
|
||||
details.txs = data.txs.map(tx => {
|
||||
let d = {
|
||||
txid: tx.hash,
|
||||
time: tx.time * 1000, //s to ms
|
||||
block: tx.block_height,
|
||||
}
|
||||
//sender list
|
||||
d.tx_senders = {};
|
||||
tx.inputs.forEach(i => {
|
||||
if (i.prev_out.addr in d.tx_senders)
|
||||
d.tx_senders[i.prev_out.addr] += i.prev_out.value;
|
||||
else d.tx_senders[i.prev_out.addr] = i.prev_out.value;
|
||||
});
|
||||
d.tx_input_value = 0;
|
||||
for (let s in d.tx_senders) {
|
||||
let val = d.tx_senders[s];
|
||||
d.tx_senders[s] = util.Sat_to_BTC(val);
|
||||
d.tx_input_value += val;
|
||||
}
|
||||
d.tx_input_value = util.Sat_to_BTC(d.tx_input_value);
|
||||
//receiver list
|
||||
d.tx_receivers = {};
|
||||
tx.out.forEach(o => {
|
||||
if (o.addr in d.tx_receivers)
|
||||
d.tx_receivers[o.addr] += o.value;
|
||||
else d.tx_receivers[o.addr] = o.value;
|
||||
});
|
||||
d.tx_output_value = 0;
|
||||
for (let r in d.tx_receivers) {
|
||||
let val = d.tx_receivers[r];
|
||||
d.tx_receivers[r] = util.Sat_to_BTC(val);
|
||||
d.tx_output_value += val;
|
||||
}
|
||||
d.tx_output_value = util.Sat_to_BTC(d.tx_output_value);
|
||||
d.tx_fee = util.Sat_to_BTC(tx.fee);
|
||||
//tx type
|
||||
if (tx.result > 0) { //net > 0, balance inc => type=in
|
||||
d.type = "in";
|
||||
d.amount = util.Sat_to_BTC(tx.result);
|
||||
d.sender = Object.keys(d.tx_senders).filter(s => s !== address);
|
||||
} else if (Object.keys(d.tx_receivers).some(r => r !== address)) { //net < 0, balance dec & receiver present => type=out
|
||||
d.type = "out";
|
||||
d.amount = util.Sat_to_BTC(tx.result * -1);
|
||||
d.receiver = Object.keys(d.tx_receivers).filter(r => r !== address);
|
||||
d.fee = d.tx_fee;
|
||||
} else { //net < 0 (fee) & no other id in receiver list => type=self
|
||||
d.type = "self";
|
||||
d.amount = d.tx_receivers[address];
|
||||
d.address = address
|
||||
}
|
||||
return d;
|
||||
})
|
||||
resolve(details);
|
||||
}).catch(error => reject(error))
|
||||
});
|
||||
|
||||
btcOperator.getBlock = block => new Promise((resolve, reject) => {
|
||||
fetch_api(`get_block/BTC/${block}`)
|
||||
.then(result => resolve(result.data))
|
||||
.catch(error => reject(error))
|
||||
fetch_api(`rawblock/${block}`).then(result => resolve({
|
||||
height: result.height,
|
||||
hash: result.hash,
|
||||
merkle_root: result.mrkl_root,
|
||||
prev_block: result.prev_block,
|
||||
next_block: result.next_block[0],
|
||||
size: result.size,
|
||||
time: result.time * 1000, //s to ms
|
||||
txs: result.tx.map(t => Object({
|
||||
fee: t.fee,
|
||||
size: t.size,
|
||||
inputs: t.inputs.map(i => Object({ address: i.prev_out.addr, value: util.Sat_to_BTC(i.prev_out.value) })),
|
||||
total_input_value: util.Sat_to_BTC(t.inputs.reduce((a, i) => a + i.prev_out.value, 0)),
|
||||
outputs: t.out.map(o => Object({ address: o.addr, value: util.Sat_to_BTC(o.value) })),
|
||||
total_output_value: util.Sat_to_BTC(t.out.reduce((a, o) => a += o.value, 0)),
|
||||
}))
|
||||
|
||||
})).catch(error => reject(error))
|
||||
});
|
||||
|
||||
})('object' === typeof module ? module.exports : window.btcOperator = {});
|
||||
})('object' === typeof module ? module.exports : window.btcOperator = {});
|
||||
|
||||
@ -177,7 +177,7 @@ function confirmVaultWithdraw() {
|
||||
}).catch(error => console.error(error));
|
||||
else if (r.asset == "BTC")
|
||||
btcOperator.getTx(r.txid).then(tx => {
|
||||
if (!tx.blockhash || !tx.confirmations) //Still not confirmed
|
||||
if (!tx.block || !tx.confirmations) //Still not confirmed
|
||||
return;
|
||||
DB.query("UPDATE VaultTransactions SET r_status=? WHERE id=?", [pCode.STATUS_SUCCESS, r.id])
|
||||
.then(result => console.info("BTC withdrawed:", r.floID, r.amount))
|
||||
@ -203,7 +203,7 @@ verifyTx.BTC = function (sender, txid, group) {
|
||||
return reject([true, "Transaction not sent by the sender"]);
|
||||
if (vin_sender.length !== tx.inputs.length)
|
||||
return reject([true, "Transaction input containes other floIDs"]);
|
||||
if (!tx.blockhash)
|
||||
if (!tx.block)
|
||||
return reject([false, "Transaction not included in any block yet"]);
|
||||
if (!tx.confirmations)
|
||||
return reject([false, "Transaction not confirmed yet"]);
|
||||
@ -278,7 +278,7 @@ function confirmConvert() {
|
||||
results.forEach(r => {
|
||||
if (r.mode == pCode.CONVERT_MODE_GET)
|
||||
btcOperator.getTx(r.out_txid).then(tx => {
|
||||
if (!tx.blockhash || !tx.confirmations) //Still not confirmed
|
||||
if (!tx.block || !tx.confirmations) //Still not confirmed
|
||||
return;
|
||||
DB.query("UPDATE DirectConvert SET r_status=? WHERE id=?", [pCode.STATUS_SUCCESS, r.id])
|
||||
.then(result => console.info(`${r.floID} converted ${r.amount} to ${r.quantity} BTC`))
|
||||
@ -342,7 +342,7 @@ function confirmConvertFundWithdraw() {
|
||||
results.forEach(r => {
|
||||
if (r.mode == pCode.CONVERT_MODE_GET) { //withdraw coin
|
||||
btcOperator.getTx(r.txid).then(tx => {
|
||||
if (!tx.blockhash || !tx.confirmations) //Still not confirmed
|
||||
if (!tx.block || !tx.confirmations) //Still not confirmed
|
||||
return;
|
||||
DB.query("UPDATE ConvertFund SET r_status=? WHERE id=?", [pCode.STATUS_SUCCESS, r.id])
|
||||
.then(result => console.info(`Withdraw-fund ${r.quantity} ${r.coin} successful`))
|
||||
@ -399,7 +399,7 @@ function confirmConvertRefund() {
|
||||
if (r.ASSET_TYPE_COIN) {
|
||||
if (r.asset == "BTC") //Convert is only for BTC right now
|
||||
btcOperator.getTx(r.out_txid).then(tx => {
|
||||
if (!tx.blockhash || !tx.confirmations) //Still not confirmed
|
||||
if (!tx.block || !tx.confirmations) //Still not confirmed
|
||||
return;
|
||||
DB.query("UPDATE RefundConvert SET r_status=? WHERE id=?", [pCode.STATUS_SUCCESS, r.id])
|
||||
.then(result => console.info(`Refunded ${r.amount} ${r.asset} to ${r.floID}`))
|
||||
@ -427,7 +427,7 @@ function confirmBondClosing() {
|
||||
DB.query("SELECT * FROM CloseBondTransact WHERE r_status=?", [pCode.STATUS_CONFIRMATION]).then(results => {
|
||||
results.forEach(r => {
|
||||
btcOperator.getTx(r.txid).then(tx => {
|
||||
if (!tx.blockhash || !tx.confirmations) //Still not confirmed
|
||||
if (!tx.block || !tx.confirmations) //Still not confirmed
|
||||
return;
|
||||
let closeBondString = bond_util.stringify.end(r.bond_id, r.end_date, r.btc_net, r.usd_net, r.amount, r.ref_sign, r.txid);
|
||||
floBlockchainAPI.writeData(keys.node_id, closeBondString, keys.node_priv, bond_util.config.adminID).then(txid => {
|
||||
@ -450,7 +450,7 @@ function confirmFundClosing() {
|
||||
DB.query("SELECT * FROM CloseFundTransact WHERE r_status=?", [pCode.STATUS_CONFIRMATION]).then(results => {
|
||||
results.forEach(r => {
|
||||
btcOperator.getTx(r.txid).then(tx => {
|
||||
if (!tx.blockhash || !tx.confirmations) //Still not confirmed
|
||||
if (!tx.block || !tx.confirmations) //Still not confirmed
|
||||
return;
|
||||
let closeFundString = fund_util.stringify.end(r.fund_id, r.floID, r.end_date, r.btc_net, r.usd_net, r.amount, r.ref_sign, r.txid);
|
||||
floBlockchainAPI.writeData(keys.node_id, closeFundString, keys.node_priv, fund_util.config.adminID).then(txid => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user