From 22881b343d0efe7a688c1a750533e20558335776 Mon Sep 17 00:00:00 2001 From: Ulisses Ferreira Date: Thu, 30 Jul 2026 16:15:51 +0100 Subject: [PATCH 1/7] fix: disclose WitnessCreateContract 9,999 TRX burn fee Include getAccountUpgradeCost in fee calculation for WitnessCreateContract so Network fee and insufficient-balance checks reflect the irreversible protocol burn. Replace the generic unsupported-simulation copy with Super Representative candidate disclosure on confirmation. Fixes WPN-1719 --- packages/tron-wallet-snap/CHANGELOG.md | 6 + packages/tron-wallet-snap/jest.config.mjs | 8 +- packages/tron-wallet-snap/locales/en.json | 3 + packages/tron-wallet-snap/locales/es.json | 3 + packages/tron-wallet-snap/messages.json | 3 + packages/tron-wallet-snap/snap.manifest.json | 2 +- .../tron-wallet-snap/src/constants/index.ts | 6 + .../send/FeeCalculatorService.test.ts | 185 ++++++++++++++++++ .../src/services/send/FeeCalculatorService.ts | 71 +++++++ .../ConfirmSignTransaction.test.tsx | 35 ++++ .../ConfirmSignTransaction.tsx | 9 +- 11 files changed, 323 insertions(+), 8 deletions(-) diff --git a/packages/tron-wallet-snap/CHANGELOG.md b/packages/tron-wallet-snap/CHANGELOG.md index 7f35c742..bb542fbe 100644 --- a/packages/tron-wallet-snap/CHANGELOG.md +++ b/packages/tron-wallet-snap/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- Disclose the mandatory 9,999 TRX `WitnessCreateContract` account-upgrade burn on confirmation + - Include `getAccountUpgradeCost` in fee calculation so Network fee and insufficient-balance checks reflect the irreversible burn + - Replace the generic "Unsupported contract for simulation" copy with Super Representative candidate disclosure for this contract type + ## [2.0.0] ### Changed diff --git a/packages/tron-wallet-snap/jest.config.mjs b/packages/tron-wallet-snap/jest.config.mjs index 299fdc07..a75f5006 100644 --- a/packages/tron-wallet-snap/jest.config.mjs +++ b/packages/tron-wallet-snap/jest.config.mjs @@ -24,10 +24,10 @@ const config = { // An object that configures minimum threshold enforcement for coverage results coverageThreshold: { global: { - branches: 69.96, - functions: 75.86, - lines: 82.61, - statements: 82.62, + branches: 70.17, + functions: 76.12, + lines: 82.72, + statements: 82.73, }, }, diff --git a/packages/tron-wallet-snap/locales/en.json b/packages/tron-wallet-snap/locales/en.json index ff2835dd..7111ee22 100644 --- a/packages/tron-wallet-snap/locales/en.json +++ b/packages/tron-wallet-snap/locales/en.json @@ -64,6 +64,9 @@ "confirmation.estimatedChanges.unsupportedContract": { "message": "Unsupported contract for simulation" }, + "confirmation.estimatedChanges.witnessCreate": { + "message": "Registers your account as a Super Representative candidate and permanently burns 9,999 TRX." + }, "confirmation.simulationTitleAPIError": { "message": "Because of an error, we couldn't check for security alerts." }, diff --git a/packages/tron-wallet-snap/locales/es.json b/packages/tron-wallet-snap/locales/es.json index 10c56146..7c707a0d 100644 --- a/packages/tron-wallet-snap/locales/es.json +++ b/packages/tron-wallet-snap/locales/es.json @@ -64,6 +64,9 @@ "confirmation.estimatedChanges.unsupportedContract": { "message": "Contrato no compatible con simulación" }, + "confirmation.estimatedChanges.witnessCreate": { + "message": "Registra tu cuenta como candidato a Super Representante y quema permanentemente 9.999 TRX." + }, "confirmation.simulationTitleAPIError": { "message": "Debido a un error, no pudimos verificar alertas de seguridad." }, diff --git a/packages/tron-wallet-snap/messages.json b/packages/tron-wallet-snap/messages.json index 52c6e271..1f26af06 100644 --- a/packages/tron-wallet-snap/messages.json +++ b/packages/tron-wallet-snap/messages.json @@ -62,6 +62,9 @@ "confirmation.estimatedChanges.unsupportedContract": { "message": "Unsupported contract for simulation" }, + "confirmation.estimatedChanges.witnessCreate": { + "message": "Registers your account as a Super Representative candidate and permanently burns 9,999 TRX." + }, "confirmation.simulationTitleAPIError": { "message": "Because of an error, we couldn't check for security alerts." }, diff --git a/packages/tron-wallet-snap/snap.manifest.json b/packages/tron-wallet-snap/snap.manifest.json index 82993016..381175f6 100644 --- a/packages/tron-wallet-snap/snap.manifest.json +++ b/packages/tron-wallet-snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/internal-snaps.git" }, "source": { - "shasum": "0TZh63x04Gncx8UgHBoWnQ4RmX6kmTL6RmJTyqgJ7G8=", + "shasum": "cboQgox22rVnEyuDsHT3oR1HrF+n5WcpCESYw9/AgTs=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/tron-wallet-snap/src/constants/index.ts b/packages/tron-wallet-snap/src/constants/index.ts index 7dbb15d0..10d7293a 100644 --- a/packages/tron-wallet-snap/src/constants/index.ts +++ b/packages/tron-wallet-snap/src/constants/index.ts @@ -8,6 +8,12 @@ export const SUN_IN_TRX = 1_000_000; export const FALLBACK_GET_TRANSACTION_FEE_SUN = 1000; export const FALLBACK_GET_ENERGY_FEE_SUN = 100; export const FALLBACK_ENERGY_PRICE_SUN = 420; +/** + * Default `getAccountUpgradeCost` (WitnessCreateContract burn) in SUN = 9,999 TRX. + * + * @see https://developers.tron.network/docs/super-representatives + */ +export const FALLBACK_ACCOUNT_UPGRADE_COST_SUN = 9_999_000_000; /** * 101 TRX */ diff --git a/packages/tron-wallet-snap/src/services/send/FeeCalculatorService.test.ts b/packages/tron-wallet-snap/src/services/send/FeeCalculatorService.test.ts index 8d28c79b..3e8909e8 100644 --- a/packages/tron-wallet-snap/src/services/send/FeeCalculatorService.test.ts +++ b/packages/tron-wallet-snap/src/services/send/FeeCalculatorService.test.ts @@ -2168,6 +2168,191 @@ describe('FeeCalculatorService', () => { }); }); + describe('WitnessCreateContract account upgrade fee scenarios', () => { + const createWitnessCreateTransaction = (): any => { + const base = getTransactionExample('native'); + return { + ...base, + raw_data: { + ...base.raw_data, + contract: [ + { + parameter: { + value: { + owner_address: '41a7d8a35b260395c14aa456297662092ba3b76fc0', + url: '68747470733a2f2f6578616d706c652e636f6d', + }, + type_url: + 'type.googleapis.com/protocol.WitnessCreateContract', + }, + type: 'WitnessCreateContract', + }, + ], + }, + }; + }; + + it('adds 9999 TRX account upgrade fee for WitnessCreateContract when chain param is present', async () => { + await withFeeCalculatorService( + async ({ feeCalculatorService, trongridApiClient }) => { + trongridApiClient.getChainParameters.mockResolvedValue([ + { key: 'getTransactionFee', value: 1000 }, + { key: 'getEnergyFee', value: 100 }, + { key: 'getAccountUpgradeCost', value: 9_999_000_000 }, + ]); + + const transaction = createWitnessCreateTransaction(); + const availableEnergy = ZERO; + const availableBandwidth = BigNumber(1000000); + + const result = await feeCalculatorService.computeFee({ + scope: Network.Mainnet, + transaction, + availableEnergy, + availableBandwidth, + }); + + expect(result).toStrictEqual([ + { + type: FeeType.Base, + asset: { + unit: 'TRX', + type: 'tron:728126428/slip44:195', + amount: '9999', + fungible: true, + }, + }, + { + type: FeeType.Base, + asset: { + unit: 'BANDWIDTH', + type: 'tron:728126428/slip44:bandwidth', + amount: '266', + fungible: true, + }, + }, + ]); + }, + ); + }); + + it('falls back to 9999 TRX when getAccountUpgradeCost is missing from chain parameters', async () => { + await withFeeCalculatorService( + async ({ feeCalculatorService, trongridApiClient }) => { + trongridApiClient.getChainParameters.mockResolvedValue([ + { key: 'getTransactionFee', value: 1000 }, + { key: 'getEnergyFee', value: 100 }, + ]); + + const result = await feeCalculatorService.computeFee({ + scope: Network.Mainnet, + transaction: createWitnessCreateTransaction(), + availableEnergy: ZERO, + availableBandwidth: BigNumber(1000000), + }); + + expect(result[0]).toStrictEqual({ + type: FeeType.Base, + asset: { + unit: 'TRX', + type: 'tron:728126428/slip44:195', + amount: '9999', + fungible: true, + }, + }); + }, + ); + }); + + it('adds account upgrade fee on top of bandwidth TRX cost', async () => { + await withFeeCalculatorService( + async ({ feeCalculatorService, trongridApiClient }) => { + trongridApiClient.getChainParameters.mockResolvedValue([ + { key: 'getTransactionFee', value: 1000 }, + { key: 'getEnergyFee', value: 100 }, + { key: 'getAccountUpgradeCost', value: 9_999_000_000 }, + ]); + + const result = await feeCalculatorService.computeFee({ + scope: Network.Mainnet, + transaction: createWitnessCreateTransaction(), + availableEnergy: ZERO, + availableBandwidth: ZERO, + }); + + // Bandwidth: 266 * 1000 SUN = 0.266 TRX + 9999 TRX upgrade = 9999.266 TRX + expect(result[0]).toStrictEqual({ + type: FeeType.Base, + asset: { + unit: 'TRX', + type: 'tron:728126428/slip44:195', + amount: '9999.266', + fungible: true, + }, + }); + }, + ); + }); + + it('uses the on-chain getAccountUpgradeCost value when it differs from the default', async () => { + await withFeeCalculatorService( + async ({ feeCalculatorService, trongridApiClient }) => { + trongridApiClient.getChainParameters.mockResolvedValue([ + { key: 'getTransactionFee', value: 1000 }, + { key: 'getEnergyFee', value: 100 }, + { key: 'getAccountUpgradeCost', value: 5_000_000_000 }, // 5000 TRX + ]); + + const result = await feeCalculatorService.computeFee({ + scope: Network.Mainnet, + transaction: createWitnessCreateTransaction(), + availableEnergy: ZERO, + availableBandwidth: BigNumber(1000000), + }); + + expect(result[0]?.asset.amount).toBe('5000'); + }, + ); + }); + + it('does not add account upgrade fee for non-WitnessCreate contracts', async () => { + await withFeeCalculatorService(async ({ feeCalculatorService }) => { + const result = await feeCalculatorService.computeFee({ + scope: Network.Mainnet, + transaction: getTransactionExample('native'), + availableEnergy: ZERO, + availableBandwidth: BigNumber(1000000), + }); + + expect(result[0]?.asset.amount).toBe('0'); + }); + }); + + it('falls back to 9999 TRX when chain parameters are unavailable', async () => { + await withFeeCalculatorService( + async ({ feeCalculatorService, trongridApiClient }) => { + trongridApiClient.getChainParameters.mockRejectedValue( + new Error('TronGrid unavailable'), + ); + trongridApiClient.peekCachedChainParameters.mockResolvedValue( + undefined, + ); + + const result = await feeCalculatorService.computeFee({ + scope: Network.Mainnet, + transaction: createWitnessCreateTransaction(), + availableEnergy: ZERO, + availableBandwidth: BigNumber(1000000), + }); + + // Enough bandwidth so we never need getTransactionFee; upgrade fee + // still discloses the default burn via fallback. + expect(result[0]?.asset.amount).toBe('9999'); + }, + ); + }); + }); + describe('Memo fee scenarios', () => { // Helper to add a memo (raw_data.data) to a transaction const addMemoToTransaction = ( diff --git a/packages/tron-wallet-snap/src/services/send/FeeCalculatorService.ts b/packages/tron-wallet-snap/src/services/send/FeeCalculatorService.ts index d324bf70..3ce69dc2 100644 --- a/packages/tron-wallet-snap/src/services/send/FeeCalculatorService.ts +++ b/packages/tron-wallet-snap/src/services/send/FeeCalculatorService.ts @@ -14,6 +14,7 @@ import type { TrongridApiClient } from '../../clients/trongrid/TrongridApiClient import type { Network } from '../../constants'; import { ACCOUNT_ACTIVATION_FEE_TRX, + FALLBACK_ACCOUNT_UPGRADE_COST_SUN, FALLBACK_ENERGY_PRICE_SUN, FALLBACK_GET_ENERGY_FEE_SUN, FALLBACK_GET_TRANSACTION_FEE_SUN, @@ -707,6 +708,64 @@ export class FeeCalculatorService { return ZERO; } + /** + * Calculate the irreversible account-upgrade burn for WitnessCreateContract. + * + * Registering as a Super Representative candidate burns + * `getAccountUpgradeCost` TRX (default 9,999). This is a protocol-level debit + * separate from bandwidth/energy, and must be disclosed before signing. + * + * @see https://developers.tron.network/docs/super-representatives + * @param options - The options object + * @param options.scope - The network scope to resolve chain parameters for + * @param options.transaction - The transaction to inspect + * @returns Promise - The upgrade burn fee in TRX (0 if not WitnessCreate) + */ + async #accountUpgradeFee({ + scope, + transaction, + }: { + scope: Network; + transaction: Transaction; + }): Promise { + const contracts = transaction.raw_data.contract; + + if (!contracts || contracts.length === 0) { + return ZERO; + } + + const hasWitnessCreate = contracts.some( + (contract) => (contract.type as string) === 'WitnessCreateContract', + ); + + if (!hasWitnessCreate) { + return ZERO; + } + + let upgradeCostSun = FALLBACK_ACCOUNT_UPGRADE_COST_SUN; + + try { + const chainParameters = await this.#getChainParameters(scope); + upgradeCostSun = + chainParameters.find((param) => param.key === 'getAccountUpgradeCost') + ?.value ?? FALLBACK_ACCOUNT_UPGRADE_COST_SUN; + } catch (error) { + // Still disclose the default burn when chain parameters are unavailable. + this.#logger.warn( + { error }, + 'Failed to fetch account upgrade cost, using fallback 9999 TRX', + ); + } + + const upgradeCostTrx = BigNumber(upgradeCostSun).div(SUN_IN_TRX); + + this.#logger.log( + `WitnessCreateContract detected, adding ${upgradeCostTrx.toString()} TRX account upgrade fee`, + ); + + return upgradeCostTrx; + } + /** * Calculate complete fee breakdown for a TRON transaction. * Supports both signed and unsigned transactions. @@ -813,6 +872,18 @@ export class FeeCalculatorService { totalTrxCost = totalTrxCost.plus(memoFee); } + /** + * Fourth, WitnessCreateContract account-upgrade burn (default 9,999 TRX) + */ + const accountUpgradeFee = await this.#accountUpgradeFee({ + scope, + transaction, + }); + + if (accountUpgradeFee.isGreaterThan(0)) { + totalTrxCost = totalTrxCost.plus(accountUpgradeFee); + } + /** * Build result array - TRX MUST always be first element, even if 0 */ diff --git a/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignTransaction/ConfirmSignTransaction.test.tsx b/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignTransaction/ConfirmSignTransaction.test.tsx index 158199ba..708c47e8 100644 --- a/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignTransaction/ConfirmSignTransaction.test.tsx +++ b/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignTransaction/ConfirmSignTransaction.test.tsx @@ -244,4 +244,39 @@ describe('ConfirmSignTransaction', () => { expect(texts).not.toContain(SIMULATION_ERROR_TITLE); }); + + it('shows unsupported-contract copy for skipped simulations of unknown contracts', () => { + const texts = renderTexts( + buildContext({ + transaction: { + rawDataHex: '0a02beef', + type: 'VoteWitnessContract', + }, + scan: buildScanResult({ + simulationStatus: SimulationStatus.Skipped, + }), + }), + ); + + expect(texts).toContain('Unsupported contract for simulation'); + }); + + it('discloses WitnessCreateContract operation and 9,999 TRX burn when simulation is skipped', () => { + const texts = renderTexts( + buildContext({ + transaction: { + rawDataHex: '0a02beef', + type: 'WitnessCreateContract', + }, + scan: buildScanResult({ + simulationStatus: SimulationStatus.Skipped, + }), + }), + ); + + expect(texts).not.toContain('Unsupported contract for simulation'); + expect(texts).toContain( + 'Registers your account as a Super Representative candidate and permanently burns 9,999 TRX.', + ); + }); }); diff --git a/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignTransaction/ConfirmSignTransaction.tsx b/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignTransaction/ConfirmSignTransaction.tsx index cdd6a415..3dfccc74 100644 --- a/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignTransaction/ConfirmSignTransaction.tsx +++ b/packages/tron-wallet-snap/src/ui/confirmation/views/ConfirmSignTransaction/ConfirmSignTransaction.tsx @@ -62,6 +62,11 @@ export const ConfirmSignTransaction = ({ let estimatedChangesSection: ComponentOrElement | null = null; if (preferences.simulateOnChainActions) { if (scan?.simulationStatus === SimulationStatus.Skipped) { + const skippedChangesMessage = + context.transaction.type === 'WitnessCreateContract' + ? translate('confirmation.estimatedChanges.witnessCreate') + : translate('confirmation.estimatedChanges.unsupportedContract'); + estimatedChangesSection = (
@@ -74,9 +79,7 @@ export const ConfirmSignTransaction = ({ - - {translate('confirmation.estimatedChanges.unsupportedContract')} - + {skippedChangesMessage}
); } else { From e99a170cbb50eb00378a54fa36a42b2e2d90cabf Mon Sep 17 00:00:00 2001 From: Ulisses Ferreira Date: Thu, 30 Jul 2026 16:16:11 +0100 Subject: [PATCH 2/7] chore: link changelog entry to PR #73 --- packages/tron-wallet-snap/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tron-wallet-snap/CHANGELOG.md b/packages/tron-wallet-snap/CHANGELOG.md index bb542fbe..d6439316 100644 --- a/packages/tron-wallet-snap/CHANGELOG.md +++ b/packages/tron-wallet-snap/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- Disclose the mandatory 9,999 TRX `WitnessCreateContract` account-upgrade burn on confirmation +- Disclose the mandatory 9,999 TRX `WitnessCreateContract` account-upgrade burn on confirmation ([#73](https://github.com/MetaMask/internal-snaps/pull/73)) - Include `getAccountUpgradeCost` in fee calculation so Network fee and insufficient-balance checks reflect the irreversible burn - Replace the generic "Unsupported contract for simulation" copy with Super Representative candidate disclosure for this contract type From 713a85dde635c87ca4ff317a41c7d1f9ce925922 Mon Sep 17 00:00:00 2001 From: Ulisses Ferreira Date: Fri, 31 Jul 2026 08:17:26 +0100 Subject: [PATCH 3/7] chore: sync tron snap.manifest shasum with CI production build --- packages/tron-wallet-snap/snap.manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tron-wallet-snap/snap.manifest.json b/packages/tron-wallet-snap/snap.manifest.json index 381175f6..f4e81c18 100644 --- a/packages/tron-wallet-snap/snap.manifest.json +++ b/packages/tron-wallet-snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/internal-snaps.git" }, "source": { - "shasum": "cboQgox22rVnEyuDsHT3oR1HrF+n5WcpCESYw9/AgTs=", + "shasum": "Y74DQi0BKsgwBddJ0yBT62UIZ4423dDiJtBV/CVd8SQ=", "location": { "npm": { "filePath": "dist/bundle.js", From 99f82a434d4978a6dc081580fd61e2dfdda70bec Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 31 Jul 2026 12:53:28 +0000 Subject: [PATCH 4/7] fix: resolve CI lint, coverage, and manifest shasum failures Replace explicit any types in FeeCalculatorService tests with the Transaction type from tronweb. Revert coverage thresholds to main values since the bumped thresholds are not met. Sync snap.manifest shasum to the value produced by CI production builds. Co-authored-by: Ulisses Ferreira --- packages/tron-wallet-snap/jest.config.mjs | 8 ++++---- packages/tron-wallet-snap/snap.manifest.json | 2 +- .../send/FeeCalculatorService.test.ts | 20 ++++++++++++------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/packages/tron-wallet-snap/jest.config.mjs b/packages/tron-wallet-snap/jest.config.mjs index a75f5006..299fdc07 100644 --- a/packages/tron-wallet-snap/jest.config.mjs +++ b/packages/tron-wallet-snap/jest.config.mjs @@ -24,10 +24,10 @@ const config = { // An object that configures minimum threshold enforcement for coverage results coverageThreshold: { global: { - branches: 70.17, - functions: 76.12, - lines: 82.72, - statements: 82.73, + branches: 69.96, + functions: 75.86, + lines: 82.61, + statements: 82.62, }, }, diff --git a/packages/tron-wallet-snap/snap.manifest.json b/packages/tron-wallet-snap/snap.manifest.json index f4e81c18..5f3cab2a 100644 --- a/packages/tron-wallet-snap/snap.manifest.json +++ b/packages/tron-wallet-snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/internal-snaps.git" }, "source": { - "shasum": "Y74DQi0BKsgwBddJ0yBT62UIZ4423dDiJtBV/CVd8SQ=", + "shasum": "9qRM4qCjRIdWCy/txZ3wHH42cMj7UsDKpqyhJ4R69Dk=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/tron-wallet-snap/src/services/send/FeeCalculatorService.test.ts b/packages/tron-wallet-snap/src/services/send/FeeCalculatorService.test.ts index 3e8909e8..2771bf0e 100644 --- a/packages/tron-wallet-snap/src/services/send/FeeCalculatorService.test.ts +++ b/packages/tron-wallet-snap/src/services/send/FeeCalculatorService.test.ts @@ -1,6 +1,8 @@ import { FeeType } from '@metamask/keyring-api'; import { BigNumber } from 'bignumber.js'; +import type { Transaction } from 'tronweb/lib/esm/types'; + import type { SnapClient } from '../../clients/snap/SnapClient'; import type { TriggerConstantContractResponse } from '../../clients/tron-http'; import type { TronHttpClient } from '../../clients/tron-http/TronHttpClient'; @@ -19,7 +21,9 @@ import { FeeUnavailableError } from './errors'; import { FeeCalculatorService } from './FeeCalculatorService'; // Helper to get transaction examples in the expected format -const getTransactionExample = (type: 'native' | 'trc10' | 'trc20'): any => { +const getTransactionExample = ( + type: 'native' | 'trc10' | 'trc20', +): Transaction => { let mockData; switch (type) { case 'native': @@ -42,11 +46,11 @@ const getTransactionExample = (type: 'native' | 'trc10' | 'trc20'): any => { txID: mockData.txID, raw_data_hex: mockData.raw_data_hex, raw_data: mockData.raw_data, - }; + } as Transaction; }; // Helper to create a large transaction by modifying the TRC20 example -const createLargeTransaction = (): any => { +const createLargeTransaction = (): Transaction => { const baseTransaction = getTransactionExample('trc20'); // Modify the data field to be much larger to simulate bandwidth issues const largeData = 'b'.repeat(2000); @@ -238,7 +242,9 @@ describe('FeeCalculatorService', () => { describe('System contract scenarios (no energy needed)', () => { // Helper to create a mock transaction with a specific contract type - const createSystemContractTransaction = (contractType: string): any => { + const createSystemContractTransaction = ( + contractType: string, + ): Transaction => { const baseTransaction = getTransactionExample('native'); return { ...baseTransaction, @@ -2169,7 +2175,7 @@ describe('FeeCalculatorService', () => { }); describe('WitnessCreateContract account upgrade fee scenarios', () => { - const createWitnessCreateTransaction = (): any => { + const createWitnessCreateTransaction = (): Transaction => { const base = getTransactionExample('native'); return { ...base, @@ -2356,9 +2362,9 @@ describe('FeeCalculatorService', () => { describe('Memo fee scenarios', () => { // Helper to add a memo (raw_data.data) to a transaction const addMemoToTransaction = ( - transaction: any, + transaction: Transaction, memoHex: string, - ): any => ({ + ): Transaction => ({ ...transaction, raw_data: { ...transaction.raw_data, From dd0779a4ab0c018c15448ae65c5ae5fcdf897798 Mon Sep 17 00:00:00 2001 From: Ulisses Ferreira Date: Fri, 31 Jul 2026 14:21:06 +0100 Subject: [PATCH 5/7] fix: format FeeCalculatorService.test.ts for lint:misc:check --- .../src/services/send/FeeCalculatorService.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/tron-wallet-snap/src/services/send/FeeCalculatorService.test.ts b/packages/tron-wallet-snap/src/services/send/FeeCalculatorService.test.ts index 2771bf0e..3ead5888 100644 --- a/packages/tron-wallet-snap/src/services/send/FeeCalculatorService.test.ts +++ b/packages/tron-wallet-snap/src/services/send/FeeCalculatorService.test.ts @@ -1,6 +1,5 @@ import { FeeType } from '@metamask/keyring-api'; import { BigNumber } from 'bignumber.js'; - import type { Transaction } from 'tronweb/lib/esm/types'; import type { SnapClient } from '../../clients/snap/SnapClient'; From 4e57c364578e3f6ce14dc6c127a03c25b8dc6b7f Mon Sep 17 00:00:00 2001 From: Ulisses Ferreira Date: Fri, 31 Jul 2026 14:24:40 +0100 Subject: [PATCH 6/7] fix: add explicit return type for test helper function --- .../src/services/send/FeeCalculatorService.test.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/tron-wallet-snap/src/services/send/FeeCalculatorService.test.ts b/packages/tron-wallet-snap/src/services/send/FeeCalculatorService.test.ts index 3ead5888..7f52cea9 100644 --- a/packages/tron-wallet-snap/src/services/send/FeeCalculatorService.test.ts +++ b/packages/tron-wallet-snap/src/services/send/FeeCalculatorService.test.ts @@ -2572,7 +2572,11 @@ describe('FeeCalculatorService', () => { describe('Graceful failure when TronGrid is unavailable', () => { // Native transfer with insufficient bandwidth so a TRX fee is owed and // the chain-params conversion path is exercised. - const buildNativeTxWithBandwidthOverage = () => ({ + const buildNativeTxWithBandwidthOverage = (): { + transaction: Transaction; + availableEnergy: BigNumber; + availableBandwidth: BigNumber; + } => ({ transaction: getTransactionExample('native'), availableEnergy: ZERO, availableBandwidth: BigNumber(100), // < 266 bytes needed From 2f70e4d5d98c84a7973bfe4c473c925948cd17a9 Mon Sep 17 00:00:00 2001 From: Ulisses Ferreira Date: Fri, 31 Jul 2026 14:29:40 +0100 Subject: [PATCH 7/7] chore: prune stale eslint suppressions for FeeCalculatorService tests --- eslint-suppressions.json | 8 -------- 1 file changed, 8 deletions(-) diff --git a/eslint-suppressions.json b/eslint-suppressions.json index 3e958920..ee52a666 100644 --- a/eslint-suppressions.json +++ b/eslint-suppressions.json @@ -321,14 +321,6 @@ "count": 1 } }, - "packages/tron-wallet-snap/src/services/send/FeeCalculatorService.test.ts": { - "@typescript-eslint/explicit-function-return-type": { - "count": 1 - }, - "@typescript-eslint/no-explicit-any": { - "count": 5 - } - }, "packages/tron-wallet-snap/src/services/send/FeeCalculatorService.ts": { "no-restricted-syntax": { "count": 1