wallet provider.
This commit is contained in:
parent
4df5b305ea
commit
e962686e93
@ -86,7 +86,6 @@ TXPool.prototype.getMap = function getMap(tx, callback) {
|
|||||||
map.input = [];
|
map.input = [];
|
||||||
map.output = [];
|
map.output = [];
|
||||||
map.all = [];
|
map.all = [];
|
||||||
map.table = {};
|
|
||||||
|
|
||||||
tx.getInputAddresses().forEach(function(address) {
|
tx.getInputAddresses().forEach(function(address) {
|
||||||
assert(map[address]);
|
assert(map[address]);
|
||||||
@ -101,10 +100,6 @@ TXPool.prototype.getMap = function getMap(tx, callback) {
|
|||||||
map.input = utils.uniqs(map.input);
|
map.input = utils.uniqs(map.input);
|
||||||
map.output = utils.uniqs(map.output);
|
map.output = utils.uniqs(map.output);
|
||||||
map.all = utils.uniqs(map.input.concat(map.output));
|
map.all = utils.uniqs(map.input.concat(map.output));
|
||||||
map.table = map.all.reduce(function(out, id) {
|
|
||||||
out[id] = true;
|
|
||||||
return out;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
return callback(null, map);
|
return callback(null, map);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,8 +44,6 @@ function Wallet(options) {
|
|||||||
options.master = bcoin.hd.fromSeed();
|
options.master = bcoin.hd.fromSeed();
|
||||||
|
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.db = options.db || null;
|
|
||||||
this.tx = options.tx || null;
|
|
||||||
this.provider = options.provider || null;
|
this.provider = options.provider || null;
|
||||||
this.addresses = [];
|
this.addresses = [];
|
||||||
this.master = options.master || null;
|
this.master = options.master || null;
|
||||||
@ -131,61 +129,36 @@ Wallet.prototype._init = function _init() {
|
|||||||
assert(!this.receiveAddress.change);
|
assert(!this.receiveAddress.change);
|
||||||
assert(this.changeAddress.change);
|
assert(this.changeAddress.change);
|
||||||
|
|
||||||
if (!this.tx)
|
if (!this.provider)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.tx.on('tx', this._onTX = function(tx) {
|
this.provider.setID(this.id);
|
||||||
if (!self.ownInput(tx) && !self.ownOutput(tx))
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
this.provider.on('tx', function(tx) {
|
||||||
self.emit('tx', tx);
|
self.emit('tx', tx);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.tx.on('updated', this._onUpdated = function(tx) {
|
this.provider.on('updated', function(tx) {
|
||||||
if (!self.ownInput(tx) && !self.ownOutput(tx))
|
|
||||||
return;
|
|
||||||
|
|
||||||
self.emit('updated', tx);
|
self.emit('updated', tx);
|
||||||
|
|
||||||
if (!self.provider)
|
|
||||||
return;
|
|
||||||
|
|
||||||
self.getBalance(function(err, balance) {
|
|
||||||
if (err)
|
|
||||||
return self.emit('error', err);
|
|
||||||
|
|
||||||
self.emit('balance', balance);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.tx.on('confirmed', this._onConfirmed = function(tx) {
|
this.provider.on('balance', function(balance) {
|
||||||
if (!self.ownInput(tx) && !self.ownOutput(tx))
|
self.emit('balance', balance);
|
||||||
return;
|
});
|
||||||
|
|
||||||
|
this.provider.on('confirmed', function(tx) {
|
||||||
self.syncOutputDepth(tx);
|
self.syncOutputDepth(tx);
|
||||||
self.emit('confirmed', tx);
|
self.emit('confirmed', tx);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.provider.on('unconfirmed', function(tx) {
|
||||||
|
self.syncOutputDepth(tx);
|
||||||
|
self.emit('unconfirmed', tx);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.destroy = function destroy() {
|
Wallet.prototype.destroy = function destroy() {
|
||||||
if (this.tx) {
|
this.provider.destroy();
|
||||||
if (this._onTX) {
|
|
||||||
this.tx.removeListener('tx', this._onTX);
|
|
||||||
delete this._onTX;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._onUpdated) {
|
|
||||||
this.tx.removeListener('updated', this._onUpdated);
|
|
||||||
delete this._onUpdated;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._onConfirmed) {
|
|
||||||
this.tx.removeListener('confirmed', this._onConfirmed);
|
|
||||||
delete this._onConfirmed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.db = null;
|
|
||||||
this.tx = null;
|
|
||||||
this.provider = null;
|
this.provider = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -407,8 +380,8 @@ Wallet.prototype.deriveAddress = function deriveAddress(change, index) {
|
|||||||
this.addressMap[address.getProgramAddress()] = data.path;
|
this.addressMap[address.getProgramAddress()] = data.path;
|
||||||
|
|
||||||
// Update the DB with the new address.
|
// Update the DB with the new address.
|
||||||
if (this.db)
|
if (this.provider && this.provider.update)
|
||||||
this.db.update(this, address);
|
this.provider.update(this, address);
|
||||||
|
|
||||||
this.emit('add address', address);
|
this.emit('add address', address);
|
||||||
|
|
||||||
@ -539,7 +512,21 @@ Wallet.prototype.fillPrevout = function fillPrevout(tx, callback) {
|
|||||||
if (!this.provider)
|
if (!this.provider)
|
||||||
return callback(new Error('No wallet provider available.'));
|
return callback(new Error('No wallet provider available.'));
|
||||||
|
|
||||||
return this.provider.fillCoin(tx, callback);
|
return this.provider.fillTX(tx, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
Wallet.prototype.getCoin = function getCoin(id, callback) {
|
||||||
|
if (!this.provider)
|
||||||
|
return callback(new Error('No wallet provider available.'));
|
||||||
|
|
||||||
|
return this.provider.getCoin(id, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
Wallet.prototype.getTX = function getTX(hash, callback) {
|
||||||
|
if (!this.provider)
|
||||||
|
return callback(new Error('No wallet provider available.'));
|
||||||
|
|
||||||
|
return this.provider.getTX(hash, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.createTX = function createTX(options, outputs, callback) {
|
Wallet.prototype.createTX = function createTX(options, outputs, callback) {
|
||||||
@ -801,45 +788,45 @@ Wallet.prototype.sign = function sign(tx, type, index) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.addTX = function addTX(tx, callback) {
|
Wallet.prototype.addTX = function addTX(tx, callback) {
|
||||||
if (!this.tx)
|
if (!this.provider || !this.provider.addTX)
|
||||||
return callback(new Error('No transaction pool available.'));
|
return callback(new Error('No transaction pool available.'));
|
||||||
|
|
||||||
return this.tx.add(tx, callback);
|
return this.provider.addTX(tx, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.getAll = function getAll(callback) {
|
Wallet.prototype.getAll = function getAll(callback) {
|
||||||
if (!this.provider)
|
if (!this.provider)
|
||||||
return callback(new Error('No wallet provider available.'));
|
return callback(new Error('No wallet provider available.'));
|
||||||
|
|
||||||
return this.provider.getAll(this, callback);
|
return this.provider.getAll(callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.getCoins = function getCoins(callback) {
|
Wallet.prototype.getCoins = function getCoins(callback) {
|
||||||
if (!this.provider)
|
if (!this.provider)
|
||||||
return callback(new Error('No wallet provider available.'));
|
return callback(new Error('No wallet provider available.'));
|
||||||
|
|
||||||
return this.provider.getCoins(this, callback);
|
return this.provider.getCoins(callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.getPending = function getPending(callback) {
|
Wallet.prototype.getPending = function getPending(callback) {
|
||||||
if (!this.provider)
|
if (!this.provider)
|
||||||
return callback(new Error('No wallet provider available.'));
|
return callback(new Error('No wallet provider available.'));
|
||||||
|
|
||||||
return this.provider.getPending(this, callback);
|
return this.provider.getPending(callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.getBalance = function getBalance(callback) {
|
Wallet.prototype.getBalance = function getBalance(callback) {
|
||||||
if (!this.provider)
|
if (!this.provider)
|
||||||
return callback(new Error('No wallet provider available.'));
|
return callback(new Error('No wallet provider available.'));
|
||||||
|
|
||||||
return this.provider.getBalance(this, callback);
|
return this.provider.getBalance(callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.getLast = function getLast(callback) {
|
Wallet.prototype.getLast = function getLast(callback) {
|
||||||
if (!this.provider)
|
if (!this.provider)
|
||||||
return callback(new Error('No wallet provider available.'));
|
return callback(new Error('No wallet provider available.'));
|
||||||
|
|
||||||
return this.provider.getLast(this, callback);
|
return this.provider.getLast(callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.getPrivateKey = function getPrivateKey(enc) {
|
Wallet.prototype.getPrivateKey = function getPrivateKey(enc) {
|
||||||
|
|||||||
@ -125,9 +125,42 @@ WalletDB.prototype._init = function _init() {
|
|||||||
self.emit('error', err);
|
self.emit('error', err);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.tx.on('tx', function(tx, map) {
|
||||||
|
map.all.forEach(function(id) {
|
||||||
|
self.emit(id + ' tx', tx);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.tx.on('confirmed', function(tx, map) {
|
||||||
|
map.all.forEach(function(id) {
|
||||||
|
self.emit(id + ' confirmed', tx);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.tx.on('unconfirmed', function(tx, map) {
|
||||||
|
map.all.forEach(function(id) {
|
||||||
|
self.emit(id + ' unconfirmed', tx);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
this.tx.on('updated', function(tx, map) {
|
this.tx.on('updated', function(tx, map) {
|
||||||
self.emit('wallet tx', tx, map);
|
self.emit('wallet tx', tx, map);
|
||||||
|
|
||||||
|
utils.forEachSerial(map.output, function(id, next) {
|
||||||
|
if (self.listeners(id + ' balance').length === 0)
|
||||||
|
return next();
|
||||||
|
|
||||||
|
self.getBalance(id, function(err, balance) {
|
||||||
|
if (err)
|
||||||
|
return self.emit('error', err);
|
||||||
|
|
||||||
|
self.emit(id + ' balance', balance);
|
||||||
|
});
|
||||||
|
}, function(err) {
|
||||||
|
if (err)
|
||||||
|
self.emit('error', err);
|
||||||
|
});
|
||||||
|
|
||||||
// Only sync for confirmed txs.
|
// Only sync for confirmed txs.
|
||||||
if (tx.ts === 0)
|
if (tx.ts === 0)
|
||||||
return;
|
return;
|
||||||
@ -145,6 +178,7 @@ WalletDB.prototype._init = function _init() {
|
|||||||
self.saveJSON(id, json, function(err) {
|
self.saveJSON(id, json, function(err) {
|
||||||
if (err)
|
if (err)
|
||||||
return next(err);
|
return next(err);
|
||||||
|
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -197,7 +231,7 @@ WalletDB.prototype.saveJSON = function saveJSON(id, json, callback) {
|
|||||||
|
|
||||||
callback = utils.ensure(callback);
|
callback = utils.ensure(callback);
|
||||||
|
|
||||||
function cb(err, json) {
|
return this._saveDB(id, json, function(err, json) {
|
||||||
var batch;
|
var batch;
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
@ -216,9 +250,7 @@ WalletDB.prototype.saveJSON = function saveJSON(id, json, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return callback(null, json);
|
return callback(null, json);
|
||||||
}
|
});
|
||||||
|
|
||||||
return this._saveDB(id, json, cb);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
WalletDB.prototype.removeJSON = function removeJSON(id, callback) {
|
WalletDB.prototype.removeJSON = function removeJSON(id, callback) {
|
||||||
@ -229,7 +261,7 @@ WalletDB.prototype.removeJSON = function removeJSON(id, callback) {
|
|||||||
if (typeof id === 'object')
|
if (typeof id === 'object')
|
||||||
id = id.id;
|
id = id.id;
|
||||||
|
|
||||||
function cb(err, json) {
|
return this._removeDB(id, function(err, json) {
|
||||||
var batch;
|
var batch;
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
@ -248,9 +280,7 @@ WalletDB.prototype.removeJSON = function removeJSON(id, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return callback(null, json);
|
return callback(null, json);
|
||||||
}
|
});
|
||||||
|
|
||||||
return this._removeDB(id, cb);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
WalletDB.prototype._getDB = function _getDB(id, callback) {
|
WalletDB.prototype._getDB = function _getDB(id, callback) {
|
||||||
@ -334,9 +364,7 @@ WalletDB.prototype.get = function get(id, passphrase, callback) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
options = bcoin.wallet._fromJSON(options, passphrase);
|
options = bcoin.wallet._fromJSON(options, passphrase);
|
||||||
options.db = self;
|
options.provider = new Provider(self);
|
||||||
options.tx = self.tx;
|
|
||||||
options.provider = self;
|
|
||||||
wallet = new bcoin.wallet(options);
|
wallet = new bcoin.wallet(options);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return callback(e);
|
return callback(e);
|
||||||
@ -398,18 +426,14 @@ WalletDB.prototype.create = function create(options, callback) {
|
|||||||
if (json) {
|
if (json) {
|
||||||
try {
|
try {
|
||||||
options = bcoin.wallet._fromJSON(json, options.passphrase);
|
options = bcoin.wallet._fromJSON(json, options.passphrase);
|
||||||
options.db = self;
|
options.provider = new Provider(self);
|
||||||
options.tx = self.tx;
|
|
||||||
options.provider = self;
|
|
||||||
wallet = new bcoin.wallet(options);
|
wallet = new bcoin.wallet(options);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return callback(e);
|
return callback(e);
|
||||||
}
|
}
|
||||||
done();
|
done();
|
||||||
} else {
|
} else {
|
||||||
options.db = self;
|
options.provider = new Provider(self);
|
||||||
options.tx = self.tx;
|
|
||||||
options.provider = self;
|
|
||||||
wallet = new bcoin.wallet(options);
|
wallet = new bcoin.wallet(options);
|
||||||
self.saveJSON(wallet.id, wallet.toJSON(), done);
|
self.saveJSON(wallet.id, wallet.toJSON(), done);
|
||||||
}
|
}
|
||||||
@ -535,6 +559,125 @@ WalletDB.prototype.removeBlock = function removeBlock(block, callback) {
|
|||||||
}, callback);
|
}, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provider
|
||||||
|
*/
|
||||||
|
|
||||||
|
function Provider(db) {
|
||||||
|
if (!(this instanceof Provider))
|
||||||
|
return new Provider(db);
|
||||||
|
|
||||||
|
EventEmitter.call(this);
|
||||||
|
|
||||||
|
this.db = db;
|
||||||
|
this.id = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
utils.inherits(Provider, EventEmitter);
|
||||||
|
|
||||||
|
Provider.prototype.setID = function setID(id) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
assert(!this.id);
|
||||||
|
|
||||||
|
this.id = id;
|
||||||
|
|
||||||
|
this.db.on(id + ' tx', this._onTX = function(tx) {
|
||||||
|
self.emit('tx', tx);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.db.on(id + ' updated', this._onUpdated = function(tx) {
|
||||||
|
self.emit('updated', tx);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.db.on(id + ' confirmed', this._onConfirmed = function(tx) {
|
||||||
|
self.emit('confirmed', tx);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.db.on(id + ' unconfirmed', this._onUnconfirmed = function(tx) {
|
||||||
|
self.emit('unconfirmed', tx);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.db.on(id + ' balance', this._onBalance = function(balance) {
|
||||||
|
self.emit('balance', balance);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Provider.prototype.destroy = function destroy() {
|
||||||
|
if (this.db) {
|
||||||
|
if (this._onTX) {
|
||||||
|
this.removeListener(this.id + ' tx', this._onTX);
|
||||||
|
delete this._onTX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._onUpdated) {
|
||||||
|
this.removeListener(this.id + ' updated', this._onUpdated);
|
||||||
|
delete this._onUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._onConfirmed) {
|
||||||
|
this.removeListener(this.id + ' confirmed', this._onConfirmed);
|
||||||
|
delete this._onConfirmed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._onUnconfirmed) {
|
||||||
|
this.removeListener(this.id + ' unconfirmed', this._onUnconfirmed);
|
||||||
|
delete this._onUnconfirmed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._onBalance) {
|
||||||
|
this.removeListener(this.id + ' balance', this._onBalance);
|
||||||
|
delete this._onBalance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.db = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
Provider.prototype.getAll = function getAll(callback) {
|
||||||
|
return this.db.getAll(this.id, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
Provider.prototype.getCoins = function getCoins(callback) {
|
||||||
|
return this.db.getCoins(this.id, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
Provider.prototype.getPending = function getPending(callback) {
|
||||||
|
return this.db.getPending(this.id, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
Provider.prototype.getBalance = function getBalance(callback) {
|
||||||
|
return this.db.getBalance(this.id, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
Provider.prototype.getLast = function getLast(callback) {
|
||||||
|
return this.db.getLast(this.id, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
Provider.prototype.getTX = function getTX(hash, callback) {
|
||||||
|
return this.db.getTX(hash, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
Provider.prototype.getCoin = function getCoin(hash, index, callback) {
|
||||||
|
return this.db.getCoin(hash, index, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
Provider.prototype.fillTX = function fillTX(tx, callback) {
|
||||||
|
return this.db.fillTX(tx, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
Provider.prototype.fillCoin = function fillCoin(tx, callback) {
|
||||||
|
return this.db.fillCoin(tx, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
Provider.prototype.addTX = function addTX(tx, callback) {
|
||||||
|
return this.db.tx.add(tx, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
Provider.prototype.update = function update(wallet, address) {
|
||||||
|
return this.db.update(wallet, address);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expose
|
* Expose
|
||||||
*/
|
*/
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user