Merge pull request #344 from isocolsky/bip44
Restrict support for BIP44 to 1-of-1 wallets
This commit is contained in:
commit
cf59b73023
|
@ -132,6 +132,18 @@ ExpressApp.prototype.start = function(opts, cb) {
|
||||||
|
|
||||||
router.post('/v1/wallets/', function(req, res) {
|
router.post('/v1/wallets/', function(req, res) {
|
||||||
var server = getServer(req, res);
|
var server = getServer(req, res);
|
||||||
|
req.body.supportBIP44 = false;
|
||||||
|
server.createWallet(req.body, function(err, walletId) {
|
||||||
|
if (err) return returnError(err, res, req);
|
||||||
|
res.json({
|
||||||
|
walletId: walletId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post('/v2/wallets/', function(req, res) {
|
||||||
|
var server = getServer(req, res);
|
||||||
|
req.body.supportBIP44 = true;
|
||||||
server.createWallet(req.body, function(err, walletId) {
|
server.createWallet(req.body, function(err, walletId) {
|
||||||
if (err) return returnError(err, res, req);
|
if (err) return returnError(err, res, req);
|
||||||
res.json({
|
res.json({
|
||||||
|
|
|
@ -203,7 +203,7 @@ WalletService.prototype._runLocked = function(cb, task) {
|
||||||
* @param {number} opts.n - Total copayers.
|
* @param {number} opts.n - Total copayers.
|
||||||
* @param {string} opts.pubKey - Public key to verify copayers joining have access to the wallet secret.
|
* @param {string} opts.pubKey - Public key to verify copayers joining have access to the wallet secret.
|
||||||
* @param {string} [opts.network = 'livenet'] - The Bitcoin network for this wallet.
|
* @param {string} [opts.network = 'livenet'] - The Bitcoin network for this wallet.
|
||||||
* @param {string} [opts.derivationStrategy = 'BIP45'] - Strategy used for address derivation (BIP44, BIP45).
|
* @param {string} [opts.supportBIP44 = false] - Client supports BIP44 paths for 1-of-1 wallets.
|
||||||
*/
|
*/
|
||||||
WalletService.prototype.createWallet = function(opts, cb) {
|
WalletService.prototype.createWallet = function(opts, cb) {
|
||||||
var self = this,
|
var self = this,
|
||||||
|
@ -220,9 +220,8 @@ WalletService.prototype.createWallet = function(opts, cb) {
|
||||||
if (!_.contains(['livenet', 'testnet'], opts.network))
|
if (!_.contains(['livenet', 'testnet'], opts.network))
|
||||||
return cb(new ClientError('Invalid network'));
|
return cb(new ClientError('Invalid network'));
|
||||||
|
|
||||||
opts.derivationStrategy = opts.derivationStrategy || WalletUtils.DERIVATION_STRATEGIES.BIP45;
|
var derivationStrategy = (opts.n == 1 && opts.supportBIP44) ?
|
||||||
if (!_.contains(_.values(WalletUtils.DERIVATION_STRATEGIES), opts.derivationStrategy))
|
WalletUtils.DERIVATION_STRATEGIES.BIP44 : WalletUtils.DERIVATION_STRATEGIES.BIP45;
|
||||||
return cb(new ClientError('Invalid address derivation strategy'));
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
pubKey = new PublicKey.fromString(opts.pubKey);
|
pubKey = new PublicKey.fromString(opts.pubKey);
|
||||||
|
@ -250,7 +249,7 @@ WalletService.prototype.createWallet = function(opts, cb) {
|
||||||
n: opts.n,
|
n: opts.n,
|
||||||
network: opts.network,
|
network: opts.network,
|
||||||
pubKey: pubKey.toString(),
|
pubKey: pubKey.toString(),
|
||||||
derivationStrategy: opts.derivationStrategy,
|
derivationStrategy: derivationStrategy,
|
||||||
});
|
});
|
||||||
self.storage.storeWallet(wallet, function(err) {
|
self.storage.storeWallet(wallet, function(err) {
|
||||||
log.debug('Wallet created', wallet.id, opts.network);
|
log.debug('Wallet created', wallet.id, opts.network);
|
||||||
|
@ -417,7 +416,7 @@ WalletService.prototype._addCopayerToWallet = function(wallet, opts, cb) {
|
||||||
requestPubKey: opts.requestPubKey,
|
requestPubKey: opts.requestPubKey,
|
||||||
signature: opts.copayerSignature,
|
signature: opts.copayerSignature,
|
||||||
customData: opts.customData,
|
customData: opts.customData,
|
||||||
derivationStrategy: opts.derivationStrategy,
|
derivationStrategy: wallet.derivationStrategy,
|
||||||
});
|
});
|
||||||
self.storage.fetchCopayerLookup(copayer.id, function(err, res) {
|
self.storage.fetchCopayerLookup(copayer.id, function(err, res) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
@ -563,7 +562,6 @@ WalletService.prototype._clientSupportsTXPv2 = function() {
|
||||||
* @param {string} opts.requestPubKey - Public Key used to check requests from this copayer.
|
* @param {string} opts.requestPubKey - Public Key used to check requests from this copayer.
|
||||||
* @param {string} opts.copayerSignature - S(name|xPubKey|requestPubKey). Used by other copayers to verify that the copayer joining knows the wallet secret.
|
* @param {string} opts.copayerSignature - S(name|xPubKey|requestPubKey). Used by other copayers to verify that the copayer joining knows the wallet secret.
|
||||||
* @param {string} opts.customData - (optional) Custom data for this copayer.
|
* @param {string} opts.customData - (optional) Custom data for this copayer.
|
||||||
* @param {string} [opts.derivationStrategy = 'BIP45'] - Strategy used for address derivation (BIP44, BIP45).
|
|
||||||
*/
|
*/
|
||||||
WalletService.prototype.joinWallet = function(opts, cb) {
|
WalletService.prototype.joinWallet = function(opts, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
@ -574,21 +572,11 @@ WalletService.prototype.joinWallet = function(opts, cb) {
|
||||||
if (_.isEmpty(opts.name))
|
if (_.isEmpty(opts.name))
|
||||||
return cb(new ClientError('Invalid copayer name'));
|
return cb(new ClientError('Invalid copayer name'));
|
||||||
|
|
||||||
opts.derivationStrategy = opts.derivationStrategy || WalletUtils.DERIVATION_STRATEGIES.BIP45;
|
|
||||||
if (!_.contains(_.values(WalletUtils.DERIVATION_STRATEGIES), opts.derivationStrategy))
|
|
||||||
return cb(new ClientError('Invalid address derivation strategy'));
|
|
||||||
|
|
||||||
self.walletId = opts.walletId;
|
self.walletId = opts.walletId;
|
||||||
self._runLocked(cb, function(cb) {
|
self._runLocked(cb, function(cb) {
|
||||||
self.storage.fetchWallet(opts.walletId, function(err, wallet) {
|
self.storage.fetchWallet(opts.walletId, function(err, wallet) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
if (!wallet) return cb(Errors.WALLET_NOT_FOUND);
|
if (!wallet) return cb(Errors.WALLET_NOT_FOUND);
|
||||||
if (wallet.addressManager.derivationStrategy != opts.derivationStrategy) {
|
|
||||||
if (!self._clientSupportsBIP44()) {
|
|
||||||
return cb(new ClientError(Errors.codes.UPGRADE_NEEDED, 'To join this wallet, you need to upgrade your client app.'));
|
|
||||||
}
|
|
||||||
return cb(new ClientError('Incompatible address derivation strategy'));
|
|
||||||
}
|
|
||||||
|
|
||||||
var hash = WalletUtils.getCopayerHash(opts.name, opts.xPubKey, opts.requestPubKey);
|
var hash = WalletUtils.getCopayerHash(opts.name, opts.xPubKey, opts.requestPubKey);
|
||||||
if (!self._verifySignature(hash, opts.copayerSignature, wallet.pubKey)) {
|
if (!self._verifySignature(hash, opts.copayerSignature, wallet.pubKey)) {
|
||||||
|
@ -1222,7 +1210,7 @@ WalletService.prototype.createTx = function(opts, cb) {
|
||||||
requiredRejections: Math.min(wallet.m, wallet.n - wallet.m + 1),
|
requiredRejections: Math.min(wallet.m, wallet.n - wallet.m + 1),
|
||||||
walletN: wallet.n,
|
walletN: wallet.n,
|
||||||
excludeUnconfirmedUtxos: !!opts.excludeUnconfirmedUtxos,
|
excludeUnconfirmedUtxos: !!opts.excludeUnconfirmedUtxos,
|
||||||
derivationStrategy: wallet.addressManager.derivationStrategy,
|
derivationStrategy: wallet.derivationStrategy,
|
||||||
customData: opts.customData
|
customData: opts.customData
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -163,7 +163,7 @@ Storage.prototype._completeTxData = function(walletId, txs, cb) {
|
||||||
action.copayerName = wallet.getCopayer(action.copayerId).name;
|
action.copayerName = wallet.getCopayer(action.copayerId).name;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (tx.status=='accepted')
|
if (tx.status == 'accepted')
|
||||||
tx.raw = tx.getRawTx();
|
tx.raw = tx.getRawTx();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -96,27 +96,27 @@ helpers.createAndJoinWallet = function(m, n, opts, cb) {
|
||||||
var copayerIds = [];
|
var copayerIds = [];
|
||||||
var offset = opts.offset || 0;
|
var offset = opts.offset || 0;
|
||||||
|
|
||||||
|
var supportBIP44 = _.isBoolean(opts.supportBIP44) ? opts.supportBIP44 : true
|
||||||
var walletOpts = {
|
var walletOpts = {
|
||||||
name: 'a wallet',
|
name: 'a wallet',
|
||||||
m: m,
|
m: m,
|
||||||
n: n,
|
n: n,
|
||||||
pubKey: TestData.keyPair.pub,
|
pubKey: TestData.keyPair.pub,
|
||||||
derivationStrategy: opts.derivationStrategy || 'BIP44',
|
supportBIP44: supportBIP44,
|
||||||
};
|
};
|
||||||
server.createWallet(walletOpts, function(err, walletId) {
|
server.createWallet(walletOpts, function(err, walletId) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
async.each(_.range(n), function(i, cb) {
|
async.each(_.range(n), function(i, cb) {
|
||||||
var copayerData = TestData.copayers[i + offset];
|
var copayerData = TestData.copayers[i + offset];
|
||||||
var bip = opts.derivationStrategy || 'BIP44';
|
|
||||||
var copayerOpts = helpers.getSignedCopayerOpts({
|
var copayerOpts = helpers.getSignedCopayerOpts({
|
||||||
walletId: walletId,
|
walletId: walletId,
|
||||||
name: 'copayer ' + (i + 1),
|
name: 'copayer ' + (i + 1),
|
||||||
xPubKey: bip == 'BIP44' ? copayerData.xPubKey_44H_0H_0H : copayerData.xPubKey_45H,
|
xPubKey: (n == 1 && supportBIP44) ? copayerData.xPubKey_44H_0H_0H : copayerData.xPubKey_45H,
|
||||||
requestPubKey: copayerData.pubKey_1H_0,
|
requestPubKey: copayerData.pubKey_1H_0,
|
||||||
customData: 'custom data ' + (i + 1),
|
customData: 'custom data ' + (i + 1),
|
||||||
derivationStrategy: bip,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
server.joinWallet(copayerOpts, function(err, result) {
|
server.joinWallet(copayerOpts, function(err, result) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
copayerIds.push(result.copayerId);
|
copayerIds.push(result.copayerId);
|
||||||
|
@ -495,7 +495,7 @@ describe('Wallet service', function() {
|
||||||
txpId = txp.id;
|
txpId = txp.id;
|
||||||
async.eachSeries(_.range(2), function(i, next) {
|
async.eachSeries(_.range(2), function(i, next) {
|
||||||
var copayer = TestData.copayers[i];
|
var copayer = TestData.copayers[i];
|
||||||
helpers.getAuthServer(copayer.id44, function(server) {
|
helpers.getAuthServer(copayer.id45, function(server) {
|
||||||
var signatures = helpers.clientSign(txp, copayer.xPrivKey);
|
var signatures = helpers.clientSign(txp, copayer.xPrivKey);
|
||||||
server.signTx({
|
server.signTx({
|
||||||
txProposalId: txp.id,
|
txProposalId: txp.id,
|
||||||
|
@ -553,7 +553,7 @@ describe('Wallet service', function() {
|
||||||
txpId = txp.id;
|
txpId = txp.id;
|
||||||
async.eachSeries(_.range(1, 3), function(i, next) {
|
async.eachSeries(_.range(1, 3), function(i, next) {
|
||||||
var copayer = TestData.copayers[i];
|
var copayer = TestData.copayers[i];
|
||||||
helpers.getAuthServer(copayer.id44, function(server) {
|
helpers.getAuthServer(copayer.id45, function(server) {
|
||||||
server.rejectTx({
|
server.rejectTx({
|
||||||
txProposalId: txp.id,
|
txProposalId: txp.id,
|
||||||
}, next);
|
}, next);
|
||||||
|
@ -1012,9 +1012,8 @@ describe('Wallet service', function() {
|
||||||
var copayerOpts = helpers.getSignedCopayerOpts({
|
var copayerOpts = helpers.getSignedCopayerOpts({
|
||||||
walletId: wallet.id,
|
walletId: wallet.id,
|
||||||
name: 'me',
|
name: 'me',
|
||||||
xPubKey: TestData.copayers[1].xPubKey_45H,
|
xPubKey: TestData.copayers[1].xPubKey_44H_0H_0H,
|
||||||
requestPubKey: TestData.copayers[1].pubKey_1H_0,
|
requestPubKey: TestData.copayers[1].pubKey_1H_0,
|
||||||
derivationStrategy: 'BIP44',
|
|
||||||
});
|
});
|
||||||
server.joinWallet(copayerOpts, function(err) {
|
server.joinWallet(copayerOpts, function(err) {
|
||||||
should.exist(err);
|
should.exist(err);
|
||||||
|
@ -1155,84 +1154,53 @@ describe('Wallet service', function() {
|
||||||
describe('Address derivation strategy', function() {
|
describe('Address derivation strategy', function() {
|
||||||
var server;
|
var server;
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
server = WalletService.getInstance({
|
server = WalletService.getInstance();
|
||||||
clientVersion: 'bwc-0.2.0',
|
|
||||||
});
|
});
|
||||||
});
|
it('should use BIP44 for 1-of-1 wallet if supported', function(done) {
|
||||||
it('should fail to join BIP45 wallet with BIP44 copayer opts', function(done) {
|
|
||||||
var walletOpts = {
|
var walletOpts = {
|
||||||
name: 'my wallet',
|
name: 'my wallet',
|
||||||
m: 2,
|
m: 1,
|
||||||
n: 3,
|
n: 1,
|
||||||
pubKey: TestData.keyPair.pub,
|
pubKey: TestData.keyPair.pub,
|
||||||
derivationStrategy: 'BIP45',
|
supportBIP44: true,
|
||||||
};
|
};
|
||||||
server.createWallet(walletOpts, function(err, wid) {
|
server.createWallet(walletOpts, function(err, wid) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
var copayerOpts = helpers.getSignedCopayerOpts({
|
server.storage.fetchWallet(wid, function(err, wallet) {
|
||||||
walletId: wid,
|
should.not.exist(err);
|
||||||
name: 'me',
|
wallet.derivationStrategy.should.equal('BIP44');
|
||||||
xPubKey: TestData.copayers[0].xPubKey_44H_0H_0H,
|
|
||||||
requestPubKey: TestData.copayers[0].pubKey_1H_0,
|
|
||||||
customData: 'dummy custom data',
|
|
||||||
derivationStrategy: 'BIP44',
|
|
||||||
});
|
|
||||||
server.joinWallet(copayerOpts, function(err, result) {
|
|
||||||
should.exist(err);
|
|
||||||
err.message.toLowerCase().should.contain('address derivation strategy');
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('should fail to join BIP44 wallet with BIP45 copayer opts', function(done) {
|
it('should use BIP45 for 1-of-1 wallet if BIP44 not supported', function(done) {
|
||||||
var walletOpts = {
|
var walletOpts = {
|
||||||
name: 'my wallet',
|
name: 'my wallet',
|
||||||
m: 2,
|
m: 1,
|
||||||
n: 3,
|
n: 1,
|
||||||
pubKey: TestData.keyPair.pub,
|
pubKey: TestData.keyPair.pub,
|
||||||
derivationStrategy: 'BIP44',
|
|
||||||
};
|
};
|
||||||
server.createWallet(walletOpts, function(err, wid) {
|
server.createWallet(walletOpts, function(err, wid) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
var copayerOpts = helpers.getSignedCopayerOpts({
|
server.storage.fetchWallet(wid, function(err, wallet) {
|
||||||
walletId: wid,
|
should.not.exist(err);
|
||||||
name: 'me',
|
wallet.derivationStrategy.should.equal('BIP45');
|
||||||
xPubKey: TestData.copayers[0].xPubKey_45H,
|
|
||||||
requestPubKey: TestData.copayers[0].pubKey_1H_0,
|
|
||||||
customData: 'dummy custom data',
|
|
||||||
derivationStrategy: 'BIP45',
|
|
||||||
});
|
|
||||||
server.joinWallet(copayerOpts, function(err, result) {
|
|
||||||
should.exist(err);
|
|
||||||
err.message.toLowerCase().should.contain('address derivation strategy');
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('should require upgrade when joining BIP44 wallet with BIP45 copayer opts from old client app', function(done) {
|
it('should always use BIP45 for shared wallets', function(done) {
|
||||||
var walletOpts = {
|
var walletOpts = {
|
||||||
name: 'my wallet',
|
name: 'my wallet',
|
||||||
m: 2,
|
m: 2,
|
||||||
n: 3,
|
n: 3,
|
||||||
pubKey: TestData.keyPair.pub,
|
pubKey: TestData.keyPair.pub,
|
||||||
derivationStrategy: 'BIP44',
|
|
||||||
};
|
};
|
||||||
server.createWallet(walletOpts, function(err, wid) {
|
server.createWallet(walletOpts, function(err, wid) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
var copayerOpts = helpers.getSignedCopayerOpts({
|
server.storage.fetchWallet(wid, function(err, wallet) {
|
||||||
walletId: wid,
|
should.not.exist(err);
|
||||||
name: 'me',
|
wallet.derivationStrategy.should.equal('BIP45');
|
||||||
xPubKey: TestData.copayers[0].xPubKey_45H,
|
|
||||||
requestPubKey: TestData.copayers[0].pubKey_1H_0,
|
|
||||||
customData: 'dummy custom data',
|
|
||||||
derivationStrategy: 'BIP45',
|
|
||||||
});
|
|
||||||
server = WalletService.getInstance({
|
|
||||||
clientVersion: 'bwc-0.1.4',
|
|
||||||
});
|
|
||||||
server.joinWallet(copayerOpts, function(err, result) {
|
|
||||||
should.exist(err);
|
|
||||||
err.code.should.equal('UPGRADE_NEEDED');
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1242,9 +1210,7 @@ describe('Wallet service', function() {
|
||||||
describe('#getStatus', function() {
|
describe('#getStatus', function() {
|
||||||
var server, wallet;
|
var server, wallet;
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
helpers.createAndJoinWallet(1, 1, {
|
helpers.createAndJoinWallet(1, 2, function(s, w) {
|
||||||
derivationStrategy: 'BIP45'
|
|
||||||
}, function(s, w) {
|
|
||||||
server = s;
|
server = s;
|
||||||
wallet = w;
|
wallet = w;
|
||||||
done();
|
done();
|
||||||
|
@ -1258,7 +1224,7 @@ describe('Wallet service', function() {
|
||||||
should.exist(status.wallet);
|
should.exist(status.wallet);
|
||||||
status.wallet.name.should.equal(wallet.name);
|
status.wallet.name.should.equal(wallet.name);
|
||||||
should.exist(status.wallet.copayers);
|
should.exist(status.wallet.copayers);
|
||||||
status.wallet.copayers.length.should.equal(1);
|
status.wallet.copayers.length.should.equal(2);
|
||||||
should.exist(status.balance);
|
should.exist(status.balance);
|
||||||
status.balance.totalAmount.should.equal(0);
|
status.balance.totalAmount.should.equal(0);
|
||||||
should.exist(status.preferences);
|
should.exist(status.preferences);
|
||||||
|
@ -1364,6 +1330,8 @@ describe('Wallet service', function() {
|
||||||
|
|
||||||
describe('#createAddress', function() {
|
describe('#createAddress', function() {
|
||||||
var server, wallet;
|
var server, wallet;
|
||||||
|
|
||||||
|
describe('shared wallets (BIP45)', function() {
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
helpers.createAndJoinWallet(2, 2, function(s, w) {
|
helpers.createAndJoinWallet(2, 2, function(s, w) {
|
||||||
server = s;
|
server = s;
|
||||||
|
@ -1378,16 +1346,16 @@ describe('Wallet service', function() {
|
||||||
should.exist(address);
|
should.exist(address);
|
||||||
address.walletId.should.equal(wallet.id);
|
address.walletId.should.equal(wallet.id);
|
||||||
address.network.should.equal('livenet');
|
address.network.should.equal('livenet');
|
||||||
address.address.should.equal('36q2G5FMGvJbPgAVEaiyAsFGmpkhPKwk2r');
|
address.address.should.equal('3BVJZ4CYzeTtawDtgwHvWV5jbvnXtYe97i');
|
||||||
address.isChange.should.be.false;
|
address.isChange.should.be.false;
|
||||||
address.path.should.equal('m/0/0');
|
address.path.should.equal('m/2147483647/0/0');
|
||||||
server.getNotifications({}, function(err, notifications) {
|
server.getNotifications({}, function(err, notifications) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
var notif = _.find(notifications, {
|
var notif = _.find(notifications, {
|
||||||
type: 'NewAddress'
|
type: 'NewAddress'
|
||||||
});
|
});
|
||||||
should.exist(notif);
|
should.exist(notif);
|
||||||
notif.data.address.should.equal('36q2G5FMGvJbPgAVEaiyAsFGmpkhPKwk2r');
|
notif.data.address.should.equal(address.address);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1400,7 +1368,7 @@ describe('Wallet service', function() {
|
||||||
}, function(err, addresses) {
|
}, function(err, addresses) {
|
||||||
addresses.length.should.equal(N);
|
addresses.length.should.equal(N);
|
||||||
_.each(_.range(N), function(i) {
|
_.each(_.range(N), function(i) {
|
||||||
addresses[i].path.should.equal('m/0/' + i);
|
addresses[i].path.should.equal('m/2147483647/0/' + i);
|
||||||
});
|
});
|
||||||
// No two identical addresses
|
// No two identical addresses
|
||||||
_.uniq(_.pluck(addresses, 'address')).length.should.equal(N);
|
_.uniq(_.pluck(addresses, 'address')).length.should.equal(N);
|
||||||
|
@ -1426,14 +1394,14 @@ describe('Wallet service', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('BIP45', function() {
|
describe('1-of-1 (BIP44)', function() {
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
helpers.createAndJoinWallet(2, 2, {
|
helpers.createAndJoinWallet(1, 1, function(s, w) {
|
||||||
derivationStrategy: 'BIP45'
|
|
||||||
}, function(s, w) {
|
|
||||||
server = s;
|
server = s;
|
||||||
wallet = w;
|
wallet = w;
|
||||||
|
w.copayers[0].id.should.equal(TestData.copayers[0].id44);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1444,16 +1412,16 @@ describe('Wallet service', function() {
|
||||||
should.exist(address);
|
should.exist(address);
|
||||||
address.walletId.should.equal(wallet.id);
|
address.walletId.should.equal(wallet.id);
|
||||||
address.network.should.equal('livenet');
|
address.network.should.equal('livenet');
|
||||||
address.address.should.equal('3BVJZ4CYzeTtawDtgwHvWV5jbvnXtYe97i');
|
address.address.should.equal('3J4J9nkFpzQjUGDh5hLKMKztFSPWMKejKE');
|
||||||
address.isChange.should.be.false;
|
address.isChange.should.be.false;
|
||||||
address.path.should.equal('m/2147483647/0/0');
|
address.path.should.equal('m/0/0');
|
||||||
server.getNotifications({}, function(err, notifications) {
|
server.getNotifications({}, function(err, notifications) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
var notif = _.find(notifications, {
|
var notif = _.find(notifications, {
|
||||||
type: 'NewAddress'
|
type: 'NewAddress'
|
||||||
});
|
});
|
||||||
should.exist(notif);
|
should.exist(notif);
|
||||||
notif.data.address.should.equal('3BVJZ4CYzeTtawDtgwHvWV5jbvnXtYe97i');
|
notif.data.address.should.equal(address.address);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1466,7 +1434,7 @@ describe('Wallet service', function() {
|
||||||
}, function(err, addresses) {
|
}, function(err, addresses) {
|
||||||
addresses.length.should.equal(N);
|
addresses.length.should.equal(N);
|
||||||
_.each(_.range(N), function(i) {
|
_.each(_.range(N), function(i) {
|
||||||
addresses[i].path.should.equal('m/2147483647/0/' + i);
|
addresses[i].path.should.equal('m/0/' + i);
|
||||||
});
|
});
|
||||||
// No two identical addresses
|
// No two identical addresses
|
||||||
_.uniq(_.pluck(addresses, 'address')).length.should.equal(N);
|
_.uniq(_.pluck(addresses, 'address')).length.should.equal(N);
|
||||||
|
@ -1679,10 +1647,10 @@ describe('Wallet service', function() {
|
||||||
reqPrivKey = new Bitcore.PrivateKey();
|
reqPrivKey = new Bitcore.PrivateKey();
|
||||||
var requestPubKey = reqPrivKey.toPublicKey();
|
var requestPubKey = reqPrivKey.toPublicKey();
|
||||||
|
|
||||||
var xPrivKey = TestData.copayers[0].xPrivKey_44H_0H_0H;
|
var xPrivKey = TestData.copayers[0].xPrivKey_45H;
|
||||||
var sig = WalletUtils.signRequestPubKey(requestPubKey, xPrivKey);
|
var sig = WalletUtils.signRequestPubKey(requestPubKey, xPrivKey);
|
||||||
|
|
||||||
var copayerId = WalletUtils.xPubToCopayerId(TestData.copayers[0].xPubKey_44H_0H_0H);
|
var copayerId = WalletUtils.xPubToCopayerId(TestData.copayers[0].xPubKey_45H);
|
||||||
opts = {
|
opts = {
|
||||||
copayerId: copayerId,
|
copayerId: copayerId,
|
||||||
requestPubKey: requestPubKey,
|
requestPubKey: requestPubKey,
|
||||||
|
@ -1693,7 +1661,9 @@ describe('Wallet service', function() {
|
||||||
|
|
||||||
describe('#addAccess 1-1', function() {
|
describe('#addAccess 1-1', function() {
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
helpers.createAndJoinWallet(1, 1, function(s, w) {
|
helpers.createAndJoinWallet(1, 1, {
|
||||||
|
supportBIP44: false
|
||||||
|
}, function(s, w) {
|
||||||
server = s;
|
server = s;
|
||||||
wallet = w;
|
wallet = w;
|
||||||
|
|
||||||
|
@ -4387,12 +4357,14 @@ describe('Wallet service', function() {
|
||||||
describe('#scan', function() {
|
describe('#scan', function() {
|
||||||
var server, wallet;
|
var server, wallet;
|
||||||
var scanConfigOld = WalletService.SCAN_CONFIG;
|
var scanConfigOld = WalletService.SCAN_CONFIG;
|
||||||
|
|
||||||
|
describe('1-of-1 wallet (BIP44)', function() {
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
this.timeout(5000);
|
this.timeout(5000);
|
||||||
WalletService.SCAN_CONFIG.scanWindow = 2;
|
WalletService.SCAN_CONFIG.scanWindow = 2;
|
||||||
WalletService.SCAN_CONFIG.derivationDelay = 0;
|
WalletService.SCAN_CONFIG.derivationDelay = 0;
|
||||||
|
|
||||||
helpers.createAndJoinWallet(1, 2, function(s, w) {
|
helpers.createAndJoinWallet(1, 1, function(s, w) {
|
||||||
server = s;
|
server = s;
|
||||||
wallet = w;
|
wallet = w;
|
||||||
done();
|
done();
|
||||||
|
@ -4404,9 +4376,9 @@ describe('Wallet service', function() {
|
||||||
|
|
||||||
it('should scan main addresses', function(done) {
|
it('should scan main addresses', function(done) {
|
||||||
helpers.stubAddressActivity(
|
helpers.stubAddressActivity(
|
||||||
['3Jc2hcN13vGBCdWR4SMNRoL9EUiBHuf4LT', // m/0/0
|
['3J4J9nkFpzQjUGDh5hLKMKztFSPWMKejKE', // m/0/0
|
||||||
'3Pk2Cn3TW6JLhGEnHg8iM2qtmx2T1uHyZM', // m/0/2
|
'384JHSf9kVBs3yXsPwCzEScRs395u8hwxj', // m/0/2
|
||||||
'3GqrwYwyLt1czKMvvqFwYj2ZeooiHtbgbc', // m/1/0
|
'3NgXBiMQvwcRU8khVoPFJ6gsbGg9ZYrRzH', // m/1/0
|
||||||
]);
|
]);
|
||||||
var expectedPaths = [
|
var expectedPaths = [
|
||||||
'm/0/0',
|
'm/0/0',
|
||||||
|
@ -4455,7 +4427,7 @@ describe('Wallet service', function() {
|
||||||
},
|
},
|
||||||
function(next) {
|
function(next) {
|
||||||
// NOTE: this works because it creates the exact same wallet!
|
// NOTE: this works because it creates the exact same wallet!
|
||||||
helpers.createAndJoinWallet(1, 2, function(server, wallet) {
|
helpers.createAndJoinWallet(1, 1, function(server, wallet) {
|
||||||
server.getBalance({}, function(err, balance) {
|
server.getBalance({}, function(err, balance) {
|
||||||
balance.totalAmount.should.equal(0);
|
balance.totalAmount.should.equal(0);
|
||||||
next(null, server, wallet);
|
next(null, server, wallet);
|
||||||
|
@ -4494,17 +4466,16 @@ describe('Wallet service', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('BIP45', function() {
|
describe('shared wallet (BIP45)', function() {
|
||||||
|
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
this.timeout(5000);
|
this.timeout(5000);
|
||||||
WalletService.SCAN_CONFIG.scanWindow = 2;
|
WalletService.SCAN_CONFIG.scanWindow = 2;
|
||||||
WalletService.SCAN_CONFIG.derivationDelay = 0;
|
WalletService.SCAN_CONFIG.derivationDelay = 0;
|
||||||
|
|
||||||
helpers.createAndJoinWallet(1, 2, {
|
helpers.createAndJoinWallet(1, 2, function(s, w) {
|
||||||
derivationStrategy: 'BIP45'
|
|
||||||
}, function(s, w) {
|
|
||||||
server = s;
|
server = s;
|
||||||
wallet = w;
|
wallet = w;
|
||||||
done();
|
done();
|
||||||
|
@ -4591,7 +4562,7 @@ describe('Wallet service', function() {
|
||||||
WalletService.SCAN_CONFIG.scanWindow = 2;
|
WalletService.SCAN_CONFIG.scanWindow = 2;
|
||||||
WalletService.SCAN_CONFIG.derivationDelay = 0;
|
WalletService.SCAN_CONFIG.derivationDelay = 0;
|
||||||
|
|
||||||
helpers.createAndJoinWallet(1, 2, function(s, w) {
|
helpers.createAndJoinWallet(1, 1, function(s, w) {
|
||||||
server = s;
|
server = s;
|
||||||
wallet = w;
|
wallet = w;
|
||||||
done();
|
done();
|
||||||
|
@ -4604,9 +4575,9 @@ describe('Wallet service', function() {
|
||||||
|
|
||||||
it('should start an asynchronous scan', function(done) {
|
it('should start an asynchronous scan', function(done) {
|
||||||
helpers.stubAddressActivity(
|
helpers.stubAddressActivity(
|
||||||
['3Jc2hcN13vGBCdWR4SMNRoL9EUiBHuf4LT', // m/0/0
|
['3J4J9nkFpzQjUGDh5hLKMKztFSPWMKejKE', // m/0/0
|
||||||
'3Pk2Cn3TW6JLhGEnHg8iM2qtmx2T1uHyZM', // m/0/2
|
'384JHSf9kVBs3yXsPwCzEScRs395u8hwxj', // m/0/2
|
||||||
'3GqrwYwyLt1czKMvvqFwYj2ZeooiHtbgbc', // m/1/0
|
'3NgXBiMQvwcRU8khVoPFJ6gsbGg9ZYrRzH', // m/1/0
|
||||||
]);
|
]);
|
||||||
var expectedPaths = [
|
var expectedPaths = [
|
||||||
'm/0/0',
|
'm/0/0',
|
||||||
|
|
Loading…
Reference in New Issue