bitcore-node-zcash/app/models/Address.js

204 lines
5.4 KiB
JavaScript
Raw Normal View History

2014-01-09 15:24:14 -08:00
'use strict';
2014-03-10 11:06:10 -07:00
var imports = require('soop').imports();
2014-03-05 18:03:56 -08:00
var async = require('async');
2014-05-07 05:45:44 -07:00
var bitcore = require('bitcore');
var BitcoreAddress = bitcore.Address;
var BitcoreTransaction = bitcore.Transaction;
var BitcoreUtil = bitcore.util;
2014-05-07 06:42:45 -07:00
var Parser = bitcore.BinaryParser;
2014-05-07 05:45:44 -07:00
var Buffer = bitcore.Buffer;
2014-03-10 11:06:10 -07:00
var TransactionDb = imports.TransactionDb || require('../../lib/TransactionDb').default();
2014-05-25 13:34:49 -07:00
var BlockDb = imports.BlockDb || require('../../lib/BlockDb').default();
var config = require('../../config/config');
2014-03-05 18:03:56 -08:00
var CONCURRENCY = 5;
function Address(addrStr) {
this.balanceSat = 0;
this.totalReceivedSat = 0;
this.totalSentSat = 0;
this.unconfirmedBalanceSat = 0;
this.txApperances = 0;
this.unconfirmedTxApperances= 0;
2014-05-25 13:34:49 -07:00
this.seen = {};
2014-03-05 18:03:56 -08:00
// TODO store only txids? +index? +all?
this.transactions = [];
2014-05-28 05:50:01 -07:00
this.unspent = [];
2014-03-05 18:03:56 -08:00
var a = new BitcoreAddress(addrStr);
a.validate();
this.addrStr = addrStr;
Object.defineProperty(this, 'totalSent', {
get: function() {
return parseFloat(this.totalSentSat) / parseFloat(BitcoreUtil.COIN);
},
set: function(i) {
this.totalSentSat = i * BitcoreUtil.COIN;
},
enumerable: 1,
});
Object.defineProperty(this, 'balance', {
get: function() {
return parseFloat(this.balanceSat) / parseFloat(BitcoreUtil.COIN);
},
set: function(i) {
this.balance = i * BitcoreUtil.COIN;
},
enumerable: 1,
});
Object.defineProperty(this, 'totalReceived', {
get: function() {
return parseFloat(this.totalReceivedSat) / parseFloat(BitcoreUtil.COIN);
},
set: function(i) {
this.totalReceived = i * BitcoreUtil.COIN;
},
enumerable: 1,
});
Object.defineProperty(this, 'unconfirmedBalance', {
get: function() {
return parseFloat(this.unconfirmedBalanceSat) / parseFloat(BitcoreUtil.COIN);
},
set: function(i) {
this.unconfirmedBalanceSat = i * BitcoreUtil.COIN;
},
enumerable: 1,
});
2014-03-05 18:03:56 -08:00
}
2014-05-27 14:02:32 -07:00
Address.prototype.getObj = function() {
// Normalize json address
return {
'addrStr': this.addrStr,
'balance': this.balance,
'balanceSat': this.balanceSat,
'totalReceived': this.totalReceived,
'totalReceivedSat': this.totalReceivedSat,
'totalSent': this.totalSent,
'totalSentSat': this.totalSentSat,
'unconfirmedBalance': this.unconfirmedBalance,
'unconfirmedBalanceSat': this.unconfirmedBalanceSat,
'unconfirmedTxApperances': this.unconfirmedTxApperances,
'txApperances': this.txApperances,
'transactions': this.transactions
};
};
2014-05-28 05:31:59 -07:00
Address.prototype._addTxItem = function(txItem, txList) {
2014-05-25 13:34:49 -07:00
var add=0, addSpend=0;
var v = txItem.value_sat;
var seen = this.seen;
2014-05-28 05:31:59 -07:00
// Founding tx
2014-05-25 13:34:49 -07:00
if ( !seen[txItem.txid] ) {
seen[txItem.txid]=1;
add=1;
2014-05-28 05:31:59 -07:00
if (txList)
2014-05-28 09:17:08 -07:00
txList.push(txItem.txid);
2014-05-25 13:34:49 -07:00
}
2014-05-28 05:31:59 -07:00
// Spent tx
2014-05-25 13:34:49 -07:00
if (txItem.spentTxId && !seen[txItem.spentTxId] ) {
2014-05-28 05:31:59 -07:00
if (txList) {
2014-05-28 09:17:08 -07:00
txList.push(txItem.spentTxId);
2014-05-25 13:34:49 -07:00
}
seen[txItem.spentTxId]=1;
addSpend=1;
}
if (txItem.isConfirmed) {
this.txApperances += add;
this.totalReceivedSat += v;
if (! txItem.spentTxId ) {
//unspent
this.balanceSat += v;
}
else if(!txItem.spentIsConfirmed) {
// unspent
this.balanceSat += v;
this.unconfirmedBalanceSat -= v;
this.unconfirmedTxApperances += addSpend;
}
else {
// spent
this.totalSentSat += v;
this.txApperances += addSpend;
}
}
else {
this.unconfirmedBalanceSat += v;
this.unconfirmedTxApperances += add;
}
};
2014-05-28 05:50:01 -07:00
// opts are
// .onlyUnspent
2014-05-28 09:17:08 -07:00
// .txLimit (=0 -> no txs, => -1 no limit)
//
2014-05-28 05:31:59 -07:00
Address.prototype.update = function(next, opts) {
2014-03-05 18:03:56 -08:00
var self = this;
if (!self.addrStr) return next();
2014-05-28 05:31:59 -07:00
opts = opts || {};
2014-03-05 18:03:56 -08:00
2014-05-30 10:10:32 -07:00
if (! ('ignoreCache' in opts) )
opts.ignoreCache = config.ignoreCache;
// should collect txList from address?
2014-05-28 09:17:08 -07:00
var txList = opts.txLimit === 0 ? null: [];
2014-05-30 10:10:32 -07:00
2014-05-25 13:34:49 -07:00
var tDb = TransactionDb;
var bDb = BlockDb;
2014-05-30 10:10:32 -07:00
tDb.fromAddr(self.addrStr, opts, function(err,txOut){
2014-05-25 13:34:49 -07:00
if (err) return next(err);
2014-03-05 18:03:56 -08:00
2014-05-25 13:34:49 -07:00
bDb.fillConfirmations(txOut, function(err) {
if (err) return next(err);
2014-05-28 05:50:01 -07:00
2014-05-25 13:34:49 -07:00
tDb.cacheConfirmations(txOut, function(err) {
2014-05-28 09:17:08 -07:00
// console.log('[Address.js.161:txOut:]',txOut); //TODO
2014-05-25 13:34:49 -07:00
if (err) return next(err);
2014-05-28 05:50:01 -07:00
if (opts.onlyUnspent) {
txOut = txOut.filter(function(x){
return !x.spentTxId;
});
tDb.fillScriptPubKey(txOut, function() {
self.unspent = txOut.map(function(x){
return {
address: self.addrStr,
txid: x.txid,
vout: x.index,
ts: x.ts,
scriptPubKey: x.scriptPubKey,
amount: x.value_sat / BitcoreUtil.COIN,
confirmations: x.isConfirmedCached ? (config.safeConfirmations+'+') : x.confirmations,
};
});
return next();
});
}
else {
txOut.forEach(function(txItem){
self._addTxItem(txItem, txList);
});
2014-05-30 10:10:32 -07:00
if (txList)
self.transactions = txList;
2014-05-28 05:50:01 -07:00
return next();
}
2014-05-25 13:34:49 -07:00
});
});
2014-03-05 18:03:56 -08:00
});
};
2014-05-28 05:31:59 -07:00
2014-03-05 18:03:56 -08:00
module.exports = require('soop')(Address);