Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TokenListController: providerConfig -> selectedNetworkClientId #4316

Merged
merged 9 commits into from
Jun 4, 2024
153 changes: 85 additions & 68 deletions packages/assets-controllers/src/TokenListController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,30 @@ import { ControllerMessenger } from '@metamask/base-controller';
import {
ChainId,
NetworkType,
NetworksTicker,
convertHexToDecimal,
toHex,
InfuraNetworkType,
} from '@metamask/controller-utils';
import type {
NetworkControllerGetNetworkClientByIdAction,
NetworkControllerStateChangeEvent,
NetworkState,
ProviderConfig,
} from '@metamask/network-controller';
import { NetworkStatus } from '@metamask/network-controller';
import type { NetworkState } from '@metamask/network-controller';
import type { Hex } from '@metamask/utils';
import nock from 'nock';
import * as sinon from 'sinon';

import { advanceTime } from '../../../tests/helpers';
import type {
ExtractAvailableAction,
ExtractAvailableEvent,
} from '../../base-controller/tests/helpers';
import {
buildCustomNetworkClientConfiguration,
buildInfuraNetworkClientConfiguration,
buildMockGetNetworkClientById,
} from '../../network-controller/tests/helpers';
import * as tokenService from './token-service';
import type {
TokenListStateChange,
GetTokenListState,
TokenListMap,
TokenListState,
TokenListControllerMessenger,
} from './TokenListController';
import { TokenListController } from './TokenListController';

Expand Down Expand Up @@ -493,8 +495,8 @@ const expiredCacheExistingState: TokenListState = {
};

type MainControllerMessenger = ControllerMessenger<
GetTokenListState | NetworkControllerGetNetworkClientByIdAction,
TokenListStateChange | NetworkControllerStateChangeEvent
ExtractAvailableAction<TokenListControllerMessenger>,
ExtractAvailableEvent<TokenListControllerMessenger>
>;

