Browse Source

promises; listtransactions, getbalance error handling

v0.25
pbca26 7 years ago
parent
commit
59611f4d23
  1. 218
      routes/shepherd.js

218
routes/shepherd.js

@ -542,6 +542,9 @@ shepherd.verifyMerkle = function(txid, height, serverList, mainServer) {
ecl.connect(); ecl.connect();
ecl.blockchainTransactionGetMerkle(txid, height) ecl.blockchainTransactionGetMerkle(txid, height)
.then((merkleData) => { .then((merkleData) => {
if (merkleData &&
merkleData.merkle &&
merkleData.pos) {
console.log('electrum getmerkle =>'); console.log('electrum getmerkle =>');
console.log(merkleData); console.log(merkleData);
ecl.close(); ecl.close();
@ -553,6 +556,8 @@ shepherd.verifyMerkle = function(txid, height, serverList, mainServer) {
ecl.connect(); ecl.connect();
ecl.blockchainBlockGetHeader(height) ecl.blockchainBlockGetHeader(height)
.then((blockInfo) => { .then((blockInfo) => {
if (blockInfo &&
blockInfo['merkle_root']) {
ecl.close(); ecl.close();
console.log('blockinfo =>'); console.log('blockinfo =>');
console.log(blockInfo); console.log(blockInfo);
@ -568,7 +573,13 @@ shepherd.verifyMerkle = function(txid, height, serverList, mainServer) {
} else { } else {
resolve(CONNECTION_ERROR_OR_INCOMPLETE_DATA); resolve(CONNECTION_ERROR_OR_INCOMPLETE_DATA);
} }
} else {
resolve(f);
}
}); });
} else {
resolve(CONNECTION_ERROR_OR_INCOMPLETE_DATA);
}
}); });
}); });
} }
@ -736,17 +747,8 @@ shepherd.kdmCalcInterest = function(locktime, value) { // value in sats
console.log(`minutes if statement ${timestampDiffMinutes}`); console.log(`minutes if statement ${timestampDiffMinutes}`);
let denominator = (365 * 24 * 60) / timestampDiffMinutes;
if (denominator === 0) {
denominator = 1; // max KOMODO_INTEREST per transfer, do it at least annually!
}
console.log(`denominator ${denominator}`);
// TODO: check if interest is > 5% yr // TODO: check if interest is > 5% yr
// calc ytd and 5% for 1 yr // calc ytd and 5% for 1 yr
const numerator = Number(value) * 0.00000001 / 20; // assumes 5%!
// const hoursInOneYear = 365 * 24; // const hoursInOneYear = 365 * 24;
// const hoursDiff = hoursInOneYear - hoursPassed; // const hoursDiff = hoursInOneYear - hoursPassed;
@ -764,6 +766,9 @@ shepherd.get('/electrum/getbalance', function(req, res, next) {
ecl.connect(); ecl.connect();
ecl.blockchainAddressGetBalance(req.query.address) ecl.blockchainAddressGetBalance(req.query.address)
.then((json) => { .then((json) => {
if (json &&
json.hasOwnProperty('confirmed') &&
json.hasOwnProperty('unconfirmed')) {
if (network === 'komodo') { if (network === 'komodo') {
ecl.connect(); ecl.connect();
ecl.blockchainAddressListunspent(req.query.address) ecl.blockchainAddressListunspent(req.query.address)
@ -788,25 +793,34 @@ shepherd.get('/electrum/getbalance', function(req, res, next) {
_utxo.length) { _utxo.length) {
let interestTotal = 0; let interestTotal = 0;
for (let i = 0; i < _utxo.length; i++) { Promise.all(_utxo.map((_utxoItem, index) => {
ecl.blockchainTransactionGet(_utxo[i]['tx_hash']) return new Promise((resolve, reject) => {
ecl.blockchainTransactionGet(_utxoItem['tx_hash'])
.then((_rawtxJSON) => { .then((_rawtxJSON) => {
console.log('electrum gettransaction ==>'); console.log('electrum gettransaction ==>');
console.log(i + ' | ' + (_rawtxJSON.length - 1)); console.log(index + ' | ' + (_rawtxJSON.length - 1));
console.log(_rawtxJSON); console.log(_rawtxJSON);
// decode tx // decode tx
const _network = shepherd.getNetworkData(network); const _network = shepherd.getNetworkData(network);
const decodedTx = electrumJSTxDecoder(_rawtxJSON, _network); const decodedTx = electrumJSTxDecoder(_rawtxJSON, _network);
if (decodedTx.format.locktime > 0) { if (decodedTx &&
interestTotal += shepherd.kdmCalcInterest(decodedTx.format.locktime, _utxo[i].value); decodedTx.format &&
decodedTx.format.locktime > 0) {
interestTotal += shepherd.kdmCalcInterest(decodedTx.format.locktime, _utxoItem.value);
} }
console.log('decoded tx =>'); console.log('decoded tx =>');
console.log(decodedTx); console.log(decodedTx);
console.log(decodedTx.format.locktime);
if (i === _utxo.length -1) { resolve(true);
});
});
}))
.then(promiseResult => {
ecl.close();
const successObj = { const successObj = {
msg: 'success', msg: 'success',
result: { result: {
@ -822,9 +836,7 @@ shepherd.get('/electrum/getbalance', function(req, res, next) {
}; };
res.end(JSON.stringify(successObj)); res.end(JSON.stringify(successObj));
}
}); });
}
} else { } else {
const successObj = { const successObj = {
msg: 'success', msg: 'success',
@ -851,6 +863,9 @@ shepherd.get('/electrum/getbalance', function(req, res, next) {
unconfirmedSats: json.unconfirmed, unconfirmedSats: json.unconfirmed,
balanceSats: json.confirmed, balanceSats: json.confirmed,
interest: 0, interest: 0,
interestSats: 0,
total: 0,
totalSats: 0,
}, },
}; };
@ -865,12 +880,21 @@ shepherd.get('/electrum/getbalance', function(req, res, next) {
const successObj = { const successObj = {
msg: 'success', msg: 'success',
result: { result: {
balance: 0.00000001 * json.confirmed, balance: Number((0.00000001 * json.confirmed).toFixed(8)),
unconfirmed: json.unconfirmed, unconfirmed: Number((0.00000001 * json.unconfirmed).toFixed(8)),
sats: json.confirmed, unconfirmedSats: json.unconfirmed,
balanceSats: json.confirmed,
}, },
}; };
res.end(JSON.stringify(successObj));
}
} else {
const successObj = {
msg: 'error',
result: CONNECTION_ERROR_OR_INCOMPLETE_DATA,
};
res.end(JSON.stringify(successObj)); res.end(JSON.stringify(successObj));
} }
}); });
@ -920,7 +944,9 @@ shepherd.get('/electrum/listtransactions', function(req, res, next) {
ecl.connect(); ecl.connect();
ecl.blockchainNumblocksSubscribe() ecl.blockchainNumblocksSubscribe()
.then(function(currentHeight) { .then((currentHeight) => {
if (currentHeight &&
Number(currentHeight) > 0) {
ecl.blockchainAddressGetHistory(req.query.address) ecl.blockchainAddressGetHistory(req.query.address)
.then((json) => { .then((json) => {
if (json && if (json &&
@ -930,14 +956,16 @@ shepherd.get('/electrum/listtransactions', function(req, res, next) {
console.log(json.length); console.log(json.length);
let _rawtx = []; let _rawtx = [];
// get raw tx Promise.all(json.map((transaction, index) => {
for (let i = 0; i < json.length; i++) { return new Promise((resolve, reject) => {
ecl.blockchainBlockGetHeader(json[i].height) ecl.blockchainBlockGetHeader(transaction.height)
.then((blockInfo) => { .then((blockInfo) => {
ecl.blockchainTransactionGet(json[i]['tx_hash']) if (blockInfo &&
blockInfo.timestamp) {
ecl.blockchainTransactionGet(transaction['tx_hash'])
.then((_rawtxJSON) => { .then((_rawtxJSON) => {
console.log('electrum gettransaction ==>'); console.log('electrum gettransaction ==>');
console.log(i + ' | ' + (_rawtxJSON.length - 1)); console.log(index + ' | ' + (_rawtxJSON.length - 1));
console.log(_rawtxJSON); console.log(_rawtxJSON);
// decode tx // decode tx
@ -949,25 +977,36 @@ shepherd.get('/electrum/listtransactions', function(req, res, next) {
console.log('decodedtx =>'); console.log('decodedtx =>');
console.log(decodedTx.outputs); console.log(decodedTx.outputs);
if (decodedTx.inputs) { if (decodedTx &&
for (let j = 0; j < decodedTx.inputs.length; j++) { decodedTx.inputs) {
if (decodedTx.inputs[j].txid !== '0000000000000000000000000000000000000000000000000000000000000000') { Promise.all(decodedTx.inputs.map((_decodedInput, index) => {
ecl.blockchainTransactionGet(decodedTx.inputs[j].txid) return new Promise((_resolve, _reject) => {
if (_decodedInput.txid !== '0000000000000000000000000000000000000000000000000000000000000000') {
ecl.blockchainTransactionGet(_decodedInput.txid)
.then((rawInput) => { .then((rawInput) => {
console.log('electrum raw input tx ==>'); console.log('electrum raw input tx ==>');
const decodedVinVout = electrumJSTxDecoder(rawInput, _network); const decodedVinVout = electrumJSTxDecoder(rawInput, _network);
console.log(decodedVinVout.outputs[decodedTx.inputs[j].n]);
txInputs.push(decodedVinVout.outputs[decodedTx.inputs[j].n]);
if (j === decodedTx.inputs.length - 1) { if (decodedVinVout) {
console.log(decodedVinVout.outputs[_decodedInput.n]);
txInputs.push(decodedVinVout.outputs[_decodedInput.n]);
_resolve(true);
}
});
} else {
_resolve(true);
}
});
}))
.then(promiseResult => {
const _parsedTx = { const _parsedTx = {
network: decodedTx.network, network: decodedTx.network,
format: decodedTx.format, format: decodedTx.format,
inputs: txInputs, inputs: txInputs,
outputs: decodedTx.outputs, outputs: decodedTx.outputs,
height: json[i].height, height: transaction.height,
timestamp: blockInfo.timestamp, timestamp: blockInfo.timestamp,
confirmations: currentHeight - json[i].height, confirmations: currentHeight - transaction.height,
}; };
const formattedTx = shepherd.parseTransactionAddresses(_parsedTx, req.query.address, network); const formattedTx = shepherd.parseTransactionAddresses(_parsedTx, req.query.address, network);
@ -978,104 +1017,68 @@ shepherd.get('/electrum/listtransactions', function(req, res, next) {
_rawtx.push(formattedTx[0]); _rawtx.push(formattedTx[0]);
_rawtx.push(formattedTx[1]); _rawtx.push(formattedTx[1]);
} }
resolve(true);
if (i === json.length - 1) {
ecl.close();
console.log('electrum gettransaction array ==>');
console.log(_rawtx);
const successObj = {
msg: 'success',
result: {
listtransactions: _rawtx,
},
};
res.end(JSON.stringify(successObj));
}
}
}); });
} else { } else {
if (j === decodedTx.inputs.length - 1) {
const _parsedTx = { const _parsedTx = {
network: decodedTx.network, network: decodedTx.network,
format: decodedTx.format, format: 'cant parse',
inputs: txInputs, inputs: 'cant parse',
outputs: decodedTx.outputs, outputs: 'cant parse',
height: json[i].height, height: transaction.height,
timestamp: blockInfo.timestamp, timestamp: blockInfo.timestamp,
confirmations: currentHeight - json[i].height, confirmations: currentHeight - transaction.height,
}; };
const formattedTx = shepherd.parseTransactionAddresses(_parsedTx, req.query.address, network); const formattedTx = shepherd.parseTransactionAddresses(_parsedTx, req.query.address, network);
if (formattedTx.type) {
_rawtx.push(formattedTx); _rawtx.push(formattedTx);
} else { resolve(true);
_rawtx.push(formattedTx[0]);
_rawtx.push(formattedTx[1]);
}
if (i === json.length - 1) {
ecl.close();
console.log('electrum gettransaction array ==>');
console.log(_rawtx);
const successObj = {
msg: 'success',
result: {
listtransactions: _rawtx,
},
};
res.end(JSON.stringify(successObj));
}
}
}
} }
});
} else { } else {
const _parsedTx = { const _parsedTx = {
network: decodedTx.network, network: 'cant parse',
format: 'cant parse', format: 'cant parse',
inputs: 'cant parse', inputs: 'cant parse',
outputs: 'cant parse', outputs: 'cant parse',
height: json[i].height, height: transaction.height,
timestamp: blockInfo.timestamp, timestamp: 'cant get block info',
confirmations: currentHeight - json[i].height, confirmations: currentHeight - transaction.height,
}; };
const formattedTx = shepherd.parseTransactionAddresses(_parsedTx, req.query.address, network); const formattedTx = shepherd.parseTransactionAddresses(_parsedTx, req.query.address, network);
_rawtx.push(formattedTx); _rawtx.push(formattedTx);
resolve(true);
if (i === json.length - 1) { }
});
});
}))
.then(promiseResult => {
ecl.close(); ecl.close();
console.log('electrum gettransaction array ==>');
console.log(_rawtx);
const successObj = { const successObj = {
msg: 'success', msg: 'success',
result: { result: _rawtx,
listtransactions: _rawtx,
},
}; };
res.end(JSON.stringify(successObj)); res.end(JSON.stringify(successObj));
}
}
});
}); });
}
} else { } else {
const successObj = { const successObj = {
msg: 'success', msg: 'success',
result: { result: [],
listtransactions: [],
},
}; };
res.end(JSON.stringify(successObj)); res.end(JSON.stringify(successObj));
} }
}); });
} else {
const successObj = {
msg: 'error',
result: 'cant get current height',
};
res.end(JSON.stringify(successObj));
}
}); });
} }
}); });
@ -1388,7 +1391,7 @@ shepherd.buildSignedTx = function(sendTo, changeAddress, wif, network, utxo, cha
let key = bitcoinJS.ECPair.fromWIF(wif, shepherd.getNetworkData(network)); let key = bitcoinJS.ECPair.fromWIF(wif, shepherd.getNetworkData(network));
let tx = new bitcoinJS.TransactionBuilder(shepherd.getNetworkData(network)); let tx = new bitcoinJS.TransactionBuilder(shepherd.getNetworkData(network));
console.log(`buildSignedTx priv key ${wif}`); // console.log(`buildSignedTx priv key ${wif}`);
console.log(`buildSignedTx pub key ${key.getAddress().toString()}`); console.log(`buildSignedTx pub key ${key.getAddress().toString()}`);
// console.log('buildSignedTx std tx fee ' + electrumServers[network].txfee); // console.log('buildSignedTx std tx fee ' + electrumServers[network].txfee);
@ -1701,6 +1704,8 @@ shepherd.listunspent = function(ecl, address, network, full, verify) {
ecl.blockchainNumblocksSubscribe() ecl.blockchainNumblocksSubscribe()
.then((currentHeight) => { .then((currentHeight) => {
if (currentHeight &&
Number(currentHeight) > 0) {
// filter out unconfirmed utxos // filter out unconfirmed utxos
for (let i = 0; i < _utxoJSON.length; i++) { for (let i = 0; i < _utxoJSON.length; i++) {
if (Number(currentHeight) - Number(_utxoJSON[i].height) !== 0) { if (Number(currentHeight) - Number(_utxoJSON[i].height) !== 0) {
@ -1755,6 +1760,10 @@ shepherd.listunspent = function(ecl, address, network, full, verify) {
if (verify) { if (verify) {
shepherd.verifyMerkleByCoin(shepherd.findCoinName(network), _utxoItem['tx_hash'], _utxoItem.height) shepherd.verifyMerkleByCoin(shepherd.findCoinName(network), _utxoItem['tx_hash'], _utxoItem.height)
.then((verifyMerkleRes) => { .then((verifyMerkleRes) => {
if (verifyMerkleRes && verifyMerkleRes === CONNECTION_ERROR_OR_INCOMPLETE_DATA) {
verifyMerkleRes = false;
}
_resolveObj.verified = verifyMerkleRes; _resolveObj.verified = verifyMerkleRes;
resolve(_resolveObj); resolve(_resolveObj);
}); });
@ -1777,6 +1786,10 @@ shepherd.listunspent = function(ecl, address, network, full, verify) {
if (verify) { if (verify) {
shepherd.verifyMerkleByCoin(shepherd.findCoinName(network), _utxoItem['tx_hash'], _utxoItem.height) shepherd.verifyMerkleByCoin(shepherd.findCoinName(network), _utxoItem['tx_hash'], _utxoItem.height)
.then((verifyMerkleRes) => { .then((verifyMerkleRes) => {
if (verifyMerkleRes && verifyMerkleRes === CONNECTION_ERROR_OR_INCOMPLETE_DATA) {
verifyMerkleRes = false;
}
_resolveObj.verified = verifyMerkleRes; _resolveObj.verified = verifyMerkleRes;
resolve(_resolveObj); resolve(_resolveObj);
}); });
@ -1800,6 +1813,9 @@ shepherd.listunspent = function(ecl, address, network, full, verify) {
} }
}); });
} }
} else {
resolve('cant get current height');
}
}); });
} else { } else {
ecl.close(); ecl.close();

Loading…
Cancel
Save