wallet: multiple refactors.
This commit is contained in:
parent
60bd3e751e
commit
e8f2c3321c
100
lib/bcoin/hd.js
100
lib/bcoin/hd.js
@ -821,6 +821,26 @@ HD.isHD = function isHD(obj) {
|
|||||||
|| HDPublicKey.isHDPublicKey(obj);
|
|| HDPublicKey.isHDPublicKey(obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether an object is an HD private key.
|
||||||
|
* @param {Object} obj
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
HD.isPrivate = function isPrivate(obj) {
|
||||||
|
return HDPrivateKey.isHDPrivateKey(obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether an object is an HD public key.
|
||||||
|
* @param {Object} obj
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
HD.isPublic = function isPublic(obj) {
|
||||||
|
return HDPublicKey.isHDPublicKey(obj);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HDPrivateKey
|
* HDPrivateKey
|
||||||
* @exports HDPrivateKey
|
* @exports HDPrivateKey
|
||||||
@ -1223,6 +1243,46 @@ HDPrivateKey.prototype.equal = function equal(obj) {
|
|||||||
&& utils.equal(this.privateKey, obj.privateKey);
|
&& utils.equal(this.privateKey, obj.privateKey);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare a key against an object.
|
||||||
|
* @param {Object} obj
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
HDPrivateKey.prototype.compare = function compare(key) {
|
||||||
|
var cmp;
|
||||||
|
|
||||||
|
if (!HDPrivateKey.isHDPrivateKey(key))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
cmp = this.depth - key.depth;
|
||||||
|
|
||||||
|
if (cmp !== 0)
|
||||||
|
return cmp;
|
||||||
|
|
||||||
|
cmp = utils.cmp(this.parentFingerPrint, key.parentFingerPrint);
|
||||||
|
|
||||||
|
if (cmp !== 0)
|
||||||
|
return cmp;
|
||||||
|
|
||||||
|
cmp = this.childIndex - key.childIndex;
|
||||||
|
|
||||||
|
if (cmp !== 0)
|
||||||
|
return cmp;
|
||||||
|
|
||||||
|
cmp = utils.cmp(this.chainCode, key.chainCode);
|
||||||
|
|
||||||
|
if (cmp !== 0)
|
||||||
|
return cmp;
|
||||||
|
|
||||||
|
cmp = utils.cmp(this.privateKey, key.privateKey);
|
||||||
|
|
||||||
|
if (cmp !== 0)
|
||||||
|
return cmp;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inject properties from seed.
|
* Inject properties from seed.
|
||||||
* @private
|
* @private
|
||||||
@ -1838,6 +1898,46 @@ HDPublicKey.prototype.equal = function equal(obj) {
|
|||||||
&& utils.equal(this.publicKey, obj.publicKey);
|
&& utils.equal(this.publicKey, obj.publicKey);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare a key against an object.
|
||||||
|
* @param {Object} obj
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
HDPublicKey.prototype.compare = function compare(key) {
|
||||||
|
var cmp;
|
||||||
|
|
||||||
|
if (!HDPublicKey.isHDPublicKey(key))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
cmp = this.depth - key.depth;
|
||||||
|
|
||||||
|
if (cmp !== 0)
|
||||||
|
return cmp;
|
||||||
|
|
||||||
|
cmp = utils.cmp(this.parentFingerPrint, key.parentFingerPrint);
|
||||||
|
|
||||||
|
if (cmp !== 0)
|
||||||
|
return cmp;
|
||||||
|
|
||||||
|
cmp = this.childIndex - key.childIndex;
|
||||||
|
|
||||||
|
if (cmp !== 0)
|
||||||
|
return cmp;
|
||||||
|
|
||||||
|
cmp = utils.cmp(this.chainCode, key.chainCode);
|
||||||
|
|
||||||
|
if (cmp !== 0)
|
||||||
|
return cmp;
|
||||||
|
|
||||||
|
cmp = utils.cmp(this.publicKey, key.publicKey);
|
||||||
|
|
||||||
|
if (cmp !== 0)
|
||||||
|
return cmp;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert key to a more json-friendly object.
|
* Convert key to a more json-friendly object.
|
||||||
* @returns {Object}
|
* @returns {Object}
|
||||||
|
|||||||
@ -1134,10 +1134,10 @@ RPC.prototype.getrawmempool = function getrawmempool(args, callback) {
|
|||||||
if (args.length > 0)
|
if (args.length > 0)
|
||||||
verbose = toBool(args[0], false);
|
verbose = toBool(args[0], false);
|
||||||
|
|
||||||
this.mempoolToJSON(verbose, callback);
|
this._mempoolToJSON(verbose, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
RPC.prototype.mempoolToJSON = function mempoolToJSON(verbose, callback) {
|
RPC.prototype._mempoolToJSON = function _mempoolToJSON(verbose, callback) {
|
||||||
var out = {};
|
var out = {};
|
||||||
var i, hashes, hash, entry;
|
var i, hashes, hash, entry;
|
||||||
|
|
||||||
@ -3239,7 +3239,6 @@ RPC.prototype._listReceived = function _listReceived(minconf, empty, account, ca
|
|||||||
|
|
||||||
for (i = 0; i < paths.length; i++) {
|
for (i = 0; i < paths.length; i++) {
|
||||||
path = paths[i];
|
path = paths[i];
|
||||||
hash = new Buffer(path.hash, 'hex');
|
|
||||||
map[path.hash] = {
|
map[path.hash] = {
|
||||||
involvesWatchonly: false,
|
involvesWatchonly: false,
|
||||||
address: path.toAddress().toBase58(self.network),
|
address: path.toAddress().toBase58(self.network),
|
||||||
|
|||||||
@ -246,13 +246,12 @@ KeyRing.fromAccount = function fromAccount(account, key, keys, change, index) {
|
|||||||
KeyRing.prototype.addKey = function addKey(key) {
|
KeyRing.prototype.addKey = function addKey(key) {
|
||||||
assert(Buffer.isBuffer(key));
|
assert(Buffer.isBuffer(key));
|
||||||
|
|
||||||
if (utils.indexOf(this.keys, key) !== -1)
|
utils.binaryInsert(this.keys, key, utils.cmp, true);
|
||||||
return;
|
|
||||||
|
|
||||||
if (this.keys.length === this.n)
|
if (this.keys.length > this.n) {
|
||||||
|
utils.binaryRemove(this.keys, key, utils.cmp);
|
||||||
throw new Error('Cannot add more keys.');
|
throw new Error('Cannot add more keys.');
|
||||||
|
}
|
||||||
utils.binaryInsert(this.keys, key, utils.cmp);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -612,25 +611,12 @@ KeyRing.prototype.ownOutput = function ownOutput(tx, index) {
|
|||||||
* @returns {Number} Total number of scripts built.
|
* @returns {Number} Total number of scripts built.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
KeyRing.prototype.scriptInputs = function scriptInputs(tx, index) {
|
KeyRing.prototype.scriptInputs = function scriptInputs(tx) {
|
||||||
var total = 0;
|
var total = 0;
|
||||||
var i, input;
|
var i, input;
|
||||||
|
|
||||||
if (index && typeof index === 'object')
|
|
||||||
index = tx.inputs.indexOf(index);
|
|
||||||
|
|
||||||
for (i = 0; i < tx.inputs.length; i++) {
|
for (i = 0; i < tx.inputs.length; i++) {
|
||||||
input = tx.inputs[i];
|
input = tx.inputs[i];
|
||||||
|
|
||||||
if (index != null && index !== i)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!input.coin)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!this.ownOutput(input.coin))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (tx.scriptInput(i, this))
|
if (tx.scriptInput(i, this))
|
||||||
total++;
|
total++;
|
||||||
}
|
}
|
||||||
@ -643,32 +629,16 @@ KeyRing.prototype.scriptInputs = function scriptInputs(tx, index) {
|
|||||||
* to build/sign inputs that are redeemable by this address.
|
* to build/sign inputs that are redeemable by this address.
|
||||||
* @param {MTX} tx
|
* @param {MTX} tx
|
||||||
* @param {HDPrivateKey|KeyPair|Buffer} key - Private key.
|
* @param {HDPrivateKey|KeyPair|Buffer} key - Private key.
|
||||||
* @param {Number?} index - Index of input. If not present,
|
|
||||||
* it will attempt to build and sign all redeemable inputs.
|
|
||||||
* @param {SighashType?} type
|
|
||||||
* @returns {Number} Total number of inputs scripts built and signed.
|
* @returns {Number} Total number of inputs scripts built and signed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
KeyRing.prototype.sign = function sign(tx, key, index, type) {
|
KeyRing.prototype.sign = function sign(tx, key) {
|
||||||
var total = 0;
|
var total = 0;
|
||||||
var i, input;
|
var i, input;
|
||||||
|
|
||||||
if (index && typeof index === 'object')
|
|
||||||
index = tx.inputs.indexOf(index);
|
|
||||||
|
|
||||||
for (i = 0; i < tx.inputs.length; i++) {
|
for (i = 0; i < tx.inputs.length; i++) {
|
||||||
input = tx.inputs[i];
|
input = tx.inputs[i];
|
||||||
|
if (tx.sign(i, this, key))
|
||||||
if (index != null && index !== i)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!input.coin)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!this.ownOutput(input.coin))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (tx.sign(i, this, key, type))
|
|
||||||
total++;
|
total++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -220,15 +220,13 @@ MTX.prototype.addOutput = function addOutput(options, value) {
|
|||||||
MTX.prototype.scriptInput = function scriptInput(index, ring) {
|
MTX.prototype.scriptInput = function scriptInput(index, ring) {
|
||||||
var input, prev, n, i, vector, redeemScript, witnessScript;
|
var input, prev, n, i, vector, redeemScript, witnessScript;
|
||||||
|
|
||||||
if (typeof index !== 'number')
|
|
||||||
index = this.inputs.indexOf(index);
|
|
||||||
|
|
||||||
// Get the input
|
// Get the input
|
||||||
input = this.inputs[index];
|
input = this.inputs[index];
|
||||||
assert(input);
|
assert(input);
|
||||||
|
|
||||||
// We should have previous outputs by now.
|
// We should have previous outputs by now.
|
||||||
assert(input.coin, 'Coins are not available for scripting.');
|
if (!input.coin)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Optimization: Don't bother with any below
|
// Optimization: Don't bother with any below
|
||||||
// calculation if the output is already templated.
|
// calculation if the output is already templated.
|
||||||
@ -391,11 +389,8 @@ MTX.prototype.scriptInput = function scriptInput(index, ring) {
|
|||||||
MTX.prototype.createSignature = function createSignature(index, prev, key, type, version) {
|
MTX.prototype.createSignature = function createSignature(index, prev, key, type, version) {
|
||||||
var hash;
|
var hash;
|
||||||
|
|
||||||
if (typeof index !== 'number')
|
|
||||||
index = this.inputs.indexOf(index);
|
|
||||||
|
|
||||||
if (type == null)
|
if (type == null)
|
||||||
type = 'all';
|
type = constants.hashType.ALL;
|
||||||
|
|
||||||
if (typeof type === 'string')
|
if (typeof type === 'string')
|
||||||
type = constants.hashType[type.toUpperCase()];
|
type = constants.hashType[type.toUpperCase()];
|
||||||
@ -423,15 +418,20 @@ MTX.prototype.signInput = function signInput(index, ring, key, type) {
|
|||||||
var input, prev, signature, keyIndex, signatures, i;
|
var input, prev, signature, keyIndex, signatures, i;
|
||||||
var len, m, n, keys, vector, version;
|
var len, m, n, keys, vector, version;
|
||||||
|
|
||||||
if (typeof index !== 'number')
|
|
||||||
index = this.inputs.indexOf(index);
|
|
||||||
|
|
||||||
// Get the input
|
// Get the input
|
||||||
input = this.inputs[index];
|
input = this.inputs[index];
|
||||||
assert(input);
|
assert(input);
|
||||||
|
|
||||||
// We should have previous outputs by now.
|
// We should have previous outputs by now.
|
||||||
assert(input.coin, 'Coins are not available for signing.');
|
if (!input.coin)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Optimization: test output against the
|
||||||
|
// address map to avoid unnecessary calculation.
|
||||||
|
// A hash table lookup may be faster than all
|
||||||
|
// the nonsense below.
|
||||||
|
if (!ring.ownOutput(input.coin))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Get the previous output's script
|
// Get the previous output's script
|
||||||
prev = input.coin.script;
|
prev = input.coin.script;
|
||||||
@ -712,12 +712,7 @@ MTX.prototype.isSigned = function isSigned() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
MTX.prototype.sign = function sign(index, ring, key, type) {
|
MTX.prototype.sign = function sign(index, ring, key, type) {
|
||||||
var input;
|
var input = this.inputs[index];
|
||||||
|
|
||||||
if (index && typeof index === 'object')
|
|
||||||
index = this.inputs.indexOf(index);
|
|
||||||
|
|
||||||
input = this.inputs[index];
|
|
||||||
assert(input);
|
assert(input);
|
||||||
|
|
||||||
// Build script for input
|
// Build script for input
|
||||||
|
|||||||
@ -1393,10 +1393,10 @@ TXDB.prototype.filterLocked = function filterLocked(coins) {
|
|||||||
for (i = 0; i < coins.length; i++) {
|
for (i = 0; i < coins.length; i++) {
|
||||||
coin = coins[i];
|
coin = coins[i];
|
||||||
if (!this.isLocked(coin))
|
if (!this.isLocked(coin))
|
||||||
out.push(coins);
|
out.push(coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
return coins;
|
return out;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -2256,14 +2256,21 @@ utils.binarySearch = function binarySearch(items, key, compare, insert) {
|
|||||||
* @returns {Number} index
|
* @returns {Number} index
|
||||||
*/
|
*/
|
||||||
|
|
||||||
utils.binaryInsert = function binaryInsert(items, item, compare) {
|
utils.binaryInsert = function binaryInsert(items, item, compare, uniq) {
|
||||||
var i = utils.binarySearch(items, item, compare, true);
|
var i = utils.binarySearch(items, item, compare, true);
|
||||||
|
|
||||||
|
if (uniq && i < items.length) {
|
||||||
|
if (compare(items[i], item) === 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (i === 0)
|
if (i === 0)
|
||||||
items.unshift(item);
|
items.unshift(item);
|
||||||
else if (i === items.length)
|
else if (i === items.length)
|
||||||
items.push(item);
|
items.push(item);
|
||||||
else
|
else
|
||||||
items.splice(i, 0, item);
|
items.splice(i, 0, item);
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1360,8 +1360,6 @@ Wallet.prototype.getRedeem = function getRedeem(hash, callback) {
|
|||||||
* sign, only creates signature slots). Only builds scripts
|
* sign, only creates signature slots). Only builds scripts
|
||||||
* for inputs that are redeemable by this wallet.
|
* for inputs that are redeemable by this wallet.
|
||||||
* @param {MTX} tx
|
* @param {MTX} tx
|
||||||
* @param {Number?} index - Index of input. If not present,
|
|
||||||
* it will attempt to sign all redeemable inputs.
|
|
||||||
* @param {Function} callback - Returns [Error, Number]
|
* @param {Function} callback - Returns [Error, Number]
|
||||||
* (total number of scripts built).
|
* (total number of scripts built).
|
||||||
*/
|
*/
|
||||||
@ -1386,16 +1384,13 @@ Wallet.prototype.scriptInputs = function scriptInputs(tx, callback) {
|
|||||||
* to build/sign inputs that are redeemable by this wallet.
|
* to build/sign inputs that are redeemable by this wallet.
|
||||||
* @param {MTX} tx
|
* @param {MTX} tx
|
||||||
* @param {Object|String|Buffer} options - Options or passphrase.
|
* @param {Object|String|Buffer} options - Options or passphrase.
|
||||||
* @param {Number?} options.index - Index of input. If not present,
|
|
||||||
* it will attempt to build and sign all redeemable inputs.
|
|
||||||
* @param {SighashType?} options.type
|
|
||||||
* @param {Function} callback - Returns [Error, Number] (total number
|
* @param {Function} callback - Returns [Error, Number] (total number
|
||||||
* of inputs scripts built and signed).
|
* of inputs scripts built and signed).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Wallet.prototype.sign = function sign(tx, options, callback) {
|
Wallet.prototype.sign = function sign(tx, options, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var passphrase, timeout, index, type;
|
var passphrase, timeout;
|
||||||
|
|
||||||
if (typeof options === 'function') {
|
if (typeof options === 'function') {
|
||||||
callback = options;
|
callback = options;
|
||||||
@ -1407,8 +1402,6 @@ Wallet.prototype.sign = function sign(tx, options, callback) {
|
|||||||
|
|
||||||
passphrase = options.passphrase;
|
passphrase = options.passphrase;
|
||||||
timeout = options.timeout;
|
timeout = options.timeout;
|
||||||
index = options.index;
|
|
||||||
type = options.type;
|
|
||||||
|
|
||||||
this.deriveInputs(tx, function(err, rings) {
|
this.deriveInputs(tx, function(err, rings) {
|
||||||
if (err)
|
if (err)
|
||||||
@ -1418,34 +1411,11 @@ Wallet.prototype.sign = function sign(tx, options, callback) {
|
|||||||
if (err)
|
if (err)
|
||||||
return callback(err);
|
return callback(err);
|
||||||
|
|
||||||
self._sign(rings, master, tx, index, type, callback);
|
self.signAsync(rings, master, tx, callback);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Sign a transaction.
|
|
||||||
* @param {KeyRing[]} rings
|
|
||||||
* @param {HDPrivateKey} master
|
|
||||||
* @param {MTX} tx
|
|
||||||
* @param {Number?} index
|
|
||||||
* @param {SighashType?} type
|
|
||||||
*/
|
|
||||||
|
|
||||||
Wallet.sign = function sign(rings, master, tx, index, type) {
|
|
||||||
var total = 0;
|
|
||||||
var i, ring, key;
|
|
||||||
|
|
||||||
for (i = 0; i < rings.length; i++) {
|
|
||||||
ring = rings[i];
|
|
||||||
key = ring.derive(master);
|
|
||||||
assert(utils.equal(key.getPublicKey(), ring.key));
|
|
||||||
total += ring.sign(tx, key, index, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
return total;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sign a transaction asynchronously.
|
* Sign a transaction asynchronously.
|
||||||
* @param {KeyRing[]} rings
|
* @param {KeyRing[]} rings
|
||||||
@ -1457,20 +1427,43 @@ Wallet.sign = function sign(rings, master, tx, index, type) {
|
|||||||
* of inputs scripts built and signed).
|
* of inputs scripts built and signed).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Wallet.prototype._sign = function _sign(rings, master, tx, index, type, callback) {
|
Wallet.prototype.signAsync = function signAsync(rings, master, tx, callback) {
|
||||||
var result;
|
var result;
|
||||||
|
|
||||||
if (!this.workerPool) {
|
if (!this.workerPool) {
|
||||||
callback = utils.asyncify(callback);
|
callback = utils.asyncify(callback);
|
||||||
try {
|
try {
|
||||||
result = Wallet.sign(rings, master, tx, index, type);
|
result = Wallet.sign(rings, master, tx);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return callback(e);
|
return callback(e);
|
||||||
}
|
}
|
||||||
return callback(null, result);
|
return callback(null, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.workerPool.sign(rings, master, tx, index, type, callback);
|
this.workerPool.sign(rings, master, tx, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sign a transaction.
|
||||||
|
* @param {KeyRing[]} rings
|
||||||
|
* @param {HDPrivateKey} master
|
||||||
|
* @param {MTX} tx
|
||||||
|
* @param {Number?} index
|
||||||
|
* @param {SighashType?} type
|
||||||
|
*/
|
||||||
|
|
||||||
|
Wallet.sign = function sign(rings, master, tx) {
|
||||||
|
var total = 0;
|
||||||
|
var i, ring, key;
|
||||||
|
|
||||||
|
for (i = 0; i < rings.length; i++) {
|
||||||
|
ring = rings[i];
|
||||||
|
key = ring.derive(master);
|
||||||
|
assert(utils.equal(key.getPublicKey(), ring.key));
|
||||||
|
total += ring.sign(tx, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return total;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2216,8 +2209,6 @@ Account.prototype.fromOptions = function fromOptions(options) {
|
|||||||
if (!this.name)
|
if (!this.name)
|
||||||
this.name = this.accountIndex + '';
|
this.name = this.accountIndex + '';
|
||||||
|
|
||||||
this.pushKey(this.accountKey);
|
|
||||||
|
|
||||||
if (options.keys) {
|
if (options.keys) {
|
||||||
assert(Array.isArray(options.keys));
|
assert(Array.isArray(options.keys));
|
||||||
for (i = 0; i < options.keys.length; i++)
|
for (i = 0; i < options.keys.length; i++)
|
||||||
@ -2255,7 +2246,7 @@ Account.MAX_LOOKAHEAD = 5;
|
|||||||
|
|
||||||
Account.prototype.init = function init(callback) {
|
Account.prototype.init = function init(callback) {
|
||||||
// Waiting for more keys.
|
// Waiting for more keys.
|
||||||
if (this.keys.length !== this.n) {
|
if (this.keys.length !== this.n - 1) {
|
||||||
assert(!this.initialized);
|
assert(!this.initialized);
|
||||||
this.save();
|
this.save();
|
||||||
return callback();
|
return callback();
|
||||||
@ -2292,40 +2283,29 @@ Account.prototype.open = function open(callback) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Account.prototype.pushKey = function pushKey(key) {
|
Account.prototype.pushKey = function pushKey(key) {
|
||||||
var index = -1;
|
var index;
|
||||||
var i;
|
|
||||||
|
|
||||||
assert(key, 'Key required.');
|
|
||||||
|
|
||||||
if (key.accountKey)
|
|
||||||
key = key.accountKey;
|
|
||||||
|
|
||||||
if (bcoin.hd.isExtended(key))
|
if (bcoin.hd.isExtended(key))
|
||||||
key = bcoin.hd.fromBase58(key);
|
key = bcoin.hd.fromBase58(key);
|
||||||
|
|
||||||
if (key.hdPublicKey)
|
if (!bcoin.hd.isPublic(key))
|
||||||
key = key.hdPublicKey;
|
|
||||||
|
|
||||||
if (!bcoin.hd.isHD(key))
|
|
||||||
throw new Error('Must add HD keys to wallet.');
|
throw new Error('Must add HD keys to wallet.');
|
||||||
|
|
||||||
if (!key.isAccount44())
|
if (!key.isAccount44())
|
||||||
throw new Error('Must add HD account keys to BIP44 wallet.');
|
throw new Error('Must add HD account keys to BIP44 wallet.');
|
||||||
|
|
||||||
for (i = 0; i < this.keys.length; i++) {
|
if (key.equal(this.accountKey))
|
||||||
if (this.keys[i].equal(key)) {
|
throw new Error('Cannot add own key.');
|
||||||
index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index !== -1)
|
index = utils.binaryInsert(this.keys, key, cmp, true);
|
||||||
|
|
||||||
|
if (index === -1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (this.keys.length === this.n)
|
if (this.keys.length > this.n - 1) {
|
||||||
|
utils.binaryRemove(this.keys, key, cmp);
|
||||||
throw new Error('Cannot add more keys.');
|
throw new Error('Cannot add more keys.');
|
||||||
|
}
|
||||||
this.keys.push(key);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@ -2339,42 +2319,22 @@ Account.prototype.pushKey = function pushKey(key) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Account.prototype.spliceKey = function spliceKey(key) {
|
Account.prototype.spliceKey = function spliceKey(key) {
|
||||||
var index = -1;
|
|
||||||
var i;
|
|
||||||
|
|
||||||
assert(key, 'Key required.');
|
|
||||||
|
|
||||||
if (key.accountKey)
|
|
||||||
key = key.accountKey;
|
|
||||||
|
|
||||||
if (bcoin.hd.isExtended(key))
|
if (bcoin.hd.isExtended(key))
|
||||||
key = bcoin.hd.fromBase58(key);
|
key = bcoin.hd.fromBase58(key);
|
||||||
|
|
||||||
if (key.hdPublicKey)
|
if (!bcoin.hd.isHDPublicKey(key))
|
||||||
key = key.hdPublicKey;
|
|
||||||
|
|
||||||
if (!bcoin.hd.isHD(key))
|
|
||||||
throw new Error('Must add HD keys to wallet.');
|
throw new Error('Must add HD keys to wallet.');
|
||||||
|
|
||||||
if (!key.isAccount44())
|
if (!key.isAccount44())
|
||||||
throw new Error('Must add HD account keys to BIP44 wallet.');
|
throw new Error('Must add HD account keys to BIP44 wallet.');
|
||||||
|
|
||||||
for (i = 0; i < this.keys.length; i++) {
|
if (key.equal(this.accountKey))
|
||||||
if (this.keys[i].equal(key)) {
|
throw new Error('Cannot remove own key.');
|
||||||
index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index === -1)
|
if (this.keys.length === this.n - 1)
|
||||||
return false;
|
|
||||||
|
|
||||||
if (this.keys.length === this.n)
|
|
||||||
throw new Error('Cannot remove key.');
|
throw new Error('Cannot remove key.');
|
||||||
|
|
||||||
this.keys.splice(index, 1);
|
return utils.binaryRemove(this.keys, key, cmp);
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2426,7 +2386,7 @@ Account.prototype._checkKeys = function _checkKeys(callback) {
|
|||||||
if (this.initialized || this.type !== keyTypes.MULTISIG)
|
if (this.initialized || this.type !== keyTypes.MULTISIG)
|
||||||
return callback(null, false);
|
return callback(null, false);
|
||||||
|
|
||||||
if (this.keys.length !== this.n)
|
if (this.keys.length !== this.n - 1)
|
||||||
return callback(null, false);
|
return callback(null, false);
|
||||||
|
|
||||||
ring = this.deriveReceive(0);
|
ring = this.deriveReceive(0);
|
||||||
@ -2708,7 +2668,7 @@ Account.prototype.toJSON = function toJSON() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Account.prototype.fromJSON = function fromJSON(json) {
|
Account.prototype.fromJSON = function fromJSON(json) {
|
||||||
var i;
|
var i, key;
|
||||||
|
|
||||||
assert.equal(json.network, this.network.type);
|
assert.equal(json.network, this.network.type);
|
||||||
assert(utils.isNumber(json.wid));
|
assert(utils.isNumber(json.wid));
|
||||||
@ -2738,8 +2698,10 @@ Account.prototype.fromJSON = function fromJSON(json) {
|
|||||||
|
|
||||||
assert(this.type != null);
|
assert(this.type != null);
|
||||||
|
|
||||||
for (i = 0; i < json.keys.length; i++)
|
for (i = 0; i < json.keys.length; i++) {
|
||||||
this.keys.push(bcoin.hd.fromBase58(json.keys[i]));
|
key = bcoin.hd.fromBase58(json.keys[i]);
|
||||||
|
this.pushKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
@ -2751,7 +2713,7 @@ Account.prototype.fromJSON = function fromJSON(json) {
|
|||||||
|
|
||||||
Account.prototype.toRaw = function toRaw(writer) {
|
Account.prototype.toRaw = function toRaw(writer) {
|
||||||
var p = new BufferWriter(writer);
|
var p = new BufferWriter(writer);
|
||||||
var i;
|
var i, key;
|
||||||
|
|
||||||
p.writeU32(this.network.magic);
|
p.writeU32(this.network.magic);
|
||||||
p.writeVarString(this.name, 'utf8');
|
p.writeVarString(this.name, 'utf8');
|
||||||
@ -2766,8 +2728,10 @@ Account.prototype.toRaw = function toRaw(writer) {
|
|||||||
p.writeBytes(this.accountKey.toRaw());
|
p.writeBytes(this.accountKey.toRaw());
|
||||||
p.writeU8(this.keys.length);
|
p.writeU8(this.keys.length);
|
||||||
|
|
||||||
for (i = 0; i < this.keys.length; i++)
|
for (i = 0; i < this.keys.length; i++) {
|
||||||
p.writeBytes(this.keys[i].toRaw());
|
key = this.keys[i];
|
||||||
|
p.writeBytes(key.toRaw());
|
||||||
|
}
|
||||||
|
|
||||||
if (!writer)
|
if (!writer)
|
||||||
p = p.render();
|
p = p.render();
|
||||||
@ -2784,7 +2748,7 @@ Account.prototype.toRaw = function toRaw(writer) {
|
|||||||
|
|
||||||
Account.prototype.fromRaw = function fromRaw(data) {
|
Account.prototype.fromRaw = function fromRaw(data) {
|
||||||
var p = new BufferReader(data);
|
var p = new BufferReader(data);
|
||||||
var i, count;
|
var i, count, key;
|
||||||
|
|
||||||
this.network = bcoin.network.fromMagic(p.readU32());
|
this.network = bcoin.network.fromMagic(p.readU32());
|
||||||
this.name = p.readVarString('utf8');
|
this.name = p.readVarString('utf8');
|
||||||
@ -2802,8 +2766,10 @@ Account.prototype.fromRaw = function fromRaw(data) {
|
|||||||
|
|
||||||
count = p.readU8();
|
count = p.readU8();
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++) {
|
||||||
this.keys.push(bcoin.hd.fromRaw(p.readBytes(82)));
|
key = bcoin.hd.fromRaw(p.readBytes(82));
|
||||||
|
this.pushKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
@ -3279,6 +3245,14 @@ MasterKey.isMasterKey = function isMasterKey(obj) {
|
|||||||
&& typeof obj.decrypt === 'function';
|
&& typeof obj.decrypt === 'function';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helpers
|
||||||
|
*/
|
||||||
|
|
||||||
|
function cmp(key1, key2) {
|
||||||
|
return key1.compare(key2);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expose
|
* Expose
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -245,13 +245,11 @@ Workers.prototype.verify = function verify(tx, flags, callback) {
|
|||||||
* @param {KeyRing[]} rings
|
* @param {KeyRing[]} rings
|
||||||
* @param {HDPrivateKey} master
|
* @param {HDPrivateKey} master
|
||||||
* @param {MTX} tx
|
* @param {MTX} tx
|
||||||
* @param {Number?} index
|
|
||||||
* @param {SighashType?} type
|
|
||||||
* @param {Function} callback
|
* @param {Function} callback
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Workers.prototype.sign = function sign(rings, master, tx, index, type, callback) {
|
Workers.prototype.sign = function sign(rings, master, tx, callback) {
|
||||||
var args = [rings, master, tx, index, type];
|
var args = [rings, master, tx];
|
||||||
var i, input, sig, sigs, total;
|
var i, input, sig, sigs, total;
|
||||||
|
|
||||||
this.execute('sign', args, -1, function(err, result) {
|
this.execute('sign', args, -1, function(err, result) {
|
||||||
@ -775,12 +773,10 @@ jobs.verify = function verify(tx, flags) {
|
|||||||
* @param {KeyRing[]} rings
|
* @param {KeyRing[]} rings
|
||||||
* @param {HDPrivateKey} master
|
* @param {HDPrivateKey} master
|
||||||
* @param {MTX} tx
|
* @param {MTX} tx
|
||||||
* @param {Number?} index
|
|
||||||
* @param {SighashType?} type
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
jobs.sign = function sign(rings, master, tx, index, type) {
|
jobs.sign = function sign(rings, master, tx) {
|
||||||
var total = bcoin.wallet.sign(rings, master, tx, index, type);
|
var total = bcoin.wallet.sign(rings, master, tx);
|
||||||
var sigs = [];
|
var sigs = [];
|
||||||
var i, input;
|
var i, input;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user