Added spentTxId and spentIndex
This commit is contained in:
parent
dcabaeba8c
commit
fe6a441a52
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
var common = require('./common');
|
var common = require('./common');
|
||||||
var bitcore = require('bitcore');
|
var bitcore = require('bitcore');
|
||||||
|
var async = require('async');
|
||||||
var TxController = require('./transactions');
|
var TxController = require('./transactions');
|
||||||
|
|
||||||
function AddressController(node) {
|
function AddressController(node) {
|
||||||
@ -167,29 +168,39 @@ AddressController.prototype.multitxs = function(req, res, next) {
|
|||||||
return common.handleErrors(err, res);
|
return common.handleErrors(err, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
res.jsonp({
|
self.transformAddressHistoryForMultiTxs(result.items, function(err, items) {
|
||||||
totalItems: result.totalCount,
|
if (err) {
|
||||||
from: options.from,
|
return common.handleErrors(err, res);
|
||||||
to: Math.min(options.to, result.totalCount),
|
}
|
||||||
items: self.transformAddressHistoryForMultiTxs(result.items)
|
res.jsonp({
|
||||||
|
totalItems: result.totalCount,
|
||||||
|
from: options.from,
|
||||||
|
to: Math.min(options.to, result.totalCount),
|
||||||
|
items: items
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
AddressController.prototype.transformAddressHistoryForMultiTxs = function(txinfos) {
|
AddressController.prototype.transformAddressHistoryForMultiTxs = function(txinfos, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var items = txinfos.map(function(txinfo) {
|
var items = txinfos.map(function(txinfo) {
|
||||||
return txinfo.tx;
|
return txinfo.tx;
|
||||||
}).filter(function(value, index, self) {
|
}).filter(function(value, index, self) {
|
||||||
return self.indexOf(value) === index;
|
return self.indexOf(value) === index;
|
||||||
}).map(function(tx) {
|
|
||||||
return self.txController.transformTransaction(tx);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return items;
|
async.map(
|
||||||
|
items,
|
||||||
|
function(item, next) {
|
||||||
|
self.txController.transformTransaction(item, next);
|
||||||
|
},
|
||||||
|
callback
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = AddressController;
|
module.exports = AddressController;
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
var bitcore = require('bitcore');
|
var bitcore = require('bitcore');
|
||||||
var _ = bitcore.deps._;
|
var _ = bitcore.deps._;
|
||||||
|
var $ = bitcore.util.preconditions;
|
||||||
var common = require('./common');
|
var common = require('./common');
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
|
|
||||||
@ -35,13 +36,22 @@ TxController.prototype.transaction = function(req, res, next, txid) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
req.transaction = self.transformTransaction(transaction);
|
self.transformTransaction(transaction, function(err, transformedTransaction) {
|
||||||
next();
|
if (err) {
|
||||||
|
return common.handleErrors(err, res);
|
||||||
|
}
|
||||||
|
req.transaction = transformedTransaction;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
TxController.prototype.transformTransaction = function(transaction) {
|
TxController.prototype.transformTransaction = function(transaction, callback) {
|
||||||
|
$.checkArgument(_.isFunction(callback));
|
||||||
|
var self = this;
|
||||||
|
var txid = transaction.id;
|
||||||
var txObj = transaction.toObject();
|
var txObj = transaction.toObject();
|
||||||
|
|
||||||
var confirmations = 0;
|
var confirmations = 0;
|
||||||
@ -67,27 +77,44 @@ TxController.prototype.transformTransaction = function(transaction) {
|
|||||||
transformed.vin = txObj.inputs.map(this.transformInput.bind(this));
|
transformed.vin = txObj.inputs.map(this.transformInput.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
transformed.vout = txObj.outputs.map(this.transformOutput.bind(this));
|
async.map(
|
||||||
|
Object.keys(txObj.outputs),
|
||||||
|
function(outputIndex, next) {
|
||||||
|
outputIndex = parseInt(outputIndex);
|
||||||
|
var output = txObj.outputs[outputIndex];
|
||||||
|
self.transformOutput(txid, output, outputIndex, next);
|
||||||
|
},
|
||||||
|
function(err, vout) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
|
||||||
transformed.blockhash = transaction.__blockHash;
|
transformed.vout = vout;
|
||||||
transformed.confirmations = confirmations;
|
|
||||||
transformed.time = transaction.__timestamp ? transaction.__timestamp : Math.round(Date.now() / 1000); // can we get this from bitcoind?
|
|
||||||
if (transformed.confirmations) {
|
|
||||||
transformed.blocktime = transformed.time;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(transaction.isCoinbase()) {
|
transformed.blockhash = transaction.__blockHash;
|
||||||
transformed.isCoinBase = true;
|
transformed.confirmations = confirmations;
|
||||||
}
|
var time = transaction.__timestamp ? transaction.__timestamp : Math.round(Date.now() / 1000);
|
||||||
|
transformed.time = time;
|
||||||
|
if (transformed.confirmations) {
|
||||||
|
transformed.blocktime = transformed.time;
|
||||||
|
}
|
||||||
|
|
||||||
transformed.valueOut = transaction.outputAmount / 1e8;
|
if(transaction.isCoinbase()) {
|
||||||
transformed.size = transaction.toBuffer().length;
|
transformed.isCoinBase = true;
|
||||||
if(transaction.hasAllUtxoInfo()) {
|
}
|
||||||
transformed.valueIn = transaction.inputAmount / 1e8;
|
|
||||||
transformed.fees = transaction.getFee() / 1e8;
|
transformed.valueOut = transaction.outputAmount / 1e8;
|
||||||
}
|
transformed.size = transaction.toBuffer().length;
|
||||||
|
if(transaction.hasAllUtxoInfo()) {
|
||||||
|
transformed.valueIn = transaction.inputAmount / 1e8;
|
||||||
|
transformed.fees = transaction.getFee() / 1e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(null, transformed);
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
return transformed;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TxController.prototype.transformInput = function(input, index) {
|
TxController.prototype.transformInput = function(input, index) {
|
||||||
@ -117,7 +144,8 @@ TxController.prototype.transformInput = function(input, index) {
|
|||||||
return transformed;
|
return transformed;
|
||||||
};
|
};
|
||||||
|
|
||||||
TxController.prototype.transformOutput = function(output, index) {
|
TxController.prototype.transformOutput = function(txid, output, index, callback) {
|
||||||
|
var self = this;
|
||||||
var transformed = {
|
var transformed = {
|
||||||
value: (output.satoshis / 1e8).toFixed(8),
|
value: (output.satoshis / 1e8).toFixed(8),
|
||||||
n: index,
|
n: index,
|
||||||
@ -125,8 +153,6 @@ TxController.prototype.transformOutput = function(output, index) {
|
|||||||
hex: output.script,
|
hex: output.script,
|
||||||
//reqSigs: null, // TODO
|
//reqSigs: null, // TODO
|
||||||
}
|
}
|
||||||
//spentTxId: undefined, // TODO
|
|
||||||
//spentIndex: undefined, // TODO
|
|
||||||
//spentTs: undefined // TODO
|
//spentTs: undefined // TODO
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -146,7 +172,25 @@ TxController.prototype.transformOutput = function(output, index) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return transformed;
|
var options = {
|
||||||
|
queryMempool: true
|
||||||
|
};
|
||||||
|
|
||||||
|
self.node.services.address.getInputForOutput(
|
||||||
|
txid,
|
||||||
|
index,
|
||||||
|
options,
|
||||||
|
function(err, inputResult) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
if (inputResult) {
|
||||||
|
transformed.spentTxId = inputResult.inputTxId;
|
||||||
|
transformed.spentIndex = inputResult.inputIndex;
|
||||||
|
}
|
||||||
|
callback(null, transformed);
|
||||||
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
TxController.prototype.transformInvTransaction = function(transaction) {
|
TxController.prototype.transformInvTransaction = function(transaction) {
|
||||||
@ -235,8 +279,7 @@ TxController.prototype.list = function(req, res) {
|
|||||||
if(err) {
|
if(err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
|
self.transformTransaction(tx, next);
|
||||||
next(null, self.transformTransaction(tx));
|
|
||||||
});
|
});
|
||||||
}, function(err, transformed) {
|
}, function(err, transformed) {
|
||||||
if(err) {
|
if(err) {
|
||||||
@ -266,13 +309,21 @@ TxController.prototype.list = function(req, res) {
|
|||||||
return self.indexOf(value) === index;
|
return self.indexOf(value) === index;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async.map(
|
||||||
var transformed = txs.map(self.transformTransaction.bind(self));
|
txs,
|
||||||
|
function(tx, next) {
|
||||||
res.jsonp({
|
self.transformTransaction(tx, next);
|
||||||
pagesTotal: Math.ceil(result.totalCount / pageLength),
|
},
|
||||||
txs: transformed
|
function(err, transformed) {
|
||||||
});
|
if (err) {
|
||||||
|
return common.handleErrors(err, res);
|
||||||
|
}
|
||||||
|
res.jsonp({
|
||||||
|
pagesTotal: Math.ceil(result.totalCount / pageLength),
|
||||||
|
txs: transformed
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return common.handleErrors(new Error('Block hash or address expected'), res);
|
return common.handleErrors(new Error('Block hash or address expected'), res);
|
||||||
|
|||||||
@ -520,6 +520,9 @@ describe('Addresses', function() {
|
|||||||
tip: {
|
tip: {
|
||||||
__height: 534232
|
__height: 534232
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
address: {
|
||||||
|
getInputForOutput: sinon.stub().callsArgWith(3, null, false),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
network: 'testnet'
|
network: 'testnet'
|
||||||
@ -544,4 +547,4 @@ describe('Addresses', function() {
|
|||||||
addresses.multitxs(req, res);
|
addresses.multitxs(req, res);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -132,13 +132,13 @@ describe('Transactions', function() {
|
|||||||
var todos = {
|
var todos = {
|
||||||
vin: [
|
vin: [
|
||||||
{
|
{
|
||||||
confirmations: 242,
|
|
||||||
isConfirmed: true,
|
isConfirmed: true,
|
||||||
|
confirmations: 242,
|
||||||
unconfirmedInput: false
|
unconfirmedInput: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
confirmations: 242,
|
|
||||||
isConfirmed: true,
|
isConfirmed: true,
|
||||||
|
confirmations: 242,
|
||||||
unconfirmedInput: false
|
unconfirmedInput: false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -152,13 +152,14 @@ describe('Transactions', function() {
|
|||||||
scriptPubKey: {
|
scriptPubKey: {
|
||||||
reqSigs: 1
|
reqSigs: 1
|
||||||
},
|
},
|
||||||
spentIndex: 1,
|
spentTs: 1440997099
|
||||||
spentTs: 1440997099,
|
|
||||||
spentTxId: '614fe1708825f9c21732394e4784cc6808ac1d8b939736bfdead970567561eec'
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var spentTxId = '614fe1708825f9c21732394e4784cc6808ac1d8b939736bfdead970567561eec';
|
||||||
|
var spentIndex = 1;
|
||||||
|
|
||||||
var bitcoreTx = bitcore.Transaction(bitcoreTxObj);
|
var bitcoreTx = bitcore.Transaction(bitcoreTxObj);
|
||||||
bitcoreTx.__blockHash = '0000000000000afa0c3c0afd450c793a1e300ec84cbe9555166e06132f19a8f7';
|
bitcoreTx.__blockHash = '0000000000000afa0c3c0afd450c793a1e300ec84cbe9555166e06132f19a8f7';
|
||||||
bitcoreTx.__height = 533974;
|
bitcoreTx.__height = 533974;
|
||||||
@ -173,6 +174,21 @@ describe('Transactions', function() {
|
|||||||
tip: {
|
tip: {
|
||||||
__height: 534203
|
__height: 534203
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
address: {
|
||||||
|
getInputForOutput: function(txid, outputIndex, options, callback) {
|
||||||
|
var data = false;
|
||||||
|
if (txid === 'b85334bf2df35c6dd5b294efe92ffc793a78edff75a2ca666fc296ffb04bbba0' &&
|
||||||
|
outputIndex === 1) {
|
||||||
|
data = {
|
||||||
|
inputTxId: spentTxId,
|
||||||
|
inputIndex: spentIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setImmediate(function() {
|
||||||
|
callback(null, data);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
network: 'testnet'
|
network: 'testnet'
|
||||||
@ -214,6 +230,9 @@ describe('Transactions', function() {
|
|||||||
tip: {
|
tip: {
|
||||||
__height: 534209
|
__height: 534209
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
address: {
|
||||||
|
getInputForOutput: sinon.stub().callsArgWith(3, null, false),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
network: 'testnet'
|
network: 'testnet'
|
||||||
@ -593,6 +612,34 @@ describe('Transactions', function() {
|
|||||||
tip: {
|
tip: {
|
||||||
__height: 534223
|
__height: 534223
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
address: {
|
||||||
|
getInputForOutput: function(txid, outputIndex, options, callback) {
|
||||||
|
var data = false;
|
||||||
|
if (txid === 'bb0ec3b96209fac9529570ea6f83a86af2cceedde4aaf2bfcc4796680d23f1c7') {
|
||||||
|
if (outputIndex === 0) {
|
||||||
|
data = {
|
||||||
|
inputTxId: '01f700df84c466f2a389440e5eeacdc47d04f380c39e5d19dce2ce91a11ecba3',
|
||||||
|
inputIndex: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else if (txid === '01f700df84c466f2a389440e5eeacdc47d04f380c39e5d19dce2ce91a11ecba3') {
|
||||||
|
if (outputIndex === 0) {
|
||||||
|
data = {
|
||||||
|
inputTxId: '661194e5533a395ce9076f292b7e0fb28fe94cd8832a81b4aa0517ff58c1ddd2',
|
||||||
|
inputIndex: 0
|
||||||
|
}
|
||||||
|
} else if (outputIndex === 1) {
|
||||||
|
data = {
|
||||||
|
inputTxId: '71a9e60c0341c9c258367f1a6d4253276f16e207bf84f41ff7412d8958a81bed',
|
||||||
|
inputIndex: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setImmediate(function() {
|
||||||
|
callback(null, data);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
network: 'testnet'
|
network: 'testnet'
|
||||||
@ -737,8 +784,6 @@ describe('Transactions', function() {
|
|||||||
"scriptPubKey": {
|
"scriptPubKey": {
|
||||||
"reqSigs": 1
|
"reqSigs": 1
|
||||||
},
|
},
|
||||||
"spentTxId": "01f700df84c466f2a389440e5eeacdc47d04f380c39e5d19dce2ce91a11ecba3",
|
|
||||||
"spentIndex": 0,
|
|
||||||
"spentTs": 1441072817
|
"spentTs": 1441072817
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -756,16 +801,12 @@ describe('Transactions', function() {
|
|||||||
"scriptPubKey": {
|
"scriptPubKey": {
|
||||||
"reqSigs": 1
|
"reqSigs": 1
|
||||||
},
|
},
|
||||||
"spentTxId": "661194e5533a395ce9076f292b7e0fb28fe94cd8832a81b4aa0517ff58c1ddd2",
|
|
||||||
"spentIndex": 0,
|
|
||||||
"spentTs": 1441077236
|
"spentTs": 1441077236
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"scriptPubKey": {
|
"scriptPubKey": {
|
||||||
"reqSigs": 1
|
"reqSigs": 1
|
||||||
},
|
},
|
||||||
"spentTxId": "71a9e60c0341c9c258367f1a6d4253276f16e207bf84f41ff7412d8958a81bed",
|
|
||||||
"spentIndex": 0,
|
|
||||||
"spentTs": 1441069523
|
"spentTs": 1441069523
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user