Skip to content

Commit

Permalink
Merge pull request #2121 from matiu/ref/rm-bip45
Browse files Browse the repository at this point in the history
Ref/rm bip45
  • Loading branch information
matiu committed Apr 12, 2019
2 parents 4b33dac + 6aa8e7f commit 3b99ab7
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 603 deletions.
23 changes: 0 additions & 23 deletions packages/bitcore-wallet-client/lib/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -2386,29 +2386,6 @@ API.prototype.getWalletIdsFromOldCopay = function(username, password, blob) {
return _.uniq(ids);
};


/**
* createWalletFromOldCopay
*
* @param username
* @param password
* @param blob
* @param cb
* @return {undefined}
*/
API.prototype.createWalletFromOldCopay = function(username, password, blob, cb) {
var self = this;
var w = this._oldCopayDecrypt(username, password, blob);
if (!w) return cb(new Error('Could not decrypt'));

if (w.publicKeyRing.copayersExtPubKeys.length != w.opts.totalCopayers)
return cb(new Error('Wallet is incomplete, cannot be imported'));

this.credentials = Credentials.fromOldCopayWallet(w);
this.request.setCredentials(this.credentials);
this.recreateWallet(cb);
};

API.PayPro = PayPro;

module.exports = API;
54 changes: 0 additions & 54 deletions packages/bitcore-wallet-client/lib/credentials.js
Original file line number Diff line number Diff line change
Expand Up @@ -484,58 +484,4 @@ Credentials.prototype.clearMnemonic = function() {
delete this.mnemonicEncrypted;
};


Credentials.fromOldCopayWallet = function(w) {
function walletPrivKeyFromOldCopayWallet(w) {
// IN BWS, the master Pub Keys are not sent to the server,
// so it is safe to use them as seed for wallet's shared secret.
var seed = w.publicKeyRing.copayersExtPubKeys.sort().join('');
var seedBuf = new Buffer(seed);
var privKey = new Bitcore.PrivateKey.fromBuffer(Bitcore.crypto.Hash.sha256(seedBuf));
return privKey.toString();
};

var credentials = new Credentials();
credentials.coin = 'btc';
credentials.derivationStrategy = Constants.DERIVATION_STRATEGIES.BIP45;
credentials.xPrivKey = w.privateKey.extendedPrivateKeyString;
credentials._expand();

credentials.addWalletPrivateKey(walletPrivKeyFromOldCopayWallet(w));
credentials.addWalletInfo(w.opts.id, w.opts.name, w.opts.requiredCopayers, w.opts.totalCopayers)

var pkr = _.map(w.publicKeyRing.copayersExtPubKeys, function(xPubStr) {

var isMe = xPubStr === credentials.xPubKey;
var requestDerivation;

if (isMe) {
var path = Constants.PATHS.REQUEST_KEY;
requestDerivation = (new Bitcore.HDPrivateKey(credentials.xPrivKey))
.deriveChild(path).hdPublicKey;
} else {
// this
var path = Constants.PATHS.REQUEST_KEY_AUTH;
requestDerivation = (new Bitcore.HDPublicKey(xPubStr)).deriveChild(path);
}

// Grab Copayer Name
var hd = new Bitcore.HDPublicKey(xPubStr).deriveChild('m/2147483646/0/0');
var pubKey = hd.publicKey.toString('hex');
var copayerName = w.publicKeyRing.nicknameFor[pubKey];
if (isMe) {
credentials.copayerName = copayerName;
}

return {
xPubKey: xPubStr,
requestPubKey: requestDerivation.publicKey.toString(),
copayerName: copayerName,
};
});
credentials.addPublicKeyRing(pkr);
return credentials;
};


module.exports = Credentials;
231 changes: 0 additions & 231 deletions packages/bitcore-wallet-client/test/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -4866,237 +4866,6 @@ describe('client API', function() {
});
});

