From afba082a0eccde1e24c3b84c092f30e4334a8a87 Mon Sep 17 00:00:00 2001 From: juanmigdr Date: Wed, 15 Jul 2026 20:10:36 +0200 Subject: [PATCH] chore: [performance] remove 30+ RPC API calls on wallet unlock and onboarding flows --- .../useNetworkConnectionBanner.test.tsx | 34 ++++++++++++++- .../useNetworkConnectionBanner.ts | 9 ++-- .../account-tracker-controller-init.test.ts | 41 +++++++++++++++++++ .../account-tracker-controller-init.ts | 7 ++++ 4 files changed, 84 insertions(+), 7 deletions(-) diff --git a/app/components/hooks/useNetworkConnectionBanner/useNetworkConnectionBanner.test.tsx b/app/components/hooks/useNetworkConnectionBanner/useNetworkConnectionBanner.test.tsx index 8890ca959ad..922a69e9506 100644 --- a/app/components/hooks/useNetworkConnectionBanner/useNetworkConnectionBanner.test.tsx +++ b/app/components/hooks/useNetworkConnectionBanner/useNetworkConnectionBanner.test.tsx @@ -273,10 +273,10 @@ describe('useNetworkConnectionBanner', () => { expect(typeof result.current.switchToInfura).toBe('function'); }); - it('should call Engine.lookupEnabledNetworks on mount', () => { + it('should NOT call Engine.lookupEnabledNetworks on mount', () => { renderHookWithProvider(); - expect(mockEngine.lookupEnabledNetworks).toHaveBeenCalledTimes(1); + expect(mockEngine.lookupEnabledNetworks).not.toHaveBeenCalled(); }); }); @@ -903,6 +903,36 @@ describe('useNetworkConnectionBanner', () => { }); }); + it('should not show banner for networks with unknown status (stale persisted state)', () => { + // Networks with unknown status are treated the same as no data to avoid + // false-positive banners when the startup probe is removed and stale + // unknown entries remain from a previous session. + const unknownNetworkMetadata = { + [NETWORK_CLIENT_ID_1]: { status: NetworkStatus.Unknown }, + [NETWORK_CLIENT_ID_89]: { status: NetworkStatus.Unknown }, + }; + + // @ts-expect-error - Mocking Engine for testing + Engine.context = { + NetworkController: { + ...mockNetworkController, + state: { networksMetadata: unknownNetworkMetadata }, + }, + }; + + jest.mocked(selectNetworkConnectionBannerState).mockReturnValue({ + visible: false, + }); + + renderHookWithProvider(); + + act(() => { + jest.advanceTimersByTime(30000); + }); + + expect(store.getActions()).toHaveLength(0); + }); + it('should not show banner for available networks', () => { const availableNetworkMetadata = { [NETWORK_CLIENT_ID_1]: { status: NetworkStatus.Available }, diff --git a/app/components/hooks/useNetworkConnectionBanner/useNetworkConnectionBanner.ts b/app/components/hooks/useNetworkConnectionBanner/useNetworkConnectionBanner.ts index 4ccc3b48ed8..12a515b320c 100644 --- a/app/components/hooks/useNetworkConnectionBanner/useNetworkConnectionBanner.ts +++ b/app/components/hooks/useNetworkConnectionBanner/useNetworkConnectionBanner.ts @@ -69,10 +69,6 @@ const useNetworkConnectionBanner = (): { const evmEnabledNetworksChainIds = useSelector(selectEVMEnabledNetworks); - useEffect(() => { - Engine.lookupEnabledNetworks(); - }, []); - function updateRpc( rpcUrl: string, status: NetworkConnectionBannerStatus, @@ -152,7 +148,10 @@ const useNetworkConnectionBanner = (): { totalEnabled += 1; - if (networkMetadata.status === NetworkStatus.Available) { + if ( + networkMetadata.status === NetworkStatus.Available || + networkMetadata.status === NetworkStatus.Unknown + ) { continue; } diff --git a/app/core/Engine/controllers/account-tracker-controller-init.test.ts b/app/core/Engine/controllers/account-tracker-controller-init.test.ts index 5d29b7493da..b002b852aa1 100644 --- a/app/core/Engine/controllers/account-tracker-controller-init.test.ts +++ b/app/core/Engine/controllers/account-tracker-controller-init.test.ts @@ -11,6 +11,7 @@ import { import { MOCK_ANY_NAMESPACE, MockAnyNamespace } from '@metamask/messenger'; import { selectAssetsAccountApiBalancesEnabled } from '../../../selectors/featureFlagController/assetsAccountApiBalances'; import { selectBasicFunctionalityEnabled } from '../../../selectors/settings'; +import { selectIsControllerDeprecated } from '../../../selectors/featureFlagController/assetsUnifyState'; jest.mock('@metamask/assets-controllers'); @@ -25,6 +26,14 @@ jest.mock('../../../selectors/settings', () => ({ selectBasicFunctionalityEnabled: jest.fn().mockReturnValue(true), })); +jest.mock('../../../selectors/featureFlagController/assetsUnifyState', () => ({ + selectIsControllerDeprecated: jest.fn().mockReturnValue(() => false), +})); + +jest.mock('../../../store', () => ({ + store: { getState: jest.fn().mockReturnValue({}) }, +})); + function getInitRequestMock(): jest.Mocked< MessengerClientInitRequest > { @@ -68,6 +77,7 @@ describe('accountTrackerControllerInit', () => { accountsApiChainIds: expect.any(Function), allowExternalServices: expect.any(Function), isHomepageSectionsV1Enabled: expect.any(Function), + isDeprecated: expect.any(Function), }), ); }); @@ -113,4 +123,35 @@ describe('accountTrackerControllerInit', () => { expect(allowExternalServices()).toBe(false); expect(selectBasicFunctionalityEnabled).toHaveBeenCalled(); }); + + describe('isDeprecated', () => { + it('returns false when AccountTrackerController is not deprecated', () => { + jest.mocked(selectIsControllerDeprecated).mockReturnValue(() => false); + + accountTrackerControllerInit(getInitRequestMock()); + + const controllerMock = jest.mocked(AccountTrackerController); + const { isDeprecated } = controllerMock.mock.calls[0][0] as { + isDeprecated: () => boolean; + }; + + expect(isDeprecated()).toBe(false); + expect(selectIsControllerDeprecated).toHaveBeenCalledWith( + 'AccountTrackerController', + ); + }); + + it('returns true when AccountTrackerController is deprecated', () => { + jest.mocked(selectIsControllerDeprecated).mockReturnValue(() => true); + + accountTrackerControllerInit(getInitRequestMock()); + + const controllerMock = jest.mocked(AccountTrackerController); + const { isDeprecated } = controllerMock.mock.calls[0][0] as { + isDeprecated: () => boolean; + }; + + expect(isDeprecated()).toBe(true); + }); + }); }); diff --git a/app/core/Engine/controllers/account-tracker-controller-init.ts b/app/core/Engine/controllers/account-tracker-controller-init.ts index bccd0a39e32..b9f265bfe30 100644 --- a/app/core/Engine/controllers/account-tracker-controller-init.ts +++ b/app/core/Engine/controllers/account-tracker-controller-init.ts @@ -5,6 +5,9 @@ import { } from '@metamask/assets-controllers'; import { selectAssetsAccountApiBalancesEnabled } from '../../../selectors/featureFlagController/assetsAccountApiBalances'; import { selectBasicFunctionalityEnabled } from '../../../selectors/settings'; +import { selectIsControllerDeprecated } from '../../../selectors/featureFlagController/assetsUnifyState'; +import { store } from '../../../store'; + /** * Initialize the accountTracker controller. * @@ -34,6 +37,10 @@ export const accountTrackerControllerInit: MessengerClientInitFunction< selectAssetsAccountApiBalancesEnabled(getState()) as `0x${string}`[], allowExternalServices: () => selectBasicFunctionalityEnabled(getState()), isHomepageSectionsV1Enabled: () => true, + isDeprecated: () => + selectIsControllerDeprecated('AccountTrackerController')( + store.getState(), + ), }); return {