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
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 `TESTNET_TICKER_SYMBOLS`
- Add `monad-testnet` to `BUILT_IN_NETWORKS`
- 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
9 changes: 9 additions & 0 deletions packages/controller-utils/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,15 @@ export const TESTNET_TICKER_SYMBOLS = {
LINEA_GOERLI: 'LineaETH',
LINEA_SEPOLIA: 'LineaETH',
MEGAETH_TESTNET: 'MegaETH',
MONAD_TESTNET: 'MON',
};

/**
* Map of all built-in custom networks to their RPC endpoints.
*/
export const BUILT_IN_CUSTOM_NETWORKS_RPC = {
MEGAETH_TESTNET: 'https://carrot.megaeth.com/rpc',
MONAD_TESTNET: 'https://testnet-rpc.monad.xyz',
};

/**
Expand Down Expand Up @@ -112,6 +114,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
1 change: 1 addition & 0 deletions packages/network-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Add optional `getBlockTrackerOptions` argument to NetworkController constructor ([#5702](https://github.com/MetaMask/core/pull/5702))
- Add Monad Testnet as default network ([#5724](https://github.com/MetaMask/core/pull/5724))

### Changed

Expand Down
35 changes: 24 additions & 11 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 @@ -723,26 +723,39 @@ function getDefaultCustomNetworkConfigurationsByChainId(): Record<
Hex,
NetworkConfiguration
> {
const { ticker, rpcPrefs } =
BUILT_IN_NETWORKS[BuiltInNetworkName.MegaETHTestnet];
return {
[ChainId[BuiltInNetworkName.MegaETHTestnet]]: {
return Object.values(CustomNetworkType).reduce<
Record<Hex, NetworkConfiguration>
>((obj, customNetworkType) => {
const chainId = ChainId[customNetworkType];
const { ticker, rpcPrefs } = BUILT_IN_NETWORKS[customNetworkType];
// It converts client id to upper case and replace '-' with '_'
// to match the key in BUILT_IN_CUSTOM_NETWORKS_RPC
// e.g. 'megaeth-testnet' to 'MEGAETH_TESTNET'
// e.g. 'monad-testnet' to 'MONAD_TESTNET'
// TODO: Refactor controller-utils to use the same format as others
const rpcEndpointUrlKey = customNetworkType
.toUpperCase()
.replace('-', '_') as keyof typeof BUILT_IN_CUSTOM_NETWORKS_RPC;

const networkConfiguration: NetworkConfiguration = {
blockExplorerUrls: [rpcPrefs.blockExplorerUrl],
chainId: ChainId[BuiltInNetworkName.MegaETHTestnet],
chainId: ChainId[customNetworkType],
defaultRpcEndpointIndex: 0,
defaultBlockExplorerUrlIndex: 0,
name: NetworkNickname[BuiltInNetworkName.MegaETHTestnet],
name: NetworkNickname[customNetworkType],
nativeCurrency: ticker,
rpcEndpoints: [
{
failoverUrls: [],
networkClientId: BuiltInNetworkName.MegaETHTestnet,
networkClientId: customNetworkType,
type: RpcEndpointType.Custom,
url: BUILT_IN_CUSTOM_NETWORKS_RPC.MEGAETH_TESTNET,
url: BUILT_IN_CUSTOM_NETWORKS_RPC[rpcEndpointUrlKey],
},
],
},
};
};

return { ...obj, [chainId]: networkConfiguration };
}, {});
}

/**
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']
| (typeof ChainId)['monad-testnet'];
Loading