diff --git a/src/SwapsController.test.ts b/src/SwapsController.test.ts index f6fd05f2..7fa6b916 100644 --- a/src/SwapsController.test.ts +++ b/src/SwapsController.test.ts @@ -2520,6 +2520,67 @@ describe('SwapsController', () => { expect(swapsUtilFetchTopAssets).not.toHaveBeenCalled(); }); }); + + describe('when the chain ID is provided', () => { + it('persists fetched top assets to the chain cache and the main part of state', async () => { + const clientId = 'client-id'; + const chainId = POLYGON_CHAIN_ID; + const fetchedTokens = [ + { + address: '0x1111111', + symbol: 'TOKEN1', + decimals: 1, + }, + { + address: '0x2222222', + symbol: 'TOKEN2', + decimals: 2, + }, + ]; + const controller = getSwapsController({ + options: { + clientId, + }, + }); + swapsUtilFetchTopAssets.mockImplementation( + async (givenChainId, givenClientId) => { + if (givenChainId === chainId && givenClientId === clientId) { + return fetchedTokens; + } + throw new Error( + `Unknown chain ID '${givenChainId}' and/or client ID '${givenClientId}'`, + ); + }, + ); + + await controller.fetchTopAssetsWithCache({ chainId }); + + expect(controller.state.topAssets).toStrictEqual(fetchedTokens); + expect(controller.state.chainCache).toStrictEqual({ + '0x1': { + aggregatorMetadata: null, + tokens: null, + topAssets: null, + aggregatorMetadataLastFetched: 0, + topAssetsLastFetched: 0, + tokensLastFetched: 0, + }, + [chainId]: { + topAssets: fetchedTokens, + topAssetsLastFetched: Date.now(), + }, + }); + }); + }); + + describe('when the chain ID is not provided and the network client ID is not provided', () => { + it('throws an error', async () => { + const controller = getSwapsController(); + await expect(controller.fetchTopAssetsWithCache({})).rejects.toThrow( + 'One of networkClientId or chainId is required', + ); + }); + }); }); describe('fetchAggregatorMetadataWithCache', () => { diff --git a/src/SwapsController.ts b/src/SwapsController.ts index d6782dad..366d5977 100644 --- a/src/SwapsController.ts +++ b/src/SwapsController.ts @@ -1013,23 +1013,34 @@ export default class SwapsController extends BaseController< * Fetches the top assets and updates the state with them. * @param args - The arguments to this method. * @param args.networkClientId - The ID of a network client from - * NetworkController. + * NetworkController. This or chainId is required. + * @param args.chainId - The chain ID to fetch the top assets for. This or + * networkClientId is required. chainId will be preferred over networkClientId. */ async fetchTopAssetsWithCache({ networkClientId, + chainId, }: { - networkClientId: NetworkClientId; + networkClientId?: NetworkClientId; + chainId?: Hex; }) { - const chainId = this.#getChainId(networkClientId); + let chainIdToUse; + if (chainId) { + chainIdToUse = chainId; + } else if (networkClientId) { + chainIdToUse = this.#getChainId(networkClientId); + } else { + throw new Error('One of networkClientId or chainId is required'); + } - if (!this.#supportedChainIds.includes(chainId)) { + if (!this.#supportedChainIds.includes(chainIdToUse)) { return; } const { topAssets } = this.state; const topAssetsLastFetchedForChain = - this.state.chainCache[chainId]?.topAssetsLastFetched ?? 0; + this.state.chainCache[chainIdToUse]?.topAssetsLastFetched ?? 0; const isPastThresholdForChain = this.#fetchTopAssetsThreshold < Date.now() - topAssetsLastFetchedForChain; @@ -1037,7 +1048,7 @@ export default class SwapsController extends BaseController< if (!topAssets || isPastThresholdForChain) { const releaseLock = await this.#mutex.acquire(); try { - const newTopAssets = await fetchTopAssets(chainId, this.#clientId); + const newTopAssets = await fetchTopAssets(chainIdToUse, this.#clientId); const data = { topAssets: newTopAssets, topAssetsLastFetched: Date.now(), @@ -1046,7 +1057,7 @@ export default class SwapsController extends BaseController< _state.topAssets = data.topAssets; _state.chainCache = getNewChainCache( _state.chainCache, - chainId, + chainIdToUse, data, ); }); @@ -1055,7 +1066,7 @@ export default class SwapsController extends BaseController< this.update((_state) => { _state.chainCache = getNewChainCache( _state.chainCache, - chainId, + chainIdToUse, data, ); });