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
67 changes: 67 additions & 0 deletions modules/bitgo/test/v2/unit/wallets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -988,6 +988,73 @@ describe('V2 Wallets:', function () {
});
});

describe('Generate shielded wallet:', function () {
const tzec = bitgo.coin('tzec');

it('should create a new shielded custodial wallet', async function () {
const keys = ['1', '2', '3'];

const walletParams: GenerateWalletOptions = {
label: 'shielded wallet',
isShielded: true,
enterprise: 'enterprise',
type: 'custodial',
};

const walletNock = nock('https://bitgo.fakeurl')
.post('/api/v2/tzec/wallet/add', (body) => {
body.multisigType.should.equal(multisigTypes.tss);
body.coinSpecific.should.deepEqual({ isShielded: true });
return true;
})
.times(1)
.reply(200, { ...walletParams, multisigType: multisigTypes.tss, keys });

const shieldedWallets = new Wallets(bitgo, tzec);

const res = await shieldedWallets.generateWallet(walletParams);
if (!isWalletWithKeychains(res)) {
throw new Error('wallet missing required keychains');
}
res.wallet.label().should.equal(walletParams.label);
should.equal(res.wallet.type(), walletParams.type);
res.wallet.toJSON().enterprise.should.equal(walletParams.enterprise);
res.wallet.multisigType().should.equal(multisigTypes.tss);
res.userKeychain.type.should.equal('tss');
res.backupKeychain.type.should.equal('tss');
res.bitgoKeychain.type.should.equal('tss');

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

it('should reject a non-custodial shielded wallet', async function () {
const walletParams: GenerateWalletOptions = {
label: 'shielded wallet',
isShielded: true,
enterprise: 'enterprise',
type: 'hot',
};

const shieldedWallets = new Wallets(bitgo, tzec);

await shieldedWallets
.generateWallet(walletParams)
.should.be.rejectedWith('shielded wallets can only be created as custodial wallets');
});

it('should reject a shielded wallet without an enterprise', async function () {
const walletParams: GenerateWalletOptions = {
label: 'shielded wallet',
isShielded: true,
type: 'custodial',
};

const shieldedWallets = new Wallets(bitgo, tzec);

await shieldedWallets.generateWallet(walletParams).should.be.rejectedWith('enterprise is required');
});
});

describe('Generate TSS MPCv2 wallet:', async function () {
const sandbox = sinon.createSandbox();

Expand Down
3 changes: 3 additions & 0 deletions modules/sdk-core/src/bitgo/wallet/iWallets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export interface GetWalletOptions {

export interface GenerateBaseMpcWalletOptions {
multisigType: 'tss';
isShielded?: boolean;
label: string;
enterprise: string;
walletVersion?: number;
Expand Down Expand Up @@ -250,6 +251,8 @@ export interface GenerateWalletOptions {
coldDerivationSeed?: string;
rootPrivateKey?: string;
multisigType?: 'onchain' | 'tss' | 'blsdkg';
// Used for zec shielded custodial wallets
isShielded?: boolean;
isDistributedCustody?: boolean;
bitgoKeyId?: string;
commonKeychain?: string;
Expand Down
18 changes: 18 additions & 0 deletions modules/sdk-core/src/bitgo/wallet/wallets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,22 @@ export class Wallets implements IWallets {
return walletData;
}

// Transparent zcash wallets are multisig and isTSS is not set inherently.
// Shielded zcash wallets are MPC
if (params.isShielded) {
assert(enterprise, 'enterprise is required for shielded wallet');
if (type !== 'custodial') {
throw new Error('shielded wallets can only be created as custodial wallets');
}
return this.generateCustodialMpcWallet({
multisigType: 'tss',
isShielded: true,
label,
enterprise,
walletVersion: params.walletVersion,
});
}

// Handle distributed custody
if (isDistributedCustody) {
if (!enterprise) {
Expand Down Expand Up @@ -2024,6 +2040,7 @@ export class Wallets implements IWallets {
private async generateCustodialMpcWallet({
label,
multisigType,
isShielded,
enterprise,
walletVersion,
}: GenerateBaseMpcWalletOptions): Promise<WalletWithKeychains> {
Expand All @@ -2045,6 +2062,7 @@ export class Wallets implements IWallets {
enterprise,
walletVersion,
type: 'custodial',
...(isShielded && { coinSpecific: { isShielded: true } }),
};

// Create Wallet
Expand Down
Loading