Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
84e1a9e
chore: add megaETH v2
stanleyyconsensys Dec 1, 2025
fa7901e
chore: update migration
stanleyyconsensys Dec 1, 2025
85bd0d9
chore: update test
stanleyyconsensys Dec 1, 2025
c8affad
chore: update e2e test
stanleyyconsensys Dec 1, 2025
7961d94
chore: update migration fixture
stanleyyconsensys Dec 2, 2025
0629091
chore: update e2e
stanleyyconsensys Dec 2, 2025
c486923
chore: update test
stanleyyconsensys Dec 2, 2025
1d49b92
chore: update migration
stanleyyconsensys Dec 2, 2025
150c484
fix: lint
stanleyyconsensys Dec 2, 2025
3e0c461
chore: update spec
stanleyyconsensys Dec 3, 2025
3f58c56
chore: update migration script
stanleyyconsensys Dec 3, 2025
b5a7cda
fix: lint
stanleyyconsensys Dec 3, 2025
ecb75d9
chore: update migration
stanleyyconsensys Dec 3, 2025
2c27bf7
fix: lint
stanleyyconsensys Dec 3, 2025
50d3631
chore: update state log
stanleyyconsensys Dec 3, 2025
ae2d694
chore: rollback state log
stanleyyconsensys Dec 3, 2025
ad052a5
chore: update statemap
stanleyyconsensys Dec 3, 2025
3f7d139
chore: update state map
stanleyyconsensys Dec 3, 2025
24cd17c
Merge branch 'main' into chore/add-megaeth-testnet-v2
stanleyyconsensys Dec 4, 2025
fcd43df
chore: update migration script ordering
stanleyyconsensys Dec 4, 2025
433e702
fix: lint
stanleyyconsensys Dec 4, 2025
58d9591
Merge branch 'main' into chore/add-megaeth-testnet-v2
stanleyyconsensys Dec 4, 2025
ad738ec
chore: address comment
stanleyyconsensys Dec 4, 2025
9d051fc
Merge branch 'main' into chore/add-megaeth-testnet-v2
stanleyyconsensys Dec 4, 2025
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
12 changes: 6 additions & 6 deletions app/scripts/controller-init/network-controller-init.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,21 +127,21 @@ describe('NetworkControllerInit', () => {
},
],
},
"0x18c6": {
"0x18c7": {
"blockExplorerUrls": [
"https://megaexplorer.xyz",
"https://megaeth-testnet-v2.blockscout.com",
],
"chainId": "0x18c6",
"chainId": "0x18c7",
"defaultBlockExplorerUrlIndex": 0,
"defaultRpcEndpointIndex": 0,
"name": "Mega Testnet",
"name": "MegaETH Testnet",
"nativeCurrency": "MegaETH",
"rpcEndpoints": [
{
"failoverUrls": [],
"networkClientId": "megaeth-testnet",
"networkClientId": "megaeth-testnet-v2",
"type": "custom",
"url": "https://carrot.megaeth.com/rpc",
"url": "https://timothy.megaeth.com/rpc",
},
],
},
Expand Down
24 changes: 20 additions & 4 deletions app/scripts/controller-init/network-controller-init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@ import {
NetworkControllerMessenger,
} from './messengers';

export const ADDITIONAL_DEFAULT_NETWORKS = [
ChainId['megaeth-testnet'],
ChainId['monad-testnet'],
];
export const ADDITIONAL_DEFAULT_NETWORKS = [ChainId['monad-testnet']];

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

// TODO: Remove this once the MegaETH Testnet v2 is released from the controller utils
networks['0x18c7'] = {
Copy link
Contributor

@mcmire mcmire Dec 4, 2025

Choose a reason for hiding this comment

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

What if someone already has this chain added? Do we need to only add this if the chain is not present? (If the chain is already present, then the migration should take care of fixing it.) Is this something to be concerned about?

chainId: '0x18c7', // 6343
name: 'MegaETH Testnet',
nativeCurrency: 'MegaETH',
blockExplorerUrls: ['https://megaeth-testnet-v2.blockscout.com'],
Copy link
Contributor

@mcmire mcmire Dec 4, 2025

Choose a reason for hiding this comment

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

Nit: Isn't this information already available in shared/constants/network.ts?

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 call, but this is for temp and removed soon once network controller bump up, i think we can keep it like that if u dont mind?

defaultRpcEndpointIndex: 0,
defaultBlockExplorerUrlIndex: 0,
rpcEndpoints: [
{
// to align the same networkClientId from the controller utils
networkClientId: 'megaeth-testnet-v2',
url: 'https://timothy.megaeth.com/rpc',
type: RpcEndpointType.Custom,
failoverUrls: [],
},
],
};

// TODO: Consider changing `getDefaultNetworkControllerState` on the
// controller side to include some of these tweaks.

Expand Down
2 changes: 1 addition & 1 deletion app/scripts/metamask-controller.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3834,7 +3834,7 @@ describe('MetaMaskController', () => {
const networksWithoutFailoverUrls = [
CHAIN_IDS.SEPOLIA,
CHAIN_IDS.LINEA_SEPOLIA,
CHAIN_IDS.MEGAETH_TESTNET,
'0x18c7', // MegaETH Testnet
'0x279f', // Monad Testnet
'0x539', // Localhost
];
Expand Down
287 changes: 287 additions & 0 deletions app/scripts/migrations/184.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,287 @@
import { RpcEndpointType } from '@metamask/network-controller';
import { cloneDeep } from 'lodash';
import { jest } from '@jest/globals';
import { KnownCaipNamespace } from '@metamask/utils';
import {
migrate,
version,
MEGAETH_TESTNET_V2_CONFIG,
MEGAETH_TESTNET_V1_CHAIN_ID,
type VersionedData,
} from './184';

const VERSION = version;
const oldVersion = VERSION - 1;

describe(`migration #${VERSION}`, () => {
let mockedCaptureException: jest.Mock;
beforeEach(() => {
mockedCaptureException = jest.fn();
global.sentry = { captureException: mockedCaptureException };
});

afterEach(() => {
global.sentry = undefined;
});

it('updates the version metadata', async () => {
const oldStorage = {
meta: { version: oldVersion },
data: {
NetworkController: {
networkConfigurationsByChainId: {},
},
},
};

const newStorage = await migrate(oldStorage);

expect(newStorage.meta).toStrictEqual({ version: VERSION });
});

const invalidStates = [
{
state: {
meta: { version: VERSION },
data: {},
},
scenario: 'NetworkController not found',
},
{
state: {
meta: { version: VERSION },
data: {
NetworkController: 'invalid',
},
},
scenario: 'invalid NetworkController state',
},
{
state: {
meta: { version: VERSION },
data: {
NetworkController: {},
},
},
scenario: 'missing networkConfigurationsByChainId property',
},
{
state: {
meta: { version: VERSION },
data: {
NetworkController: {
networkConfigurationsByChainId: 'invalid',
},
},
},
scenario: 'invalid networkConfigurationsByChainId state',
},
{
state: {
meta: { version: VERSION },
data: {
NetworkController: {
networkConfigurationsByChainId: {},
selectedNetworkClientId: 'megaeth-testnet',
},
},
},
scenario: 'missing NetworkEnablementController',
},
{
state: {
meta: { version: VERSION },
data: {
NetworkController: {
networkConfigurationsByChainId: {},
selectedNetworkClientId: 'megaeth-testnet',
},
NetworkEnablementController: 'invalid',
},
},
scenario: 'invalid NetworkEnablementController state',
},
{
state: {
meta: { version: VERSION },
data: {
NetworkController: {
networkConfigurationsByChainId: {},
selectedNetworkClientId: 'megaeth-testnet',
},
NetworkEnablementController: {
enabledNetworkMap: 'invalid',
},
},
},
scenario: 'invalid enabledNetworkMap state',
},
{
state: {
meta: { version: VERSION },
data: {
NetworkController: {
networkConfigurationsByChainId: {},
selectedNetworkClientId: 'megaeth-testnet',
},
NetworkEnablementController: {
enabledNetworkMap: {},
},
},
},
scenario: 'missing enabledNetworkMap property',
},
{
state: {
meta: { version: VERSION },
data: {
NetworkController: {
networkConfigurationsByChainId: {},
selectedNetworkClientId: 'megaeth-testnet',
},
NetworkEnablementController: {
enabledNetworkMap: {
eip155: 'invalid',
},
},
},
},
scenario: 'invalid enabledNetworkMap[eip155] state',
},
];

// @ts-expect-error 'each' function is not recognized by TypeScript types
it.each(invalidStates)(
'should capture exception if $scenario',
async ({ state }: { errorMessage: string; state: VersionedData }) => {
const orgState = cloneDeep(state);

const migratedState = await migrate(state);

// State should be unchanged
expect(migratedState).toStrictEqual(orgState);
expect(mockedCaptureException).toHaveBeenCalledWith(expect.any(Error));
},
);

it('removes the megaeth testnet v1 network configuration and adds the megaeth testnet v2 network configuration', async () => {
const oldStorage = {
meta: { version: oldVersion },
data: {
NetworkController: {
networkConfigurationsByChainId: {
[MEGAETH_TESTNET_V1_CHAIN_ID]: {
chainId: MEGAETH_TESTNET_V1_CHAIN_ID,
name: 'Mega Testnet',
nativeCurrency: 'MegaETH',
blockExplorerUrls: ['https://explorer.com'],
defaultRpcEndpointIndex: 0,
defaultBlockExplorerUrlIndex: 0,
rpcEndpoints: [
{
networkClientId: 'megaeth-testnet',
type: RpcEndpointType.Custom,
url: 'https://rpc.com',
},
],
},
},
},
NetworkEnablementController: {
enabledNetworkMap: {
[KnownCaipNamespace.Eip155]: {
[MEGAETH_TESTNET_V1_CHAIN_ID]: false,
},
},
},
},
};

const expectedStorage = {
meta: { version: VERSION },
data: {
NetworkController: {
networkConfigurationsByChainId: {
[MEGAETH_TESTNET_V2_CONFIG.chainId]: MEGAETH_TESTNET_V2_CONFIG,
},
},
NetworkEnablementController: {
enabledNetworkMap: {
[KnownCaipNamespace.Eip155]: {
[MEGAETH_TESTNET_V2_CONFIG.chainId]: false,
},
},
},
},
};

const newStorage = await migrate(oldStorage);

expect(newStorage).toStrictEqual(expectedStorage);
});

// @ts-expect-error 'each' function is not recognized by TypeScript types
it.each(['megaeth-testnet', 'random-network-client-id'])(
'switchs to mainnet when the selected network client id is in MegaETH Testnet v1 - %s',
async (selectedNetworkClientId: string) => {
const oldStorage = {
meta: { version: oldVersion },
data: {
NetworkController: {
networkConfigurationsByChainId: {
[MEGAETH_TESTNET_V1_CHAIN_ID]: {
chainId: MEGAETH_TESTNET_V1_CHAIN_ID,
name: 'Mega Testnet',
nativeCurrency: 'MegaETH',
blockExplorerUrls: ['https://explorer.com'],
defaultRpcEndpointIndex: 0,
defaultBlockExplorerUrlIndex: 0,
rpcEndpoints: [
{
networkClientId: selectedNetworkClientId,
type: RpcEndpointType.Custom,
url: 'https://rpc.com',
},
],
},
},
selectedNetworkClientId,
},
NetworkEnablementController: {
enabledNetworkMap: {
[KnownCaipNamespace.Eip155]: {
[MEGAETH_TESTNET_V1_CHAIN_ID]: false,
// to simulate the mainnet is not being enabled
'0x1': false,
},
},
},
},
};

const expectedStorage = {
meta: { version: VERSION },
data: {
NetworkController: {
networkConfigurationsByChainId: {
[MEGAETH_TESTNET_V2_CONFIG.chainId]: MEGAETH_TESTNET_V2_CONFIG,
},
selectedNetworkClientId: 'mainnet',
},
NetworkEnablementController: {
enabledNetworkMap: {
[KnownCaipNamespace.Eip155]: {
[MEGAETH_TESTNET_V2_CONFIG.chainId]: false,
'0x1': true,
},
},
},
},
};

const newStorage = await migrate(oldStorage);

expect(newStorage).toStrictEqual(expectedStorage);
},
);
});
Loading
Loading