|
@ -50,9 +50,10 @@ module.exports = (shepherd) => { |
|
|
.then((json) => { |
|
|
.then((json) => { |
|
|
if (json && |
|
|
if (json && |
|
|
json.length) { |
|
|
json.length) { |
|
|
|
|
|
let _rawtx = []; |
|
|
|
|
|
|
|
|
json = shepherd.sortTransactions(json); |
|
|
json = shepherd.sortTransactions(json); |
|
|
json = json.length > MAX_TX ? json.slice(0, MAX_TX) : json; |
|
|
json = json.length > MAX_TX ? json.slice(0, MAX_TX) : json; |
|
|
let _rawtx = []; |
|
|
|
|
|
|
|
|
|
|
|
shepherd.log(json.length, true); |
|
|
shepherd.log(json.length, true); |
|
|
|
|
|
|
|
@ -189,7 +190,7 @@ module.exports = (shepherd) => { |
|
|
}); |
|
|
}); |
|
|
} else { |
|
|
} else { |
|
|
ecl.close(); |
|
|
ecl.close(); |
|
|
|
|
|
|
|
|
const successObj = { |
|
|
const successObj = { |
|
|
msg: 'success', |
|
|
msg: 'success', |
|
|
result: [], |
|
|
result: [], |
|
@ -248,10 +249,11 @@ module.exports = (shepherd) => { |
|
|
} |
|
|
} |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
shepherd.parseTransactionAddresses = (tx, targetAddress, network) => { |
|
|
shepherd.parseTransactionAddresses = (tx, targetAddress, network, skipTargetAddress) => { |
|
|
// TODO: - sum vins / sum vouts to the same address
|
|
|
// TODO: - sum vins / sum vouts to the same address
|
|
|
// - multi vin multi vout
|
|
|
// - multi vin multi vout
|
|
|
// - detect change address
|
|
|
// - detect change address
|
|
|
|
|
|
// - double check for exact sum input/output values
|
|
|
let result = []; |
|
|
let result = []; |
|
|
let _parse = { |
|
|
let _parse = { |
|
|
inputs: {}, |
|
|
inputs: {}, |
|
@ -265,6 +267,10 @@ module.exports = (shepherd) => { |
|
|
inputs: 0, |
|
|
inputs: 0, |
|
|
outputs: 0, |
|
|
outputs: 0, |
|
|
}; |
|
|
}; |
|
|
|
|
|
let _addresses = { |
|
|
|
|
|
inputs: [], |
|
|
|
|
|
outputs: [], |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
shepherd.log('parseTransactionAddresses result ==>', true); |
|
|
shepherd.log('parseTransactionAddresses result ==>', true); |
|
|
|
|
|
|
|
@ -294,39 +300,99 @@ module.exports = (shepherd) => { |
|
|
|
|
|
|
|
|
_total[key] += Number(_parse[key][i].value); |
|
|
_total[key] += Number(_parse[key][i].value); |
|
|
|
|
|
|
|
|
|
|
|
// ignore op return outputs
|
|
|
if (_parse[key][i].scriptPubKey && |
|
|
if (_parse[key][i].scriptPubKey && |
|
|
_parse[key][i].scriptPubKey.addresses && |
|
|
_parse[key][i].scriptPubKey.addresses && |
|
|
|
|
|
_parse[key][i].scriptPubKey.addresses[0] && |
|
|
_parse[key][i].scriptPubKey.addresses[0] === targetAddress && |
|
|
_parse[key][i].scriptPubKey.addresses[0] === targetAddress && |
|
|
_parse[key][i].value) { |
|
|
_parse[key][i].value) { |
|
|
_sum[key] += Number(_parse[key][i].value); |
|
|
_sum[key] += Number(_parse[key][i].value); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (_parse[key][i].scriptPubKey && |
|
|
|
|
|
_parse[key][i].scriptPubKey.addresses && |
|
|
|
|
|
_parse[key][i].scriptPubKey.addresses[0]) { |
|
|
|
|
|
_addresses[key].push(_parse[key][i].scriptPubKey.addresses[0]); |
|
|
|
|
|
|
|
|
|
|
|
if (_parse[key][i].scriptPubKey.addresses[0] === targetAddress && skipTargetAddress) { |
|
|
|
|
|
_addresses[key].pop(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
_addresses.inputs = [ ...new Set(_addresses.inputs) ]; |
|
|
|
|
|
_addresses.outputs = [ ...new Set(_addresses.outputs) ]; |
|
|
|
|
|
|
|
|
|
|
|
shepherd.log('addresses in =>', true); |
|
|
|
|
|
shepherd.log(_addresses.inputs, true); |
|
|
|
|
|
shepherd.log('addresses out =>', true); |
|
|
|
|
|
shepherd.log(_addresses.outputs, true); |
|
|
|
|
|
|
|
|
|
|
|
let isSelfSend = { |
|
|
|
|
|
inputs: false, |
|
|
|
|
|
outputs: false, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
for (let key in _parse) { |
|
|
|
|
|
for (let i = 0; i < _addresses[key].length; i++) { |
|
|
|
|
|
if (_addresses[key][i] === targetAddress && _addresses[key].length === 1) { |
|
|
|
|
|
isSelfSend[key] = true; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (_sum.inputs > 0 && |
|
|
if (_sum.inputs > 0 && |
|
|
_sum.outputs > 0) { |
|
|
_sum.outputs > 0) { |
|
|
// vin + change, break into two tx
|
|
|
// vin + change, break into two tx
|
|
|
result = [{ // reorder since tx sort by default is from newest to oldest
|
|
|
|
|
|
type: 'sent', |
|
|
|
|
|
amount: Number(_sum.inputs.toFixed(8)), |
|
|
|
|
|
address: targetAddress, |
|
|
|
|
|
timestamp: tx.timestamp, |
|
|
|
|
|
txid: tx.format.txid, |
|
|
|
|
|
confirmations: tx.confirmations, |
|
|
|
|
|
}, { |
|
|
|
|
|
type: 'received', |
|
|
|
|
|
amount: Number(_sum.outputs.toFixed(8)), |
|
|
|
|
|
address: targetAddress, |
|
|
|
|
|
timestamp: tx.timestamp, |
|
|
|
|
|
txid: tx.format.txid, |
|
|
|
|
|
confirmations: tx.confirmations, |
|
|
|
|
|
}]; |
|
|
|
|
|
|
|
|
|
|
|
if (network === 'komodo') { // calc claimed interest amount
|
|
|
// send to self
|
|
|
const vinVoutDiff = _total.inputs - _total.outputs; |
|
|
if (isSelfSend.inputs && isSelfSend.outputs) { |
|
|
|
|
|
result = { |
|
|
|
|
|
type: 'self', |
|
|
|
|
|
amount: Number(_sum.inputs - _sum.outputs).toFixed(8), |
|
|
|
|
|
sumIn: _sum.inputs, |
|
|
|
|
|
sumOut: _sum.outputs, |
|
|
|
|
|
address: targetAddress, |
|
|
|
|
|
timestamp: tx.timestamp, |
|
|
|
|
|
txid: tx.format.txid, |
|
|
|
|
|
confirmations: tx.confirmations, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
if (vinVoutDiff < 0) { |
|
|
if (network === 'komodo') { // calc claimed interest amount
|
|
|
result[1].interest = Number(vinVoutDiff.toFixed(8)); |
|
|
const vinVoutDiff = _total.inputs - _total.outputs; |
|
|
|
|
|
|
|
|
|
|
|
if (vinVoutDiff < 0) { |
|
|
|
|
|
result.interest = Number(vinVoutDiff.toFixed(8)); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
result = [{ // reorder since tx sort by default is from newest to oldest
|
|
|
|
|
|
type: 'sent', |
|
|
|
|
|
amount: Number(_sum.inputs.toFixed(8)), |
|
|
|
|
|
address: _addresses.outputs[0], |
|
|
|
|
|
timestamp: tx.timestamp, |
|
|
|
|
|
txid: tx.format.txid, |
|
|
|
|
|
confirmations: tx.confirmations, |
|
|
|
|
|
inputAddresses: _addresses.inputs, |
|
|
|
|
|
outputAddresses: _addresses.outputs, |
|
|
|
|
|
}, { |
|
|
|
|
|
type: 'received', |
|
|
|
|
|
amount: Number(_sum.outputs.toFixed(8)), |
|
|
|
|
|
address: targetAddress, |
|
|
|
|
|
timestamp: tx.timestamp, |
|
|
|
|
|
txid: tx.format.txid, |
|
|
|
|
|
confirmations: tx.confirmations, |
|
|
|
|
|
inputAddresses: _addresses.inputs, |
|
|
|
|
|
outputAddresses: _addresses.outputs, |
|
|
|
|
|
}]; |
|
|
|
|
|
|
|
|
|
|
|
if (network === 'komodo') { // calc claimed interest amount
|
|
|
|
|
|
const vinVoutDiff = _total.inputs - _total.outputs; |
|
|
|
|
|
|
|
|
|
|
|
if (vinVoutDiff < 0) { |
|
|
|
|
|
result[1].interest = Number(vinVoutDiff.toFixed(8)); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} else if (_sum.inputs === 0 && _sum.outputs > 0) { |
|
|
} else if (_sum.inputs === 0 && _sum.outputs > 0) { |
|
@ -337,22 +403,26 @@ module.exports = (shepherd) => { |
|
|
timestamp: tx.timestamp, |
|
|
timestamp: tx.timestamp, |
|
|
txid: tx.format.txid, |
|
|
txid: tx.format.txid, |
|
|
confirmations: tx.confirmations, |
|
|
confirmations: tx.confirmations, |
|
|
|
|
|
inputAddresses: _addresses.inputs, |
|
|
|
|
|
outputAddresses: _addresses.outputs, |
|
|
}; |
|
|
}; |
|
|
} else if (_sum.inputs > 0 && _sum.outputs === 0) { |
|
|
} else if (_sum.inputs > 0 && _sum.outputs === 0) { |
|
|
result = { |
|
|
result = { |
|
|
type: 'sent', |
|
|
type: 'sent', |
|
|
amount: Number(_sum.inputs.toFixed(8)), |
|
|
amount: Number(_sum.inputs.toFixed(8)), |
|
|
address: targetAddress, |
|
|
address: isSelfSend.inputs && isSelfSend.outputs ? targetAddress : _addresses.outputs[0], |
|
|
timestamp: tx.timestamp, |
|
|
timestamp: tx.timestamp, |
|
|
txid: tx.format.txid, |
|
|
txid: tx.format.txid, |
|
|
confirmations: tx.confirmations, |
|
|
confirmations: tx.confirmations, |
|
|
|
|
|
inputAddresses: _addresses.inputs, |
|
|
|
|
|
outputAddresses: _addresses.outputs, |
|
|
}; |
|
|
}; |
|
|
} else { |
|
|
} else { |
|
|
// (?)
|
|
|
// (?)
|
|
|
result = { |
|
|
result = { |
|
|
type: 'other', |
|
|
type: 'other', |
|
|
amount: 'unknown', |
|
|
amount: 'unknown', |
|
|
address: targetAddress, |
|
|
address: 'unknown', |
|
|
timestamp: tx.timestamp, |
|
|
timestamp: tx.timestamp, |
|
|
txid: tx.format.txid, |
|
|
txid: tx.format.txid, |
|
|
confirmations: tx.confirmations, |
|
|
confirmations: tx.confirmations, |
|
|