mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Consolidate network stores (#18595)
* Consolidate network stores The network controller used to have multiple different state stores, which were composed together to form the main controller state store. They have been consolidated into a single store. This required few changes because most state access was already being done through the composed store. Fixes https://github.com/MetaMask/metamask-extension/issues/18303 * Add JSDoc comment
This commit is contained in:
parent
3588e6d28e
commit
39dff02a04
@ -1,6 +1,6 @@
|
|||||||
import { strict as assert } from 'assert';
|
import { strict as assert } from 'assert';
|
||||||
import EventEmitter from 'events';
|
import EventEmitter from 'events';
|
||||||
import { ComposedStore, ObservableStore } from '@metamask/obs-store';
|
import { ObservableStore } from '@metamask/obs-store';
|
||||||
import log from 'loglevel';
|
import log from 'loglevel';
|
||||||
import {
|
import {
|
||||||
createSwappableProxy,
|
createSwappableProxy,
|
||||||
@ -379,6 +379,21 @@ function buildDefaultNetworkConfigurationsState(): NetworkConfigurations {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the default state for the network controller.
|
||||||
|
*
|
||||||
|
* @returns The default network controller state.
|
||||||
|
*/
|
||||||
|
function buildDefaultState() {
|
||||||
|
return {
|
||||||
|
provider: buildDefaultProviderConfigState(),
|
||||||
|
networkId: buildDefaultNetworkIdState(),
|
||||||
|
networkStatus: buildDefaultNetworkStatusState(),
|
||||||
|
networkDetails: buildDefaultNetworkDetailsState(),
|
||||||
|
networkConfigurations: buildDefaultNetworkConfigurationsState(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the given argument is a type that our Infura middleware
|
* Returns whether the given argument is a type that our Infura middleware
|
||||||
* recognizes. We can't calculate this inline because the usual type of `type`,
|
* recognizes. We can't calculate this inline because the usual type of `type`,
|
||||||
@ -414,43 +429,17 @@ export class NetworkController extends EventEmitter {
|
|||||||
*/
|
*/
|
||||||
#messenger: NetworkControllerMessenger;
|
#messenger: NetworkControllerMessenger;
|
||||||
|
|
||||||
/**
|
|
||||||
* Observable store containing the provider configuration.
|
|
||||||
*/
|
|
||||||
providerStore: ObservableStore<ProviderConfiguration>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Observable store containing the provider configuration for the previously
|
* Observable store containing the provider configuration for the previously
|
||||||
* configured network.
|
* configured network.
|
||||||
*/
|
*/
|
||||||
#previousProviderConfig: ProviderConfiguration;
|
#previousProviderConfig: ProviderConfiguration;
|
||||||
|
|
||||||
/**
|
|
||||||
* Observable store containing the network ID for the current network or null
|
|
||||||
* if there is no current network.
|
|
||||||
*/
|
|
||||||
networkIdStore: ObservableStore<NetworkIdState>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Observable store for the network status.
|
|
||||||
*/
|
|
||||||
networkStatusStore: ObservableStore<NetworkStatus>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Observable store for details about the network.
|
|
||||||
*/
|
|
||||||
networkDetails: ObservableStore<NetworkDetails>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Observable store for network configurations.
|
|
||||||
*/
|
|
||||||
networkConfigurationsStore: ObservableStore<NetworkConfigurations>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Observable store containing a combination of data from all of the
|
* Observable store containing a combination of data from all of the
|
||||||
* individual stores.
|
* individual stores.
|
||||||
*/
|
*/
|
||||||
store: ComposedStore<NetworkControllerState>;
|
store: ObservableStore<NetworkControllerState>;
|
||||||
|
|
||||||
#provider: SafeEventEmitterProvider | null;
|
#provider: SafeEventEmitterProvider | null;
|
||||||
|
|
||||||
@ -484,35 +473,11 @@ export class NetworkController extends EventEmitter {
|
|||||||
|
|
||||||
this.#messenger = messenger;
|
this.#messenger = messenger;
|
||||||
|
|
||||||
// create stores
|
this.store = new ObservableStore({
|
||||||
this.providerStore = new ObservableStore(
|
...buildDefaultState(),
|
||||||
state.provider || buildDefaultProviderConfigState(),
|
...state,
|
||||||
);
|
|
||||||
this.#previousProviderConfig = this.providerStore.getState();
|
|
||||||
this.networkIdStore = new ObservableStore(buildDefaultNetworkIdState());
|
|
||||||
this.networkStatusStore = new ObservableStore(
|
|
||||||
buildDefaultNetworkStatusState(),
|
|
||||||
);
|
|
||||||
// We need to keep track of a few details about the current network.
|
|
||||||
// Ideally we'd merge this.networkStatusStore with this new store, but doing
|
|
||||||
// so will require a decent sized refactor of how we're accessing network
|
|
||||||
// state. Currently this is only used for detecting EIP-1559 support but can
|
|
||||||
// be extended to track other network details.
|
|
||||||
this.networkDetails = new ObservableStore(
|
|
||||||
state.networkDetails || buildDefaultNetworkDetailsState(),
|
|
||||||
);
|
|
||||||
|
|
||||||
this.networkConfigurationsStore = new ObservableStore(
|
|
||||||
state.networkConfigurations || buildDefaultNetworkConfigurationsState(),
|
|
||||||
);
|
|
||||||
|
|
||||||
this.store = new ComposedStore<NetworkControllerState>({
|
|
||||||
provider: this.providerStore,
|
|
||||||
networkId: this.networkIdStore,
|
|
||||||
networkStatus: this.networkStatusStore,
|
|
||||||
networkDetails: this.networkDetails,
|
|
||||||
networkConfigurations: this.networkConfigurationsStore,
|
|
||||||
});
|
});
|
||||||
|
this.#previousProviderConfig = this.store.getState().provider;
|
||||||
|
|
||||||
// provider and block tracker
|
// provider and block tracker
|
||||||
this.#provider = null;
|
this.#provider = null;
|
||||||
@ -543,7 +508,7 @@ export class NetworkController extends EventEmitter {
|
|||||||
* using the provider to gather details about the network.
|
* using the provider to gather details about the network.
|
||||||
*/
|
*/
|
||||||
async initializeProvider(): Promise<void> {
|
async initializeProvider(): Promise<void> {
|
||||||
const { type, rpcUrl, chainId } = this.providerStore.getState();
|
const { type, rpcUrl, chainId } = this.store.getState().provider;
|
||||||
this.#configureProvider({ type, rpcUrl, chainId });
|
this.#configureProvider({ type, rpcUrl, chainId });
|
||||||
await this.lookupNetwork();
|
await this.lookupNetwork();
|
||||||
}
|
}
|
||||||
@ -569,7 +534,7 @@ export class NetworkController extends EventEmitter {
|
|||||||
* and false otherwise.
|
* and false otherwise.
|
||||||
*/
|
*/
|
||||||
async getEIP1559Compatibility(): Promise<boolean> {
|
async getEIP1559Compatibility(): Promise<boolean> {
|
||||||
const { EIPS } = this.networkDetails.getState();
|
const { EIPS } = this.store.getState().networkDetails;
|
||||||
// NOTE: This isn't necessary anymore because the block cache middleware
|
// NOTE: This isn't necessary anymore because the block cache middleware
|
||||||
// already prevents duplicate requests from taking place
|
// already prevents duplicate requests from taking place
|
||||||
if (EIPS[1559] !== undefined) {
|
if (EIPS[1559] !== undefined) {
|
||||||
@ -585,11 +550,15 @@ export class NetworkController extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const supportsEIP1559 = await this.#determineEIP1559Compatibility(provider);
|
const supportsEIP1559 = await this.#determineEIP1559Compatibility(provider);
|
||||||
this.networkDetails.updateState({
|
const { networkDetails } = this.store.getState();
|
||||||
|
this.store.updateState({
|
||||||
|
networkDetails: {
|
||||||
|
...networkDetails,
|
||||||
EIPS: {
|
EIPS: {
|
||||||
...this.networkDetails.getState().EIPS,
|
...networkDetails.EIPS,
|
||||||
1559: supportsEIP1559,
|
1559: supportsEIP1559,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
return supportsEIP1559;
|
return supportsEIP1559;
|
||||||
}
|
}
|
||||||
@ -606,7 +575,7 @@ export class NetworkController extends EventEmitter {
|
|||||||
* blocking requests, or if the network is not Infura-supported.
|
* blocking requests, or if the network is not Infura-supported.
|
||||||
*/
|
*/
|
||||||
async lookupNetwork(): Promise<void> {
|
async lookupNetwork(): Promise<void> {
|
||||||
const { chainId, type } = this.providerStore.getState();
|
const { chainId, type } = this.store.getState().provider;
|
||||||
const { provider } = this.getProviderAndBlockTracker();
|
const { provider } = this.getProviderAndBlockTracker();
|
||||||
let networkChanged = false;
|
let networkChanged = false;
|
||||||
let networkId: NetworkIdState = null;
|
let networkId: NetworkIdState = null;
|
||||||
@ -692,15 +661,21 @@ export class NetworkController extends EventEmitter {
|
|||||||
listener,
|
listener,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.networkStatusStore.putState(networkStatus);
|
this.store.updateState({
|
||||||
|
networkStatus,
|
||||||
|
});
|
||||||
|
|
||||||
if (networkStatus === NetworkStatus.Available) {
|
if (networkStatus === NetworkStatus.Available) {
|
||||||
this.networkIdStore.putState(networkId);
|
const { networkDetails } = this.store.getState();
|
||||||
this.networkDetails.updateState({
|
this.store.updateState({
|
||||||
|
networkId,
|
||||||
|
networkDetails: {
|
||||||
|
...networkDetails,
|
||||||
EIPS: {
|
EIPS: {
|
||||||
...this.networkDetails.getState().EIPS,
|
...networkDetails.EIPS,
|
||||||
1559: supportsEIP1559,
|
1559: supportsEIP1559,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.#resetNetworkId();
|
this.#resetNetworkId();
|
||||||
@ -731,7 +706,7 @@ export class NetworkController extends EventEmitter {
|
|||||||
*/
|
*/
|
||||||
setActiveNetwork(networkConfigurationId: NetworkConfigurationId): string {
|
setActiveNetwork(networkConfigurationId: NetworkConfigurationId): string {
|
||||||
const targetNetwork =
|
const targetNetwork =
|
||||||
this.networkConfigurationsStore.getState()[networkConfigurationId];
|
this.store.getState().networkConfigurations[networkConfigurationId];
|
||||||
|
|
||||||
if (!targetNetwork) {
|
if (!targetNetwork) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@ -779,7 +754,7 @@ export class NetworkController extends EventEmitter {
|
|||||||
* Re-initializes the provider and block tracker for the current network.
|
* Re-initializes the provider and block tracker for the current network.
|
||||||
*/
|
*/
|
||||||
resetConnection(): void {
|
resetConnection(): void {
|
||||||
this.#setProviderConfig(this.providerStore.getState());
|
this.#setProviderConfig(this.store.getState().provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -789,7 +764,9 @@ export class NetworkController extends EventEmitter {
|
|||||||
*/
|
*/
|
||||||
async rollbackToPreviousProvider() {
|
async rollbackToPreviousProvider() {
|
||||||
const config = this.#previousProviderConfig;
|
const config = this.#previousProviderConfig;
|
||||||
this.providerStore.putState(config);
|
this.store.updateState({
|
||||||
|
provider: config,
|
||||||
|
});
|
||||||
await this.#switchNetwork(config);
|
await this.#switchNetwork(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -843,21 +820,27 @@ export class NetworkController extends EventEmitter {
|
|||||||
* Clears the stored network ID.
|
* Clears the stored network ID.
|
||||||
*/
|
*/
|
||||||
#resetNetworkId(): void {
|
#resetNetworkId(): void {
|
||||||
this.networkIdStore.putState(buildDefaultNetworkIdState());
|
this.store.updateState({
|
||||||
|
networkId: buildDefaultNetworkIdState(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets network status to the default ("unknown").
|
* Resets network status to the default ("unknown").
|
||||||
*/
|
*/
|
||||||
#resetNetworkStatus(): void {
|
#resetNetworkStatus(): void {
|
||||||
this.networkStatusStore.putState(buildDefaultNetworkStatusState());
|
this.store.updateState({
|
||||||
|
networkStatus: buildDefaultNetworkStatusState(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears details previously stored for the network.
|
* Clears details previously stored for the network.
|
||||||
*/
|
*/
|
||||||
#resetNetworkDetails(): void {
|
#resetNetworkDetails(): void {
|
||||||
this.networkDetails.putState(buildDefaultNetworkDetailsState());
|
this.store.updateState({
|
||||||
|
networkDetails: buildDefaultNetworkDetailsState(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -867,8 +850,8 @@ export class NetworkController extends EventEmitter {
|
|||||||
* @param providerConfig - The provider configuration.
|
* @param providerConfig - The provider configuration.
|
||||||
*/
|
*/
|
||||||
async #setProviderConfig(providerConfig: ProviderConfiguration) {
|
async #setProviderConfig(providerConfig: ProviderConfiguration) {
|
||||||
this.#previousProviderConfig = this.providerStore.getState();
|
this.#previousProviderConfig = this.store.getState().provider;
|
||||||
this.providerStore.putState(providerConfig);
|
this.store.updateState({ provider: providerConfig });
|
||||||
await this.#switchNetwork(providerConfig);
|
await this.#switchNetwork(providerConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1105,7 +1088,7 @@ export class NetworkController extends EventEmitter {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const networkConfigurations = this.networkConfigurationsStore.getState();
|
const { networkConfigurations } = this.store.getState();
|
||||||
const newNetworkConfiguration = {
|
const newNetworkConfiguration = {
|
||||||
rpcUrl,
|
rpcUrl,
|
||||||
chainId,
|
chainId,
|
||||||
@ -1120,12 +1103,14 @@ export class NetworkController extends EventEmitter {
|
|||||||
)?.id;
|
)?.id;
|
||||||
|
|
||||||
const newNetworkConfigurationId = oldNetworkConfigurationId || uuid();
|
const newNetworkConfigurationId = oldNetworkConfigurationId || uuid();
|
||||||
this.networkConfigurationsStore.putState({
|
this.store.updateState({
|
||||||
|
networkConfigurations: {
|
||||||
...networkConfigurations,
|
...networkConfigurations,
|
||||||
[newNetworkConfigurationId]: {
|
[newNetworkConfigurationId]: {
|
||||||
...newNetworkConfiguration,
|
...newNetworkConfiguration,
|
||||||
id: newNetworkConfigurationId,
|
id: newNetworkConfigurationId,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!oldNetworkConfigurationId) {
|
if (!oldNetworkConfigurationId) {
|
||||||
@ -1160,9 +1145,11 @@ export class NetworkController extends EventEmitter {
|
|||||||
networkConfigurationId: NetworkConfigurationId,
|
networkConfigurationId: NetworkConfigurationId,
|
||||||
): void {
|
): void {
|
||||||
const networkConfigurations = {
|
const networkConfigurations = {
|
||||||
...this.networkConfigurationsStore.getState(),
|
...this.store.getState().networkConfigurations,
|
||||||
};
|
};
|
||||||
delete networkConfigurations[networkConfigurationId];
|
delete networkConfigurations[networkConfigurationId];
|
||||||
this.networkConfigurationsStore.putState(networkConfigurations);
|
this.store.updateState({
|
||||||
|
networkConfigurations,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -544,7 +544,7 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
messenger: currencyRateMessenger,
|
messenger: currencyRateMessenger,
|
||||||
state: {
|
state: {
|
||||||
...initState.CurrencyController,
|
...initState.CurrencyController,
|
||||||
nativeCurrency: this.networkController.providerStore.getState().ticker,
|
nativeCurrency: this.networkController.store.getState().provider.ticker,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -981,8 +981,16 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
getNetworkId: () => this.networkController.store.getState().networkId,
|
getNetworkId: () => this.networkController.store.getState().networkId,
|
||||||
getNetworkStatus: () =>
|
getNetworkStatus: () =>
|
||||||
this.networkController.store.getState().networkStatus,
|
this.networkController.store.getState().networkStatus,
|
||||||
onNetworkStateChange: (listener) =>
|
onNetworkStateChange: (listener) => {
|
||||||
this.networkController.networkIdStore.subscribe(listener),
|
let previousNetworkId =
|
||||||
|
this.networkController.store.getState().networkId;
|
||||||
|
this.networkController.store.subscribe((state) => {
|
||||||
|
if (previousNetworkId !== state.networkId) {
|
||||||
|
listener();
|
||||||
|
previousNetworkId = state.networkId;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
getCurrentChainId: () =>
|
getCurrentChainId: () =>
|
||||||
this.networkController.store.getState().provider.chainId,
|
this.networkController.store.getState().provider.chainId,
|
||||||
preferencesStore: this.preferencesController.store,
|
preferencesStore: this.preferencesController.store,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user