diff --git a/modules/bitgo/test/v2/unit/staking/stakingWalletCommon.ts b/modules/bitgo/test/v2/unit/staking/stakingWalletCommon.ts index 80ddab3997..81aabd61c8 100644 --- a/modules/bitgo/test/v2/unit/staking/stakingWalletCommon.ts +++ b/modules/bitgo/test/v2/unit/staking/stakingWalletCommon.ts @@ -84,6 +84,54 @@ describe('Staking Wallet Common', function () { msScope.isDone().should.be.True(); }); + it('should forward top-level staking subtype to staking-service', async function () { + const expected = fixtures.stakingRequest([fixtures.transaction('NEW')]); + const msScope = nock(microservicesUri) + .post(`/api/staking/v1/${stakingWallet.coin}/wallets/${stakingWallet.walletId}/requests`, { + amount: '1', + clientId: 'clientId', + subType: 'ETH_STAKE_PECTRA', + type: 'STAKE', + }) + .reply(201, expected); + + const stakingRequest = await stakingWallet.stake({ + amount: '1', + clientId: 'clientId', + subType: 'ETH_STAKE_PECTRA', + }); + + should.exist(stakingRequest); + stakingRequest.should.deepEqual(expected); + msScope.isDone().should.be.True(); + }); + + it('should preserve the legacy PoX-5 subtype on the wire', async function () { + const expected = fixtures.stakingRequest([fixtures.transaction('NEW')]); + const msScope = nock(microservicesUri) + .post(`/api/staking/v1/${stakingWallet.coin}/wallets/${stakingWallet.walletId}/requests`, { + amount: '1', + bondIndex: 0, + clientId: 'clientId', + signerManager: 'manager', + subType: 'pox5-bond', + type: 'STAKE', + }) + .reply(201, expected); + + const stakingRequest = await stakingWallet.stake({ + amount: '1', + bondIndex: 0, + clientId: 'clientId', + signerManager: 'manager', + subType: 'pox5-bond', + }); + + should.exist(stakingRequest); + stakingRequest.should.deepEqual(expected); + msScope.isDone().should.be.True(); + }); + it('should call staking-service to stake with optional stakeMany parameters', async function () { const expected = fixtures.stakingRequest([fixtures.transaction('NEW')]); const msScope = nock(microservicesUri) diff --git a/modules/sdk-core/src/bitgo/staking/iStakingWallet.ts b/modules/sdk-core/src/bitgo/staking/iStakingWallet.ts index ec7c8ef90f..0010b4f7ed 100644 --- a/modules/sdk-core/src/bitgo/staking/iStakingWallet.ts +++ b/modules/sdk-core/src/bitgo/staking/iStakingWallet.ts @@ -1,6 +1,34 @@ import { SignedTransaction } from '../baseCoin'; import { PrebuildTransactionOptions, PrebuildTransactionResult } from '../wallet'; +/** + * All known staking subtypes across coins. + * Used by StakeOptions.subType for compile-time type safety. + */ +export type StakingSubType = + | 'STAKE' + | 'ETH_STAKE_PECTRA' + | 'LIDO' + | 'SOL_STAKE' + | 'MARINADE' + | 'MARINADE_SELECT' + | 'NATIVE_STAKE' + | 'INFRARED_LIQUID_STAKE' + | 'WCT_STAKE' + | 'STACK' + | 'SELF_STACK' + | 'MULTI_NOMINATOR_STAKE' + | 'SINGLE_NOMINATOR_STAKE' + | 'TON_WHALES' + | 'VET_VALIDATOR_REGISTRATION' + | 'VET_UNSTAKE' + | 'VET_INCREASE_STAKE' + | 'STAVAX_STAKE' + | 'PSTAVAX_STAKE' + | 'WFLR_STAKE' + | 'VOTE' + | 'pox5-bond'; + export interface StakingRequest { id: string; amount: string; @@ -88,9 +116,10 @@ export interface StakeOptions { */ blsSignature?: string; /** - * subtype-specific interfaces provide their own discriminant + * coin-specific staking subtype, forwarded to staking-service. + * Restricted to known values via StakingSubType union. */ - subType?: never; + subType?: StakingSubType; /** * stx btc reward address */ @@ -214,9 +243,10 @@ export interface UnstakeOptions { clientId?: string; delegationId?: string; /** - * coin sepcific staking subtype + * coin-specific staking subtype for unstaking. + * Restricted to known values via StakingSubType union. */ - subType?: string; + subType?: StakingSubType; } export interface EthUnstakeOptions {