diff --git a/packages/starknet-snap/src/__tests__/helper.ts b/packages/starknet-snap/src/__tests__/helper.ts index 6eed3806..f0b6f319 100644 --- a/packages/starknet-snap/src/__tests__/helper.ts +++ b/packages/starknet-snap/src/__tests__/helper.ts @@ -2,6 +2,8 @@ import { BIP44CoinTypeNode, getBIP44AddressKeyDeriver, } from '@metamask/key-tree'; +import type { UserInputEvent } from '@metamask/snaps-sdk'; +import { UserInputEventType } from '@metamask/snaps-sdk'; import { generateMnemonic } from 'bip39'; import { getRandomValues } from 'crypto'; import type { constants, EstimateFee } from 'starknet'; @@ -17,6 +19,7 @@ import { } from 'starknet'; import { v4 as uuidv4 } from 'uuid'; +import { FeeToken } from '../types/snapApi'; import type { AccContract, Transaction, @@ -83,7 +86,7 @@ export async function generateBip44Entropy( * @returns An array of StarknetAccount object. */ export async function generateAccounts( - network: constants.StarknetChainId, + network: constants.StarknetChainId | string, cnt: number = 1, cairoVersion = '1', mnemonic?: string, @@ -298,7 +301,7 @@ export function generateTransactionRequests({ contractAddresses = PRELOADED_TOKENS.map((token) => token.address), cnt = 1, }: { - chainId: constants.StarknetChainId; + chainId: constants.StarknetChainId | string; address: string; contractAddresses?: string[]; cnt?: number; @@ -359,12 +362,13 @@ export function generateTransactionRequests({ return requests; } + /** * Method to generate a mock estimate fee response. * * @returns An array containing a mock EstimateFee object. */ -export function getEstimateFees() { +export function generateEstimateFeesResponse() { return [ { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -393,3 +397,36 @@ export function getEstimateFees() { } as unknown as EstimateFee, ]; } + +/** + * Method to generate a mock input event. + * + * @param params - The parameter for generate the mock input event. + * @param params.transactionRequest - The transaction request object. + * @param [params.eventValue] - The value of the event. + * @param [params.eventType] - The type of the event. + * @param [params.eventName] - The name of the event. + * @returns An array containing a mock input event object. + */ +export function generateInputEvent({ + transactionRequest, + eventValue = FeeToken.ETH, + eventType = UserInputEventType.InputChangeEvent, + eventName = 'feeTokenSelector', +}: { + transactionRequest: TransactionRequest; + eventValue?: string; + eventType?: UserInputEventType; + eventName?: string; +}) { + return { + event: { + name: eventName, + type: eventType, + value: eventValue, + } as unknown as UserInputEvent, + context: { + request: transactionRequest, + }, + }; +} diff --git a/packages/starknet-snap/src/rpcs/__tests__/helper.ts b/packages/starknet-snap/src/rpcs/__tests__/helper.ts index 8d20363f..0aee47be 100644 --- a/packages/starknet-snap/src/rpcs/__tests__/helper.ts +++ b/packages/starknet-snap/src/rpcs/__tests__/helper.ts @@ -3,7 +3,6 @@ import type { constants } from 'starknet'; import type { StarknetAccount } from '../../__tests__/helper'; import { generateAccounts, generateRandomValue } from '../../__tests__/helper'; -import { TransactionRequestStateManager } from '../../state/request-state-manager'; import type { SnapState } from '../../types/snapState'; import * as snapUiUtils from '../../ui/utils'; import { getExplorerUrl, shortenAddress, toJson } from '../../utils'; @@ -11,27 +10,6 @@ import * as snapHelper from '../../utils/snap'; import * as snapUtils from '../../utils/snapUtils'; import * as starknetUtils from '../../utils/starknetUtils'; -export const mockTransactionRequestStateManager = () => { - const upsertTransactionRequestSpy = jest.spyOn( - TransactionRequestStateManager.prototype, - 'upsertTransactionRequest', - ); - const getTransactionRequestSpy = jest.spyOn( - TransactionRequestStateManager.prototype, - 'getTransactionRequest', - ); - const removeTransactionRequestSpy = jest.spyOn( - TransactionRequestStateManager.prototype, - 'removeTransactionRequest', - ); - - return { - upsertTransactionRequestSpy, - getTransactionRequestSpy, - removeTransactionRequestSpy, - }; -}; - /** * * @param chainId diff --git a/packages/starknet-snap/src/rpcs/estimate-fee.test.ts b/packages/starknet-snap/src/rpcs/estimate-fee.test.ts index 87e1234a..9ab8a2af 100644 --- a/packages/starknet-snap/src/rpcs/estimate-fee.test.ts +++ b/packages/starknet-snap/src/rpcs/estimate-fee.test.ts @@ -2,7 +2,7 @@ import type { Invocations } from 'starknet'; import { constants, TransactionType } from 'starknet'; import type { Infer } from 'superstruct'; -import { getEstimateFees } from '../__tests__/helper'; +import { generateEstimateFeesResponse } from '../__tests__/helper'; import { FeeTokenUnit } from '../types/snapApi'; import { STARKNET_SEPOLIA_TESTNET_NETWORK } from '../utils/constants'; import { InvalidRequestParamsError } from '../utils/exceptions'; @@ -45,7 +45,7 @@ const prepareMockEstimateFee = ({ details: { version }, } as unknown as EstimateFeeParams; - const estimateResults = getEstimateFees(); + const estimateResults = generateEstimateFeesResponse(); const estimateBulkFeeRespMock = { suggestedMaxFee: BigInt(1000000000000000).toString(10), diff --git a/packages/starknet-snap/src/rpcs/execute-txn.test.ts b/packages/starknet-snap/src/rpcs/execute-txn.test.ts index d49419fc..81f6d64a 100644 --- a/packages/starknet-snap/src/rpcs/execute-txn.test.ts +++ b/packages/starknet-snap/src/rpcs/execute-txn.test.ts @@ -2,7 +2,8 @@ import type { UniversalDetails, Call, InvokeFunctionResponse } from 'starknet'; import { constants } from 'starknet'; import callsExamples from '../__tests__/fixture/callsExamples.json'; // Assuming you have a similar fixture -import { getEstimateFees } from '../__tests__/helper'; +import { generateEstimateFeesResponse } from '../__tests__/helper'; +import { mockTransactionRequestStateManager } from '../state/__tests__/helper'; import type { FeeTokenUnit } from '../types/snapApi'; import { STARKNET_SEPOLIA_TESTNET_NETWORK } from '../utils/constants'; import { @@ -14,7 +15,6 @@ import { executeTxn as executeTxnUtil } from '../utils/starknetUtils'; import { generateRandomFee, mockAccount, - mockTransactionRequestStateManager, prepareConfirmDialogInteractiveUI, prepareMockAccount, } from './__tests__/helper'; @@ -53,7 +53,7 @@ const prepareMockExecuteTxn = async ( transaction_hash: transactionHash, }; - const estimateResults = getEstimateFees(); + const estimateResults = generateEstimateFeesResponse(); const getEstimatedFeesRepsMock = { suggestedMaxFee: generateRandomFee('1000000000000000', '2000000000000000'), diff --git a/packages/starknet-snap/src/state/__tests__/helper.ts b/packages/starknet-snap/src/state/__tests__/helper.ts index 68d47bc3..6f31e09c 100644 --- a/packages/starknet-snap/src/state/__tests__/helper.ts +++ b/packages/starknet-snap/src/state/__tests__/helper.ts @@ -7,7 +7,14 @@ import type { Transaction, TransactionRequest, } from '../../types/snapState'; +import { + ETHER_SEPOLIA_TESTNET, + STRK_SEPOLIA_TESTNET, +} from '../../utils/constants'; import * as snapHelper from '../../utils/snap'; +import { NetworkStateManager } from '../network-state-manager'; +import { TransactionRequestStateManager } from '../request-state-manager'; +import { TokenStateManager } from '../token-state-manager'; jest.mock('../../utils/snap'); jest.mock('../../utils/logger'); @@ -51,3 +58,47 @@ export const mockState = async ({ state, }; }; + +export const mockTokenStateManager = () => { + const getEthTokenSpy = jest.spyOn(TokenStateManager.prototype, 'getEthToken'); + const getStrkTokenSpy = jest.spyOn( + TokenStateManager.prototype, + 'getStrkToken', + ); + getStrkTokenSpy.mockResolvedValue(STRK_SEPOLIA_TESTNET); + getEthTokenSpy.mockResolvedValue(ETHER_SEPOLIA_TESTNET); + + return { + getEthTokenSpy, + getStrkTokenSpy, + }; +}; + +export const mockTransactionRequestStateManager = () => { + const upsertTransactionRequestSpy = jest.spyOn( + TransactionRequestStateManager.prototype, + 'upsertTransactionRequest', + ); + const getTransactionRequestSpy = jest.spyOn( + TransactionRequestStateManager.prototype, + 'getTransactionRequest', + ); + const removeTransactionRequestSpy = jest.spyOn( + TransactionRequestStateManager.prototype, + 'removeTransactionRequest', + ); + + return { + upsertTransactionRequestSpy, + getTransactionRequestSpy, + removeTransactionRequestSpy, + }; +}; + +export const mockNetworkStateManager = (network: Network) => { + const getNetworkSpy = jest.spyOn(NetworkStateManager.prototype, 'getNetwork'); + getNetworkSpy.mockResolvedValue(network); + return { + getNetworkSpy, + }; +}; diff --git a/packages/starknet-snap/src/ui/controllers/user-input-event-controller.test.ts b/packages/starknet-snap/src/ui/controllers/user-input-event-controller.test.ts new file mode 100644 index 00000000..17270a35 --- /dev/null +++ b/packages/starknet-snap/src/ui/controllers/user-input-event-controller.test.ts @@ -0,0 +1,465 @@ +import type { InterfaceContext, UserInputEvent } from '@metamask/snaps-sdk'; +import { constants, ec, num as numUtils, TransactionType } from 'starknet'; + +import type { StarknetAccount } from '../../__tests__/helper'; +import { + generateAccounts, + generateTransactionRequests, + generateEstimateFeesResponse, + generateInputEvent, +} from '../../__tests__/helper'; +import { + mockTransactionRequestStateManager, + mockNetworkStateManager, + mockTokenStateManager, +} from '../../state/__tests__/helper'; +import { FeeToken, FeeTokenUnit } from '../../types/snapApi'; +import type { Erc20Token } from '../../types/snapState'; +import { + ETHER_SEPOLIA_TESTNET, + STARKNET_TESTNET_NETWORK, + STRK_SEPOLIA_TESTNET, +} from '../../utils/constants'; +import * as keyPairUtils from '../../utils/keyPair'; +import * as StarknetUtils from '../../utils/starknetUtils'; +import * as UiUtils from '../utils'; +import { UserInputEventController } from './user-input-event-controller'; + +jest.mock('../../utils/logger'); + +class MockUserInputEventController extends UserInputEventController { + async deriveAccount(index: number) { + return super.deriveAccount(index); + } + + feeTokenToTransactionVersion(feeToken: FeeToken) { + return super.feeTokenToTransactionVersion(feeToken); + } + + async getTokenAddress(chainId: string, feeToken: FeeToken) { + return super.getTokenAddress(chainId, feeToken); + } + + async getNetwork(chainId: string) { + return super.getNetwork(chainId); + } + + async handleFeeTokenChange() { + return super.handleFeeTokenChange(); + } +} + +describe('UserInputEventController', () => { + const createMockController = ({ + eventId = 'mock-event-id', + event = {} as UserInputEvent, + context = {} as InterfaceContext, + }: { + eventId?: string; + event?: UserInputEvent; + context?: InterfaceContext; + }) => { + return new MockUserInputEventController(eventId, event, context); + }; + + const mockKeyPairUtils = ({ addressKey, index }) => { + const getAddressKeySpy = jest.spyOn(keyPairUtils, 'getAddressKey'); + getAddressKeySpy.mockResolvedValue({ + addressKey, + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + derivationPath: `m / bip32:${9004}' / bip32:${0}' / bip32:${0}' / bip32:${index}'`, + }); + return { + getAddressKeySpy, + }; + }; + + const mockDeriveAccount = (account: StarknetAccount) => { + const deriveAccountSpy = jest.spyOn( + MockUserInputEventController.prototype, + 'deriveAccount', + ); + deriveAccountSpy.mockResolvedValue({ + publicKey: account.publicKey, + privateKey: account.privateKey, + }); + return { + deriveAccountSpy, + }; + }; + + const mockEstimateFee = (feeToken: FeeToken) => { + const getEstimatedFeesSpy = jest.spyOn(StarknetUtils, 'getEstimatedFees'); + const mockEstimateFeeResponse = generateEstimateFeesResponse(); + const concatedFee = StarknetUtils.addFeesFromAllTransactions( + mockEstimateFeeResponse, + ); + + const mockGetEstimatedFeesResponse = { + suggestedMaxFee: concatedFee.suggestedMaxFee.toString(10), + overallFee: concatedFee.overall_fee.toString(10), + unit: FeeTokenUnit[feeToken], + includeDeploy: true, + estimateResults: mockEstimateFeeResponse, + }; + + getEstimatedFeesSpy.mockResolvedValue(mockGetEstimatedFeesResponse); + + return { + getEstimatedFeesSpy, + mockGetEstimatedFeesResponse, + }; + }; + + const mockUpdateExecuteTxnFlow = () => { + const updateExecuteTxnFlowSpy = jest.spyOn(UiUtils, 'updateExecuteTxnFlow'); + updateExecuteTxnFlowSpy.mockReturnThis(); + return { + updateExecuteTxnFlowSpy, + }; + }; + + const mockHasSufficientFundsForFee = (result = true) => { + const hasSufficientFundsForFeeSpy = jest.spyOn( + UiUtils, + 'hasSufficientFundsForFee', + ); + hasSufficientFundsForFeeSpy.mockResolvedValue(result); + + return { + hasSufficientFundsForFeeSpy, + }; + }; + + const mockHandleFeeTokenChange = () => { + const handleFeeTokenChangeSpy = jest.spyOn( + MockUserInputEventController.prototype, + 'handleFeeTokenChange', + ); + handleFeeTokenChangeSpy.mockReturnThis(); + return { + handleFeeTokenChangeSpy, + }; + }; + + describe('deriveAccount', () => { + it('returns the privateKey and Public of the derived account', async () => { + const { chainId } = STARKNET_TESTNET_NETWORK; + const [account] = await generateAccounts(chainId, 1); + + const addressKey = account.privateKey; + mockKeyPairUtils({ addressKey, index: 0 }); + + const publicKey = ec.starkCurve.getStarkKey(addressKey); + const privateKey = numUtils.toHex(addressKey); + + const controller = createMockController({}); + const result = await controller.deriveAccount(0); + expect(result).toStrictEqual({ publicKey, privateKey }); + }); + }); + + describe('feeTokenToTransactionVersion', () => { + it.each([ + { + feeToken: FeeToken.STRK, + transactionVersion: constants.TRANSACTION_VERSION.V3, + }, + { + feeToken: FeeToken.ETH, + transactionVersion: undefined, + }, + ])( + 'returns transaction version $transactionVersion if the fee token is $feeToken', + ({ feeToken, transactionVersion }) => { + const controller = createMockController({}); + expect(controller.feeTokenToTransactionVersion(feeToken)).toStrictEqual( + transactionVersion, + ); + }, + ); + }); + + describe('getTokenAddress', () => { + it.each([ + { + feeToken: FeeToken.STRK, + token: STRK_SEPOLIA_TESTNET, + }, + { + feeToken: FeeToken.ETH, + token: ETHER_SEPOLIA_TESTNET, + }, + { + feeToken: undefined, + token: ETHER_SEPOLIA_TESTNET, + }, + ])( + 'returns the $token.name address for the fee token is $feeToken', + async ({ feeToken, token }) => { + const { chainId } = STARKNET_TESTNET_NETWORK; + mockTokenStateManager(); + + const controller = createMockController({}); + // feeToken could be undefined, so we have to force to cast it as FeeToken + const result = await controller.getTokenAddress( + chainId, + feeToken as unknown as FeeToken, + ); + + expect(result).toStrictEqual(token.address); + }, + ); + + it('throws `Token not found` error if the token is not found', async () => { + const { chainId } = STARKNET_TESTNET_NETWORK; + const { getEthTokenSpy } = mockTokenStateManager(); + getEthTokenSpy.mockResolvedValue(null); + + const controller = createMockController({}); + await expect( + controller.getTokenAddress(chainId, FeeToken.ETH), + ).rejects.toThrow('Token not found'); + }); + }); + + describe('getNetwork', () => { + it('returns the network with the given chainId', async () => { + const network = STARKNET_TESTNET_NETWORK; + mockNetworkStateManager(network); + + const controller = createMockController({}); + const result = await controller.getNetwork(network.chainId); + + expect(result).toStrictEqual(network); + }); + + it('throws `Network not found` error if the network is not found', async () => { + const network = STARKNET_TESTNET_NETWORK; + const { getNetworkSpy } = mockNetworkStateManager(network); + getNetworkSpy.mockResolvedValue(null); + + const controller = createMockController({}); + await expect(controller.getNetwork(network.chainId)).rejects.toThrow( + 'Network not found', + ); + }); + }); + + describe('handleEvent', () => { + const prepareHandleEvent = async () => { + const { chainId } = STARKNET_TESTNET_NETWORK; + const [account] = await generateAccounts(chainId, 1); + const [transactionRequest] = generateTransactionRequests({ + chainId, + address: account.address, + }); + + const event = generateInputEvent({ + transactionRequest, + eventValue: FeeToken.STRK, + }); + const { getTransactionRequestSpy } = mockTransactionRequestStateManager(); + getTransactionRequestSpy.mockResolvedValue(transactionRequest); + + const { handleFeeTokenChangeSpy } = mockHandleFeeTokenChange(); + + const controller = createMockController(event); + + return { + controller, + getTransactionRequestSpy, + handleFeeTokenChangeSpy, + transactionRequest, + event, + }; + }; + + it('calls `handleFeeTokenChange` if the event key is `FeeTokenSelectorEventKey.FeeTokenChange`', async () => { + const { + controller, + getTransactionRequestSpy, + handleFeeTokenChangeSpy, + transactionRequest, + } = await prepareHandleEvent(); + await controller.handleEvent(); + + expect(getTransactionRequestSpy).toHaveBeenCalledWith({ + requestId: transactionRequest.id, + }); + expect(handleFeeTokenChangeSpy).toHaveBeenCalledTimes(1); + }); + + it('throws `Transaction request not found` error if the transaction request not found', async () => { + const { controller, getTransactionRequestSpy } = + await prepareHandleEvent(); + getTransactionRequestSpy.mockResolvedValue(null); + + await expect(controller.handleEvent()).rejects.toThrow( + 'Transaction request not found', + ); + }); + + it.each([undefined, 'other-event'])( + 'does nothing if the event key is not `FeeTokenSelectorEventKey.FeeTokenChange` - event name: %s', + async (eventName) => { + const { handleFeeTokenChangeSpy, event } = await prepareHandleEvent(); + + event.event.name = eventName; + const controller = createMockController(event); + await controller.handleEvent(); + + expect(handleFeeTokenChangeSpy).toHaveBeenCalledTimes(0); + }, + ); + }); + + describe('handleFeeTokenChange', () => { + const prepareHandleFeeTokenChange = async ( + feeToken: FeeToken = FeeToken.STRK, + ) => { + const network = STARKNET_TESTNET_NETWORK; + const { chainId } = network; + + const [account] = await generateAccounts(chainId, 1); + const [transactionRequest] = generateTransactionRequests({ + chainId, + address: account.address, + }); + + const event = generateInputEvent({ + transactionRequest, + eventValue: feeToken, + }); + + mockNetworkStateManager(network); + mockDeriveAccount(account); + mockTokenStateManager(); + + return { + ...mockHasSufficientFundsForFee(), + ...mockUpdateExecuteTxnFlow(), + ...mockEstimateFee(feeToken), + ...mockTransactionRequestStateManager(), + event, + transactionRequest, + account, + network, + feeToken, + }; + }; + + it.each([STRK_SEPOLIA_TESTNET, ETHER_SEPOLIA_TESTNET])( + 'updates the transaction request with the updated estimated fee: feeToken - %symbol', + async (token: Erc20Token) => { + const feeToken = FeeToken[token.symbol]; + const { + event, + account, + network, + getEstimatedFeesSpy, + hasSufficientFundsForFeeSpy, + updateExecuteTxnFlowSpy, + mockGetEstimatedFeesResponse, + upsertTransactionRequestSpy, + transactionRequest, + } = await prepareHandleFeeTokenChange(feeToken); + const feeTokenAddress = token.address; + const { signer, calls } = transactionRequest; + const { publicKey, privateKey, address } = account; + const { suggestedMaxFee } = mockGetEstimatedFeesResponse; + + const controller = createMockController(event); + await controller.handleFeeTokenChange(); + + expect(getEstimatedFeesSpy).toHaveBeenCalledWith( + network, + signer, + privateKey, + publicKey, + [ + { + type: TransactionType.INVOKE, + payload: calls.map((call) => ({ + calldata: call.calldata, + contractAddress: call.contractAddress, + entrypoint: call.entrypoint, + })), + }, + ], + { + version: controller.feeTokenToTransactionVersion(feeToken), + }, + ); + expect(hasSufficientFundsForFeeSpy).toHaveBeenCalledWith({ + address, + network, + calls, + feeTokenAddress, + suggestedMaxFee, + }); + // transactionRequest will be pass by reference, so we can use this to check the updated value + expect(transactionRequest.maxFee).toStrictEqual(suggestedMaxFee); + expect(updateExecuteTxnFlowSpy).toHaveBeenCalledWith( + controller.eventId, + transactionRequest, + ); + expect(upsertTransactionRequestSpy).toHaveBeenCalledWith( + transactionRequest, + ); + }, + ); + + it('updates the transaction request with an insufficient funds error message if the account balance is insufficient to cover the fee.', async () => { + const { + event, + hasSufficientFundsForFeeSpy, + transactionRequest, + updateExecuteTxnFlowSpy, + upsertTransactionRequestSpy, + feeToken, + } = await prepareHandleFeeTokenChange(); + hasSufficientFundsForFeeSpy.mockResolvedValue(false); + + const controller = createMockController(event); + await controller.handleFeeTokenChange(); + + expect(upsertTransactionRequestSpy).not.toHaveBeenCalled(); + expect(updateExecuteTxnFlowSpy).toHaveBeenCalledWith( + controller.eventId, + transactionRequest, + { + errors: { + fees: `Not enough ${feeToken} to pay for fee`, + }, + }, + ); + }); + + it('updates the transaction request with an general error message if other error was thrown.', async () => { + const { + event, + hasSufficientFundsForFeeSpy, + transactionRequest, + updateExecuteTxnFlowSpy, + upsertTransactionRequestSpy, + } = await prepareHandleFeeTokenChange(); + // Simulate an error thrown to test the error handling + hasSufficientFundsForFeeSpy.mockRejectedValue(false); + + const controller = createMockController(event); + await controller.handleFeeTokenChange(); + + expect(upsertTransactionRequestSpy).not.toHaveBeenCalled(); + expect(updateExecuteTxnFlowSpy).toHaveBeenCalledWith( + controller.eventId, + transactionRequest, + { + errors: { + fees: `Fail to calculate the fees`, + }, + }, + ); + }); + }); +}); diff --git a/packages/starknet-snap/src/ui/controllers/user-input-event-controller.ts b/packages/starknet-snap/src/ui/controllers/user-input-event-controller.ts index 631ab5e4..191f48fc 100644 --- a/packages/starknet-snap/src/ui/controllers/user-input-event-controller.ts +++ b/packages/starknet-snap/src/ui/controllers/user-input-event-controller.ts @@ -60,7 +60,7 @@ export class UserInputEventController { if ( !(await this.reqStateMgr.getTransactionRequest({ - requestId: request.id, + requestId: request?.id, })) ) { throw new Error('Transaction request not found'); @@ -165,6 +165,7 @@ export class UserInputEventController { ); if ( + // TODO: we should create a payment controller class to handle this !(await hasSufficientFundsForFee({ address: signer, network, diff --git a/packages/starknet-snap/src/utils/starknetUtils.test.ts b/packages/starknet-snap/src/utils/starknetUtils.test.ts index 45d882fd..307729d3 100644 --- a/packages/starknet-snap/src/utils/starknetUtils.test.ts +++ b/packages/starknet-snap/src/utils/starknetUtils.test.ts @@ -1,7 +1,7 @@ import type { EstimateFee, Invocations } from 'starknet'; import { constants, TransactionType } from 'starknet'; -import { getEstimateFees } from '../__tests__/helper'; +import { generateEstimateFeesResponse } from '../__tests__/helper'; import { mockAccount, prepareMockAccount } from '../rpcs/__tests__/helper'; import { FeeTokenUnit } from '../types/snapApi'; import type { SnapState } from '../types/snapState'; @@ -40,7 +40,7 @@ describe('getEstimatedFees', () => { const accountDeployedSpy = jest.spyOn(starknetUtils, 'isAccountDeployed'); accountDeployedSpy.mockResolvedValue(deployed); - const estimateResults = getEstimateFees(); + const estimateResults = generateEstimateFeesResponse(); const { resourceBounds } = estimateResults[0]; const estimateFeeResp = {