Skip to content

Commit

Permalink
Merge pull request #4842 from BitGo/WP-2525
Browse files Browse the repository at this point in the history
feat(sdk-core): add encryptedWalletPassphrase to generateWallet method
  • Loading branch information
alebusse authored Aug 23, 2024
2 parents 6f665f2 + bce6011 commit b297c9a
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 10 deletions.
10 changes: 9 additions & 1 deletion modules/bitgo/test/v2/unit/lightning/lightningWallets.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as assert from 'assert';
import { TestBitGo } from '@bitgo/sdk-test';
import * as nock from 'nock';

Expand Down Expand Up @@ -164,7 +165,14 @@ describe('Lightning wallets', function () {
.post('/api/v2/tlnbtc/wallet', (body) => validateWalletRequest(body))
.reply(200, { id: 'walletId' });

await wallets.generateWallet(params);
const response = await wallets.generateWallet(params);

assert.ok(response.wallet);
assert.ok(response.encryptedWalletPassphrase);
assert.equal(
bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }),
params.passphrase
);
});
});
});
108 changes: 102 additions & 6 deletions modules/bitgo/test/v2/unit/wallets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -429,9 +429,47 @@ describe('V2 Wallets:', function () {
.post('/api/v2/tbtc/key', _.matches({ source: 'backup' }))
.reply(200, { pub: 'backupPub' });

await wallets.generateWallet(params);
const response = await wallets.generateWallet(params);

walletNock.isDone().should.be.true();

assert.ok(response.encryptedWalletPassphrase === undefined);
assert.ok(response.wallet);
});

it('should generate hot onchain wallet', async () => {
const params: GenerateWalletOptions = {
label: 'test wallet',
passphrase: 'multisig password',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
};

const walletNock = nock(bgUrl)
.post('/api/v2/tbtc/wallet', function (body) {
body.type.should.equal('hot');
return true;
})
.reply(200);

nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ source: 'bitgo' }))
.reply(200, { pub: 'bitgoPub' });
nock(bgUrl).post('/api/v2/tbtc/key', _.matches({})).reply(200);
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ source: 'backup' }))
.reply(200, { pub: 'backupPub' });

const response = await wallets.generateWallet(params);

walletNock.isDone().should.be.true();

assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.equal(
bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }),
params.passphrase
);
});
});

Expand Down Expand Up @@ -490,15 +528,64 @@ describe('V2 Wallets:', function () {

const wallets = new Wallets(bitgo, tsol);

await wallets.generateWallet({
const params = {
label: 'tss wallet',
passphrase: 'tss password',
multisigType: 'tss',
multisigType: 'tss' as any,
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
};

const response = await wallets.generateWallet(params);

walletNock.isDone().should.be.true();

assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.equal(
bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }),
params.passphrase
);
});

it('should create a new TSS wallet without providing passcodeEncryptionCode', async function () {
const stubbedKeychainsTriplet: KeychainsTriplet = {
userKeychain: {
id: '1',
pub: 'userPub',
type: 'independent',
source: 'user',
},
backupKeychain: {
id: '2',
pub: 'userPub',
type: 'independent',
source: 'backup',
},
bitgoKeychain: {
id: '3',
pub: 'userPub',
type: 'independent',
source: 'bitgo',
},
};
sandbox.stub(TssUtils.prototype, 'createKeychains').resolves(stubbedKeychainsTriplet);

const walletNock = nock('https://bitgo.fakeurl').post('/api/v2/tsol/wallet').reply(200);

const wallets = new Wallets(bitgo, tsol);

const response = await wallets.generateWallet({
label: 'tss wallet',
passphrase: 'tss password',
multisigType: 'tss',
enterprise: 'enterprise',
});

walletNock.isDone().should.be.true();

assert.ok(response.wallet);
assert.ok(response.encryptedWalletPassphrase === undefined);
});

it('should create a new ECDSA TSS wallet with BitGoTrustAsKrs as backup provider', async function () {
Expand Down Expand Up @@ -831,17 +918,26 @@ describe('V2 Wallets:', function () {

const wallets = new Wallets(bitgo, testCoin);

await wallets.generateWallet({
const params = {
label: 'tss wallet',
passphrase: 'tss password',
multisigType: 'tss',
multisigType: 'tss' as const,
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
walletVersion: 3,
});
};

const response = await wallets.generateWallet(params);

walletNock.isDone().should.be.true();
stubCreateKeychains.calledOnce.should.be.true();

assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.equal(
bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }),
params.passphrase
);
});
});

Expand Down
2 changes: 2 additions & 0 deletions modules/sdk-core/src/bitgo/wallet/iWallets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ export interface WalletWithKeychains extends KeychainsTriplet {
responseType: 'WalletWithKeychains';
wallet: IWallet;
warning?: string;
encryptedWalletPassphrase?: string;
}

export interface LightningWalletWithKeychains extends LightningKeychainsTriplet {
responseType: 'LightningWalletWithKeychains';
wallet: IWallet;
warning?: string;
encryptedWalletPassphrase?: string;
}

export interface GetWalletOptions {
Expand Down
25 changes: 22 additions & 3 deletions modules/sdk-core/src/bitgo/wallet/wallets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,13 @@ export class Wallets implements IWallets {
throw new Error(`error(s) parsing generate lightning wallet request params: ${errors}`);
}
);
return this.generateLightningWallet(options);

const walletData = await this.generateLightningWallet(options);
walletData.encryptedWalletPassphrase = this.bitgo.encrypt({
input: options.passphrase,
password: options.passcodeEncryptionCode,
});
return walletData;
}

common.validateParams(params, ['label'], ['passphrase', 'userKey', 'backupXpub']);
Expand Down Expand Up @@ -325,8 +331,7 @@ export class Wallets implements IWallets {
}

assert(passphrase, 'cannot generate TSS keys without passphrase');

return this.generateMpcWallet({
const walletData = await this.generateMpcWallet({
multisigType: 'tss',
label,
passphrase,
Expand All @@ -335,6 +340,13 @@ export class Wallets implements IWallets {
walletVersion: params.walletVersion,
backupProvider: params.backupProvider,
});
if (params.passcodeEncryptionCode) {
walletData.encryptedWalletPassphrase = this.bitgo.encrypt({
input: passphrase,
password: params.passcodeEncryptionCode,
});
}
return walletData;
}

const isBlsDkg = params.multisigType ? params.multisigType === 'blsdkg' : this.baseCoin.supportsBlsDkg();
Expand Down Expand Up @@ -559,6 +571,13 @@ export class Wallets implements IWallets {
userKeychain.derivationPath = derivationPath;
}

if (canEncrypt && params.passcodeEncryptionCode) {
result.encryptedWalletPassphrase = this.bitgo.encrypt({
input: passphrase,
password: params.passcodeEncryptionCode,
});
}

return result;
}

Expand Down

0 comments on commit b297c9a

Please sign in to comment.