describe('Legacy Copay Import', function() {
var db2;
before( (done) => {
helpers.newDb(2,(err,in_db) => {
db2 = in_db;
return done(err);
});
});

it('Should get wallets from profile', function(done) {
var t = ImportData.copayers[0];
var c = helpers.newClient(app);
var ids = c.getWalletIdsFromOldCopay(t.username, t.password, t.ls['profile::4872dd8b2ceaa54f922e8e6ba6a8eaa77b488721']);
ids.should.deep.equal([
'8f197244e661f4d0',
'4d32f0737a05f072',
'e2c2d72024979ded',
'7065a73486c8cb5d'
]);
done();
});
it('Should import a 1-1 wallet', function(done) {
var t = ImportData.copayers[0];
var c = helpers.newClient(app);
c.createWalletFromOldCopay(t.username, t.password, t.ls['wallet::e2c2d72024979ded'], function(err) {
should.not.exist(err);
c.credentials.m.should.equal(1);
c.credentials.n.should.equal(1);

c.createAddress(function(err, x0) {
should.not.exist(err);
// This is the first 'shared' address, created automatically
// by old copay
x0.address.should.equal('2N3w8sJUyAXCQirqNsTayWr7pWADFNdncmf');
c.getStatus({}, function(err, status) {
should.not.exist(err);
status.wallet.name.should.equal('1-1');
status.wallet.status.should.equal('complete');
c.credentials.walletId.should.equal('e2c2d72024979ded');
c.credentials.walletPrivKey.should.equal('c3463113c6e1d0fc2f2bd520f7d9d62f8e1fdcdd96005254571c64902aeb1648');
c.credentials.sharedEncryptingKey.should.equal('x3D/7QHa4PkKMbSXEvXwaw==');
status.wallet.copayers.length.should.equal(1);
status.wallet.copayers[0].name.should.equal('123');
done();
});
});
});
});

it('Should to import the same wallet twice with different clients', function(done) {
var t = ImportData.copayers[0];
var c = helpers.newClient(app);
c.createWalletFromOldCopay(t.username, t.password, t.ls['wallet::4d32f0737a05f072'], function(err) {
should.not.exist(err);
c.getStatus({}, function(err, status) {
should.not.exist(err);
status.wallet.status.should.equal('complete');
c.credentials.walletId.should.equal('4d32f0737a05f072');
var c2 = helpers.newClient(app);
c2.createWalletFromOldCopay(t.username, t.password, t.ls['wallet::4d32f0737a05f072'], function(err) {
should.not.exist(err);
c2.getStatus({}, function(err, status) {
should.not.exist(err);
status.wallet.status.should.equal('complete');
c2.credentials.walletId.should.equal('4d32f0737a05f072');
done();
});
});
});
});
});

it('Should not fail when importing the same wallet twice, same copayer', function(done) {
var t = ImportData.copayers[0];
var c = helpers.newClient(app);
c.createWalletFromOldCopay(t.username, t.password, t.ls['wallet::4d32f0737a05f072'], function(err) {
should.not.exist(err);
c.getStatus({}, function(err, status) {
should.not.exist(err);
status.wallet.status.should.equal('complete');
c.credentials.walletId.should.equal('4d32f0737a05f072');
c.createWalletFromOldCopay(t.username, t.password, t.ls['wallet::4d32f0737a05f072'], function(err) {
should.not.exist(err);
done();
});
});
});
});

it('Should import and complete 2-2 wallet from 2 copayers, and create addresses', function(done) {
var t = ImportData.copayers[0];
var c = helpers.newClient(app);
c.createWalletFromOldCopay(t.username, t.password, t.ls['wallet::4d32f0737a05f072'], function(err) {
should.not.exist(err);
c.getStatus({}, function(err, status) {
should.not.exist(err);
status.wallet.status.should.equal('complete');
c.credentials.sharedEncryptingKey.should.equal('Ou2j4kq3z1w4yTr9YybVxg==');

var t2 = ImportData.copayers[1];
var c2 = helpers.newClient(app);
c2.createWalletFromOldCopay(t2.username, t2.password, t2.ls['wallet::4d32f0737a05f072'], function(err) {
should.not.exist(err);
c2.credentials.sharedEncryptingKey.should.equal('Ou2j4kq3z1w4yTr9YybVxg==');

// This should pull the non-temporary keys
c2.getStatus({}, function(err, status) {
should.not.exist(err);
status.wallet.status.should.equal('complete');
c2.createAddress(function(err, x0) {
x0.address.should.be.equal('2Mv1DHpozzZ9fup2nZ1kmdRXoNnDJ8b1JF2');
c.createAddress(function(err, x0) {
x0.address.should.be.equal('2N2dZ1HogpxHVKv3CD2R4WrhWRwqZtpDc2M');
done();
});
});
});
});
});
});
});

it('Should import and complete 2-3 wallet from 2 copayers, and create addresses', function(done) {
var w = 'wallet::7065a73486c8cb5d';
var key = 'fS4HhoRd25KJY4VpNpO1jg==';
var t = ImportData.copayers[0];
var c = helpers.newClient(app);
c.createWalletFromOldCopay(t.username, t.password, t.ls[w], function(err) {
should.not.exist(err);
c.getStatus({}, function(err, status) {
should.not.exist(err);
status.wallet.status.should.equal('complete');
c.credentials.sharedEncryptingKey.should.equal(key);

var t2 = ImportData.copayers[1];
var c2 = helpers.newClient(app);
c2.createWalletFromOldCopay(t2.username, t2.password, t2.ls[w], function(err) {
should.not.exist(err);
c2.credentials.sharedEncryptingKey.should.equal(key);

c2.getStatus({}, function(err, status) {
should.not.exist(err);
status.wallet.status.should.equal('complete');

var t3 = ImportData.copayers[2];
var c3 = helpers.newClient(app);
c3.createWalletFromOldCopay(t3.username, t3.password, t3.ls[w], function(err) {
should.not.exist(err);
c3.credentials.sharedEncryptingKey.should.equal(key);

// This should pull the non-temporary keys
c3.getStatus({}, function(err, status) {
should.not.exist(err);
status.wallet.status.should.equal('complete');
done();
});
});
});
});
});
});
});

it('Should import a 2-3 wallet from 2 copayers, and recreate it, and then on the recreated other copayers should be able to access', function(done) {
var w = 'wallet::7065a73486c8cb5d';
var key = 'fS4HhoRd25KJY4VpNpO1jg==';
var t = ImportData.copayers[0];
var c = helpers.newClient(app);
c.createWalletFromOldCopay(t.username, t.password, t.ls[w], function(err) {
should.not.exist(err);
var t2 = ImportData.copayers[1];
var c2 = helpers.newClient(app);
c2.createWalletFromOldCopay(t2.username, t2.password, t2.ls[w], function(err) {
should.not.exist(err);

// New BWS server...
var storage = new Storage({
db: db2,
});
var newApp;
var expressApp = new ExpressApp();
expressApp.start({
storage: storage,
blockchainExplorer: blockchainExplorerMock,
disableLogs: true,
},
function() {
newApp = expressApp.app;
});
var recoveryClient = helpers.newClient(newApp);
recoveryClient.import(c.export());

/*
* This is to export 2 old BIP45 wallets
var b= c.export();
var e = sjcl.encrypt('hola', b, {
iter: 10000
});
console.log("[client.js.4813] C EXPORT\n", e); //TODO
b= c2.export();
e= sjcl.encrypt('hola', b, {
iter: 10000
});
console.log("[client.js.4813] C2 EXPORT\n", e); //TODO
*/

recoveryClient.recreateWallet(function(err) {
should.not.exist(err);
recoveryClient.getStatus({}, function(err, status) {
should.not.exist(err);
_.map(status.wallet.copayers, 'name').sort().should.deep.equal(['123', '234', '345']);
var t2 = ImportData.copayers[1];
var c2p = helpers.newClient(newApp);
c2p.createWalletFromOldCopay(t2.username, t2.password, t2.ls[w], function(err) {
should.not.exist(err);
c2p.getStatus({}, function(err, status) {
should.not.exist(err);
_.map(status.wallet.copayers, 'name').sort().should.deep.equal(['123', '234', '345']);
done();
});
});
});
});
});
});
});
});