const getControllerMessenger = (): MainControllerMessenger => {
Expand All @@ -513,31 +515,6 @@ const getRestrictedMessenger = (
return messenger;
};

/**
* Builds an object that satisfies the NetworkState shape using the given
* provider config. This can be used to return a complete value for the
* `NetworkController:stateChange` event.
*
* @param providerConfig - The provider config to use.
* @returns A complete state object for NetworkController.
*/
function buildNetworkControllerStateWithProviderConfig(
providerConfig: ProviderConfig,
): NetworkState {
const selectedNetworkClientId = providerConfig.type || 'uuid-1';
return {
selectedNetworkClientId,
providerConfig,
networksMetadata: {
[selectedNetworkClientId]: {
EIPS: {},
status: NetworkStatus.Available,
},
},
networkConfigurations: {},
};
}

describe('TokenListController', () => {
afterEach(() => {
jest.restoreAllMocks();
Expand Down Expand Up @@ -653,8 +630,17 @@ describe('TokenListController', () => {
.get(getTokensPath(ChainId.mainnet))
.reply(200, sampleMainnetTokenList)
.persist();

const selectedNetworkClientId = 'selectedNetworkClientId';
const controllerMessenger = getControllerMessenger();
const getNetworkClientById = buildMockGetNetworkClientById({
[selectedNetworkClientId]: buildCustomNetworkClientConfiguration({
chainId: toHex(1337),
}),
});
controllerMessenger.registerActionHandler(
'NetworkController:getNetworkClientById',
getNetworkClientById,
);
const messenger = getRestrictedMessenger(controllerMessenger);
let onNetworkStateChangeCallback!: (state: NetworkState) => void;
const controller = new TokenListController({
Expand All @@ -669,13 +655,13 @@ describe('TokenListController', () => {
expect(controller.state.tokenList).toStrictEqual(
sampleSingleChainState.tokenList,
);
onNetworkStateChangeCallback(
buildNetworkControllerStateWithProviderConfig({
chainId: ChainId.goerli,
type: NetworkType.goerli,
ticker: NetworksTicker.goerli,
}),
);
onNetworkStateChangeCallback({
selectedNetworkClientId,
networkConfigurations: {},
networksMetadata: {},
// @ts-expect-error This property isn't used and will get removed later.
providerConfig: {},
});
await new Promise<void>((resolve) => setTimeout(() => resolve(), 500));

expect(controller.state.tokenList).toStrictEqual({});
Expand Down Expand Up @@ -971,8 +957,20 @@ describe('TokenListController', () => {
.get(getTokensPath(toHex(56)))
.reply(200, sampleBinanceTokenList)
.persist();

const selectedCustomNetworkClientId = 'selectedCustomNetworkClientId';
const controllerMessenger = getControllerMessenger();
const getNetworkClientById = buildMockGetNetworkClientById({
[InfuraNetworkType.goerli]: buildInfuraNetworkClientConfiguration(
InfuraNetworkType.goerli,
),
[selectedCustomNetworkClientId]: buildCustomNetworkClientConfiguration({
chainId: toHex(56),
}),
});
controllerMessenger.registerActionHandler(
'NetworkController:getNetworkClientById',
getNetworkClientById,
);
const messenger = getRestrictedMessenger(controllerMessenger);
const controller = new TokenListController({
chainId: ChainId.mainnet,
Expand All @@ -995,11 +993,13 @@ describe('TokenListController', () => {

controllerMessenger.publish(
'NetworkController:stateChange',
buildNetworkControllerStateWithProviderConfig({
type: NetworkType.goerli,
chainId: ChainId.goerli,
ticker: NetworksTicker.goerli,
}),
{
selectedNetworkClientId: InfuraNetworkType.goerli,
networkConfigurations: {},
networksMetadata: {},
// @ts-expect-error This property isn't used and will get removed later.
providerConfig: {},
},
[],
);

Expand All @@ -1014,12 +1014,13 @@ describe('TokenListController', () => {

controllerMessenger.publish(
'NetworkController:stateChange',
buildNetworkControllerStateWithProviderConfig({
type: NetworkType.rpc,
chainId: toHex(56),
rpcUrl: 'http://localhost:8545',
ticker: 'TEST',
}),
{
selectedNetworkClientId: selectedCustomNetworkClientId,
networkConfigurations: {},
networksMetadata: {},
// @ts-expect-error This property isn't used and will get removed later.
providerConfig: {},
},
[],
);

Expand Down Expand Up @@ -1069,7 +1070,20 @@ describe('TokenListController', () => {
.reply(200, sampleBinanceTokenList)
.persist();

const selectedCustomNetworkClientId = 'selectedCustomNetworkClientId';
const controllerMessenger = getControllerMessenger();
const getNetworkClientById = buildMockGetNetworkClientById({
[InfuraNetworkType.mainnet]: buildInfuraNetworkClientConfiguration(
InfuraNetworkType.mainnet,
),
[selectedCustomNetworkClientId]: buildCustomNetworkClientConfiguration({
chainId: toHex(56),
}),
});
controllerMessenger.registerActionHandler(
'NetworkController:getNetworkClientById',
getNetworkClientById,
);
const messenger = getRestrictedMessenger(controllerMessenger);
const controller = new TokenListController({
chainId: ChainId.goerli,
Expand All @@ -1080,11 +1094,13 @@ describe('TokenListController', () => {
await controller.start();
controllerMessenger.publish(
'NetworkController:stateChange',
buildNetworkControllerStateWithProviderConfig({
type: NetworkType.mainnet,
chainId: ChainId.mainnet,
ticker: NetworksTicker.mainnet,
}),
{
selectedNetworkClientId: InfuraNetworkType.mainnet,
networkConfigurations: {},
networksMetadata: {},
// @ts-expect-error This property isn't used and will get removed later.
providerConfig: {},
},
[],
);

Expand Down Expand Up @@ -1128,12 +1144,13 @@ describe('TokenListController', () => {

controllerMessenger.publish(
'NetworkController:stateChange',
buildNetworkControllerStateWithProviderConfig({
type: NetworkType.rpc,
chainId: toHex(56),
rpcUrl: 'http://localhost:8545',
ticker: 'TEST',
}),
{
selectedNetworkClientId: selectedCustomNetworkClientId,
networkConfigurations: {},
networksMetadata: {},
// @ts-expect-error This property isn't used and will get removed later.
providerConfig: {},
},
[],
);
});
Expand Down
10 changes: 8 additions & 2 deletions packages/assets-controllers/src/TokenListController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,16 @@ export class TokenListController extends StaticIntervalPollingController<
* @param networkControllerState - The updated network controller state.
*/
async #onNetworkControllerStateChange(networkControllerState: NetworkState) {
if (this.chainId !== networkControllerState.providerConfig.chainId) {
const selectedNetworkClient = this.messagingSystem.call(
'NetworkController:getNetworkClientById',
networkControllerState.selectedNetworkClientId,
);
const { chainId } = selectedNetworkClient.configuration;

if (this.chainId !== chainId) {
this.abortController.abort();
this.abortController = new AbortController();
this.chainId = networkControllerState.providerConfig.chainId;
this.chainId = chainId;
if (this.state.preventPollingOnNetworkRestart) {
this.clearingTokenListData();
} else {
Expand Down
Loading