Skip to content

Commit d058e75

Browse files
chore: migrate testnet network MegaETH Testnet v1 to MegaETH Testnet v2 (#38426)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** This PR migrates the MegaETH Testnet from v1 (chain ID 0x18c6 / 6342) to v2 (chain ID 0x18c7 / 6343) across the MetaMask extension codebase. The migration updates the network's RPC endpoint from https://carrot.megaeth.com/rpc to https://timothy.megaeth.com/rpc, the block explorer from https://megaexplorer.xyz to https://megaeth-testnet-v2.blockscout.com, and standardizes the network name to "MegaETH Testnet". The changes include a state migration script that removes the v1 configuration and adds v2, along with updates to all network constants, test fixtures, and e2e tests. Adds migration to transition user state from MegaETH Testnet v1 to v2 Updates network constants to include both v1 (for backward compatibility) and v2 configurations Updates all test fixtures and e2e tests to use the new v2 network configuration <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/38426?quickstart=1) ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: Added new network client `megaeth-testnet-v2` CHANGELOG entry: Removed network client `megaeth-testnet` ## **Related issues** Fixes: ## **Manual testing steps** 1. Go to network list 2. Select MegaETH testnet 3. the network should be able to select 4. click `edit` on the network menu of MegaETH testnet 5. we should see the information to be the same as the screen capture ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <img width="300" alt="image" src="https://github.com/user-attachments/assets/b0f369e0-af98-40d9-bc1d-d43e7bd9ad6d" /> <!-- [screenshots/recordings] --> ### **After** <img width="300" alt="image" src="https://github.com/user-attachments/assets/5fe1d6fa-f68f-47dc-bd85-7b82d7ece216" /> <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.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. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Migrates MegaETH Testnet to chain 0x18c7 with new RPC/explorer, adds migration 184 to replace v1 config and switch selection, and updates constants, tests, fixtures, and privacy lists. > > - **Migration 184**: > - Adds `MegaETH Testnet v2` config (`chainId` `0x18c7`, RPC `https://timothy.megaeth.com/rpc`, explorer `https://megaeth-testnet-v2.blockscout.com`). > - Removes `MegaETH Testnet v1` (`0x18c6`) from configs and enabled map; switches `selectedNetworkClientId` to `mainnet` if it referenced v1. > - **Controller Init**: > - Drops `megaeth-testnet` from `ADDITIONAL_DEFAULT_NETWORKS`; temporarily injects `0x18c7` config into initial state. > - **Network Constants**: > - Adds `MEGAETH_TESTNET_V2` across `CHAIN_IDS`, names, images, RPC map, currency maps, display names, test network lists, and ethers mapping; defines `MEGAETH_TESTNET_V2_RPC_URL`. > - **Tests/Fixtures**: > - Updates fixtures, snapshots, and mocks to `megaeth-testnet-v2` IDs/URLs; adjusts unit/e2e tests (including EIP-7702 networks ordering); comments out MegaETH v2 network-connection test temporarily. > - **Privacy/Mocks**: > - Adds `timothy.megaeth.com` to privacy snapshot and e2e blocklist; updates `chainid.network` mock for v2. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 9d051fc. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent ed717f4 commit d058e75

File tree

16 files changed

+613
-51
lines changed

16 files changed

+613
-51
lines changed

app/scripts/controller-init/network-controller-init.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,21 +127,21 @@ describe('NetworkControllerInit', () => {
127127
},
128128
],
129129
},
130-
"0x18c6": {
130+
"0x18c7": {
131131
"blockExplorerUrls": [
132-
"https://megaexplorer.xyz",
132+
"https://megaeth-testnet-v2.blockscout.com",
133133
],
134-
"chainId": "0x18c6",
134+
"chainId": "0x18c7",
135135
"defaultBlockExplorerUrlIndex": 0,
136136
"defaultRpcEndpointIndex": 0,
137-
"name": "Mega Testnet",
137+
"name": "MegaETH Testnet",
138138
"nativeCurrency": "MegaETH",
139139
"rpcEndpoints": [
140140
{
141141
"failoverUrls": [],
142-
"networkClientId": "megaeth-testnet",
142+
"networkClientId": "megaeth-testnet-v2",
143143
"type": "custom",
144-
"url": "https://carrot.megaeth.com/rpc",
144+
"url": "https://timothy.megaeth.com/rpc",
145145
},
146146
],
147147
},

app/scripts/controller-init/network-controller-init.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,7 @@ import {
2828
NetworkControllerMessenger,
2929
} from './messengers';
3030

31-
export const ADDITIONAL_DEFAULT_NETWORKS = [
32-
ChainId['megaeth-testnet'],
33-
ChainId['monad-testnet'],
34-
];
31+
export const ADDITIONAL_DEFAULT_NETWORKS = [ChainId['monad-testnet']];
3532

3633
function getInitialState(initialState?: Partial<NetworkController['state']>) {
3734
let initialNetworkControllerState = initialState;
@@ -44,6 +41,25 @@ function getInitialState(initialState?: Partial<NetworkController['state']>) {
4441
const networks =
4542
initialNetworkControllerState.networkConfigurationsByChainId ?? {};
4643

44+
// TODO: Remove this once the MegaETH Testnet v2 is released from the controller utils
45+
networks['0x18c7'] = {
46+
chainId: '0x18c7', // 6343
47+
name: 'MegaETH Testnet',
48+
nativeCurrency: 'MegaETH',
49+
blockExplorerUrls: ['https://megaeth-testnet-v2.blockscout.com'],
50+
defaultRpcEndpointIndex: 0,
51+
defaultBlockExplorerUrlIndex: 0,
52+
rpcEndpoints: [
53+
{
54+
// to align the same networkClientId from the controller utils
55+
networkClientId: 'megaeth-testnet-v2',
56+
url: 'https://timothy.megaeth.com/rpc',
57+
type: RpcEndpointType.Custom,
58+
failoverUrls: [],
59+
},
60+
],
61+
};
62+
4763
// TODO: Consider changing `getDefaultNetworkControllerState` on the
4864
// controller side to include some of these tweaks.
4965

app/scripts/metamask-controller.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3850,7 +3850,7 @@ describe('MetaMaskController', () => {
38503850
const networksWithoutFailoverUrls = [
38513851
CHAIN_IDS.SEPOLIA,
38523852
CHAIN_IDS.LINEA_SEPOLIA,
3853-
CHAIN_IDS.MEGAETH_TESTNET,
3853+
'0x18c7', // MegaETH Testnet
38543854
'0x279f', // Monad Testnet
38553855
'0x539', // Localhost
38563856
];

app/scripts/migrations/184.test.ts

Lines changed: 287 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
1+
import { RpcEndpointType } from '@metamask/network-controller';
2+
import { cloneDeep } from 'lodash';
3+
import { jest } from '@jest/globals';
4+
import { KnownCaipNamespace } from '@metamask/utils';
5+
import {
6+
migrate,
7+
version,
8+
MEGAETH_TESTNET_V2_CONFIG,
9+
MEGAETH_TESTNET_V1_CHAIN_ID,
10+
type VersionedData,
11+
} from './184';
12+
13+
const VERSION = version;
14+
const oldVersion = VERSION - 1;
15+
16+
describe(`migration #${VERSION}`, () => {
17+
let mockedCaptureException: jest.Mock;
18+
beforeEach(() => {
19+
mockedCaptureException = jest.fn();
20+
global.sentry = { captureException: mockedCaptureException };
21+
});
22+
23+
afterEach(() => {
24+
global.sentry = undefined;
25+
});
26+
27+
it('updates the version metadata', async () => {
28+
const oldStorage = {
29+
meta: { version: oldVersion },
30+
data: {
31+
NetworkController: {
32+
networkConfigurationsByChainId: {},
33+
},
34+
},
35+
};
36+
37+
const newStorage = await migrate(oldStorage);
38+
39+
expect(newStorage.meta).toStrictEqual({ version: VERSION });
40+
});
41+
42+
const invalidStates = [
43+
{
44+
state: {
45+
meta: { version: VERSION },
46+
data: {},
47+
},
48+
scenario: 'NetworkController not found',
49+
},
50+
{
51+
state: {
52+
meta: { version: VERSION },
53+
data: {
54+
NetworkController: 'invalid',
55+
},
56+
},
57+
scenario: 'invalid NetworkController state',
58+
},
59+
{
60+
state: {
61+
meta: { version: VERSION },
62+
data: {
63+
NetworkController: {},
64+
},
65+
},
66+
scenario: 'missing networkConfigurationsByChainId property',
67+
},
68+
{
69+
state: {
70+
meta: { version: VERSION },
71+
data: {
72+
NetworkController: {
73+
networkConfigurationsByChainId: 'invalid',
74+
},
75+
},
76+
},
77+
scenario: 'invalid networkConfigurationsByChainId state',
78+
},
79+
{
80+
state: {
81+
meta: { version: VERSION },
82+
data: {
83+
NetworkController: {
84+
networkConfigurationsByChainId: {},
85+
selectedNetworkClientId: 'megaeth-testnet',
86+
},
87+
},
88+
},
89+
scenario: 'missing NetworkEnablementController',
90+
},
91+
{
92+
state: {
93+
meta: { version: VERSION },
94+
data: {
95+
NetworkController: {
96+
networkConfigurationsByChainId: {},
97+
selectedNetworkClientId: 'megaeth-testnet',
98+
},
99+
NetworkEnablementController: 'invalid',
100+
},
101+
},
102+
scenario: 'invalid NetworkEnablementController state',
103+
},
104+
{
105+
state: {
106+
meta: { version: VERSION },
107+
data: {
108+
NetworkController: {
109+
networkConfigurationsByChainId: {},
110+
selectedNetworkClientId: 'megaeth-testnet',
111+
},
112+
NetworkEnablementController: {
113+
enabledNetworkMap: 'invalid',
114+
},
115+
},
116+
},
117+
scenario: 'invalid enabledNetworkMap state',
118+
},
119+
{
120+
state: {
121+
meta: { version: VERSION },
122+
data: {
123+
NetworkController: {
124+
networkConfigurationsByChainId: {},
125+
selectedNetworkClientId: 'megaeth-testnet',
126+
},
127+
NetworkEnablementController: {
128+
enabledNetworkMap: {},
129+
},
130+
},
131+
},
132+
scenario: 'missing enabledNetworkMap property',
133+
},
134+
{
135+
state: {
136+
meta: { version: VERSION },
137+
data: {
138+
NetworkController: {
139+
networkConfigurationsByChainId: {},
140+
selectedNetworkClientId: 'megaeth-testnet',
141+
},
142+
NetworkEnablementController: {
143+
enabledNetworkMap: {
144+
eip155: 'invalid',
145+
},
146+
},
147+
},
148+
},
149+
scenario: 'invalid enabledNetworkMap[eip155] state',
150+
},
151+
];
152+
153+
// @ts-expect-error 'each' function is not recognized by TypeScript types
154+
it.each(invalidStates)(
155+
'should capture exception if $scenario',
156+
async ({ state }: { errorMessage: string; state: VersionedData }) => {
157+
const orgState = cloneDeep(state);
158+
159+
const migratedState = await migrate(state);
160+
161+
// State should be unchanged
162+
expect(migratedState).toStrictEqual(orgState);
163+
expect(mockedCaptureException).toHaveBeenCalledWith(expect.any(Error));
164+
},
165+
);
166+
167+
it('removes the megaeth testnet v1 network configuration and adds the megaeth testnet v2 network configuration', async () => {
168+
const oldStorage = {
169+
meta: { version: oldVersion },
170+
data: {
171+
NetworkController: {
172+
networkConfigurationsByChainId: {
173+
[MEGAETH_TESTNET_V1_CHAIN_ID]: {
174+
chainId: MEGAETH_TESTNET_V1_CHAIN_ID,
175+
name: 'Mega Testnet',
176+
nativeCurrency: 'MegaETH',
177+
blockExplorerUrls: ['https://explorer.com'],
178+
defaultRpcEndpointIndex: 0,
179+
defaultBlockExplorerUrlIndex: 0,
180+
rpcEndpoints: [
181+
{
182+
networkClientId: 'megaeth-testnet',
183+
type: RpcEndpointType.Custom,
184+
url: 'https://rpc.com',
185+
},
186+
],
187+
},
188+
},
189+
},
190+
NetworkEnablementController: {
191+
enabledNetworkMap: {
192+
[KnownCaipNamespace.Eip155]: {
193+
[MEGAETH_TESTNET_V1_CHAIN_ID]: false,
194+
},
195+
},
196+
},
197+
},
198+
};
199+
200+
const expectedStorage = {
201+
meta: { version: VERSION },
202+
data: {
203+
NetworkController: {
204+
networkConfigurationsByChainId: {
205+
[MEGAETH_TESTNET_V2_CONFIG.chainId]: MEGAETH_TESTNET_V2_CONFIG,
206+
},
207+
},
208+
NetworkEnablementController: {
209+
enabledNetworkMap: {
210+
[KnownCaipNamespace.Eip155]: {
211+
[MEGAETH_TESTNET_V2_CONFIG.chainId]: false,
212+
},
213+
},
214+
},
215+
},
216+
};
217+
218+
const newStorage = await migrate(oldStorage);
219+
220+
expect(newStorage).toStrictEqual(expectedStorage);
221+
});
222+
223+
// @ts-expect-error 'each' function is not recognized by TypeScript types
224+
it.each(['megaeth-testnet', 'random-network-client-id'])(
225+
'switchs to mainnet when the selected network client id is in MegaETH Testnet v1 - %s',
226+
async (selectedNetworkClientId: string) => {
227+
const oldStorage = {
228+
meta: { version: oldVersion },
229+
data: {
230+
NetworkController: {
231+
networkConfigurationsByChainId: {
232+
[MEGAETH_TESTNET_V1_CHAIN_ID]: {
233+
chainId: MEGAETH_TESTNET_V1_CHAIN_ID,
234+
name: 'Mega Testnet',
235+
nativeCurrency: 'MegaETH',
236+
blockExplorerUrls: ['https://explorer.com'],
237+
defaultRpcEndpointIndex: 0,
238+
defaultBlockExplorerUrlIndex: 0,
239+
rpcEndpoints: [
240+
{
241+
networkClientId: selectedNetworkClientId,
242+
type: RpcEndpointType.Custom,
243+
url: 'https://rpc.com',
244+
},
245+
],
246+
},
247+
},
248+
selectedNetworkClientId,
249+
},
250+
NetworkEnablementController: {
251+
enabledNetworkMap: {
252+
[KnownCaipNamespace.Eip155]: {
253+
[MEGAETH_TESTNET_V1_CHAIN_ID]: false,
254+
// to simulate the mainnet is not being enabled
255+
'0x1': false,
256+
},
257+
},
258+
},
259+
},
260+
};
261+
262+
const expectedStorage = {
263+
meta: { version: VERSION },
264+
data: {
265+
NetworkController: {
266+
networkConfigurationsByChainId: {
267+
[MEGAETH_TESTNET_V2_CONFIG.chainId]: MEGAETH_TESTNET_V2_CONFIG,
268+
},
269+
selectedNetworkClientId: 'mainnet',
270+
},
271+
NetworkEnablementController: {
272+
enabledNetworkMap: {
273+
[KnownCaipNamespace.Eip155]: {
274+
[MEGAETH_TESTNET_V2_CONFIG.chainId]: false,
275+
'0x1': true,
276+
},
277+
},
278+
},
279+
},
280+
};
281+
282+
const newStorage = await migrate(oldStorage);
283+
284+
expect(newStorage).toStrictEqual(expectedStorage);
285+
},
286+
);
287+
});

0 commit comments

Comments
 (0)