MetaMask / MetaMask/core

Network Controller: Multi Networks Enablement feature

Open
#5,737 4 comments 0 reactions 1 assignee Claimed by @gambinish View on GitHub
Dominant language
TypeScript
Stars
413
Forks
308
Avg merge
1d 4h
Merged PRs (30d)
253

Description

## Overview

Designs: [Figma Link](https://www.figma.com/design/CvBEDNwQqfW4Wbil40Bhr1/Substitute-Global-Network-selector?node-id=740-38494&t=nHAwq1kuxmf7OOcB-4)

As we scale to support more networks, we're transitioning toward a **native multichain experience** — removing the Global Network Selector (GNS) and allowing users to view assets across multiple networks. While GNS will be deprecated, we will retain the concept of a **selected network** for dApp connectivity and transactions.

This feature introduces the concept of **enabled networks**, separating networks that are *added* from those that are *enabled* (visible in the UI and actively polling for token data).

Currently, users can either:
- Enable all **popular networks** (indexed via our API), or
- View a **single custom network** (polled via direct RPC).

[Asset polling](https://github.com/MetaMask/metamask-extension/blob/7ac581ced7f5f608f7aa7c0a95d866481b192092/ui/contexts/assetPolling.tsx#L11) is based on an array of enabled `chainIds` that control which networks to fetch data from. Indexed networks use our API for balance/metadata retrieval; unsupported networks fall back to RPC. This fallback doesn't scale, which is why only one custom network is supported today.

In **v1** of Network Enablement, users will be able to:
- Multi-select from **popular networks**, or
- Enable a **single custom/test network**.

> ⚠️ Custom networks are limited to one in v1 for performance reasons, but this design will support enabling more in the future. This feature also does not affect `selectedNetworkClientId`, which remains the source of truth for dApp connectivity and network-specific transactions.

### Goals
- **Performance**: Avoid unnecessary polling across many chains.
- **Native multichain UX**: Let users customize how they view assets across networks.
- **Separation of concerns**: Distinguish between networks that are added vs. enabled.
- **Future-readiness**: Support enabling combinations of popular and custom networks.

---

## 🧩 Controller Integration

We’ll extend `NetworkOrderController` to manage both network ordering and enablement.

### Why this controller?

1. Avoids changes to `NetworkController`, reducing risk to dApp connectivity
2. Already listens to `NetworkController:stateChange`, simplifying sync
3. Centralizes logic outside `PreferencesController`, which differs across platforms
4. Prepares `NetworkOrderController` for use on Mobile

### 🔧 Changes to [NetworkOrderController](https://github.com/MetaMask/metamask-extension/blob/main/app/scripts/controllers/network-order.ts)

We will extend the `NetworkOrderControllerState` type to include a mapping `enabledNetworkMap`:

```ts
type NetworkOrderControllerState = {
orderedNetworkList: CaipChainId[];
enabledNetworkMap: Record;
};
```

**Key advantages:**

- O(1) lookup for enabled networks
- Clean separation of enablement vs. ordering

Introduce two public methods:

```ts
setSingleEnabledNetwork(chainId: CaipChainId): void;
setMultiEnabledNetworks(chainIds: CaipChainId[]): void;
```
- `setSingleEnabledNetwork`: Enables only the specified network and disables all others.
- `setMultiEnabledNetworks`: Enables the provided networks and disables others

The controller will accept and persist any combination of `enabled` networks passed to it. It is the responsibility of the UI to determine which networks can be toggled based on category of network, selection mode, and/or platform-specific rules (we may want to have different limits on mobile vs extension)

### 🎛️ UI Changes (Network Filter)

The current UI writes enabled network state to `PreferencesController.tokenNetworkFilter`.

With Network Enablement:
- Enabled state will come from `NetworkOrderController.enabledNetworkMap`
- `setEnabledNetworks` will be used for updates
- The UI will enforce selection rules (multi vs. single)

---

### 🧼 Cleanup

- Remove all reads/writes to `tokenNetworkFilter`
- Deprecate `PreferencesController.tokenNetworkFilter`
- Add a migration to clear it from persisted state

## ⚙️ Summary of Actions

| Change | Status |
|----------------------------------------|----------------|
| Get design feedback | 🔲 To implement |
| Extend `NetworkOrderController` | 🔲 To implement |
| Migrate `NetworkOrderController` from extension into core, publish package | 🔲 To implement |
| Integrate `NetworkOrderController` in extension | 🔲 To implement |
| Build new extension UI, based on design feedback | 🔲 To implement |
| Integrate `NetworkOrderController` in mobile | 🔲 To implement |
| Build new extension Mobile UI | 🔲 To implement |

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.