describe('Private key encryption', function() {
var password = 'jesuissatoshi';
var c1, c2;
Expand Down
30 changes: 3 additions & 27 deletions packages/bitcore-wallet-service/src/lib/expressapp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,19 +244,7 @@ export class ExpressApp {
// DEPRECATED
router.post('/v1/wallets/', createWalletLimiter, (req, res) => {
logDeprecated(req);
let server;
try {
server = getServer(req, res);
} catch (ex) {
return returnError(ex, res, req);
}
req.body.supportBIP44AndP2PKH = false;
server.createWallet(req.body, (err, walletId) => {
if (err) return returnError(err, res, req);
res.json({
walletId
});
});
return returnError(new ClientError('BIP45 wallet creation no longer supported'), res, req);
});

router.post('/v2/wallets/', createWalletLimiter, (req, res) => {
Expand Down Expand Up @@ -291,19 +279,7 @@ export class ExpressApp {
// DEPRECATED
router.post('/v1/wallets/:id/copayers/', (req, res) => {
logDeprecated(req);
req.body.walletId = req.params['id'];
req.body.supportBIP44AndP2PKH = false;
let server;
try {
server = getServer(req, res);
} catch (ex) {
return returnError(ex, res, req);
}
server.joinWallet(req.body, (err, result) => {
if (err) return returnError(err, res, req);

res.json(result);
});
return returnError(new ClientError('BIP45 wallet creation no longer supported'), res, req);
});

router.post('/v2/wallets/:id/copayers/', (req, res) => {
Expand Down Expand Up @@ -944,4 +920,4 @@ export class ExpressApp {

WalletService.initialize(opts, cb);
}
}
}
Loading

0 comments on commit 3b99ab7

Please sign in to comment.