Skip to content

Commit bab1445

Browse files
Update token rates controller for multi evm fetching (#4866)
## Explanation This PR Updates the `TokenRatesController` to be used in clients across multiple chains. ## References * Related to [#67890](MetaMask/metamask-extension#28158) ## Changelog <!-- If you're making any consumer-facing changes, list those changes here as if you were updating a changelog, using the template below as a guide. (CATEGORY is one of BREAKING, ADDED, CHANGED, DEPRECATED, REMOVED, or FIXED. For security-related issues, follow the Security Advisory process.) Please take care to name the exact pieces of the API you've added or changed (e.g. types, interfaces, functions, or methods). If there are any breaking changes, make sure to offer a solution for consumers to follow once they upgrade to the changes. Finally, if you're only making changes to development scripts or tests, you may replace the template below with "None". --> ### `@metamask/assets-controllers` - **CHANGED**: When the `TokensController:stateChange` subscription is fired, token prices are now updated across all chain IDs whose tokens changed, instead of just the current chain. ## Checklist - [ ] I've updated the test suite for new or updated code as appropriate - [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate - [ ] I've highlighted breaking changes using the "BREAKING" category above as appropriate - [ ] I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes --------- Co-authored-by: sahar-fehri <sahar.fehri@consensys.net>
1 parent 674fa0b commit bab1445

File tree

2 files changed

+44
-11
lines changed

2 files changed

+44
-11
lines changed

packages/assets-controllers/src/TokenRatesController.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ describe('TokenRatesController', () => {
152152
},
153153
async ({ controller, triggerTokensStateChange }) => {
154154
const updateExchangeRatesSpy = jest
155-
.spyOn(controller, 'updateExchangeRates')
155+
.spyOn(controller, 'updateExchangeRatesByChainId')
156156
.mockResolvedValue();
157157
await controller.start();
158158
triggerTokensStateChange({
@@ -198,7 +198,7 @@ describe('TokenRatesController', () => {
198198
},
199199
async ({ controller, triggerTokensStateChange }) => {
200200
const updateExchangeRatesSpy = jest
201-
.spyOn(controller, 'updateExchangeRates')
201+
.spyOn(controller, 'updateExchangeRatesByChainId')
202202
.mockResolvedValue();
203203
await controller.start();
204204
triggerTokensStateChange({

packages/assets-controllers/src/TokenRatesController.ts

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -314,17 +314,46 @@ export class TokenRatesController extends StaticIntervalPollingController<TokenR
314314
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
315315
// eslint-disable-next-line @typescript-eslint/no-misused-promises
316316
async ({ allTokens, allDetectedTokens }) => {
317-
const previousTokenAddresses = this.#getTokenAddresses(this.#chainId);
317+
if (this.#disabled) {
318+
return;
319+
}
320+
321+
const chainIds = [
322+
...new Set([
323+
...Object.keys(allTokens),
324+
...Object.keys(allDetectedTokens),
325+
]),
326+
] as Hex[];
327+
328+
const chainIdsToUpdate = chainIds.filter(
329+
(chainId) =>
330+
!isEqual(this.#allTokens[chainId], allTokens[chainId]) ||
331+
!isEqual(
332+
this.#allDetectedTokens[chainId],
333+
allDetectedTokens[chainId],
334+
),
335+
);
336+
318337
this.#allTokens = allTokens;
319338
this.#allDetectedTokens = allDetectedTokens;
320339

321-
const newTokenAddresses = this.#getTokenAddresses(this.#chainId);
322-
if (
323-
!isEqual(previousTokenAddresses, newTokenAddresses) &&
324-
this.#pollState === PollState.Active
325-
) {
326-
await this.updateExchangeRates();
327-
}
340+
const { networkConfigurationsByChainId } = this.messagingSystem.call(
341+
'NetworkController:getState',
342+
);
343+
344+
await Promise.allSettled(
345+
chainIdsToUpdate.map(async (chainId) => {
346+
const nativeCurrency =
347+
networkConfigurationsByChainId[chainId as Hex]?.nativeCurrency;
348+
349+
if (nativeCurrency) {
350+
await this.updateExchangeRatesByChainId({
351+
chainId: chainId as Hex,
352+
nativeCurrency,
353+
});
354+
}
355+
}),
356+
);
328357
},
329358
({ allTokens, allDetectedTokens }) => {
330359
return { allTokens, allDetectedTokens };
@@ -591,6 +620,7 @@ export class TokenRatesController extends StaticIntervalPollingController<TokenR
591620
}
592621

593622
return await this.#fetchAndMapExchangeRatesForUnsupportedNativeCurrency({
623+
chainId,
594624
tokenAddresses,
595625
nativeCurrency,
596626
});
@@ -695,16 +725,19 @@ export class TokenRatesController extends StaticIntervalPollingController<TokenR
695725
* API, then convert the prices to our desired native currency.
696726
*
697727
* @param args - The arguments to this function.
728+
* @param args.chainId - The chain id to fetch prices for.
698729
* @param args.tokenAddresses - Addresses for tokens.
699730
* @param args.nativeCurrency - The native currency in which to request
700731
* prices.
701732
* @returns A map of the token addresses (as checksums) to their prices in the
702733
* native currency.
703734
*/
704735
async #fetchAndMapExchangeRatesForUnsupportedNativeCurrency({
736+
chainId,
705737
tokenAddresses,
706738
nativeCurrency,
707739
}: {
740+
chainId: Hex;
708741
tokenAddresses: Hex[];
709742
nativeCurrency: string;
710743
}): Promise<ContractMarketData> {
@@ -714,7 +747,7 @@ export class TokenRatesController extends StaticIntervalPollingController<TokenR
714747
] = await Promise.all([
715748
this.#fetchAndMapExchangeRatesForSupportedNativeCurrency({
716749
tokenAddresses,
717-
chainId: this.#chainId,
750+
chainId,
718751
nativeCurrency: FALL_BACK_VS_CURRENCY,
719752
}),
720753
getCurrencyConversionRate({

0 commit comments

Comments
 (0)