add bip45 to hd.js.

This commit is contained in:
Christopher Jeffrey 2016-02-03 13:22:43 -08:00
parent e0ab0ab88d
commit 28a2cab787

View File

@ -171,35 +171,24 @@ function HDPrivateKey(options) {
this.isPrivate = true;
}
HDPrivateKey.prototype.scan = function scan(options, txByAddress, callback) {
HDPrivateKey.prototype.scan44 = function scan44(options, txByAddress, callback) {
var self = this;
var keys = [];
var purpose, coinType, root;
if (!callback) {
callback = txByAddress;
txByAddress = options;
options = null;
}
if (!options)
options = {};
purpose = options.purpose;
coinType = options.coinType;
if (purpose == null)
purpose = 44;
if (coinType == null)
coinType = network.type === 'main' ? 0 : 1;
assert(utils.isFinite(purpose));
assert(utils.isFinite(coinType));
var coinType;
// 0. get the root node
root = this
.derive(purpose, true)
.derive(coinType, true);
if (!(this instanceof HDPublicKey)) {
coinType = options.coinType;
if (coinType == null)
coinType = network.type === 'main' ? 0 : 1;
assert(utils.isFinite(coinType));
root = this
.derive(44, true)
.derive(coinType, true);
}
return (function scanner(accountIndex) {
var addressIndex = 0;
@ -207,7 +196,9 @@ HDPrivateKey.prototype.scan = function scan(options, txByAddress, callback) {
var gap = 0;
// 1. derive the first account's node (index = 0)
var account = root.derive(accountIndex, true);
var account = (self instanceof HDPublicKey)
? self
: root.derive(accountIndex, true);
// 2. derive the external chain node of this account
var chain = account.derive(0);
@ -252,54 +243,56 @@ HDPrivateKey.prototype.scan = function scan(options, txByAddress, callback) {
// 5. if there are some transactions, increase
// the account index and go to step 1
if (self instanceof HDPublicKey)
return callback(null, keys);
return scanner(accountIndex + 1);
});
})();
})(0);
};
HDPrivateKey.prototype.deriveBIP44 = function deriveBIP44(options) {
var purpose = options.purpose;
HDPrivateKey.prototype.deriveRoot44 = function deriveRoot44(options) {
var coinType = options.coinType;
var accountIndex = options.accountIndex;
var chain = options.chain;
var addressIndex = options.addressIndex;
var child;
if (purpose == null)
purpose = 44;
if (this instanceof HDPublicKey)
return this;
if (coinType == null)
coinType = network.type === 'main' ? 0 : 1;
assert(utils.isFinite(coinType));
assert(utils.isFinite(accountIndex));
return this
.derive(44, true)
.derive(coinType, true)
.derive(accountIndex, true);
};
HDPrivateKey.prototype.deriveBIP44 = function deriveBIP44(options, isPublic) {
var chain = options.chain;
var addressIndex = options.addressIndex;
if (chain == null)
chain = options.change ? 1 : 0;
assert(utils.isFinite(purpose));
assert(utils.isFinite(coinType));
assert(utils.isFinite(accountIndex));
assert(utils.isFinite(chain));
assert(utils.isFinite(addressIndex));
child = this
.derive(purpose, true)
.derive(coinType, true)
.derive(accountIndex, true)
return this
.deriveRoot44(options)
.derive(chain)
.derive(addressIndex);
return child;
};
HDPrivateKey.prototype.deriveAccount = function deriveAccount(accountIndex) {
return this.deriveBIP44({
accountIndex: accountIndex,
chain: 0,
addressIndex: 0
});
};
HDPrivateKey.prototype.deriveChange = function deriveChange(accountIndex, addressIndex) {
if (this instanceof HDPublicKey) {
addressIndex = accountIndex;
accountIndex = null;
}
return this.deriveBIP44({
accountIndex: accountIndex,
chain: 1,
@ -308,6 +301,11 @@ HDPrivateKey.prototype.deriveChange = function deriveChange(accountIndex, addres
};
HDPrivateKey.prototype.deriveAddress = function deriveAddress(accountIndex, addressIndex) {
if (this instanceof HDPublicKey) {
addressIndex = accountIndex;
accountIndex = null;
}
return this.deriveBIP44({
accountIndex: accountIndex,
chain: 0,
@ -315,6 +313,106 @@ HDPrivateKey.prototype.deriveAddress = function deriveAddress(accountIndex, addr
});
};
HDPrivateKey.prototype.scan45 = function scan45(options, txByAddress, callback) {
var keys = [];
var root;
root = this.deriveRoot45(options);
return (function chainCheck(chainConstant) {
return (function scanner(cosignerIndex) {
var addressIndex = 0;
var total = 0;
var gap = 0;
var cosigner = root.derive(cosignerIndex);
var chain = cosigner.derive(chainConstant);
return (function next() {
var address = chain.derive(addressIndex++);
var addr = bcoin.address.hash2addr(
bcoin.address.key2hash(address.publicKey),
'pubkey');
return txByAddress(addr, function(err, txs) {
var result;
if (err)
return callback(err);
if (txs) {
if (typeof txs === 'boolean')
result = txs;
else if (Array.isArray(txs))
result = txs.length > 0;
else
result = false;
}
if (result) {
keys.push(address);
total++;
gap = 0;
return next();
}
if (++gap < 20)
return next();
if (total === 0) {
if (chainConstant === 0)
return chainCheck(1);
return callback(null, keys);
}
return scanner(accountIndex + 1);
});
})();
})(0);
})(0);
};
HDPrivateKey.prototype.deriveRoot45 = function deriveRoot45(options) {
if (this instanceof HDPublicKey)
return this;
return this.derive(45, true);
};
HDPrivateKey.prototype.deriveBIP45 = function deriveBIP45(options) {
var cosignerIndex = options.cosignerIndex;
var chain = options.chain;
var addressIndex = options.addressIndex;
if (chain == null)
chain = options.change ? 1 : 0;
assert(utils.isFinite(cosignerIndex));
assert(utils.isFinite(chain));
assert(utils.isFinite(addressIndex));
return this
.deriveRoot45(options)
.derive(cosignerIndex)
.derive(chain)
.derive(addressIndex);
};
HDPrivateKey.prototype.deriveCosignerChange = function deriveCosignerChange(cosignerIndex, addressIndex) {
return this.deriveBIP45({
cosignerIndex: cosignerIndex,
chain: 1,
addressIndex: addressIndex
});
};
HDPrivateKey.prototype.deriveCosignerAddress = function deriveCosignerAddress(cosignerIndex, addressIndex) {
return this.deriveBIP45({
cosignerIndex: cosignerIndex,
chain: 0,
addressIndex: addressIndex
});
};
HDPrivateKey.getPath = function getPath(options) {
var purpose, coinType, accountIndex, chain, addressIndex;
@ -666,11 +764,18 @@ function HDPublicKey(options) {
this.isPublic = true;
}
HDPublicKey.prototype.scan44 = HDPrivateKey.prototype.scan44;
HDPublicKey.prototype.deriveRoot44 = HDPrivateKey.prototype.deriveRoot44;
HDPublicKey.prototype.deriveBIP44 = HDPrivateKey.prototype.deriveBIP44;
HDPublicKey.prototype.deriveAccount = HDPrivateKey.prototype.deriveAccount;
HDPublicKey.prototype.deriveChange = HDPrivateKey.prototype.deriveChange;
HDPublicKey.prototype.deriveAddress = HDPrivateKey.prototype.deriveAddress;
HDPublicKey.prototype.scan45 = HDPrivateKey.prototype.scan45;
HDPublicKey.prototype.deriveRoot45 = HDPrivateKey.prototype.deriveRoot45;
HDPublicKey.prototype.deriveBIP45 = HDPrivateKey.prototype.deriveBIP45;
HDPublicKey.prototype.deriveCosignerChange = HDPrivateKey.prototype.deriveCosignerChange;
HDPublicKey.prototype.deriveCosignerAddress = HDPrivateKey.prototype.deriveCosignerAddress;
HDPublicKey.isExtended = function isExtended(data) {
if (typeof data !== 'string')
return false;