From fc05303960bffe482891f6885b472339f5122fef Mon Sep 17 00:00:00 2001 From: juanmigdr Date: Fri, 7 Aug 2026 18:42:45 +0200 Subject: [PATCH 1/3] fix(earn-controller): reduce redundant/eager staking API calls on unlock Wallet unlock was triggering ~14 staking/lending API calls, including 3 exact duplicates and 4 calls for the Hoodi testnet that most users never need. This addresses both, without changing any consumer-facing behavior for real account switches or explicit Hoodi requests: - Skip the AccountTreeController:selectedAccountGroupChange refresh when the resolved address is unchanged from the last refresh (this event fires again right after init() during startup hydration with the same address, producing 3 wasted duplicate calls). - Only eagerly prefetch pooled staking data for Ethereum Mainnet on startup/network change. Hoodi is still fully supported via explicit chainId calls, it is just no longer unconditionally prefetched. --- packages/earn-controller/CHANGELOG.md | 5 + .../src/EarnController.test.ts | 151 +++++++++--------- .../earn-controller/src/EarnController.ts | 19 ++- 3 files changed, 101 insertions(+), 74 deletions(-) diff --git a/packages/earn-controller/CHANGELOG.md b/packages/earn-controller/CHANGELOG.md index 6733cc4e6c6..c1c8690c736 100644 --- a/packages/earn-controller/CHANGELOG.md +++ b/packages/earn-controller/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- Avoid duplicate `refreshEarnEligibility`/`refreshPooledStakes`/`refreshLendingPositions` calls when `AccountTreeController:selectedAccountGroupChange` fires with an address that was already just refreshed (e.g. immediately after `init()` during startup hydration) +- Only eagerly prefetch pooled staking data for Ethereum Mainnet on startup/network change, no longer also prefetching the Hoodi testnet by default; Hoodi remains fully supported via explicit `chainId` calls + ## [12.2.4] ### Changed diff --git a/packages/earn-controller/src/EarnController.test.ts b/packages/earn-controller/src/EarnController.test.ts index 796a8c0c8bc..20d2aa481e9 100644 --- a/packages/earn-controller/src/EarnController.test.ts +++ b/packages/earn-controller/src/EarnController.test.ts @@ -874,7 +874,7 @@ describe('EarnController', () => { expect(EarnSdk.create).toHaveBeenCalledTimes(1); expect( mockedEarnApiService?.pooledStaking?.getPooledStakes, - ).toHaveBeenCalledTimes(2); // 2 chains (ETH + HOODI) from the first init() + ).toHaveBeenCalledTimes(1); // 1 chain (ETH only) from the first init() }); it('does not re-run initialization when called concurrently before init has completed', async () => { @@ -919,7 +919,7 @@ describe('EarnController', () => { expect(EarnSdk.create).toHaveBeenCalledTimes(1); expect( mockedEarnApiService?.pooledStaking?.getPooledStakes, - ).toHaveBeenCalledTimes(2); // 2 chains (ETH + HOODI), not doubled to 4 + ).toHaveBeenCalledTimes(1); // 1 chain (ETH only), not doubled to 2 }); it('allows retry when init fails', async () => { @@ -974,7 +974,7 @@ describe('EarnController', () => { expect(EarnSdk.create).toHaveBeenCalledTimes(1); expect( mockedEarnApiService?.pooledStaking?.getPooledStakes, - ).toHaveBeenCalledTimes(2); // 2 chains (ETH + HOODI) + ).toHaveBeenCalledTimes(1); // 1 chain (ETH only) }); describe('when no EVM account is available at init time', () => { @@ -1251,8 +1251,8 @@ describe('EarnController', () => { expect( mockedEarnApiService?.pooledStaking?.getPooledStakes, ).toHaveBeenNthCalledWith( - // First 2 calls occur during setupController() - 3, + // First call occurs during setupController() + 2, [mockAccount1Address], 1, false, @@ -1266,8 +1266,8 @@ describe('EarnController', () => { expect( mockedEarnApiService?.pooledStaking?.getPooledStakes, ).toHaveBeenNthCalledWith( - // First 2 calls occur during setupController() - 3, + // First call occurs during setupController() + 2, [mockAccount1Address], 1, true, @@ -1283,8 +1283,8 @@ describe('EarnController', () => { expect( mockedEarnApiService?.pooledStaking?.getPooledStakes, ).toHaveBeenNthCalledWith( - // First 2 calls occur during setupController() - 3, + // First call occurs during setupController() + 2, [mockAccount2Address], 1, false, @@ -1322,7 +1322,7 @@ describe('EarnController', () => { const { controller } = await setupController(); await expect(controller.refreshPooledStakingData()).rejects.toThrow( - 'Failed to refresh some staking data: API Error getPooledStakes, API Error getVaultData, API Error getVaultDailyApys, API Error getVaultApyAverages, API Error getPooledStakes, API Error getVaultData, API Error getVaultDailyApys, API Error getVaultApyAverages', + 'Failed to refresh some staking data: API Error getPooledStakes, API Error getVaultData, API Error getVaultDailyApys, API Error getVaultApyAverages', ); expect(consoleErrorSpy).toHaveBeenCalled(); consoleErrorSpy.mockRestore(); @@ -1360,11 +1360,10 @@ describe('EarnController', () => { const { controller } = await setupController(); await controller.refreshPooledStakes({ resetCache: false }); - // Assertion on third call since the first two are part of controller setup. + // Assertion on second call since the first one is part of controller setup. expect( mockedEarnApiService?.pooledStaking?.getPooledStakes, - ).toHaveBeenNthCalledWith( - 3, + ).toHaveBeenNthCalledWith(2, [mockAccount1Address], ChainId.ETHEREUM, false, @@ -1375,11 +1374,10 @@ describe('EarnController', () => { const { controller } = await setupController(); await controller.refreshPooledStakes(); - // Assertion on third call since the first two are part of controller setup. + // Assertion on second call since the first one is part of controller setup. expect( mockedEarnApiService?.pooledStaking?.getPooledStakes, - ).toHaveBeenNthCalledWith( - 3, + ).toHaveBeenNthCalledWith(2, [mockAccount1Address], ChainId.ETHEREUM, false, @@ -1390,11 +1388,10 @@ describe('EarnController', () => { const { controller } = await setupController(); await controller.refreshPooledStakes({ resetCache: true }); - // Assertion on third call since the first two are part of controller setup. + // Assertion on second call since the first one is part of controller setup. expect( mockedEarnApiService?.pooledStaking?.getPooledStakes, - ).toHaveBeenNthCalledWith( - 3, + ).toHaveBeenNthCalledWith(2, [mockAccount1Address], ChainId.ETHEREUM, true, @@ -1405,11 +1402,10 @@ describe('EarnController', () => { const { controller } = await setupController(); await controller.refreshPooledStakes(); - // Assertion on third call since the first two are part of controller setup. + // Assertion on second call since the first one is part of controller setup. expect( mockedEarnApiService?.pooledStaking?.getPooledStakes, - ).toHaveBeenNthCalledWith( - 3, + ).toHaveBeenNthCalledWith(2, [mockAccount1Address], ChainId.ETHEREUM, false, @@ -1420,21 +1416,20 @@ describe('EarnController', () => { const { controller } = await setupController(); await controller.refreshPooledStakes({ address: mockAccount2Address }); - // Assertion on third call since the first two are part of controller setup. + // Assertion on second call since the first one is part of controller setup. expect( mockedEarnApiService?.pooledStaking?.getPooledStakes, - ).toHaveBeenNthCalledWith(3, [mockAccount2Address], 1, false); + ).toHaveBeenNthCalledWith(2, [mockAccount2Address], 1, false); }); it('fetches using Ethereum Mainnet fallback if chainId is not provided', async () => { const { controller } = await setupController(); await controller.refreshPooledStakes(); - // Assertion on third call since the first two are part of controller setup. + // Assertion on second call since the first one is part of controller setup. expect( mockedEarnApiService?.pooledStaking?.getPooledStakes, - ).toHaveBeenNthCalledWith( - 3, + ).toHaveBeenNthCalledWith(2, [mockAccount1Address], ChainId.ETHEREUM, false, @@ -1446,11 +1441,10 @@ describe('EarnController', () => { const { controller } = await setupController(); await controller.refreshPooledStakes({ chainId: 2 }); - // Assertion on third call since the first two are part of controller setup. + // Assertion on second call since the first one is part of controller setup. expect( mockedEarnApiService?.pooledStaking?.getPooledStakes, - ).toHaveBeenNthCalledWith( - 3, + ).toHaveBeenNthCalledWith(2, [mockAccount1Address], ChainId.ETHEREUM, false, @@ -1461,11 +1455,10 @@ describe('EarnController', () => { const { controller } = await setupController(); await controller.refreshPooledStakes({ chainId: ChainId.HOODI }); - // Assertion on third call since the first two are part of controller setup. + // Assertion on second call since the first one is part of controller setup. expect( mockedEarnApiService?.pooledStaking?.getPooledStakes, - ).toHaveBeenNthCalledWith( - 3, + ).toHaveBeenNthCalledWith(2, [mockAccount1Address], ChainId.HOODI, false, @@ -1517,7 +1510,7 @@ describe('EarnController', () => { expect( mockedEarnApiService?.pooledStaking?.getVaultData, - ).toHaveBeenCalledTimes(3); + ).toHaveBeenCalledTimes(2); }); it('fetches using Ethereum Mainnet fallback if chainId is not provided', async () => { @@ -1526,7 +1519,7 @@ describe('EarnController', () => { expect( mockedEarnApiService?.pooledStaking?.getVaultData, - ).toHaveBeenNthCalledWith(3, ChainId.ETHEREUM); + ).toHaveBeenNthCalledWith(2, ChainId.ETHEREUM); }); it('fetches using Ethereum Mainnet fallback if pooled-staking does not support provided chainId', async () => { @@ -1536,7 +1529,7 @@ describe('EarnController', () => { expect( mockedEarnApiService?.pooledStaking?.getVaultData, - ).toHaveBeenNthCalledWith(3, ChainId.ETHEREUM); + ).toHaveBeenNthCalledWith(2, ChainId.ETHEREUM); }); it('fetches using Ethereum Hoodi if it is the provided chainId', async () => { @@ -1545,7 +1538,7 @@ describe('EarnController', () => { expect( mockedEarnApiService?.pooledStaking?.getVaultData, - ).toHaveBeenNthCalledWith(3, ChainId.HOODI); + ).toHaveBeenNthCalledWith(2, ChainId.HOODI); }); }); @@ -1556,7 +1549,7 @@ describe('EarnController', () => { expect( mockedEarnApiService?.pooledStaking?.getVaultDailyApys, - ).toHaveBeenCalledTimes(3); + ).toHaveBeenCalledTimes(2); expect(controller.state.pooled_staking[1].vaultDailyApys).toStrictEqual( mockPooledStakingVaultDailyApys, ); @@ -1572,7 +1565,7 @@ describe('EarnController', () => { expect( mockedEarnApiService?.pooledStaking?.getVaultDailyApys, - ).toHaveBeenNthCalledWith(3, 1, 180, 'desc'); + ).toHaveBeenNthCalledWith(2, 1, 180, 'desc'); expect(controller.state.pooled_staking[1].vaultDailyApys).toStrictEqual( mockPooledStakingVaultDailyApys, ); @@ -1588,7 +1581,7 @@ describe('EarnController', () => { expect( mockedEarnApiService?.pooledStaking?.getVaultDailyApys, - ).toHaveBeenNthCalledWith(3, 1, 365, 'asc'); + ).toHaveBeenNthCalledWith(2, 1, 365, 'asc'); expect(controller.state.pooled_staking[1].vaultDailyApys).toStrictEqual( mockPooledStakingVaultDailyApys, ); @@ -1604,7 +1597,7 @@ describe('EarnController', () => { expect( mockedEarnApiService?.pooledStaking?.getVaultDailyApys, - ).toHaveBeenNthCalledWith(3, 1, 180, 'asc'); + ).toHaveBeenNthCalledWith(2, 1, 180, 'asc'); expect(controller.state.pooled_staking[1].vaultDailyApys).toStrictEqual( mockPooledStakingVaultDailyApys, ); @@ -1617,7 +1610,7 @@ describe('EarnController', () => { expect( mockedEarnApiService?.pooledStaking?.getVaultDailyApys, - ).toHaveBeenNthCalledWith(3, 1, 365, 'desc'); + ).toHaveBeenNthCalledWith(2, 1, 365, 'desc'); expect(controller.state.pooled_staking[1].vaultDailyApys).toStrictEqual( mockPooledStakingVaultDailyApys, ); @@ -1632,7 +1625,7 @@ describe('EarnController', () => { expect( mockedEarnApiService?.pooledStaking?.getVaultDailyApys, - ).toHaveBeenNthCalledWith(3, ChainId.HOODI, 365, 'desc'); + ).toHaveBeenNthCalledWith(2, ChainId.HOODI, 365, 'desc'); expect( controller.state.pooled_staking[ChainId.HOODI].vaultDailyApys, ).toStrictEqual(mockPooledStakingVaultDailyApys); @@ -1673,7 +1666,7 @@ describe('EarnController', () => { expect( mockedEarnApiService?.pooledStaking?.getVaultApyAverages, - ).toHaveBeenCalledTimes(3); + ).toHaveBeenCalledTimes(2); expect( controller.state.pooled_staking[1].vaultApyAverages, ).toStrictEqual(mockPooledStakingVaultApyAverages); @@ -1686,7 +1679,7 @@ describe('EarnController', () => { expect( mockedEarnApiService?.pooledStaking?.getVaultApyAverages, - ).toHaveBeenNthCalledWith(3, 1); + ).toHaveBeenNthCalledWith(2, 1); expect( controller.state.pooled_staking[1].vaultApyAverages, ).toStrictEqual(mockPooledStakingVaultApyAverages); @@ -1699,7 +1692,7 @@ describe('EarnController', () => { expect( mockedEarnApiService?.pooledStaking?.getVaultApyAverages, - ).toHaveBeenNthCalledWith(3, ChainId.HOODI); + ).toHaveBeenNthCalledWith(2, ChainId.HOODI); }); it('uses default chain state when refreshing vault apy averages for uninitialized chain', async () => { @@ -1768,30 +1761,63 @@ describe('EarnController', () => { }); describe('On selected account group change', () => { - it('updates earn eligibility, pooled stakes, and lending positions', async () => { - const { controller, messenger } = await setupController(); + it('updates earn eligibility, pooled stakes, and lending positions when the resolved address changed', async () => { + // setupController() already runs init() for mockAccount1Address, so + // resolve a different address (mockAccount2Address) on the group + // change to simulate an actual account switch. + const mockGetAccounts = jest + .fn() + .mockReturnValue([mockInternalAccount1]); + const { controller, messenger } = await setupController({ + mockGetAccountsFromSelectedAccountGroup: mockGetAccounts, + }); jest.spyOn(controller, 'refreshEarnEligibility').mockResolvedValue(); jest.spyOn(controller, 'refreshPooledStakes').mockResolvedValue(); jest.spyOn(controller, 'refreshLendingPositions').mockResolvedValue(); + mockGetAccounts.mockReturnValue([ + createMockInternalAccount({ address: mockAccount2Address }), + ]); + messenger.publish( 'AccountTreeController:selectedAccountGroupChange', 'keyring:test/0', '', ); - // Expect address argument to be the EVM address from mockGetAccountsFromSelectedAccountGroup expect(controller.refreshEarnEligibility).toHaveBeenNthCalledWith(1, { - address: mockAccount1Address, + address: mockAccount2Address, }); expect(controller.refreshPooledStakes).toHaveBeenNthCalledWith(1, { - address: mockAccount1Address, + address: mockAccount2Address, }); expect(controller.refreshLendingPositions).toHaveBeenNthCalledWith(1, { - address: mockAccount1Address, + address: mockAccount2Address, }); }); + + it('does not re-fetch when the resolved address is unchanged from the last refresh', async () => { + // setupController() already runs init() -> #refreshEarnPortfolio for + // mockAccount1Address. A selectedAccountGroupChange firing again + // with the same resolved address (e.g. during startup hydration) + // should be a no-op. + const { controller, messenger } = await setupController(); + + jest.spyOn(controller, 'refreshEarnEligibility').mockResolvedValue(); + jest.spyOn(controller, 'refreshPooledStakes').mockResolvedValue(); + jest.spyOn(controller, 'refreshLendingPositions').mockResolvedValue(); + + messenger.publish( + 'AccountTreeController:selectedAccountGroupChange', + 'keyring:test/0', + '', + ); + + expect(controller.refreshEarnEligibility).not.toHaveBeenCalled(); + expect(controller.refreshPooledStakes).not.toHaveBeenCalled(); + expect(controller.refreshLendingPositions).not.toHaveBeenCalled(); + }); }); describe('On transaction confirmed', () => { @@ -3011,13 +3037,6 @@ describe('EarnController', () => { vaultDailyApys: mockPooledStakingVaultDailyApys, vaultApyAverages: mockPooledStakingVaultApyAverages, }, - '560048': { - pooledStakes: mockPooledStakes, - exchangeRate: '1.5', - vaultMetadata: mockVaultMetadata, - vaultDailyApys: mockPooledStakingVaultDailyApys, - vaultApyAverages: mockPooledStakingVaultApyAverages, - }, isEligible: true, }); expect(derivedTronStaking).toBeNull(); @@ -3104,13 +3123,6 @@ describe('EarnController', () => { vaultDailyApys: mockPooledStakingVaultDailyApys, vaultApyAverages: mockPooledStakingVaultApyAverages, }, - '560048': { - pooledStakes: mockPooledStakes, - exchangeRate: '1.5', - vaultMetadata: mockVaultMetadata, - vaultDailyApys: mockPooledStakingVaultDailyApys, - vaultApyAverages: mockPooledStakingVaultApyAverages, - }, isEligible: true, }); expect(derivedTronStaking).toBeNull(); @@ -3196,13 +3208,6 @@ describe('EarnController', () => { vaultDailyApys: mockPooledStakingVaultDailyApys, vaultApyAverages: mockPooledStakingVaultApyAverages, }, - '560048': { - pooledStakes: mockPooledStakes, - exchangeRate: '1.5', - vaultMetadata: mockVaultMetadata, - vaultDailyApys: mockPooledStakingVaultDailyApys, - vaultApyAverages: mockPooledStakingVaultApyAverages, - }, isEligible: true, }); expect(derivedTronStaking).toBeNull(); diff --git a/packages/earn-controller/src/EarnController.ts b/packages/earn-controller/src/EarnController.ts index 7a0ade618a6..710328d3f3f 100644 --- a/packages/earn-controller/src/EarnController.ts +++ b/packages/earn-controller/src/EarnController.ts @@ -346,6 +346,8 @@ export class EarnController extends BaseController< #initPromise: Promise | null = null; + #lastRefreshedAddress: string | undefined; + readonly #earnApiService: EarnApiService; readonly #addTransactionFn: typeof TransactionController.prototype.addTransaction; @@ -382,7 +384,12 @@ export class EarnController extends BaseController< // temporary array of supported chains // TODO: remove this once we export a supported chains list from the sdk // from sdk or api to get lending and pooled staking chains - this.#supportedPooledStakingChains = [ChainId.ETHEREUM, ChainId.HOODI]; + // + // Only eagerly prefetch Ethereum on startup/network-change; Hoodi + // (testnet) is still fully supported on-demand via explicit chainId + // calls (e.g. refreshPooledStakes({ chainId: ChainId.HOODI })), we just + // don't unconditionally fetch it for every user on every unlock. + this.#supportedPooledStakingChains = [ChainId.ETHEREUM]; this.#addTransactionFn = addTransactionFn; @@ -417,6 +424,15 @@ export class EarnController extends BaseController< () => { const address = this.#getSelectedEvmAccountAddress(); + // Skip if this account group change didn't actually change the + // resolved address (e.g. it can fire again right after init() + // during startup hydration) - nothing new to fetch. + if (!address || address === this.#lastRefreshedAddress) { + return; + } + + this.#lastRefreshedAddress = address; + // TODO: temp solution, this will refresh lending eligibility also // we could have a more general check, as what is happening is a compliance address check this.refreshEarnEligibility({ address }).catch(console.error); @@ -461,6 +477,7 @@ export class EarnController extends BaseController< } #refreshEarnPortfolio(address: string): void { + this.#lastRefreshedAddress = address; this.refreshEarnEligibility({ address }).catch(console.error); this.refreshPooledStakingData({ address }).catch(console.error); this.refreshLendingData().catch(console.error); From 0054a308ce66cc00e8acfa93d7470c5f3770bbc6 Mon Sep 17 00:00:00 2001 From: juanmigdr Date: Fri, 7 Aug 2026 18:43:24 +0200 Subject: [PATCH 2/3] docs: link changelog entries to PR #9804 --- packages/earn-controller/CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/earn-controller/CHANGELOG.md b/packages/earn-controller/CHANGELOG.md index c1c8690c736..65cef0aceaf 100644 --- a/packages/earn-controller/CHANGELOG.md +++ b/packages/earn-controller/CHANGELOG.md @@ -9,8 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- Avoid duplicate `refreshEarnEligibility`/`refreshPooledStakes`/`refreshLendingPositions` calls when `AccountTreeController:selectedAccountGroupChange` fires with an address that was already just refreshed (e.g. immediately after `init()` during startup hydration) -- Only eagerly prefetch pooled staking data for Ethereum Mainnet on startup/network change, no longer also prefetching the Hoodi testnet by default; Hoodi remains fully supported via explicit `chainId` calls +- Avoid duplicate `refreshEarnEligibility`/`refreshPooledStakes`/`refreshLendingPositions` calls when `AccountTreeController:selectedAccountGroupChange` fires with an address that was already just refreshed (e.g. immediately after `init()` during startup hydration) ([#9804](https://github.com/MetaMask/core/pull/9804)) +- Only eagerly prefetch pooled staking data for Ethereum Mainnet on startup/network change, no longer also prefetching the Hoodi testnet by default; Hoodi remains fully supported via explicit `chainId` calls ([#9804](https://github.com/MetaMask/core/pull/9804)) ## [12.2.4] From ea13341e10ee57437570bee58fc57ef1af05151e Mon Sep 17 00:00:00 2001 From: juanmigdr Date: Fri, 7 Aug 2026 19:00:02 +0200 Subject: [PATCH 3/3] style: fix prettier formatting in EarnController.test.ts --- .../src/EarnController.test.ts | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/packages/earn-controller/src/EarnController.test.ts b/packages/earn-controller/src/EarnController.test.ts index 20d2aa481e9..da256ea0aaf 100644 --- a/packages/earn-controller/src/EarnController.test.ts +++ b/packages/earn-controller/src/EarnController.test.ts @@ -1363,7 +1363,8 @@ describe('EarnController', () => { // Assertion on second call since the first one is part of controller setup. expect( mockedEarnApiService?.pooledStaking?.getPooledStakes, - ).toHaveBeenNthCalledWith(2, + ).toHaveBeenNthCalledWith( + 2, [mockAccount1Address], ChainId.ETHEREUM, false, @@ -1377,7 +1378,8 @@ describe('EarnController', () => { // Assertion on second call since the first one is part of controller setup. expect( mockedEarnApiService?.pooledStaking?.getPooledStakes, - ).toHaveBeenNthCalledWith(2, + ).toHaveBeenNthCalledWith( + 2, [mockAccount1Address], ChainId.ETHEREUM, false, @@ -1391,7 +1393,8 @@ describe('EarnController', () => { // Assertion on second call since the first one is part of controller setup. expect( mockedEarnApiService?.pooledStaking?.getPooledStakes, - ).toHaveBeenNthCalledWith(2, + ).toHaveBeenNthCalledWith( + 2, [mockAccount1Address], ChainId.ETHEREUM, true, @@ -1405,7 +1408,8 @@ describe('EarnController', () => { // Assertion on second call since the first one is part of controller setup. expect( mockedEarnApiService?.pooledStaking?.getPooledStakes, - ).toHaveBeenNthCalledWith(2, + ).toHaveBeenNthCalledWith( + 2, [mockAccount1Address], ChainId.ETHEREUM, false, @@ -1429,7 +1433,8 @@ describe('EarnController', () => { // Assertion on second call since the first one is part of controller setup. expect( mockedEarnApiService?.pooledStaking?.getPooledStakes, - ).toHaveBeenNthCalledWith(2, + ).toHaveBeenNthCalledWith( + 2, [mockAccount1Address], ChainId.ETHEREUM, false, @@ -1444,7 +1449,8 @@ describe('EarnController', () => { // Assertion on second call since the first one is part of controller setup. expect( mockedEarnApiService?.pooledStaking?.getPooledStakes, - ).toHaveBeenNthCalledWith(2, + ).toHaveBeenNthCalledWith( + 2, [mockAccount1Address], ChainId.ETHEREUM, false, @@ -1458,7 +1464,8 @@ describe('EarnController', () => { // Assertion on second call since the first one is part of controller setup. expect( mockedEarnApiService?.pooledStaking?.getPooledStakes, - ).toHaveBeenNthCalledWith(2, + ).toHaveBeenNthCalledWith( + 2, [mockAccount1Address], ChainId.HOODI, false,