Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions eslint-warning-thresholds.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,8 @@
"import-x/order": 3
},
"packages/assets-controllers/src/TokenRatesController.ts": {
"@typescript-eslint/prefer-readonly": 2,
"jsdoc/check-tag-names": 11,
"no-unused-private-class-members": 1
"@typescript-eslint/prefer-readonly": 1,
"jsdoc/check-tag-names": 11
},
"packages/assets-controllers/src/TokensController.test.ts": {
"import-x/namespace": 1,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@metamask/core-monorepo",
"version": "372.0.0",
"version": "373.0.0",
"private": true,
"description": "Monorepo for packages shared between MetaMask clients",
"repository": {
Expand Down
16 changes: 13 additions & 3 deletions packages/assets-controllers/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add token detection support
- Add NFT detection support

### Changed

- Refactor `TokenRatesController` to support processing multiple chains simultaneously ([#5645](https://github.com/MetaMask/core/pull/5645))
- The controller now accepts an array of chain IDs instead of a single value, streamlining the polling process by iterating over all chains in one loop

### Removed

- **BREAKING:** Eliminate legacy network dependency handling in `TokenRatesController` ([#5645](https://github.com/MetaMask/core/pull/5645))
- We're no longer relying on the currently selected network.

## [58.0.0]

### Added
Expand Down Expand Up @@ -61,9 +71,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **BREAKING:** Remove deprecated state fields scoped to the current chain ([#5310](https://github.com/MetaMask/core/pull/5310))
- This change removes the following state fields from the following controllers:
- `TokensControllerState`
- `detectedTokens` (replaced by `detectedTokensByChainId`)
- `ignoredTokens` (replaced by `ignoredTokensByChainId`)
- `tokens` (replaced by `tokensByChainId`)
- `detectedTokens` (replaced by `allDetectedTokens`)
- `ignoredTokens` (replaced by `allIgnoredTokens`)
- `tokens` (replaced by `allTokens`)
- `TokenListControllerState`
- `tokenList` (replaced by `tokensChainsCache`)
- `AccountTrackerControllerState`
Expand Down
142 changes: 84 additions & 58 deletions packages/assets-controllers/src/TokenRatesController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ describe('TokenRatesController', () => {
const updateExchangeRatesSpy = jest
.spyOn(controller, 'updateExchangeRatesByChainId')
.mockResolvedValue();
await controller.start();
await controller.start(ChainId.mainnet, 'ETH');
triggerTokensStateChange({
...getDefaultTokensState(),
allTokens: {
Expand Down Expand Up @@ -203,7 +203,7 @@ describe('TokenRatesController', () => {
const updateExchangeRatesSpy = jest
.spyOn(controller, 'updateExchangeRatesByChainId')
.mockResolvedValue();
await controller.start();
await controller.start(ChainId.mainnet, 'ETH');
triggerTokensStateChange({
...getDefaultTokensState(),
allTokens: {
Expand Down Expand Up @@ -249,7 +249,7 @@ describe('TokenRatesController', () => {
const updateExchangeRatesSpy = jest
.spyOn(controller, 'updateExchangeRatesByChainId')
.mockResolvedValue();
await controller.start();
await controller.start(ChainId.mainnet, 'ETH');
triggerTokensStateChange({
...getDefaultTokensState(),
allDetectedTokens: {
Expand Down Expand Up @@ -296,7 +296,7 @@ describe('TokenRatesController', () => {
const updateExchangeRatesSpy = jest
.spyOn(controller, 'updateExchangeRates')
.mockResolvedValue();
await controller.start();
await controller.start(ChainId.mainnet, 'ETH');
triggerTokensStateChange({
...getDefaultTokensState(),
...tokensState,
Expand Down Expand Up @@ -331,7 +331,7 @@ describe('TokenRatesController', () => {
const updateExchangeRatesSpy = jest
.spyOn(controller, 'updateExchangeRates')
.mockResolvedValue();
await controller.start();
await controller.start(ChainId.mainnet, 'ETH');
triggerTokensStateChange({
...getDefaultTokensState(),
allDetectedTokens: tokens,
Expand Down Expand Up @@ -366,7 +366,7 @@ describe('TokenRatesController', () => {
const updateExchangeRatesSpy = jest
.spyOn(controller, 'updateExchangeRates')
.mockResolvedValue();
await controller.start();
await controller.start(ChainId.mainnet, 'ETH');
triggerTokensStateChange({
...getDefaultTokensState(),
allTokens: tokens,
Expand Down Expand Up @@ -402,7 +402,7 @@ describe('TokenRatesController', () => {
const updateExchangeRatesSpy = jest
.spyOn(controller, 'updateExchangeRates')
.mockResolvedValue();
await controller.start();
await controller.start(ChainId.mainnet, 'ETH');
triggerTokensStateChange({
...getDefaultTokensState(),
allTokens: tokens,
Expand Down Expand Up @@ -438,7 +438,7 @@ describe('TokenRatesController', () => {
const updateExchangeRatesSpy = jest
.spyOn(controller, 'updateExchangeRates')
.mockResolvedValue();
await controller.start();
await controller.start(ChainId.mainnet, 'ETH');
triggerTokensStateChange({
...getDefaultTokensState(),
allDetectedTokens: {
Expand Down Expand Up @@ -483,7 +483,7 @@ describe('TokenRatesController', () => {
const updateExchangeRatesSpy = jest
.spyOn(controller, 'updateExchangeRates')
.mockResolvedValue();
await controller.start();
await controller.start(ChainId.mainnet, 'ETH');
triggerTokensStateChange({
...getDefaultTokensState(),
allDetectedTokens: {
Expand Down Expand Up @@ -534,7 +534,7 @@ describe('TokenRatesController', () => {
const updateExchangeRatesSpy = jest
.spyOn(controller, 'updateExchangeRates')
.mockResolvedValue();
await controller.start();
await controller.start(ChainId.mainnet, 'ETH');
triggerTokensStateChange({
...getDefaultTokensState(),
allDetectedTokens: {
Expand Down Expand Up @@ -681,7 +681,7 @@ describe('TokenRatesController', () => {
},
},
async ({ controller, triggerNetworkStateChange }) => {
await controller.start();
await controller.start(ChainId.mainnet, 'ETH');
const updateExchangeRatesSpy = jest
.spyOn(controller, 'updateExchangeRates')
.mockResolvedValue();
Expand Down Expand Up @@ -709,7 +709,7 @@ describe('TokenRatesController', () => {
},
},
async ({ controller, triggerNetworkStateChange }) => {
await controller.start();
await controller.start(ChainId.mainnet, 'ETH');
const updateExchangeRatesSpy = jest
.spyOn(controller, 'updateExchangeRates')
.mockResolvedValue();
Expand Down Expand Up @@ -765,7 +765,7 @@ describe('TokenRatesController', () => {
},
},
async ({ controller, triggerNetworkStateChange }) => {
await controller.start();
await controller.start(ChainId.mainnet, 'ETH');
jest.spyOn(controller, 'updateExchangeRates').mockResolvedValue();
triggerNetworkStateChange({
...getDefaultNetworkControllerState(),
Expand Down Expand Up @@ -825,7 +825,7 @@ describe('TokenRatesController', () => {
},
},
async ({ controller, triggerNetworkStateChange }) => {
await controller.start();
await controller.start(ChainId.mainnet, 'ETH');
jest.spyOn(controller, 'updateExchangeRates').mockResolvedValue();
triggerNetworkStateChange({
...getDefaultNetworkControllerState(),
Expand All @@ -843,7 +843,7 @@ describe('TokenRatesController', () => {
);
});

it('should not update exchange rates when network state changes without a ticker/chain id change', async () => {
it('should update exchange rates when network state changes without adding a new network', async () => {
await withController(
{
options: {
Expand All @@ -857,16 +857,23 @@ describe('TokenRatesController', () => {
},
},
async ({ controller, triggerNetworkStateChange }) => {
await controller.start();
await controller.start(ChainId.mainnet, 'ETH');
const updateExchangeRatesSpy = jest
.spyOn(controller, 'updateExchangeRates')
.mockResolvedValue();
triggerNetworkStateChange({
...getDefaultNetworkControllerState(),
selectedNetworkClientId: 'AAAA-BBBB-CCCC-DDDD',
});

expect(updateExchangeRatesSpy).not.toHaveBeenCalled();
triggerNetworkStateChange(
{
...getDefaultNetworkControllerState(),
selectedNetworkClientId: 'AAAA-BBBB-CCCC-DDDD',
},
[
{
op: 'add',
path: ['networkConfigurationsByChainId', ChainId.mainnet],
},
],
);
expect(updateExchangeRatesSpy).toHaveBeenCalled();
},
);
});
Expand Down Expand Up @@ -1218,7 +1225,7 @@ describe('TokenRatesController', () => {
},
},
async ({ controller, triggerSelectedAccountChange }) => {
await controller.start();
await controller.start(ChainId.mainnet, 'ETH');
const updateExchangeRatesSpy = jest
.spyOn(controller, 'updateExchangeRates')
.mockResolvedValue();
Expand Down Expand Up @@ -1314,7 +1321,7 @@ describe('TokenRatesController', () => {
},
},
async ({ controller }) => {
await controller.start();
await controller.start(ChainId.mainnet, 'ETH');

expect(tokenPricesService.fetchTokenPrices).toHaveBeenCalledTimes(
1,
Expand Down Expand Up @@ -1361,7 +1368,7 @@ describe('TokenRatesController', () => {
},
},
async ({ controller }) => {
await controller.start();
await controller.start(ChainId.mainnet, 'ETH');

expect(tokenPricesService.fetchTokenPrices).toHaveBeenCalledTimes(
1,
Expand Down Expand Up @@ -1417,7 +1424,7 @@ describe('TokenRatesController', () => {
},
async ({ controller }) => {
controller.startPolling({
chainId: ChainId.mainnet,
chainIds: [ChainId.mainnet],
});

await advanceTime({ clock, duration: 0 });
Expand Down Expand Up @@ -1471,7 +1478,7 @@ describe('TokenRatesController', () => {
},
async ({ controller }) => {
controller.startPolling({
chainId: ChainId.mainnet,
chainIds: [ChainId.mainnet],
});
await advanceTime({ clock, duration: 0 });

Expand Down Expand Up @@ -1576,7 +1583,7 @@ describe('TokenRatesController', () => {
},
async ({ controller }) => {
controller.startPolling({
chainId: ChainId.mainnet,
chainIds: [ChainId.mainnet],
});
// flush promises and advance setTimeouts they enqueue 3 times
// needed because fetch() doesn't resolve immediately, so any
Expand Down Expand Up @@ -1678,7 +1685,7 @@ describe('TokenRatesController', () => {
},
async ({ controller }) => {
controller.startPolling({
chainId: ChainId.mainnet,
chainIds: [ChainId.mainnet],
});
// flush promises and advance setTimeouts they enqueue 3 times
// needed because fetch() doesn't resolve immediately, so any
Expand Down Expand Up @@ -1721,7 +1728,7 @@ describe('TokenRatesController', () => {
},
async ({ controller }) => {
const pollingToken = controller.startPolling({
chainId: ChainId.mainnet,
chainIds: [ChainId.mainnet],
});
await advanceTime({ clock, duration: 0 });
expect(tokenPricesService.fetchTokenPrices).toHaveBeenCalledTimes(
Expand Down Expand Up @@ -1849,30 +1856,29 @@ describe('TokenRatesController', () => {
}) => {
const tokenAddress = '0x0000000000000000000000000000000000000001';

await expect(
async () =>
await callUpdateExchangeRatesMethod({
allTokens: {
[ChainId.mainnet]: {
[defaultSelectedAddress]: [
{
address: tokenAddress,
decimals: 18,
symbol: 'TST',
aggregators: [],
},
],
const updateExchangeRates = await callUpdateExchangeRatesMethod({
allTokens: {
[ChainId.mainnet]: {
[defaultSelectedAddress]: [
{
address: tokenAddress,
decimals: 18,
symbol: 'TST',
aggregators: [],
},
},
chainId: ChainId.mainnet,
controller,
triggerTokensStateChange,
triggerNetworkStateChange,
method,
nativeCurrency: 'ETH',
selectedNetworkClientId: InfuraNetworkType.mainnet,
}),
).rejects.toThrow('Failed to fetch');
],
},
},
chainId: ChainId.mainnet,
controller,
triggerTokensStateChange,
triggerNetworkStateChange,
method,
nativeCurrency: 'ETH',
selectedNetworkClientId: InfuraNetworkType.mainnet,
});

expect(updateExchangeRates).toBeUndefined();
expect(controller.state.marketData).toStrictEqual({});
},
);
Expand Down Expand Up @@ -2269,6 +2275,19 @@ describe('TokenRatesController', () => {
mockNetworkClientConfigurationsByNetworkClientId: {
[selectedNetworkClientId]: selectedNetworkClientConfiguration,
},
mockNetworkState: {
networkConfigurationsByChainId: {
[selectedNetworkClientConfiguration.chainId]: {
nativeCurrency: selectedNetworkClientConfiguration.ticker,
chainId: selectedNetworkClientConfiguration.chainId,
name: 'UNSUPPORTED',
rpcEndpoints: [],
blockExplorerUrls: [],
defaultRpcEndpointIndex: 0,
},
},
selectedNetworkClientId,
},
},
async ({
controller,
Expand Down Expand Up @@ -2866,12 +2885,19 @@ async function callUpdateExchangeRatesMethod({
}

if (method === 'updateExchangeRates') {
await controller.updateExchangeRates();
await controller.updateExchangeRates([
{
chainId,
nativeCurrency,
},
]);
} else {
await controller.updateExchangeRatesByChainId({
chainId,
nativeCurrency,
});
await controller.updateExchangeRatesByChainId([
{
chainId,
nativeCurrency,
},
]);
}
}

Expand Down
Loading
Loading