Skip to content

Commit

Permalink
Merge branch 'feat/bwc-credentials-v3' of https://github.com/gonzalol…
Browse files Browse the repository at this point in the history
  • Loading branch information
kajoseph committed Jul 16, 2021
2 parents df10d60 + ffc3cae commit 4adfcb2
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 14 deletions.
133 changes: 125 additions & 8 deletions packages/bitcore-wallet-client/src/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2704,6 +2704,44 @@ export class API extends EventEmitter {
return { key: k, credentials: c };
}

// /**
// * upgradeCredentialsV2
// * upgrade Credentials V2 to Credentials V3 object
// *
// * @param {Object} x - Credentials V2 Object

// * @returns {Callback} cb - Returns { err, {key, credentials} }
// */
static upgradeCredentialsV2(x) {
$.shouldBeObject(x);
// Check if credential is v2, if not upgrade first to v2.
if(!x.version || x.version < 2) {
const credentialV2 = this.upgradeCredentialsV1(x);
if(credentialV2 && credentialV2.credentials) {
x = credentialV2.credentials;
}else{
const _errMsg = 'An error has ocurred when upgrading credentials to V2';
log.error(_errMsg);
throw new Error(_errMsg);
}
}

let k;
if (x.xPrivKey || x.xPrivKeyEncrypted) {
k = new Key({ seedData: x, seedType: 'objectV1' });
} else {
// RO credentials
k = false;
}
var c = new Credentials();
_.each(Credentials.FIELDS, f => {
if (f != 'version') c[f] = x[f]; // use new version
});

c.chain = Utils.getChain(c.coin).toLowerCase();
return { key: k, credentials: c };
}

