1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

NetworkController: Use messenger for events (#18041)

Currently, the network controller notifies consumers about events by
emitting them directly from the controller. In order to migrate the
controller to the core repo, where controllers use the BaseControllerV2
interface, events should be emitted via a messenger object.

This commit updates the network controller to use a messenger, and then
updates all of the controllers that listen for network events to use the
messenger as well.
This commit is contained in:
Elliot Winkler 2023-03-30 12:39:36 -06:00 committed by GitHub
parent b3e45ea4bc
commit 9b0a6ecc90
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 508 additions and 253 deletions

View File

@ -13,7 +13,7 @@ import { convertHexToDecimal } from '@metamask/controller-utils';
import { NETWORK_TYPES } from '../../../shared/constants/network'; import { NETWORK_TYPES } from '../../../shared/constants/network';
import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils'; import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils';
import DetectTokensController from './detect-tokens'; import DetectTokensController from './detect-tokens';
import NetworkController, { NETWORK_EVENTS } from './network'; import NetworkController, { NetworkControllerEventTypes } from './network';
import PreferencesController from './preferences'; import PreferencesController from './preferences';
describe('DetectTokensController', function () { describe('DetectTokensController', function () {
@ -34,7 +34,11 @@ describe('DetectTokensController', function () {
beforeEach(async function () { beforeEach(async function () {
keyringMemStore = new ObservableStore({ isUnlocked: false }); keyringMemStore = new ObservableStore({ isUnlocked: false });
network = new NetworkController({ infuraProjectId: 'foo' }); const networkControllerMessenger = new ControllerMessenger();
network = new NetworkController({
messenger: networkControllerMessenger,
infuraProjectId: 'foo',
});
network.initializeProvider(networkControllerProviderConfig); network.initializeProvider(networkControllerProviderConfig);
provider = network.getProviderAndBlockTracker().provider; provider = network.getProviderAndBlockTracker().provider;
@ -54,6 +58,8 @@ describe('DetectTokensController', function () {
network, network,
provider, provider,
tokenListController, tokenListController,
onInfuraIsBlocked: sinon.stub(),
onInfuraIsUnblocked: sinon.stub(),
}); });
preferences.setAddresses([ preferences.setAddresses([
'0x7e57e2', '0x7e57e2',
@ -82,7 +88,9 @@ describe('DetectTokensController', function () {
preferences.store, preferences.store,
), ),
onNetworkStateChange: (cb) => onNetworkStateChange: (cb) =>
network.on(NETWORK_EVENTS.NETWORK_DID_CHANGE, () => { networkControllerMessenger.subscribe(
NetworkControllerEventTypes.NetworkDidChange,
() => {
const networkState = network.store.getState(); const networkState = network.store.getState();
const modifiedNetworkState = { const modifiedNetworkState = {
...networkState, ...networkState,
@ -92,7 +100,8 @@ describe('DetectTokensController', function () {
}, },
}; };
return cb(modifiedNetworkState); return cb(modifiedNetworkState);
}), },
),
}); });
sandbox sandbox

View File

@ -15,7 +15,6 @@ import {
} from '../../../shared/constants/network'; } from '../../../shared/constants/network';
import * as Utils from '../lib/util'; import * as Utils from '../lib/util';
import MetaMetricsController from './metametrics'; import MetaMetricsController from './metametrics';
import { NETWORK_EVENTS } from './network';
const segment = createSegmentMock(2, 10000); const segment = createSegmentMock(2, 10000);
@ -72,17 +71,17 @@ function getMockNetworkController() {
}, },
network: 'loading', network: 'loading',
}; };
const on = sinon.stub().withArgs(NETWORK_EVENTS.NETWORK_DID_CHANGE); const onNetworkDidChange = sinon.stub();
const updateState = (newState) => { const updateState = (newState) => {
state = { ...state, ...newState }; state = { ...state, ...newState };
on.getCall(0).args[1](); onNetworkDidChange.getCall(0).args[0]();
}; };
return { return {
store: { store: {
getState: () => state, getState: () => state,
updateState, updateState,
}, },
on, onNetworkDidChange,
}; };
} }
@ -136,10 +135,8 @@ function getMetaMetricsController({
segment: segmentInstance || segment, segment: segmentInstance || segment,
getCurrentChainId: () => getCurrentChainId: () =>
networkController.store.getState().provider.chainId, networkController.store.getState().provider.chainId,
onNetworkDidChange: networkController.on.bind( onNetworkDidChange:
networkController, networkController.onNetworkDidChange.bind(networkController),
NETWORK_EVENTS.NETWORK_DID_CHANGE,
),
preferencesStore, preferencesStore,
version: '0.0.1', version: '0.0.1',
environment: 'test', environment: 'test',

View File

@ -1 +1 @@
export { default, NETWORK_EVENTS } from './network-controller'; export { default, NetworkControllerEventTypes } from './network-controller';

View File

@ -7,6 +7,9 @@ import {
createEventEmitterProxy, createEventEmitterProxy,
} from 'swappable-obj-proxy'; } from 'swappable-obj-proxy';
import EthQuery from 'eth-query'; import EthQuery from 'eth-query';
// ControllerMessenger is referred to in the JSDocs
// eslint-disable-next-line no-unused-vars
import { ControllerMessenger } from '@metamask/base-controller';
import { v4 as random } from 'uuid'; import { v4 as random } from 'uuid';
import { import {
INFURA_PROVIDER_TYPES, INFURA_PROVIDER_TYPES,
@ -36,6 +39,8 @@ import { createNetworkClient } from './create-network-client';
const env = process.env.METAMASK_ENV; const env = process.env.METAMASK_ENV;
const fetchWithTimeout = getFetchWithTimeout(); const fetchWithTimeout = getFetchWithTimeout();
const name = 'NetworkController';
let defaultProviderConfigOpts; let defaultProviderConfigOpts;
if (process.env.IN_TEST) { if (process.env.IN_TEST) {
defaultProviderConfigOpts = { defaultProviderConfigOpts = {
@ -66,15 +71,30 @@ const defaultNetworkDetailsState = {
EIPS: { 1559: undefined }, EIPS: { 1559: undefined },
}; };
export const NETWORK_EVENTS = { /**
// Fired after the actively selected network is changed * The set of event types that this controller can publish via its messenger.
NETWORK_DID_CHANGE: 'networkDidChange', */
// Fired when the actively selected network *will* change export const NetworkControllerEventTypes = {
NETWORK_WILL_CHANGE: 'networkWillChange', /**
// Fired when Infura returns an error indicating no support * Fired after the current network is changed.
INFURA_IS_BLOCKED: 'infuraIsBlocked', */
// Fired when not using an Infura network or when Infura returns no error, indicating support NetworkDidChange: `${name}:networkDidChange`,
INFURA_IS_UNBLOCKED: 'infuraIsUnblocked', /**
* Fired when there is a request to change the current network, but no state
* changes have occurred yet.
*/
NetworkWillChange: `${name}:networkWillChange`,
/**
* Fired after the network is changed to an Infura network, but when Infura
* returns an error denying support for the user's location.
*/
InfuraIsBlocked: `${name}:infuraIsBlocked`,
/**
* Fired after the network is changed to an Infura network and Infura does not
* return an error denying support for the user's location, or after the
* network is changed to a custom network.
*/
InfuraIsUnblocked: `${name}:infuraIsUnblocked`,
}; };
export default class NetworkController extends EventEmitter { export default class NetworkController extends EventEmitter {
@ -83,14 +103,22 @@ export default class NetworkController extends EventEmitter {
/** /**
* Construct a NetworkController. * Construct a NetworkController.
* *
* @param {object} [options] - NetworkController options. * @param {object} options - Options for this controller.
* @param {ControllerMessenger} options.messenger - The controller messenger.
* @param {object} [options.state] - Initial controller state. * @param {object} [options.state] - Initial controller state.
* @param {string} [options.infuraProjectId] - The Infura project ID. * @param {string} [options.infuraProjectId] - The Infura project ID.
* @param {string} [options.trackMetaMetricsEvent] - A method to forward events to the MetaMetricsController * @param {string} [options.trackMetaMetricsEvent] - A method to forward events to the MetaMetricsController
*/ */
constructor({ state = {}, infuraProjectId, trackMetaMetricsEvent } = {}) { constructor({
messenger,
state = {},
infuraProjectId,
trackMetaMetricsEvent,
} = {}) {
super(); super();
this.messenger = messenger;
// create stores // create stores
this.providerStore = new ObservableStore( this.providerStore = new ObservableStore(
state.provider || { ...defaultProviderConfig }, state.provider || { ...defaultProviderConfig },
@ -134,11 +162,8 @@ export default class NetworkController extends EventEmitter {
throw new Error('Invalid Infura project ID'); throw new Error('Invalid Infura project ID');
} }
this._infuraProjectId = infuraProjectId; this._infuraProjectId = infuraProjectId;
this._trackMetaMetricsEvent = trackMetaMetricsEvent;
this.on(NETWORK_EVENTS.NETWORK_DID_CHANGE, () => { this._trackMetaMetricsEvent = trackMetaMetricsEvent;
this.lookupNetwork();
});
} }
/** /**
@ -210,7 +235,7 @@ export default class NetworkController extends EventEmitter {
if (isInfura) { if (isInfura) {
this._checkInfuraAvailability(type); this._checkInfuraAvailability(type);
} else { } else {
this.emit(NETWORK_EVENTS.INFURA_IS_UNBLOCKED); this.messenger.publish(NetworkControllerEventTypes.InfuraIsUnblocked);
} }
let networkVersion; let networkVersion;
@ -373,9 +398,17 @@ export default class NetworkController extends EventEmitter {
const rpcUrl = `https://${network}.infura.io/v3/${this._infuraProjectId}`; const rpcUrl = `https://${network}.infura.io/v3/${this._infuraProjectId}`;
let networkChanged = false; let networkChanged = false;
this.once(NETWORK_EVENTS.NETWORK_DID_CHANGE, () => { const listener = () => {
networkChanged = true; networkChanged = true;
}); this.messenger.unsubscribe(
NetworkControllerEventTypes.NetworkDidChange,
listener,
);
};
this.messenger.subscribe(
NetworkControllerEventTypes.NetworkDidChange,
listener,
);
try { try {
const response = await fetchWithTimeout(rpcUrl, { const response = await fetchWithTimeout(rpcUrl, {
@ -393,14 +426,14 @@ export default class NetworkController extends EventEmitter {
} }
if (response.ok) { if (response.ok) {
this.emit(NETWORK_EVENTS.INFURA_IS_UNBLOCKED); this.messenger.publish(NetworkControllerEventTypes.InfuraIsUnblocked);
} else { } else {
const responseMessage = await response.json(); const responseMessage = await response.json();
if (networkChanged) { if (networkChanged) {
return; return;
} }
if (responseMessage.error === INFURA_BLOCKED_KEY) { if (responseMessage.error === INFURA_BLOCKED_KEY) {
this.emit(NETWORK_EVENTS.INFURA_IS_BLOCKED); this.messenger.publish(NetworkControllerEventTypes.InfuraIsBlocked);
} }
} }
} catch (err) { } catch (err) {
@ -410,7 +443,7 @@ export default class NetworkController extends EventEmitter {
_switchNetwork(opts) { _switchNetwork(opts) {
// Indicate to subscribers that network is about to change // Indicate to subscribers that network is about to change
this.emit(NETWORK_EVENTS.NETWORK_WILL_CHANGE); this.messenger.publish(NetworkControllerEventTypes.NetworkWillChange);
// Set loading state // Set loading state
this._setNetworkState('loading'); this._setNetworkState('loading');
// Reset network details // Reset network details
@ -418,7 +451,11 @@ export default class NetworkController extends EventEmitter {
// Configure the provider appropriately // Configure the provider appropriately
this._configureProvider(opts); this._configureProvider(opts);
// Notify subscribers that network has changed // Notify subscribers that network has changed
this.emit(NETWORK_EVENTS.NETWORK_DID_CHANGE, opts.type); this.messenger.publish(
NetworkControllerEventTypes.NetworkDidChange,
opts.type,
);
this.lookupNetwork();
} }
_configureProvider({ type, rpcUrl, chainId }) { _configureProvider({ type, rpcUrl, chainId }) {

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,6 @@ import { normalize as normalizeAddress } from 'eth-sig-util';
import { IPFS_DEFAULT_GATEWAY_URL } from '../../../shared/constants/network'; import { IPFS_DEFAULT_GATEWAY_URL } from '../../../shared/constants/network';
import { LedgerTransportTypes } from '../../../shared/constants/hardware-wallets'; import { LedgerTransportTypes } from '../../../shared/constants/hardware-wallets';
import { ThemeType } from '../../../shared/constants/preferences'; import { ThemeType } from '../../../shared/constants/preferences';
import { NETWORK_EVENTS } from './network';
export default class PreferencesController { export default class PreferencesController {
/** /**
@ -70,7 +69,8 @@ export default class PreferencesController {
...opts.initState, ...opts.initState,
}; };
this.network = opts.network; this._onInfuraIsBlocked = opts.onInfuraIsBlocked;
this._onInfuraIsUnblocked = opts.onInfuraIsUnblocked;
this.store = new ObservableStore(initState); this.store = new ObservableStore(initState);
this.store.setMaxListeners(13); this.store.setMaxListeners(13);
this.openPopup = opts.openPopup; this.openPopup = opts.openPopup;
@ -511,10 +511,11 @@ export default class PreferencesController {
// //
_subscribeToInfuraAvailability() { _subscribeToInfuraAvailability() {
this.network.on(NETWORK_EVENTS.INFURA_IS_BLOCKED, () => { this._onInfuraIsBlocked(() => {
this._setInfuraBlocked(true); this._setInfuraBlocked(true);
}); });
this.network.on(NETWORK_EVENTS.INFURA_IS_UNBLOCKED, () => {
this._onInfuraIsUnblocked(() => {
this._setInfuraBlocked(false); this._setInfuraBlocked(false);
}); });
} }

View File

@ -19,8 +19,10 @@ describe('preferences controller', function () {
const networkControllerProviderConfig = { const networkControllerProviderConfig = {
getAccounts: () => undefined, getAccounts: () => undefined,
}; };
const networkControllerMessenger = new ControllerMessenger();
network = new NetworkController({ network = new NetworkController({
infuraProjectId: 'foo', infuraProjectId: 'foo',
messenger: networkControllerMessenger,
state: { state: {
provider: { provider: {
type: 'mainnet', type: 'mainnet',
@ -50,6 +52,8 @@ describe('preferences controller', function () {
network, network,
provider, provider,
tokenListController, tokenListController,
onInfuraIsBlocked: sinon.spy(),
onInfuraIsUnblocked: sinon.spy(),
}); });
}); });

View File

@ -41,7 +41,6 @@ import fetchEstimatedL1Fee from '../../../ui/helpers/utils/optimism/fetchEstimat
import { Numeric } from '../../../shared/modules/Numeric'; import { Numeric } from '../../../shared/modules/Numeric';
import { EtherDenomination } from '../../../shared/constants/common'; import { EtherDenomination } from '../../../shared/constants/common';
import { NETWORK_EVENTS } from './network';
// The MAX_GAS_LIMIT is a number that is higher than the maximum gas costs we have observed on any aggregator // The MAX_GAS_LIMIT is a number that is higher than the maximum gas costs we have observed on any aggregator
const MAX_GAS_LIMIT = 2500000; const MAX_GAS_LIMIT = 2500000;
@ -114,6 +113,7 @@ export default class SwapsController {
fetchTradesInfo = defaultFetchTradesInfo, fetchTradesInfo = defaultFetchTradesInfo,
getCurrentChainId, getCurrentChainId,
getEIP1559GasFeeEstimates, getEIP1559GasFeeEstimates,
onNetworkDidChange,
}) { }) {
this.store = new ObservableStore({ this.store = new ObservableStore({
swapsState: { ...initialState.swapsState }, swapsState: { ...initialState.swapsState },
@ -137,7 +137,7 @@ export default class SwapsController {
this.ethersProvider = new Web3Provider(provider); this.ethersProvider = new Web3Provider(provider);
this._currentNetwork = networkController.store.getState().network; this._currentNetwork = networkController.store.getState().network;
networkController.on(NETWORK_EVENTS.NETWORK_DID_CHANGE, (network) => { onNetworkDidChange((network) => {
if (network !== 'loading' && network !== this._currentNetwork) { if (network !== 'loading' && network !== this._currentNetwork) {
this._currentNetwork = network; this._currentNetwork = network;
this.ethersProvider = new Web3Provider(provider); this.ethersProvider = new Web3Provider(provider);

View File

@ -14,7 +14,6 @@ import {
FALLBACK_SMART_TRANSACTIONS_MAX_FEE_MULTIPLIER, FALLBACK_SMART_TRANSACTIONS_MAX_FEE_MULTIPLIER,
} from '../../../shared/constants/smartTransactions'; } from '../../../shared/constants/smartTransactions';
import SwapsController, { utils } from './swaps'; import SwapsController, { utils } from './swaps';
import { NETWORK_EVENTS } from './network';
const MOCK_FETCH_PARAMS = { const MOCK_FETCH_PARAMS = {
slippage: 3, slippage: 3,
@ -104,10 +103,6 @@ function getMockNetworkController() {
}; };
}, },
}, },
on: sinon
.stub()
.withArgs(NETWORK_EVENTS.NETWORK_DID_CHANGE)
.callsArgAsync(1),
}; };
} }
@ -162,6 +157,7 @@ describe('SwapsController', function () {
return new SwapsController({ return new SwapsController({
getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT, getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT,
networkController: getMockNetworkController(), networkController: getMockNetworkController(),
onNetworkDidChange: sinon.stub(),
provider, provider,
getProviderConfig: MOCK_GET_PROVIDER_CONFIG, getProviderConfig: MOCK_GET_PROVIDER_CONFIG,
getTokenRatesState: MOCK_TOKEN_RATES_STORE, getTokenRatesState: MOCK_TOKEN_RATES_STORE,
@ -209,9 +205,11 @@ describe('SwapsController', function () {
it('should replace ethers instance when network changes', function () { it('should replace ethers instance when network changes', function () {
const networkController = getMockNetworkController(); const networkController = getMockNetworkController();
const onNetworkDidChange = sinon.stub();
const swapsController = new SwapsController({ const swapsController = new SwapsController({
getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT, getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT,
networkController, networkController,
onNetworkDidChange,
provider, provider,
getProviderConfig: MOCK_GET_PROVIDER_CONFIG, getProviderConfig: MOCK_GET_PROVIDER_CONFIG,
getTokenRatesState: MOCK_TOKEN_RATES_STORE, getTokenRatesState: MOCK_TOKEN_RATES_STORE,
@ -219,9 +217,9 @@ describe('SwapsController', function () {
getCurrentChainId: getCurrentChainIdStub, getCurrentChainId: getCurrentChainIdStub,
}); });
const currentEthersInstance = swapsController.ethersProvider; const currentEthersInstance = swapsController.ethersProvider;
const onNetworkDidChange = networkController.on.getCall(0).args[1]; const changeNetwork = onNetworkDidChange.getCall(0).args[0];
onNetworkDidChange(NETWORK_IDS.MAINNET); changeNetwork(NETWORK_IDS.MAINNET);
const newEthersInstance = swapsController.ethersProvider; const newEthersInstance = swapsController.ethersProvider;
assert.notStrictEqual( assert.notStrictEqual(
@ -233,9 +231,11 @@ describe('SwapsController', function () {
it('should not replace ethers instance when network changes to loading', function () { it('should not replace ethers instance when network changes to loading', function () {
const networkController = getMockNetworkController(); const networkController = getMockNetworkController();
const onNetworkDidChange = sinon.stub();
const swapsController = new SwapsController({ const swapsController = new SwapsController({
getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT, getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT,
networkController, networkController,
onNetworkDidChange,
provider, provider,
getProviderConfig: MOCK_GET_PROVIDER_CONFIG, getProviderConfig: MOCK_GET_PROVIDER_CONFIG,
getTokenRatesState: MOCK_TOKEN_RATES_STORE, getTokenRatesState: MOCK_TOKEN_RATES_STORE,
@ -243,9 +243,9 @@ describe('SwapsController', function () {
getCurrentChainId: getCurrentChainIdStub, getCurrentChainId: getCurrentChainIdStub,
}); });
const currentEthersInstance = swapsController.ethersProvider; const currentEthersInstance = swapsController.ethersProvider;
const onNetworkDidChange = networkController.on.getCall(0).args[1]; const changeNetwork = onNetworkDidChange.getCall(0).args[0];
onNetworkDidChange('loading'); changeNetwork('loading');
const newEthersInstance = swapsController.ethersProvider; const newEthersInstance = swapsController.ethersProvider;
assert.strictEqual( assert.strictEqual(
@ -257,9 +257,11 @@ describe('SwapsController', function () {
it('should not replace ethers instance when network changes to the same network', function () { it('should not replace ethers instance when network changes to the same network', function () {
const networkController = getMockNetworkController(); const networkController = getMockNetworkController();
const onNetworkDidChange = sinon.stub();
const swapsController = new SwapsController({ const swapsController = new SwapsController({
getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT, getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT,
networkController, networkController,
onNetworkDidChange,
provider, provider,
getProviderConfig: MOCK_GET_PROVIDER_CONFIG, getProviderConfig: MOCK_GET_PROVIDER_CONFIG,
getTokenRatesState: MOCK_TOKEN_RATES_STORE, getTokenRatesState: MOCK_TOKEN_RATES_STORE,
@ -267,9 +269,9 @@ describe('SwapsController', function () {
getCurrentChainId: getCurrentChainIdStub, getCurrentChainId: getCurrentChainIdStub,
}); });
const currentEthersInstance = swapsController.ethersProvider; const currentEthersInstance = swapsController.ethersProvider;
const onNetworkDidChange = networkController.on.getCall(0).args[1]; const changeNetwork = onNetworkDidChange.getCall(0).args[0];
onNetworkDidChange(NETWORK_IDS.GOERLI); changeNetwork(NETWORK_IDS.GOERLI);
const newEthersInstance = swapsController.ethersProvider; const newEthersInstance = swapsController.ethersProvider;
assert.strictEqual( assert.strictEqual(

View File

@ -135,7 +135,9 @@ import createTabIdMiddleware from './lib/createTabIdMiddleware';
import createOnboardingMiddleware from './lib/createOnboardingMiddleware'; import createOnboardingMiddleware from './lib/createOnboardingMiddleware';
import { setupMultiplex } from './lib/stream-utils'; import { setupMultiplex } from './lib/stream-utils';
import EnsController from './controllers/ens'; import EnsController from './controllers/ens';
import NetworkController, { NETWORK_EVENTS } from './controllers/network'; import NetworkController, {
NetworkControllerEventTypes,
} from './controllers/network';
import PreferencesController from './controllers/preferences'; import PreferencesController from './controllers/preferences';
import AppStateController from './controllers/app-state'; import AppStateController from './controllers/app-state';
import CachedBalancesController from './controllers/cached-balances'; import CachedBalancesController from './controllers/cached-balances';
@ -249,7 +251,12 @@ export default class MetamaskController extends EventEmitter {
showApprovalRequest: opts.showUserConfirmation, showApprovalRequest: opts.showUserConfirmation,
}); });
const networkControllerMessenger = this.controllerMessenger.getRestricted({
name: 'NetworkController',
allowedEvents: Object.values(NetworkControllerEventTypes),
});
this.networkController = new NetworkController({ this.networkController = new NetworkController({
messenger: networkControllerMessenger,
state: initState.NetworkController, state: initState.NetworkController,
infuraProjectId: opts.infuraProjectId, infuraProjectId: opts.infuraProjectId,
trackMetaMetricsEvent: (...args) => trackMetaMetricsEvent: (...args) =>
@ -292,7 +299,14 @@ export default class MetamaskController extends EventEmitter {
initState: initState.PreferencesController, initState: initState.PreferencesController,
initLangCode: opts.initLangCode, initLangCode: opts.initLangCode,
openPopup: opts.openPopup, openPopup: opts.openPopup,
network: this.networkController, onInfuraIsBlocked: networkControllerMessenger.subscribe.bind(
networkControllerMessenger,
NetworkControllerEventTypes.InfuraIsBlocked,
),
onInfuraIsUnblocked: networkControllerMessenger.subscribe.bind(
networkControllerMessenger,
NetworkControllerEventTypes.InfuraIsUnblocked,
),
tokenListController: this.tokenListController, tokenListController: this.tokenListController,
provider: this.provider, provider: this.provider,
}); });
@ -320,8 +334,7 @@ export default class MetamaskController extends EventEmitter {
onPreferencesStateChange: (listener) => onPreferencesStateChange: (listener) =>
this.preferencesController.store.subscribe(listener), this.preferencesController.store.subscribe(listener),
onNetworkStateChange: (cb) => onNetworkStateChange: (cb) =>
this.networkController.on(NETWORK_EVENTS.NETWORK_DID_CHANGE, () => { this.networkController.store.subscribe((networkState) => {
const networkState = this.networkController.store.getState();
const modifiedNetworkState = { const modifiedNetworkState = {
...networkState, ...networkState,
providerConfig: { providerConfig: {
@ -427,9 +440,9 @@ export default class MetamaskController extends EventEmitter {
this.metaMetricsController = new MetaMetricsController({ this.metaMetricsController = new MetaMetricsController({
segment, segment,
preferencesStore: this.preferencesController.store, preferencesStore: this.preferencesController.store,
onNetworkDidChange: this.networkController.on.bind( onNetworkDidChange: networkControllerMessenger.subscribe.bind(
this.networkController, networkControllerMessenger,
NETWORK_EVENTS.NETWORK_DID_CHANGE, NetworkControllerEventTypes.NetworkDidChange,
), ),
getNetworkIdentifier: () => { getNetworkIdentifier: () => {
const { type, rpcUrl } = const { type, rpcUrl } =
@ -464,9 +477,9 @@ export default class MetamaskController extends EventEmitter {
clientId: SWAPS_CLIENT_ID, clientId: SWAPS_CLIENT_ID,
getProvider: () => getProvider: () =>
this.networkController.getProviderAndBlockTracker().provider, this.networkController.getProviderAndBlockTracker().provider,
onNetworkStateChange: this.networkController.on.bind( onNetworkStateChange: networkControllerMessenger.subscribe.bind(
this.networkController, networkControllerMessenger,
NETWORK_EVENTS.NETWORK_DID_CHANGE, NetworkControllerEventTypes.NetworkDidChange,
), ),
getCurrentNetworkEIP1559Compatibility: getCurrentNetworkEIP1559Compatibility:
this.networkController.getEIP1559Compatibility.bind( this.networkController.getEIP1559Compatibility.bind(
@ -578,9 +591,9 @@ export default class MetamaskController extends EventEmitter {
provider: this.provider, provider: this.provider,
getCurrentChainId: () => getCurrentChainId: () =>
this.networkController.store.getState().provider.chainId, this.networkController.store.getState().provider.chainId,
onNetworkDidChange: this.networkController.on.bind( onNetworkDidChange: networkControllerMessenger.subscribe.bind(
this.networkController, networkControllerMessenger,
NETWORK_EVENTS.NETWORK_DID_CHANGE, NetworkControllerEventTypes.NetworkDidChange,
), ),
}); });
@ -590,9 +603,9 @@ export default class MetamaskController extends EventEmitter {
this.incomingTransactionsController = new IncomingTransactionsController({ this.incomingTransactionsController = new IncomingTransactionsController({
blockTracker: this.blockTracker, blockTracker: this.blockTracker,
onNetworkDidChange: this.networkController.on.bind( onNetworkDidChange: networkControllerMessenger.subscribe.bind(
this.networkController, networkControllerMessenger,
NETWORK_EVENTS.NETWORK_DID_CHANGE, NetworkControllerEventTypes.NetworkDidChange,
), ),
getCurrentChainId: () => getCurrentChainId: () =>
this.networkController.store.getState().provider.chainId, this.networkController.store.getState().provider.chainId,
@ -1041,7 +1054,9 @@ export default class MetamaskController extends EventEmitter {
} }
}); });
this.networkController.on(NETWORK_EVENTS.NETWORK_DID_CHANGE, async () => { networkControllerMessenger.subscribe(
NetworkControllerEventTypes.NetworkDidChange,
async () => {
const { ticker } = this.networkController.store.getState().provider; const { ticker } = this.networkController.store.getState().provider;
try { try {
await this.currencyRateController.setNativeCurrency(ticker); await this.currencyRateController.setNativeCurrency(ticker);
@ -1049,7 +1064,8 @@ export default class MetamaskController extends EventEmitter {
// TODO: Handle failure to get conversion rate more gracefully // TODO: Handle failure to get conversion rate more gracefully
console.error(error); console.error(error);
} }
}); },
);
this.networkController.lookupNetwork(); this.networkController.lookupNetwork();
this.decryptMessageManager = new DecryptMessageManager({ this.decryptMessageManager = new DecryptMessageManager({
@ -1083,6 +1099,10 @@ export default class MetamaskController extends EventEmitter {
this.txController.txGasUtil, this.txController.txGasUtil,
), ),
networkController: this.networkController, networkController: this.networkController,
onNetworkDidChange: networkControllerMessenger.subscribe.bind(
networkControllerMessenger,
NetworkControllerEventTypes.NetworkDidChange,
),
provider: this.provider, provider: this.provider,
getProviderConfig: () => this.networkController.store.getState().provider, getProviderConfig: () => this.networkController.store.getState().provider,
getTokenRatesState: () => this.tokenRatesController.state, getTokenRatesState: () => this.tokenRatesController.state,
@ -1122,17 +1142,23 @@ export default class MetamaskController extends EventEmitter {
); );
// ensure accountTracker updates balances after network change // ensure accountTracker updates balances after network change
this.networkController.on(NETWORK_EVENTS.NETWORK_DID_CHANGE, () => { networkControllerMessenger.subscribe(
NetworkControllerEventTypes.NetworkDidChange,
() => {
this.accountTracker._updateAccounts(); this.accountTracker._updateAccounts();
}); },
);
// clear unapproved transactions and messages when the network will change // clear unapproved transactions and messages when the network will change
this.networkController.on(NETWORK_EVENTS.NETWORK_WILL_CHANGE, () => { networkControllerMessenger.subscribe(
NetworkControllerEventTypes.NetworkWillChange,
() => {
this.txController.txStateManager.clearUnapprovedTxs(); this.txController.txStateManager.clearUnapprovedTxs();
this.encryptionPublicKeyManager.clearUnapproved(); this.encryptionPublicKeyManager.clearUnapproved();
this.decryptMessageManager.clearUnapproved(); this.decryptMessageManager.clearUnapproved();
this.signController.clearUnapproved(); this.signController.clearUnapproved();
}); },
);
this.metamaskMiddleware = createMetamaskMiddleware({ this.metamaskMiddleware = createMetamaskMiddleware({
static: { static: {