add bip45 to hd.js.
This commit is contained in:
parent
e0ab0ab88d
commit
28a2cab787
209
lib/bcoin/hd.js
209
lib/bcoin/hd.js
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user