Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions modules/bitgo/test/v2/unit/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1994,6 +1994,37 @@ describe('V2 Wallet:', function () {
createShareNock.isDone().should.be.True();
});

it('should share wallet when key fetch returns 404 (cold wallet with missing key records)', async function () {
const userId = '123';
const email = 'shareto@sdktest.com';
const permissions = 'view,spend';

const getSharingKeyNock = nock(bgUrl).post('/api/v1/user/sharingkey', { email }).reply(200, { userId });

// Simulate cold storage wallets where key records do not exist on the backend (404)
const getKeyNock = nock(bgUrl)
.get(`/api/v2/tbtc/key/${coldWallet.keyIds()[0]}`)
.reply(404, { error: 'key not found' })
.get(`/api/v2/tbtc/key/${coldWallet.keyIds()[1]}`)
.reply(404, { error: 'key not found' })
.get(`/api/v2/tbtc/key/${coldWallet.keyIds()[2]}`)
.reply(404, { error: 'key not found' });

const createShareNock = nock(bgUrl)
.post(`/api/v2/tbtc/wallet/${coldWallet.id()}/share`, {
user: userId,
permissions,
skipKeychain: true,
})
.reply(200, {});

await coldWallet.shareWallet({ email, permissions });

getSharingKeyNock.isDone().should.be.True();
getKeyNock.isDone().should.be.True();
createShareNock.isDone().should.be.True();
});

describe('Hot Wallet Sharing', function () {
const userId = '123';
const email = 'shareto@sdktest.com';
Expand Down
14 changes: 13 additions & 1 deletion modules/sdk-core/src/bitgo/wallet/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { BitGoBase } from '../bitgoBase';
import { getSharedSecret } from '../ecdh';
import {
AddressGenerationError,
ApiResponseError,
IncorrectPasswordError,
MethodNotImplementedError,
MissingEncryptedKeychainError,
Expand Down Expand Up @@ -1714,7 +1715,18 @@ export class Wallet implements IWallet {

const params = { id: this._wallet.keys[index] };

const keychain = await this.baseCoin.keychains().get(params);
let keychain: Keychain;
try {
keychain = await this.baseCoin.keychains().get(params);
} catch (e) {
// A 404 means the key record does not exist on the server (e.g. cold wallet keys
// or KMS-backed keys that have no keychain entry). Treat this the same as a key
// without an encryptedPrv and try the next one.
if (e instanceof ApiResponseError && e.status === 404) {
return tryKeyChain(index + 1);
}
throw e;
}
// If we find the prv, then this is probably the user keychain we're looking for
if (keychain.encryptedPrv) {
return keychain as KeychainWithEncryptedPrv;
Expand Down
Loading