diff --git a/examples/js/.DS_Store b/examples/js/.DS_Store new file mode 100644 index 0000000000..5008ddfcf5 Binary files /dev/null and b/examples/js/.DS_Store differ diff --git a/modules/sdk-coin-polyx/src/polyx.ts b/modules/sdk-coin-polyx/src/polyx.ts index a49061b367..e0b5d40dad 100644 --- a/modules/sdk-coin-polyx/src/polyx.ts +++ b/modules/sdk-coin-polyx/src/polyx.ts @@ -12,6 +12,7 @@ import { Environments, MPCSweepRecoveryOptions, MPCTxs, + TokenEnablementConfig, } from '@bitgo/sdk-core'; import { ApiPromise, WsProvider } from '@polkadot/api'; import { BaseCoin as StaticsBaseCoin, coins, SubstrateSpecNameType } from '@bitgo/statics'; @@ -343,4 +344,23 @@ export class Polyx extends SubstrateCoin { } return { transactions: broadcastableTransactions, lastScanIndex }; } + + /** + * Gets config for how token enablements work for this coin + * @returns + * requiresTokenEnablement: True if tokens need to be enabled for this coin + * supportsMultipleTokenEnablements: True if multiple tokens can be enabled in one transaction + * validateWallet: Function to validate wallet type for token enablement + */ + getTokenEnablementConfig(): TokenEnablementConfig { + return { + requiresTokenEnablement: true, + supportsMultipleTokenEnablements: false, + validateWallet: (walletType: string) => { + if (walletType !== 'custodial') { + throw new Error('Token enablement for Polymesh (polyx) is only supported for custodial wallets'); + } + }, + }; + } } diff --git a/modules/sdk-coin-polyx/test/unit/polyx.ts b/modules/sdk-coin-polyx/test/unit/polyx.ts index 6cb15afb6e..a8a6c6f4d4 100644 --- a/modules/sdk-coin-polyx/test/unit/polyx.ts +++ b/modules/sdk-coin-polyx/test/unit/polyx.ts @@ -179,4 +179,24 @@ describe('Polyx:', function () { should.deepEqual(txJson.eraPeriod, baseCoin.SWEEP_TXN_DURATION); }); }); + + describe('Token Enablement:', function () { + it('should have correct token enablement config', function () { + const config = baseCoin.getTokenEnablementConfig(); + should.exist(config); + config.requiresTokenEnablement.should.equal(true); + config.supportsMultipleTokenEnablements.should.equal(false); + }); + + it('should validate wallet type for token enablement', function () { + const config = baseCoin.getTokenEnablementConfig(); + (() => config.validateWallet('custodial')).should.not.throw(); + (() => config.validateWallet('hot')).should.throw( + /Token enablement for Polymesh \(polyx\) is only supported for custodial wallets/ + ); + (() => config.validateWallet('cold')).should.throw( + /Token enablement for Polymesh \(polyx\) is only supported for custodial wallets/ + ); + }); + }); }); diff --git a/modules/sdk-core/src/bitgo/baseCoin/iBaseCoin.ts b/modules/sdk-core/src/bitgo/baseCoin/iBaseCoin.ts index 6b99050a5c..71eb910b5a 100644 --- a/modules/sdk-core/src/bitgo/baseCoin/iBaseCoin.ts +++ b/modules/sdk-core/src/bitgo/baseCoin/iBaseCoin.ts @@ -455,6 +455,7 @@ export interface RecoverTokenTransaction { export interface TokenEnablementConfig { requiresTokenEnablement: boolean; supportsMultipleTokenEnablements: boolean; + validateWallet?: (walletType: string) => void; } export interface MessagePrep { diff --git a/modules/sdk-core/src/bitgo/wallet/wallet.ts b/modules/sdk-core/src/bitgo/wallet/wallet.ts index f62e6cf63f..6c24a1f878 100644 --- a/modules/sdk-core/src/bitgo/wallet/wallet.ts +++ b/modules/sdk-core/src/bitgo/wallet/wallet.ts @@ -3118,6 +3118,12 @@ export class Wallet implements IWallet { if (!teConfig.requiresTokenEnablement) { throw new Error(`${this.baseCoin.getFullName()} does not require token enablements`); } + + // Validate wallet type if coin requires it + if (typeof teConfig.validateWallet === 'function' && this._wallet.type) { + teConfig.validateWallet(this._wallet.type); + } + if (params.enableTokens.length === 0) { throw new Error('No tokens are being specified'); } @@ -3185,6 +3191,11 @@ export class Wallet implements IWallet { throw new Error(`${this.baseCoin.getFullName()} does not require token enablement transactions`); } + // Validate wallet type if coin requires it + if (teConfig.validateWallet && this._wallet.type) { + teConfig.validateWallet(this._wallet.type); + } + if (typeof params.prebuildTx === 'string' || params.prebuildTx?.buildParams?.type !== 'enabletoken') { throw new Error('Invalid build of token enablement.'); }