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

Group network configurations by chain #4286

Merged
merged 68 commits into from
Sep 3, 2024

Conversation

mcmire
Copy link
Contributor

@mcmire mcmire commented May 17, 2024

Explanation

Currently, in the client, it is possible to have multiple networks with different RPC endpoint URLs representing the same chain. This creates a problem because if all we have is a chain ID, we don't know which URL to use for requests.

To solve this, we plan on consolidating the UX on the client side such that each network corresponds to exactly one chain. Users can then select which default RPC URL they'd like to use for requests. This commit implements the controller changes necessary to support this UX.

Here are some more details on the changes here:

  • The concept of a network configuration has been repurposed such that instead of representing an RPC endpoint, it now represents a whole chain.

    • A network configuration may have multiple RPC endpoints, and one of them must be designated as the default.
    • Some RPC endpoints are special in that they represent Infura API URLs; these have the same object shape as "non-Infura" (custom) RPC endpoints, but the Infura project ID is hidden and injected into the RPC URL when creating the network client.
    • There is no longer a 1-to-1 relationship between network configuration and network client; rather, the 1-to-1 relationship exists between RPC endpoint and network client. This means that the ID of the network client which is created for an RPC endpoint is stored on that RPC endpoint instead of the whole network configuration.
  • The networkConfigurations state property has been replaced with networkConfigurationsByChainId. This continues to be an object, but the data inside is organized such that network configurations are identified by chain ID instead of network client ID as they were previously.

  • The methods upsertNetworkConfiguration and removeNetworkConfiguration have been removed. These methods always did more than simply add or remove a network configuration; they also updated the registry of network clients. Instead, these methods have been replaced with addNetwork, updateNetwork, and removeNetwork.

    • addNetwork creates new network clients for each RPC endpoint in the given network configuration.
    • updateNetwork takes a chain ID referring to a network configuration and a draft version of that network configuration, and adds or removes network clients for added or removed RPC
      endpoints.
    • removeNetwork takes a chain ID referring to a network configuration and removes the network clients for each of its RPC endpoints.
  • In addition, due to the changes to network configuration itself, there are new restrictions on networkConfigurationsByChainId, which are validated on initialization and on update. These are:

    • The network controller cannot be initialized with an empty collection of network configurations. This is because there must be a selected network client so that consumers have a provider to use out of the gate.
    • Consequently, the last network configuration cannot be removed.
    • The network configuration that contains a reference to the currently selected network client cannot be removed.
    • The chain ID of a network configuration must match the same chain that it's filed under in networkConfigurationsByChainId.
    • No two network configurations can have the same chain ID.
    • A RPC endpoint in a network configuration must have a well-formed URL.
    • A network configuration cannot have duplicate RPC endpoints.
    • No two RPC endpoints (regardless of network configuration) can have the same URL. Equality is currently determined by normalizing URLs as per RFC 3986 and may include data like request headers in the future.
    • If a network configuration has an Infura RPC endpoint, its chain ID must match the set chain ID of the network configuration.
      • Changing the chain ID of a network configuration is possible, but any existing Infura RPC endpoint must be replaced with the one that matches the new chain ID.
    • No two RPC endpoints (regardless of network configuration) can have the same network client ID.
  • Finally, the trackMetaMetricsEvent option has been removed from the constructor. This was previously used in upsertNetworkConfiguration to create a MetaMetrics event when a new network added, but I've added a new event NetworkController:networkAdded to allow the client to do this on its own accord.

References

Fixes #4189.
Fixes #3793.

Changelog

(Updated in the PR.)

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've highlighted breaking changes using the "BREAKING" category above as appropriate

Copy link

socket-security bot commented May 17, 2024

👍 Dependency issues cleared. Learn more about Socket for GitHub ↗︎

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

View full report↗︎

@mcmire mcmire force-pushed the group-network-configurations-by-chain branch from eb2e882 to 7f4d92b Compare May 20, 2024 23:04
@mcmire mcmire changed the base branch from main to remove-provider-config May 21, 2024 23:10
@mcmire mcmire force-pushed the group-network-configurations-by-chain branch 5 times, most recently from 6b46044 to f208b5b Compare May 22, 2024 03:12
@@ -1,4 +1,38 @@
export * from './NetworkController';
export type {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am explicitly naming these exports because there are some types that I am technically exporting but I don't want to make public (and we are introducing this pattern for each controller anyway).

No types that are exported today should be missing from this list except for the ones noted below.

NetworkControllerOptions,
} from './NetworkController';
export {
getDefaultNetworkControllerState,
Copy link
Contributor Author

@mcmire mcmire May 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getDefaultNetworkControllerState and RpcEndpointType should be the only new exports (in addition, defaultState has been removed).

packages/controller-utils/src/types.ts Show resolved Hide resolved
packages/network-controller/src/NetworkController.ts Outdated Show resolved Hide resolved
@@ -926,79 +949,103 @@ describe('TransactionController Integration', () => {
});
});

