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
10 changes: 10 additions & 0 deletions packages/assets-controllers/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Add dynamic fetching of supported networks from `/v2/supportedNetworks` API endpoint with fallback to hardcoded list ([#7716](https://github.com/MetaMask/core/pull/7716))
- Add `fetchSupportedNetworks()`, `getSupportedNetworks()`, and `resetSupportedNetworksCache()` exports from token-prices-service
- Add `setNativeAssetIdentifiers()` method to `CodefiTokenPricesServiceV2` for CAIP-19 native token lookups
- Add `updateSupportedNetworks()` method to `CodefiTokenPricesServiceV2`
- Add `NativeAssetIdentifiersMap` type export from token-prices-service
- Integrate `TokenRatesController` with `NetworkEnablementController` to use native asset identifiers for token price lookups ([#7716](https://github.com/MetaMask/core/pull/7716))

### Changed

- Bump `@metamask/keyring-controller` from `^25.0.0` to `^25.1.0` ([#7713](https://github.com/MetaMask/core/pull/7713))
- Add `@metamask/network-enablement-controller` as a dependency ([#7716](https://github.com/MetaMask/core/pull/7716))

## [96.0.0]

Expand Down
1 change: 1 addition & 0 deletions packages/assets-controllers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"@metamask/metamask-eth-abis": "^3.1.1",
"@metamask/multichain-account-service": "^5.1.0",
"@metamask/network-controller": "^29.0.0",
"@metamask/network-enablement-controller": "^4.1.0",
"@metamask/permission-controller": "^12.2.0",
"@metamask/phishing-controller": "^16.1.0",
"@metamask/polling-controller": "^16.0.2",
Expand Down
61 changes: 60 additions & 1 deletion packages/assets-controllers/src/TokenRatesController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@ function buildTokenRatesControllerMessenger(
});
messenger.delegate({
messenger: tokenRatesControllerMessenger,
actions: ['TokensController:getState', 'NetworkController:getState'],
actions: [
'TokensController:getState',
'NetworkController:getState',
'NetworkEnablementController:getState',
],
events: ['TokensController:stateChange', 'NetworkController:stateChange'],
});
return tokenRatesControllerMessenger;
Expand All @@ -83,6 +87,48 @@ describe('TokenRatesController', () => {
});
});
});

it('should call setNativeAssetIdentifiers on tokenPricesService if available', async () => {
const setNativeAssetIdentifiers = jest.fn();
const tokenPricesService = buildMockTokenPricesService({
setNativeAssetIdentifiers,
});

await withController(
{
options: {
tokenPricesService,
},
},
async () => {
expect(setNativeAssetIdentifiers).toHaveBeenCalledWith({
'eip155:1': 'eip155:1/slip44:60',
'eip155:137': 'eip155:137/slip44:966',
});
},
);
});

it('should not fail if tokenPricesService does not have setNativeAssetIdentifiers', async () => {
const tokenPricesService = buildMockTokenPricesService();
// Explicitly remove setNativeAssetIdentifiers to simulate an old service
delete (tokenPricesService as Partial<AbstractTokenPricesService>)
.setNativeAssetIdentifiers;

await withController(
{
options: {
tokenPricesService,
},
},
async ({ controller }) => {
// Should not throw and controller should be created
expect(controller.state).toStrictEqual({
marketData: {},
});
},
);
});
});

describe('updateExchangeRates', () => {
Expand Down Expand Up @@ -1213,6 +1259,18 @@ async function withController<ReturnValue>(
}),
);

// Register NetworkEnablementController:getState handler
messenger.registerActionHandler(
'NetworkEnablementController:getState',
jest.fn().mockReturnValue({
enabledNetworkMap: {},
nativeAssetIdentifiers: {
'eip155:1': 'eip155:1/slip44:60',
'eip155:137': 'eip155:137/slip44:966',
},
}),
);

const controller = new TokenRatesController({
tokenPricesService: buildMockTokenPricesService(),
messenger: buildTokenRatesControllerMessenger(messenger),
Expand Down Expand Up @@ -1259,6 +1317,7 @@ function buildMockTokenPricesService(
validateCurrencySupported(_currency: unknown): _currency is string {
return true;
},
setNativeAssetIdentifiers: jest.fn(),
...overrides,
};
}
Expand Down
22 changes: 21 additions & 1 deletion packages/assets-controllers/src/TokenRatesController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {
NetworkControllerGetStateAction,
NetworkControllerStateChangeEvent,
} from '@metamask/network-controller';
import type { NetworkEnablementControllerGetStateAction } from '@metamask/network-enablement-controller';
import { StaticIntervalPollingController } from '@metamask/polling-controller';
import type { Hex } from '@metamask/utils';
import { isEqual } from 'lodash';
Expand Down Expand Up @@ -93,7 +94,8 @@ type ChainIdAndNativeCurrency = {
*/
export type AllowedActions =
| TokensControllerGetStateAction
| NetworkControllerGetStateAction;
| NetworkControllerGetStateAction
| NetworkEnablementControllerGetStateAction;

/**
* The external events available to the {@link TokenRatesController}.
Expand Down Expand Up @@ -234,6 +236,9 @@ export class TokenRatesController extends StaticIntervalPollingController<TokenR
this.#allTokens = allTokens;
this.#allDetectedTokens = allDetectedTokens;

// Set native asset identifiers from NetworkEnablementController for CAIP-19 native token lookups
this.#initNativeAssetIdentifiers();

this.#subscribeToTokensStateChange();

this.#subscribeToNetworkStateChange();
Expand Down Expand Up @@ -317,6 +322,21 @@ export class TokenRatesController extends StaticIntervalPollingController<TokenR
);
}

/**
* Initialize the native asset identifiers from NetworkEnablementController.
* This provides CAIP-19 native asset IDs for the token prices service.
*/
#initNativeAssetIdentifiers(): void {
if (this.#tokenPricesService.setNativeAssetIdentifiers) {
const { nativeAssetIdentifiers } = this.messenger.call(
'NetworkEnablementController:getState',
);
this.#tokenPricesService.setNativeAssetIdentifiers(
nativeAssetIdentifiers,
);
}
}

/**
* Get the tokens for the given chain.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import type { ServicePolicy } from '@metamask/controller-utils';
import type { CaipAssetType, Hex } from '@metamask/utils';
import type { CaipAssetType, CaipChainId, Hex } from '@metamask/utils';

import type { MarketDataDetails } from '../TokenRatesController';

/**
* A map of CAIP-2 chain IDs to their native asset identifiers (CAIP-19 format).
*/
export type NativeAssetIdentifiersMap = Record<CaipChainId, CaipAssetType>;

/**
* Represents an exchange rate.
*/
Expand Down Expand Up @@ -103,4 +108,14 @@ export type AbstractTokenPricesService<
* @returns True if the API supports the currency, false otherwise.
*/
validateCurrencySupported(currency: unknown): currency is Currency;

/**
* Sets the native asset identifiers map for resolving native token CAIP-19 IDs.
* This should be called with data from NetworkEnablementController.state.nativeAssetIdentifiers.
*
* @param nativeAssetIdentifiers - Map of CAIP-2 chain IDs to native asset identifiers.
*/
setNativeAssetIdentifiers?(
nativeAssetIdentifiers: NativeAssetIdentifiersMap,
): void;
};
Loading
Loading