// /**
// * upgradeMultipleCredentialsV1
// * upgrade multiple Credentials V1 and (opionally) keys to Key and Credentials V2 object
Expand All @@ -2720,22 +2758,101 @@ export class API extends EventEmitter {
let newKeys = [],
newCrededentials = [];
// Try to migrate to Credentials 2.0
_.each(oldCredentials, credentials => {
_.each(oldCredentials, credential => {
let migrated;

if (!credentials.version || credentials.version < 2) {
log.info('About to migrate : ' + credentials.walletId);
if (!credential.version || credential.version < 2) {
log.info('About to migrate : ' + credential.walletId);
migrated = API.upgradeCredentialsV1(credential);
newCrededentials.push(migrated.credentials);

migrated = API.upgradeCredentialsV1(credentials);
newCrededentials.push(migrated.credentials);
if (migrated.key) {
log.info(`Wallet ${credential.walletId} key's extracted`);
newKeys.push(migrated.key);
} else {
log.info(`READ-ONLY Wallet ${credential.walletId} migrated`);
}
}
});

if (newKeys.length > 0) {
// Find and merge dup keys.
let credGroups = _.groupBy(newCrededentials, x => {
$.checkState(x.xPubKey, 'Failed state: no xPubKey at credentials!');
let xpub = new Bitcore.HDPublicKey(x.xPubKey);
let fingerPrint = xpub.fingerPrint.toString('hex');
return fingerPrint;
});

if (_.keys(credGroups).length < newCrededentials.length) {
log.info('Found some wallets using the SAME key. Merging...');

let uniqIds = {};

_.each(_.values(credGroups), credList => {
let toKeep = credList.shift();
if (!toKeep.keyId) return;
uniqIds[toKeep.keyId] = true;

if (!credList.length) return;
log.info(`Merging ${credList.length} keys to ${toKeep.keyId}`);
_.each(credList, x => {
log.info(`\t${x.keyId} is now ${toKeep.keyId}`);
x.keyId = toKeep.keyId;
});
});

newKeys = _.filter(newKeys, x => uniqIds[x.id]);
}
}

return {
keys: newKeys,
credentials: newCrededentials
};
}

// /**
// * upgradeMultipleCredentialsToLatestVersion
// * upgrade multiple Old Credentials to latest credential version
// * Duplicate keys will be identified and merged.
// *
// * @param {Object} credentials - Credentials Old Version
// * @param {Object} keys - Key object
// *

// * @returns {Callback} cb - Returns { err, {keys, credentials} }
// */

static upgradeMultipleCredentialsToLatestVersion(oldCredentials) {
let newKeys = [],
newCrededentials = [];
// Try to migrate to new Credentials Version
_.each(oldCredentials, credential => {
let migrated;

if (!credential.version || credential.version < 2) {
log.info('About to migrate : ' + credential.walletId);
migrated = API.upgradeCredentialsV1(credential);
}

if (credential.version == 2 || migrated.credentials.version == 2) {
log.info('About to migrate to V3 : ' + credential.walletId);
migrated = API.upgradeCredentialsV2(
migrated && migrated.credentials ? migrated.credentials : credential
);
}

if (migrated) {
if (migrated.key) {
log.info(`Wallet ${credentials.walletId} key's extracted`);
log.info(`Wallet ${credential.walletId} key's extracted`);
newKeys.push(migrated.key);
} else {
log.info(`READ-ONLY Wallet ${credentials.walletId} migrated`);
log.info(`READ-ONLY Wallet ${credential.walletId} migrated`);
}
}

if (migrated) newCrededentials.push(migrated.credentials);
});

if (newKeys.length > 0) {
Expand Down Expand Up @@ -2798,11 +2915,11 @@ export class API extends EventEmitter {
var checkCredentials = (key, opts, icb) => {
let c = key.createCredentials(null, {
coin: opts.coin,
chain: opts.chain,
network: opts.network,
account: opts.account,
n: opts.n
});

if (copayerIdAlreadyTested[c.copayerId + ':' + opts.n]) {
// console.log('[api.js.2226] ALREADY T:', opts.n); // TODO
return icb();
Expand Down
16 changes: 10 additions & 6 deletions packages/bitcore-wallet-client/src/lib/credentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const sjcl = require('sjcl');
export class Credentials {
static FIELDS = [
'coin',
'chain', // new -> start using chain when needed instead of coin
'network',
'xPrivKey', // obsolete
'xPrivKeyEncrypted', // obsolte
Expand Down Expand Up @@ -62,6 +63,7 @@ export class Credentials {
derivationStrategy: any;
network: string;
coin: string;
chain: string;
use145forBCH: any;

addressType: string;
Expand All @@ -71,7 +73,7 @@ export class Credentials {
externalSource?: boolean; // deprecated property?

constructor() {
this.version = 2;
this.version = 3;
this.account = 0;
}

Expand All @@ -92,6 +94,7 @@ export class Credentials {

var x: any = new Credentials();
x.coin = opts.coin;
x.chain = opts.chain || Utils.getChain(x.coin).toLowerCase();
x.network = opts.network;
x.account = opts.account;
x.n = opts.n;
Expand Down Expand Up @@ -194,19 +197,19 @@ export class Credentials {
Constants.UTXO_COINS.includes(this.coin)
) {
coin = '1';
} else if (this.coin == 'bch') {
} else if (this.coin == 'bch' || this.chain == 'bch') {
if (this.use145forBCH) {
coin = '145';
} else {
coin = '0';
}
} else if (this.coin == 'btc') {
} else if (this.coin == 'btc' || this.chain == 'btc') {
coin = '0';
} else if (this.coin == 'eth') {
} else if (this.coin == 'eth' || this.chain == 'eth') {
coin = '60';
} else if (this.coin == 'xrp') {
} else if (this.coin == 'xrp' || this.chain == 'xrp') {
coin = '144';
} else if (this.coin == 'doge') {
} else if (this.coin == 'doge' || this.chain == 'doge') {
coin = '3';
} else if (this.coin == 'ltc') {
coin = '2';
Expand Down Expand Up @@ -242,6 +245,7 @@ export class Credentials {
}

x.coin = x.coin || 'btc';
x.chain = x.chain || Utils.getChain(x.coin).toLowerCase();
x.addressType = x.addressType || Constants.SCRIPT_TYPES.P2SH;
x.account = x.account || 0;

Expand Down
2 changes: 2 additions & 0 deletions packages/bitcore-wallet-client/src/lib/key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ export class Key {

if (password) $.shouldBeString(password, 'provide password');

// this._checkCoin(opts.coin);
this._checkNetwork(opts.network);
$.shouldBeNumber(opts.account, 'Invalid account');
$.shouldBeNumber(opts.n, 'Invalid n');
Expand Down Expand Up @@ -445,6 +446,7 @@ export class Key {

return Credentials.fromDerivedKey({
xPubKey: xPrivKey.hdPublicKey.toString(),
chain: opts.chain,
coin: opts.coin,
network: opts.network,
account: opts.account,
Expand Down

0 comments on commit 4adfcb2

Please sign in to comment.