wallet/keypair: fixes.
This commit is contained in:
parent
156601e40a
commit
f3fd85354e
@ -5,10 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
var bcoin = require('../bcoin');
|
var bcoin = require('../bcoin');
|
||||||
var hash = require('hash.js');
|
|
||||||
var bn = require('bn.js');
|
var bn = require('bn.js');
|
||||||
var inherits = require('inherits');
|
|
||||||
var EventEmitter = require('events').EventEmitter;
|
|
||||||
var utils = bcoin.utils;
|
var utils = bcoin.utils;
|
||||||
var assert = utils.assert;
|
var assert = utils.assert;
|
||||||
var constants = bcoin.protocol.constants;
|
var constants = bcoin.protocol.constants;
|
||||||
@ -32,36 +29,36 @@ function KeyPair(options) {
|
|||||||
return options.key;
|
return options.key;
|
||||||
|
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.key = options.key || null;
|
this._key = options.key || null;
|
||||||
this.hd = options.hd || null;
|
this.hd = options.hd || null;
|
||||||
this.compressed = options.compressed !== false;
|
this.compressed = options.compressed !== false;
|
||||||
|
|
||||||
if (options.priv instanceof bcoin.hd.priv) {
|
if (options.priv instanceof bcoin.hd.priv) {
|
||||||
this.hd = options.priv;
|
this.hd = options.priv;
|
||||||
this.key = options.priv.pair;
|
this._key = options.priv.pair;
|
||||||
} else if (options.pub instanceof bcoin.hd.pub) {
|
} else if (options.pub instanceof bcoin.hd.pub) {
|
||||||
this.hd = options.pub;
|
this.hd = options.pub;
|
||||||
this.key = options.pub.pair;
|
this._key = options.pub.pair;
|
||||||
} else if (options.hd) {
|
} else if (options.hd) {
|
||||||
this.hd = typeof options.hd === 'object'
|
this.hd = typeof options.hd === 'object'
|
||||||
? bcoin.hd.priv(options.hd)
|
? bcoin.hd.priv(options.hd)
|
||||||
: bcoin.hd.priv();
|
: bcoin.hd.priv();
|
||||||
this.key = this.hd.pair;
|
this._key = this.hd.pair;
|
||||||
} else if (options.key) {
|
} else if (options.key) {
|
||||||
if ((options.key instanceof bcoin.hd.priv)
|
if ((options.key instanceof bcoin.hd.priv)
|
||||||
|| (options.key instanceof bcoin.hd.pub)) {
|
|| (options.key instanceof bcoin.hd.pub)) {
|
||||||
this.hd = options.key;
|
this.hd = options.key;
|
||||||
this.key = options.key.pair;
|
this._key = options.key.pair;
|
||||||
} else {
|
} else {
|
||||||
this.key = options.key;
|
this._key = options.key;
|
||||||
}
|
}
|
||||||
} else if (options.priv || options.pub) {
|
} else if (options.priv || options.pub) {
|
||||||
this.key = bcoin.ecdsa.keyPair({
|
this._key = bcoin.ecdsa.keyPair({
|
||||||
priv: options.priv,
|
priv: options.priv,
|
||||||
pub: options.pub
|
pub: options.pub
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.key = bcoin.ecdsa.genKeyPair({
|
this._key = bcoin.ecdsa.genKeyPair({
|
||||||
pers: options.personalization,
|
pers: options.personalization,
|
||||||
entropy: options.entropy
|
entropy: options.entropy
|
||||||
|| (options.passphrase ? utils.sha256(options.passphrase) : null)
|
|| (options.passphrase ? utils.sha256(options.passphrase) : null)
|
||||||
@ -70,15 +67,15 @@ function KeyPair(options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
KeyPair.prototype.__defineGetter__('priv', function() {
|
KeyPair.prototype.__defineGetter__('priv', function() {
|
||||||
return this.key.getPrivate();
|
return this._key.getPrivate();
|
||||||
});
|
});
|
||||||
|
|
||||||
KeyPair.prototype.__defineGetter__('pub', function() {
|
KeyPair.prototype.__defineGetter__('pub', function() {
|
||||||
return this.key.getPublic();
|
return this._key.getPublic();
|
||||||
});
|
});
|
||||||
|
|
||||||
KeyPair.prototype.getPrivate = function getPrivate(enc) {
|
KeyPair.prototype.getPrivate = function getPrivate(enc) {
|
||||||
var priv = this.key.getPrivate();
|
var priv = this._key.getPrivate();
|
||||||
|
|
||||||
if (!priv)
|
if (!priv)
|
||||||
return;
|
return;
|
||||||
@ -95,7 +92,7 @@ KeyPair.prototype.getPrivate = function getPrivate(enc) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
KeyPair.prototype.getPublic = function getPublic(enc) {
|
KeyPair.prototype.getPublic = function getPublic(enc) {
|
||||||
var pub = this.key.getPublic(this.compressed, 'array');
|
var pub = this._key.getPublic(this.compressed, 'array');
|
||||||
|
|
||||||
if (enc === 'base58')
|
if (enc === 'base58')
|
||||||
return utils.toBase58(pub);
|
return utils.toBase58(pub);
|
||||||
@ -182,7 +179,7 @@ KeyPair.prototype.toJSON = function toJSON(encrypt) {
|
|||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.key.priv) {
|
if (this._key.priv) {
|
||||||
json.priv = encrypt
|
json.priv = encrypt
|
||||||
? encrypt(this.getPrivate('base58'))
|
? encrypt(this.getPrivate('base58'))
|
||||||
: this.getPrivate('base58');
|
: this.getPrivate('base58');
|
||||||
|
|||||||
@ -64,12 +64,17 @@ TXPool.prototype._init = function init() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
TXPool.prototype.add = function add(tx, noWrite) {
|
TXPool.prototype.add = function add(tx, noWrite, strict) {
|
||||||
var hash = tx.hash('hex');
|
var hash = tx.hash('hex');
|
||||||
var updated;
|
var updated;
|
||||||
var i, input, key, unspent, index, orphan;
|
var i, input, key, unspent, index, orphan;
|
||||||
var out, key, orphans, some;
|
var out, key, orphans, some;
|
||||||
|
|
||||||
|
if (strict) {
|
||||||
|
if (!this._wallet.ownInput(tx) && !this._wallet.ownOutput(tx))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Ignore stale pending transactions
|
// Ignore stale pending transactions
|
||||||
if (tx.ts === 0 && tx.ps + 2 * 24 * 3600 < utils.now()) {
|
if (tx.ts === 0 && tx.ps + 2 * 24 * 3600 < utils.now()) {
|
||||||
this._removeTX(tx, noWrite);
|
this._removeTX(tx, noWrite);
|
||||||
@ -80,9 +85,12 @@ TXPool.prototype.add = function add(tx, noWrite) {
|
|||||||
if (this._all[hash]) {
|
if (this._all[hash]) {
|
||||||
// Transaction was confirmed, update it in storage
|
// Transaction was confirmed, update it in storage
|
||||||
if (tx.ts !== 0 && this._all[hash].ts === 0) {
|
if (tx.ts !== 0 && this._all[hash].ts === 0) {
|
||||||
|
this._all[hash].ps = 0;
|
||||||
this._all[hash].ts = tx.ts;
|
this._all[hash].ts = tx.ts;
|
||||||
this._all[hash].block = tx.block;
|
this._all[hash].block = tx.block;
|
||||||
this._storeTX(hash, tx, noWrite);
|
this._storeTX(hash, tx, noWrite);
|
||||||
|
this.emit('tx', tx);
|
||||||
|
this.emit('confirmed', tx);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,6 +29,8 @@ function Wallet(options) {
|
|||||||
if (!options)
|
if (!options)
|
||||||
options = {};
|
options = {};
|
||||||
|
|
||||||
|
options = utils.merge({}, options);
|
||||||
|
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.addresses = [];
|
this.addresses = [];
|
||||||
this.master = options.master || null;
|
this.master = options.master || null;
|
||||||
@ -39,23 +41,24 @@ function Wallet(options) {
|
|||||||
this.addressIndex = options.addressIndex || 0;
|
this.addressIndex = options.addressIndex || 0;
|
||||||
this.changeIndex = options.changeIndex || 0;
|
this.changeIndex = options.changeIndex || 0;
|
||||||
|
|
||||||
if (options.addresses && options.addresses.length > 0) {
|
if (!options.addresses)
|
||||||
options.addresses.forEach(function(address) {
|
options.addresses = [];
|
||||||
this.addAddress(address);
|
|
||||||
}, this);
|
if (!options.addresses.length)
|
||||||
} else {
|
options.addresses.push(utils.merge({}, options));
|
||||||
this.createNewAddress(options);
|
|
||||||
}
|
options.addresses.forEach(function(address) {
|
||||||
|
this.addAddress(address);
|
||||||
|
}, this);
|
||||||
|
|
||||||
// Create a non-master account address if we don't have one.
|
// Create a non-master account address if we don't have one.
|
||||||
// Might not be necessary now.
|
|
||||||
if (this.master) {
|
if (this.master) {
|
||||||
for (i = 0; i < this.addresses.length; i++) {
|
for (i = 0; i < this.addresses.length; i++) {
|
||||||
if (this.addresses[i].key.hd && !this.addresses[i].change)
|
if (this.addresses[i].key.hd && !this.addresses[i].change)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i === this.addresses.length)
|
if (i === this.addresses.length)
|
||||||
this.createNewAddress(options);
|
this.createNewAddress(this._cleanOptions(options.addresses[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the last change address if there is one.
|
// Find the last change address if there is one.
|
||||||
@ -70,7 +73,6 @@ function Wallet(options) {
|
|||||||
this.changeAddress = this.addresses[i];
|
this.changeAddress = this.addresses[i];
|
||||||
|
|
||||||
this.storage = options.storage;
|
this.storage = options.storage;
|
||||||
this.label = options.label || '';
|
|
||||||
this.loaded = false;
|
this.loaded = false;
|
||||||
this.lastTs = 0;
|
this.lastTs = 0;
|
||||||
|
|
||||||
@ -83,6 +85,15 @@ function Wallet(options) {
|
|||||||
|
|
||||||
inherits(Wallet, EventEmitter);
|
inherits(Wallet, EventEmitter);
|
||||||
|
|
||||||
|
Wallet.prototype._cleanOptions = function _cleanOptions(options) {
|
||||||
|
return utils.merge(options, {
|
||||||
|
key: null,
|
||||||
|
priv: null,
|
||||||
|
pub: null,
|
||||||
|
hd: null
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
Wallet.prototype._init = function init() {
|
Wallet.prototype._init = function init() {
|
||||||
var self = this;
|
var self = this;
|
||||||
var prevBalance = null;
|
var prevBalance = null;
|
||||||
@ -104,8 +115,10 @@ Wallet.prototype._init = function init() {
|
|||||||
this.tx.on('tx', function(tx) {
|
this.tx.on('tx', function(tx) {
|
||||||
// TX using this change address was
|
// TX using this change address was
|
||||||
// confirmed. Allocate a new change address.
|
// confirmed. Allocate a new change address.
|
||||||
if (self.changeAddress.ownOutput(tx))
|
if (tx.block) {
|
||||||
self.changeAddress = self.createChangeAddress();
|
if (self.changeAddress.ownOutput(tx))
|
||||||
|
self.changeAddress = self.createChangeAddress();
|
||||||
|
}
|
||||||
self.emit('tx', tx);
|
self.emit('tx', tx);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -231,6 +244,9 @@ Wallet.prototype.addAddress = function addAddress(address) {
|
|||||||
|
|
||||||
this._addressTable[address.getKeyAddress()] = index;
|
this._addressTable[address.getKeyAddress()] = index;
|
||||||
|
|
||||||
|
if (address.label && this._labelTable[address.label] == null)
|
||||||
|
this._labelTable[address.label] = index;
|
||||||
|
|
||||||
this.emit('add address', address);
|
this.emit('add address', address);
|
||||||
|
|
||||||
return address;
|
return address;
|
||||||
@ -258,6 +274,9 @@ Wallet.prototype.removeAddress = function removeAddress(address) {
|
|||||||
delete address._onUpdate;
|
delete address._onUpdate;
|
||||||
delete address._wallet;
|
delete address._wallet;
|
||||||
|
|
||||||
|
if (this._labelTable[address.label] === i)
|
||||||
|
delete this._labelTable[address.label];
|
||||||
|
|
||||||
this.emit('remove address', address);
|
this.emit('remove address', address);
|
||||||
|
|
||||||
return address;
|
return address;
|
||||||
@ -538,7 +557,6 @@ Wallet.prototype.toJSON = function toJSON(encrypt) {
|
|||||||
v: 3,
|
v: 3,
|
||||||
name: 'wallet',
|
name: 'wallet',
|
||||||
network: network.type,
|
network: network.type,
|
||||||
label: this.label,
|
|
||||||
accountIndex: this.accountIndex,
|
accountIndex: this.accountIndex,
|
||||||
addressIndex: this.addressIndex,
|
addressIndex: this.addressIndex,
|
||||||
changeIndex: this.changeIndex,
|
changeIndex: this.changeIndex,
|
||||||
@ -569,7 +587,6 @@ Wallet.fromJSON = function fromJSON(json, decrypt) {
|
|||||||
assert.equal(json.network, network.type);
|
assert.equal(json.network, network.type);
|
||||||
|
|
||||||
w = new Wallet({
|
w = new Wallet({
|
||||||
label: json.label,
|
|
||||||
accountIndex: json.accountIndex,
|
accountIndex: json.accountIndex,
|
||||||
addressIndex: json.addressIndex,
|
addressIndex: json.addressIndex,
|
||||||
changeIndex: json.changeIndex,
|
changeIndex: json.changeIndex,
|
||||||
@ -589,7 +606,7 @@ Wallet.fromJSON = function fromJSON(json, decrypt) {
|
|||||||
for (i = 0; i < w.changeIndex; i++) {
|
for (i = 0; i < w.changeIndex; i++) {
|
||||||
w.addAddress({
|
w.addAddress({
|
||||||
change: true,
|
change: true,
|
||||||
key: w.master.key.hd.deriveChange(w.accountIndex, i)
|
priv: w.master.key.hd.deriveChange(w.accountIndex, i)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user