describe('when changing rpcUrl of networkClient', () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This describe is inaccurate now, since the RPC URL of a network configuration is no longer being changed, a new RPC endpoint is being added to an existing network instead. And "when a new network is added" already takes care of this.

],
});
const otherGoerliRpcEndpoint =
updatedGoerliNetworkConfiguration.rpcEndpoints.find((rpcEndpoint) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was considering adding a new method to NetworkController to make finding the network client ID associated with a RPC URL easier, but it seems like something we only need in tests, so minimally we could add a new test helper, but this is only happening a few times so it didn't seem worth it to do this.

- The `defaultRpcEndpointUrl` of a network configuration in `networkConfigurationsByChainId` must match an entry in its `rpcEndpoints`.
- `selectedNetworkClientId` must match the `networkClientId` of an RPC endpoint in `networkConfigurationsByChainId`.
- **BREAKING:** Update `getNetworkConfigurationByNetworkClientId` so that when given an Infura network name (that is, a value from `InfuraNetworkType`), it will return a masked version of the RPC endpoint URL for the associated Infura network ([#4268](https://github.com/MetaMask/core/pull/4286))
- If you want the unmasked version, you'll need the `url` property from the network _client_ configuration, which you can get by calling `getNetworkClientById` and then accessing the `configuration` property off of the network client.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an alternative to requiring this step, I could make getNetworkConfigurationByNetworkClientId (or any other methods that return a single network configuration or multiple network configurations) unmask the Infura API URL automatically. Thoughts?

@mcmire mcmire requested a review from a team May 23, 2024 22:32
Copy link
Contributor

@MajorLift MajorLift left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So far these comments are focused on the NetworkController.ts file. I'll continue looking at the rest.

packages/network-controller/src/NetworkController.ts Outdated Show resolved Hide resolved
Comment on lines +301 to 306
export type NetworksMetadata = Record<NetworkClientId, NetworkMetadata>;

Copy link
Contributor

@MajorLift MajorLift Jun 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tangent: This is probably outside of the PR's scope, but looks like NetworkProperties might be a better name for NetworkMetadata, which could be confused with NetworkStateMetadata.

In general, we might want to look into categorizing our data types and properties so that they consistently distinguish between the following categories. TransactionMeta, for example, might benefit from being broken up into a few types:

  • Metadata: Static descriptors (e.g. NetworkClientId, NetworkConfiguration['nativeTokenName'])
  • State: Transient state variables (NetworkMetadata['status'])
  • Properties: Inherent/immutable properties that affect behavior (e.g. NetworkMetadata['EIPS'])
  • Configurations: Assignable/mutable properties that affect behavior (e.g. NetworkConfiguration['rpcEndpoints'])

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea to rename NetworkMetadata. I have never quite liked that name.

Also a good idea to think about how state properties ought to be categorized. Knowing that some state properties are transient and can easily be recreated, and that some properties are expected to be immutable is important.

packages/network-controller/src/NetworkController.ts Outdated Show resolved Hide resolved
packages/network-controller/src/NetworkController.ts Outdated Show resolved Hide resolved
packages/network-controller/src/NetworkController.ts Outdated Show resolved Hide resolved
packages/network-controller/src/NetworkController.ts Outdated Show resolved Hide resolved
packages/network-controller/src/NetworkController.ts Outdated Show resolved Hide resolved
packages/network-controller/src/NetworkController.ts Outdated Show resolved Hide resolved
packages/network-controller/src/NetworkController.ts Outdated Show resolved Hide resolved
@mcmire mcmire force-pushed the remove-provider-config branch 4 times, most recently from cd8a065 to 65fa9a8 Compare June 7, 2024 23:26
Base automatically changed from remove-provider-config to main June 12, 2024 15:27
Currently, in the client, it is possible to have multiple networks with
different RPC endpoint URLs representing the same chain. This creates a
problem because if all we have is a chain ID, we don't know which URL to
use for requests.

To solve this, we plan on consolidating the UX on the client side such
that each network corresponds to exactly one chain. Users can then
select which default RPC URL they'd like to use for requests. This
commit implements the controller changes necessary to support this UX.

Here are some more details on the changes here:

- The concept of a network configuration has been repurposed such that
  instead of representing an RPC endpoint, it now represents a whole
  chain.

  - A network configuration may have multiple RPC endpoints, and
    one of them must be designated as the default.
  - Some RPC endpoints are special in that they represent Infura API
    URLs; these have the same object shape as "non-Infura" (custom) RPC
    endpoints, but the Infura project ID is hidden and injected into the
    RPC URL when creating the network client.
  - There is no longer a 1-to-1 relationship between network
    configuration and network client; rather, the 1-to-1 relationship
    exists between RPC endpoint and network client. This means that the
    ID of the network client which is created for an RPC endpoint
    is stored on that RPC endpoint instead of the whole network
    configuration.

- The `networkConfigurations` state property has been replaced with
  `networkConfigurationsByChainId`. This continues to be an object, but
  the data inside is organized such that network configurations are
  identified by chain ID instead of network client ID as they were
  previously.

- The methods `upsertNetworkConfiguration` and
  `removeNetworkConfiguration` have been removed. These methods always
  did more than simply add or remove a network configuration; they also
  updated the registry of network clients. Instead, these methods have
  been replaced with `addNetwork`, `updateNetwork`, and `removeNetwork`.

  - `addNetwork` creates new network clients for each RPC endpoint in
    the given network configuration.
  - `updateNetwork` takes a chain ID referring to a network
    configuration and a draft version of that network configuration,
    and adds or removes network clients for added or removed RPC
    endpoints.
  - `removeNetwork` takes a chain ID referring to a network
    configuration and removes the network clients for each of its RPC
    endpoints.

- In addition, due to the changes to network configuration itself, there
  are new restrictions on `networkConfigurationsByChainId`, which are
  validated on initialization and on update. These are:

  - The network controller cannot be initialized with an empty
    collection of network configurations. This is because there must be
    a selected network client so that consumers have a provider to use
    out of the gate.
  - Consequently, the last network configuration cannot be removed.
  - The chain ID of a network configuration must match the same chain
    that it's filed under in `networkConfigurationsByChainId`.
  - No two network configurations can have the same chain ID.
  - A RPC endpoint in a network configuration must have a well-formed
    URL.
  - A network configuration cannot have duplicate RPC endpoints.
  - No two RPC endpoints (regardless of network configuration) can have
    the same URL. Equality is currently determined by normalizing URLs
    as per RFC 3986 and may include data like request headers in the
    future.
  - If a network configuration has an Infura RPC endpoint, its chain ID
    must match the set chain ID of the network configuration.
    - Changing the chain ID of a network configuration is possible, but
      any existing Infura RPC endpoint must be replaced with the one
      that matches the new chain ID.
  - No two RPC endpoints (regardless of network configuration) can have
    the same network client ID.

- Finally, the `trackMetaMetricsEvent` option has been removed from the
  constructor. This was previously used in `upsertNetworkConfiguration`
  to create a MetaMetrics event when a new network added, but I've added
  a new event `NetworkController:networkAdded` to allow the client to do
  this on its own accord.
This reverts commit 417ab4ef6f6c2fe6e9dcabb93f0b4f3498d1145b.
@mcmire mcmire force-pushed the group-network-configurations-by-chain branch from 5897b85 to c5f4534 Compare June 12, 2024 19:52
mcmire and others added 2 commits June 13, 2024 10:31
Co-authored-by: Jongsun Suh <jongsun.suh@icloud.com>
BlockTrackerProxy,
ProviderProxy,
AddNetworkFields,
UpdateNetworkFields,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
UpdateNetworkFields,
UpdateNetworkFields,
RpcEndpoint,

RpcEndpoint would be convenient to export


this.#networkConfigurationsByNetworkClientId =
buildNetworkConfigurationsByNetworkClientId(
this.state.networkConfigurationsByChainId,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
this.state.networkConfigurationsByChainId,
state.networkConfigurationsByChainId,

I think this fixes a sneaky bug in the context of adding or updating a network.

The network is added to state.networkConfigurationsByChainId a few lines above. But it's not yet added to this.state.networkConfigurationsByChainId at this point, because we're still inside an update function. Without this fix, the new network does not get passed to buildNetworkConfigurationsByNetworkClientId.

Screenshot 2024-08-26 at 8 35 38 PM

Copy link
Contributor

@bergeron bergeron Aug 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I committed this change in b59ee0c so I can publish a preview version containing it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had to take another pass and fix it this way instead: 02e7ff9

@bergeron
Copy link
Contributor

@metamaskbot publish-preview

Copy link
Contributor

Preview builds have been published. See these instructions for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/accounts-controller": "18.1.0-preview-b59ee0c8",
  "@metamask-previews/address-book-controller": "5.0.0-preview-b59ee0c8",
  "@metamask-previews/announcement-controller": "7.0.0-preview-b59ee0c8",
  "@metamask-previews/approval-controller": "7.0.2-preview-b59ee0c8",
  "@metamask-previews/assets-controllers": "37.0.0-preview-b59ee0c8",
  "@metamask-previews/base-controller": "6.0.3-preview-b59ee0c8",
  "@metamask-previews/build-utils": "3.0.0-preview-b59ee0c8",
  "@metamask-previews/chain-controller": "0.1.1-preview-b59ee0c8",
  "@metamask-previews/composable-controller": "8.0.0-preview-b59ee0c8",
  "@metamask-previews/controller-utils": "11.0.2-preview-b59ee0c8",
  "@metamask-previews/ens-controller": "13.0.1-preview-b59ee0c8",
  "@metamask-previews/eth-json-rpc-provider": "4.1.3-preview-b59ee0c8",
  "@metamask-previews/gas-fee-controller": "19.0.1-preview-b59ee0c8",
  "@metamask-previews/json-rpc-engine": "9.0.2-preview-b59ee0c8",
  "@metamask-previews/json-rpc-middleware-stream": "8.0.2-preview-b59ee0c8",
  "@metamask-previews/keyring-controller": "17.1.2-preview-b59ee0c8",
  "@metamask-previews/logging-controller": "5.0.0-preview-b59ee0c8",
  "@metamask-previews/message-manager": "10.0.2-preview-b59ee0c8",
  "@metamask-previews/name-controller": "8.0.0-preview-b59ee0c8",
  "@metamask-previews/network-controller": "20.2.0-preview-b59ee0c8",
  "@metamask-previews/notification-controller": "6.0.0-preview-b59ee0c8",
  "@metamask-previews/notification-services-controller": "0.2.1-preview-b59ee0c8",
  "@metamask-previews/permission-controller": "11.0.0-preview-b59ee0c8",
  "@metamask-previews/permission-log-controller": "3.0.0-preview-b59ee0c8",
  "@metamask-previews/phishing-controller": "11.0.0-preview-b59ee0c8",
  "@metamask-previews/polling-controller": "9.0.1-preview-b59ee0c8",
  "@metamask-previews/preferences-controller": "13.0.1-preview-b59ee0c8",
  "@metamask-previews/profile-sync-controller": "0.2.1-preview-b59ee0c8",
  "@metamask-previews/queued-request-controller": "4.0.0-preview-b59ee0c8",
  "@metamask-previews/rate-limit-controller": "6.0.0-preview-b59ee0c8",
  "@metamask-previews/selected-network-controller": "17.0.0-preview-b59ee0c8",
  "@metamask-previews/signature-controller": "18.1.0-preview-b59ee0c8",
  "@metamask-previews/transaction-controller": "35.2.0-preview-b59ee0c8",
  "@metamask-previews/user-operation-controller": "14.0.1-preview-b59ee0c8"
}

@bergeron
Copy link
Contributor

bergeron commented Aug 29, 2024

@mikesposito The only remaining thing I can't figure out, is an error Cannot perform 'get' on a proxy that has been revoked on various places that call getNetworkConfigurationByNetworkClientId.

The easiest repro is on thrown by TokenDetectionController when switching chains here:

image

It's possible it was introduced by b59ee0c. Perhaps using the draft state passed to this.update becomes revoked on later reference. But then we'll need another way to fix #4286 (comment)

Edit: I think I've fixed it in 02e7ff9 by performing buildNetworkConfigurationsByNetworkClientId after the call to this.update instead of inside it. This satisfies both criteria. That we're including the added/updated/removed network in the call to build...(), but it's also not revoked due to being a reference to draft state.

@bergeron
Copy link
Contributor

@metamaskbot publish-preview

Copy link
Contributor

Preview builds have been published. See these instructions for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/accounts-controller": "18.1.0-preview-02e7ff99",
  "@metamask-previews/address-book-controller": "5.0.0-preview-02e7ff99",
  "@metamask-previews/announcement-controller": "7.0.0-preview-02e7ff99",
  "@metamask-previews/approval-controller": "7.0.2-preview-02e7ff99",
  "@metamask-previews/assets-controllers": "37.0.0-preview-02e7ff99",
  "@metamask-previews/base-controller": "6.0.3-preview-02e7ff99",
  "@metamask-previews/build-utils": "3.0.0-preview-02e7ff99",
  "@metamask-previews/chain-controller": "0.1.1-preview-02e7ff99",
  "@metamask-previews/composable-controller": "8.0.0-preview-02e7ff99",
  "@metamask-previews/controller-utils": "11.0.2-preview-02e7ff99",
  "@metamask-previews/ens-controller": "13.0.1-preview-02e7ff99",
  "@metamask-previews/eth-json-rpc-provider": "4.1.3-preview-02e7ff99",
  "@metamask-previews/gas-fee-controller": "19.0.1-preview-02e7ff99",
  "@metamask-previews/json-rpc-engine": "9.0.2-preview-02e7ff99",
  "@metamask-previews/json-rpc-middleware-stream": "8.0.2-preview-02e7ff99",
  "@metamask-previews/keyring-controller": "17.1.2-preview-02e7ff99",
  "@metamask-previews/logging-controller": "5.0.0-preview-02e7ff99",
  "@metamask-previews/message-manager": "10.0.2-preview-02e7ff99",
  "@metamask-previews/name-controller": "8.0.0-preview-02e7ff99",
  "@metamask-previews/network-controller": "20.2.0-preview-02e7ff99",
  "@metamask-previews/notification-controller": "6.0.0-preview-02e7ff99",
  "@metamask-previews/notification-services-controller": "0.2.1-preview-02e7ff99",
  "@metamask-previews/permission-controller": "11.0.0-preview-02e7ff99",
  "@metamask-previews/permission-log-controller": "3.0.0-preview-02e7ff99",
  "@metamask-previews/phishing-controller": "11.0.0-preview-02e7ff99",
  "@metamask-previews/polling-controller": "9.0.1-preview-02e7ff99",
  "@metamask-previews/preferences-controller": "13.0.1-preview-02e7ff99",
  "@metamask-previews/profile-sync-controller": "0.2.1-preview-02e7ff99",
  "@metamask-previews/queued-request-controller": "4.0.0-preview-02e7ff99",
  "@metamask-previews/rate-limit-controller": "6.0.0-preview-02e7ff99",
  "@metamask-previews/selected-network-controller": "17.0.0-preview-02e7ff99",
  "@metamask-previews/signature-controller": "18.1.0-preview-02e7ff99",
  "@metamask-previews/transaction-controller": "35.2.0-preview-02e7ff99",
  "@metamask-previews/user-operation-controller": "14.0.1-preview-02e7ff99"
}

@mikesposito
Copy link
Member

Edit: I think I've fixed it in 02e7ff9 by performing buildNetworkConfigurationsByNetworkClientId after the call to this.update instead of inside it. This satisfies both criteria. That we're including the added/updated/removed network in the call to build...(), but it's also not revoked due to being a reference to draft state.

Thanks for taking care of that, the fix makes sense.

@mikesposito
Copy link
Member

@bergeron CI fixed here: #4638

## Explanation

<!--
Thanks for your contribution! Take a moment to answer these questions so
that reviewers have the information they need to properly understand
your changes:

* What is the current state of things and why does it need to change?
* What is the solution your changes offer and how does it work?
* Are there any changes whose purpose might not obvious to those
unfamiliar with the domain?
* If your primary goal was to update one package but you found you had
to update another one along the way, why did you do so?
* If you had to upgrade a dependency, why did you do so?
-->

Currently, `SelectedNetworkController` subscribes to the
`NetworkController:stateChange` event to make sure that network client
ids associated with managed domains stay valid. Though, we are currently
checking on the specific immer patch applied to the NetworkController
state: this means that based on how the state draft was manipulated on
the origin controller, we may or may not capture the change and react to
it.

To fix it, now `SelectedNetworkController` will look at the actual
content of the updated state, instead of relying on immer patches. To
reduce the amount of event instances received by the controller, a
selector is applied to the subscription, filtering out irrelevant
instances.

## References

<!--
Are there any issues that this pull request is tied to? Are there other
links that reviewers should consult to understand these changes better?

For example:

* Fixes #12345
* Related to #67890
-->

## Changelog

<!--
If you're making any consumer-facing changes, list those changes here as
if you were updating a changelog, using the template below as a guide.

(CATEGORY is one of BREAKING, ADDED, CHANGED, DEPRECATED, REMOVED, or
FIXED. For security-related issues, follow the Security Advisory
process.)

Please take care to name the exact pieces of the API you've added or
changed (e.g. types, interfaces, functions, or methods).

If there are any breaking changes, make sure to offer a solution for
consumers to follow once they upgrade to the changes.

Finally, if you're only making changes to development scripts or tests,
you may replace the template below with "None".
-->

### `@metamask/network-controller`

- **ADDED**: Added `getNetworkConfigurations`,
`getAvailableNetworkClientIds` and `selectAvailableNetworkClientIds`
selectors
  - These new selectors can be applied to messenger event subscriptions

### `@metamask/selected-network-controller`

No consumer-faced changes

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [ ] I've highlighted breaking changes using the "BREAKING" category
above as appropriate
Copy link
Member

@mikesposito mikesposito left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes from @mcmire and @bergeron look great.

Since I made some changes as well, it would be nice to have an additional approval before merging this

Comment on lines +195 to +209
(availableNetworkClientIds) => {
// if a network is updated or removed, update the networkClientId for all domains
// that were using it to the selected network client id
const { selectedNetworkClientId } = this.messagingSystem.call(
'NetworkController:getState',
);
Object.entries(this.state.domains).forEach(
([domain, networkClientIdForDomain]) => {
if (!availableNetworkClientIds.includes(networkClientIdForDomain)) {
this.setNetworkClientIdForDomain(domain, selectedNetworkClientId);
}
},
);
},
selectAvailableNetworkClientIds,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See: #4638

Copy link

socket-security bot commented Sep 3, 2024

New dependencies detected. Learn more about Socket for GitHub ↗︎

Package New capabilities Transitives Size Publisher
npm/reselect@5.1.1 None 0 646 kB acemarke

View full report↗︎

@bergeron
Copy link
Contributor

bergeron commented Sep 3, 2024

This is ready to go on extension. Mobile is still in progress, but extension needs to go first

@bergeron bergeron merged commit 442a300 into main Sep 3, 2024
116 of 117 checks passed
@bergeron bergeron deleted the group-network-configurations-by-chain branch September 3, 2024 15:40
bergeron added a commit to MetaMask/metamask-extension that referenced this pull request Sep 20, 2024
## **Description**

This PR upgrades the network controller, and enables a new UI for adding
and editing networks.

The network controller changes are described in full in
MetaMask/core#4286

In short, there's now a single network per chain id. Multiple RPC
endpoints for a chain are now represented as an array under the single
network configuration, instead of being separate networks. Each network
has some RPC endpoint chosen as the default. Also the built in Infura
networks are now represented in state, where they were not before.

A migration is added to transform the network controller state to this
new format.

For the UI, networks are now added, edited, and deleted directly in the
network list. Networks are no longer edited via the settings page.

Users with multiple RPC endpoints per chain are shown a modal upon
upgrade, allowing them to select a different endpoint as the default.

The UI for `wallet_addEthereumChain` is changed, to message that users
may be adding an additional endpoint to an existing network, rather than
adding a new network.

This PR contains both the controller upgrade and UI, because it's not
possible to perfectly recrate the old UI with the new state or vice
versa.

To minimize changes, some selectors are shimmed to return equivalent
data. This includes `getProviderConfig` and `getCurrentNetwork`.

Other selectors have been removed in favor of selecting the new state,
as there was no behavior that satisfied every caller. This includes
`getNetworkConfigurations` and its dependents like `getNonTestNetworks`
`getTestNetworks`. Places listing networks now go through the new
`getNetworkConfigurationsByChainId`.


[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/26433?quickstart=1)

## **Related issues**

Fixes:

## **Manual testing steps**


1. Upgrade from an older build with custom networks
2. Verify they all still appear in the network dropdown
- Verify multiple endpoints for the same chain have been merged into 1
network with multiple RPC endponits
3. Click the network dropdown
4. Try:
   - Adding popular networks
   - Adding a custom network
   - Editing an existing network
   - Deleting an existing network
5. Try adding a new network via a dapp
6. Try adding a new RPC endpoint to an existing network via a dapp

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**



https://github.com/user-attachments/assets/dd215f30-9c83-4490-83c3-8aaf39412763



## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

---------

Co-authored-by: salimtb <salim.toubal@outlook.com>
Co-authored-by: MetaMask Bot <metamaskbot@users.noreply.github.com>
Co-authored-by: David Walsh <davidwalsh83@gmail.com>
Co-authored-by: Howard Braham <howrad@gmail.com>
Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
8 participants