Skip to content

feat: add Monad Testnet to network-controller and controller-utils #5724

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

Merged
merged 14 commits into from
May 6, 2025
Merged
11 changes: 11 additions & 0 deletions packages/controller-utils/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Add Monad Testnet to various constants, enums, and types ([#5724](https://github.com/MetaMask/core/pull/5724))
- Add `monad-testnet` to `BUILT_IN_NETWORKS`
- Add `monad-testnet` and `megaeth-testnet` to `BUILT_IN_CUSTOM_NETWORKS_RPC`
- Add `MonadTestnet` to `BuiltInNetworkName` enum
- Add `monad-testnet` to `ChainId` type
- Add `MonadTestnet` to `NetworksTicker` enum
- Add `MonadTestnet` to `BlockExplorerUrl` quasi-enum
- Add `MonadTestnet` to `NetworkNickname` quasi-enum

## [11.7.0]

### Added
Expand Down
12 changes: 12 additions & 0 deletions packages/controller-utils/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,12 @@ export const TESTNET_TICKER_SYMBOLS = {
* Map of all built-in custom networks to their RPC endpoints.
*/
export const BUILT_IN_CUSTOM_NETWORKS_RPC = {
/**
* @deprecated Please use `megaeth-testnet` instead.
*/
MEGAETH_TESTNET: 'https://carrot.megaeth.com/rpc',
'megaeth-testnet': 'https://carrot.megaeth.com/rpc',
'monad-testnet': 'https://testnet-rpc.monad.xyz',
};

/**
Expand Down Expand Up @@ -112,6 +117,13 @@ export const BUILT_IN_NETWORKS = {
blockExplorerUrl: BlockExplorerUrl['megaeth-testnet'],
},
},
[NetworkType['monad-testnet']]: {
chainId: ChainId['monad-testnet'],
ticker: NetworksTicker['monad-testnet'],
rpcPrefs: {
blockExplorerUrl: BlockExplorerUrl['monad-testnet'],
},
},
[NetworkType.rpc]: {
chainId: undefined,
blockExplorerUrl: undefined,
Expand Down
6 changes: 6 additions & 0 deletions packages/controller-utils/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export type InfuraNetworkType =
*/
export const CustomNetworkType = {
'megaeth-testnet': 'megaeth-testnet',
'monad-testnet': 'monad-testnet',
} as const;
export type CustomNetworkType =
(typeof CustomNetworkType)[keyof typeof CustomNetworkType];
Expand Down Expand Up @@ -76,6 +77,7 @@ export enum BuiltInNetworkName {
LineaMainnet = 'linea-mainnet',
Aurora = 'aurora',
MegaETHTestnet = 'megaeth-testnet',
MonadTestnet = 'monad-testnet',
}

/**
Expand All @@ -92,6 +94,7 @@ export const ChainId = {
[BuiltInNetworkName.LineaSepolia]: '0xe705', // toHex(59141)
[BuiltInNetworkName.LineaMainnet]: '0xe708', // toHex(59144)
[BuiltInNetworkName.MegaETHTestnet]: '0x18c6', // toHex(6342)
[BuiltInNetworkName.MonadTestnet]: '0x279f', // toHex(10143)
} as const;
export type ChainId = (typeof ChainId)[keyof typeof ChainId];

Expand All @@ -109,6 +112,7 @@ export enum NetworksTicker {
'linea-sepolia' = 'LineaETH',
'linea-mainnet' = 'ETH',
'megaeth-testnet' = 'MegaETH',
'monad-testnet' = 'MON',
// TODO: Either fix this lint violation or explain why it's necessary to ignore.
// eslint-disable-next-line @typescript-eslint/naming-convention
rpc = '',
Expand All @@ -122,6 +126,7 @@ export const BlockExplorerUrl = {
[BuiltInNetworkName.LineaSepolia]: 'https://sepolia.lineascan.build',
[BuiltInNetworkName.LineaMainnet]: 'https://lineascan.build',
[BuiltInNetworkName.MegaETHTestnet]: 'https://megaexplorer.xyz',
[BuiltInNetworkName.MonadTestnet]: 'https://testnet.monadexplorer.com',
} as const satisfies Record<BuiltInNetworkType, string>;
export type BlockExplorerUrl =
(typeof BlockExplorerUrl)[keyof typeof BlockExplorerUrl];
Expand All @@ -134,6 +139,7 @@ export const NetworkNickname = {
[BuiltInNetworkName.LineaSepolia]: 'Linea Sepolia',
[BuiltInNetworkName.LineaMainnet]: 'Linea',
[BuiltInNetworkName.MegaETHTestnet]: 'Mega Testnet',
[BuiltInNetworkName.MonadTestnet]: 'Monad Testnet',
} as const satisfies Record<BuiltInNetworkType, string>;
export type NetworkNickname =
(typeof NetworkNickname)[keyof typeof NetworkNickname];
Expand Down
4 changes: 4 additions & 0 deletions packages/network-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Add Monad Testnet as default network ([#5724](https://github.com/MetaMask/core/pull/5724))

## [23.3.0]

### Added
Expand Down
59 changes: 40 additions & 19 deletions packages/network-controller/src/NetworkController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { BaseController } from '@metamask/base-controller';
import type { Partialize } from '@metamask/controller-utils';
import {
InfuraNetworkType,
CustomNetworkType,
NetworkType,
isSafeChainId,
isInfuraNetworkType,
Expand All @@ -15,7 +16,6 @@ import {
NetworkNickname,
BUILT_IN_CUSTOM_NETWORKS_RPC,
BUILT_IN_NETWORKS,
BuiltInNetworkName,
} from '@metamask/controller-utils';
import type { PollingBlockTrackerOptions } from '@metamask/eth-block-tracker';
import EthQuery from '@metamask/eth-query';
Expand Down Expand Up @@ -728,25 +728,46 @@ function getDefaultCustomNetworkConfigurationsByChainId(): Record<
Hex,
NetworkConfiguration
> {
const { ticker, rpcPrefs } =
BUILT_IN_NETWORKS[BuiltInNetworkName.MegaETHTestnet];
// Create the `networkConfigurationsByChainId` objects explicitly,
// Because it is not always guaranteed that the custom networks are included in the
// default networks.
return {
[ChainId[BuiltInNetworkName.MegaETHTestnet]]: {
blockExplorerUrls: [rpcPrefs.blockExplorerUrl],
chainId: ChainId[BuiltInNetworkName.MegaETHTestnet],
defaultRpcEndpointIndex: 0,
defaultBlockExplorerUrlIndex: 0,
name: NetworkNickname[BuiltInNetworkName.MegaETHTestnet],
nativeCurrency: ticker,
rpcEndpoints: [
{
failoverUrls: [],
networkClientId: BuiltInNetworkName.MegaETHTestnet,
type: RpcEndpointType.Custom,
url: BUILT_IN_CUSTOM_NETWORKS_RPC.MEGAETH_TESTNET,
},
],
},
[ChainId['megaeth-testnet']]: getCustomNetworkConfiguration(
CustomNetworkType['megaeth-testnet'],
),
[ChainId['monad-testnet']]: getCustomNetworkConfiguration(
CustomNetworkType['monad-testnet'],
),
};
}

/**
* Constructs a `NetworkConfiguration` object by `CustomNetworkType`.
*
* @param customNetworkType - The type of the custom network.
* @returns The `NetworkConfiguration` object.
*/
function getCustomNetworkConfiguration(
customNetworkType: CustomNetworkType,
): NetworkConfiguration {
const { ticker, rpcPrefs } = BUILT_IN_NETWORKS[customNetworkType];
const rpcEndpointUrl = BUILT_IN_CUSTOM_NETWORKS_RPC[customNetworkType];

return {
blockExplorerUrls: [rpcPrefs.blockExplorerUrl],
chainId: ChainId[customNetworkType],
defaultRpcEndpointIndex: 0,
defaultBlockExplorerUrlIndex: 0,
name: NetworkNickname[customNetworkType],
nativeCurrency: ticker,
rpcEndpoints: [
{
failoverUrls: [],
networkClientId: customNetworkType,
type: RpcEndpointType.Custom,
url: rpcEndpointUrl,
},
],
};
}

Expand Down
6 changes: 4 additions & 2 deletions packages/network-controller/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ChainId, InfuraNetworkType } from '@metamask/controller-utils';
import type { InfuraNetworkType, ChainId } from '@metamask/controller-utils';
import type { BlockTracker as BaseBlockTracker } from '@metamask/eth-block-tracker';
import type { SafeEventEmitterProvider } from '@metamask/eth-json-rpc-provider';
import type { Hex } from '@metamask/utils';
Expand Down Expand Up @@ -57,4 +57,6 @@ export type NetworkClientConfiguration =
/**
* The Chain ID representing the additional networks to be included as default.
*/
export type AdditionalDefaultNetwork = (typeof ChainId)['megaeth-testnet'];
export type AdditionalDefaultNetwork = (typeof ChainId)[
| 'megaeth-testnet'
| 'monad-testnet'];
Loading