Skip to content

Commit 1900595

Browse files
authored
Merge branch 'main' into feat/plan-836-ledger-hid-prompt-up-issue
2 parents 29d8173 + e144891 commit 1900595

33 files changed

+846
-180
lines changed

.yarnrc.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ npmAuditIgnoreAdvisories:
5454
# We are ignoring this on March 11, 2025 to unblock CI, we will follow with a proper fix or confirmation this does not affect our users
5555
- 1102472
5656

57+
# Issue: Issue: Babel has inefficient RexExp complexity in generated code with .replace when transpiling named capturing groups
58+
# We are ignoring this on March 12, 2025 to unblock CI, we will follow with a proper fix or confirmation this does not affect our users
59+
- 1103026
60+
5761
# Temp fix for https://github.com/MetaMask/metamask-extension/pull/16920 for the sake of 11.7.1 hotfix
5862
# This will be removed in this ticket https://github.com/MetaMask/metamask-extension/issues/22299
5963
- 'ts-custom-error (deprecation)'

app/_locales/en/messages.json

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/_locales/en_GB/messages.json

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/scripts/controllers/bridge-status/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export const getStatusRequestDto = (
1919
const statusRequestNoQuoteFormatted = Object.fromEntries(
2020
Object.entries(statusRequestNoQuote).map(([key, value]) => [
2121
key,
22-
value.toString(),
22+
value?.toString(),
2323
]),
2424
) as unknown as Omit<StatusRequestDto, 'requestId'>;
2525

app/scripts/controllers/bridge-status/validators.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { validHex, validateData } from '../../../../shared/lib/swaps-utils';
2-
import { isValidHexAddress } from '../../../../shared/modules/hexstring-utils';
1+
import { truthyString, validateData } from '../../../../shared/lib/swaps-utils';
32
import {
43
BridgeId,
54
DestChainStatus,
@@ -35,7 +34,7 @@ const assetValidators = [
3534
{
3635
property: 'address',
3736
type: 'string',
38-
validator: (v: unknown): v is string => isValidHexAddress(v as string),
37+
validator: (v: unknown): v is string => truthyString(v as string),
3938
},
4039
{
4140
property: 'symbol',
@@ -75,7 +74,7 @@ const srcChainStatusValidators = [
7574
{
7675
property: 'txHash',
7776
type: 'string',
78-
validator: validHex,
77+
validator: truthyString,
7978
},
8079
{
8180
property: 'amount',
@@ -159,7 +158,7 @@ export const validators = [
159158
property: 'bridge',
160159
type: 'string|undefined',
161160
validator: (v: unknown): v is BridgeId | undefined =>
162-
v === undefined || Object.values(BridgeId).includes(v as BridgeId),
161+
v === undefined || typeof v === 'string',
163162
},
164163
{
165164
property: 'isExpectedToken',

app/scripts/metamask-controller.js

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { createEngineStream } from '@metamask/json-rpc-middleware-stream';
1919
import { ObservableStore } from '@metamask/obs-store';
2020
import { storeAsStream } from '@metamask/obs-store/dist/asStream';
2121
import { providerAsMiddleware } from '@metamask/eth-json-rpc-middleware';
22-
import { debounce, throttle, memoize, wrap, pick } from 'lodash';
22+
import { debounce, throttle, memoize, wrap, pick, cloneDeep } from 'lodash';
2323
import {
2424
KeyringController,
2525
KeyringTypes,
@@ -135,6 +135,7 @@ import { isSnapId } from '@metamask/snaps-utils';
135135
import { Interface } from '@ethersproject/abi';
136136
import { abiERC1155, abiERC721 } from '@metamask/metamask-eth-abis';
137137
import { isEvmAccountType } from '@metamask/keyring-api';
138+
import { hasProperty, hexToBigInt, toCaipChainId } from '@metamask/utils';
138139
import { normalize } from '@metamask/eth-sig-util';
139140

140141
import {
@@ -162,7 +163,6 @@ import {
162163
walletRevokeSession,
163164
walletInvokeMethod,
164165
} from '@metamask/multichain';
165-
import { hexToBigInt, toCaipChainId } from '@metamask/utils';
166166
import {
167167
methodsRequiringNetworkSwitch,
168168
methodsThatCanSwitchNetworkWithoutApproval,
@@ -185,10 +185,8 @@ import {
185185
NETWORK_TYPES,
186186
NetworkStatus,
187187
MAINNET_DISPLAY_NAME,
188+
DEFAULT_CUSTOM_TESTNET_MAP,
188189
UNSUPPORTED_RPC_METHODS,
189-
MEGAETH_TESTNET_DISPLAY_NAME,
190-
TEST_NETWORK_TICKER_MAP,
191-
MEGAETH_TESTNET_IMAGE_URL,
192190
} from '../../shared/constants/network';
193191
import { getAllowedSmartTransactionsChainIds } from '../../shared/constants/smartTransactions';
194192

@@ -606,27 +604,18 @@ export default class MetamaskController extends EventEmitter {
606604
networks[CHAIN_IDS.MAINNET].name = MAINNET_DISPLAY_NAME;
607605
delete networks[CHAIN_IDS.GOERLI];
608606
delete networks[CHAIN_IDS.LINEA_GOERLI];
609-
// Add MegaETH Testnet as a default network
610-
networks[CHAIN_IDS.MEGAETH_TESTNET] = {
611-
chainId: CHAIN_IDS.MEGAETH_TESTNET,
612-
name: MEGAETH_TESTNET_DISPLAY_NAME,
613-
nativeCurrency: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.MEGAETH_TESTNET],
614-
blockExplorerUrls: ['https://www.megaexplorer.xyz'],
615-
defaultRpcEndpointIndex: 0,
616-
rpcEndpoints: [
617-
{
618-
networkClientId: 'megaeth-testnet',
619-
url: 'https://carrot.megaeth.com/rpc',
620-
type: 'custom',
621-
},
622-
],
623-
imageUrl: MEGAETH_TESTNET_IMAGE_URL,
624-
};
607+
608+
// Due to the MegaETH Testnet not being included in getDefaultNetworkControllerState().
609+
// and it is not using Infura as a provider, we need to add it manually.
610+
networks[CHAIN_IDS.MEGAETH_TESTNET] = cloneDeep(
611+
DEFAULT_CUSTOM_TESTNET_MAP[CHAIN_IDS.MEGAETH_TESTNET],
612+
);
625613

626614
Object.values(networks).forEach((network) => {
627615
const id = network.rpcEndpoints[0].networkClientId;
628-
if (id !== 'megaeth-testnet') {
629-
// Skip for our custom network
616+
// Process only if the default network has a corresponding networkClientId in BlockExplorerUrl.
617+
// Note: The MegaETH Testnet is currently the only network that is not included.
618+
if (hasProperty(BlockExplorerUrl, id)) {
630619
network.blockExplorerUrls = [BlockExplorerUrl[id]];
631620
}
632621
network.defaultBlockExplorerUrlIndex = 0;

app/scripts/migrations/146.test.ts

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
import { cloneDeep } from 'lodash';
2+
import {
3+
CHAIN_IDS,
4+
DEFAULT_CUSTOM_TESTNET_MAP,
5+
} from '../../../shared/constants/network';
6+
import { migrate, version } from './146';
7+
8+
const oldVersion = 145;
9+
10+
describe(`migration #${version}`, () => {
11+
it('updates the version metadata', async () => {
12+
const oldStorage = {
13+
meta: { version: oldVersion },
14+
data: {},
15+
};
16+
const newStorage = await migrate(oldStorage);
17+
expect(newStorage.meta).toStrictEqual({ version });
18+
});
19+
20+
describe(`migration #${version}`, () => {
21+
it('does nothing if `NetworkController` is missing', async () => {
22+
const oldStorage = {
23+
meta: { version: oldVersion },
24+
data: {},
25+
};
26+
const newStorage = await migrate(oldStorage);
27+
expect(newStorage.data).toStrictEqual({});
28+
});
29+
30+
it('does nothing if `NetworkController` is not an object', async () => {
31+
const oldStorage = {
32+
meta: { version: oldVersion },
33+
data: {
34+
NetworkController: 'invalidData',
35+
},
36+
};
37+
const newStorage = await migrate(oldStorage);
38+
expect(newStorage.data).toStrictEqual(oldStorage.data);
39+
});
40+
41+
it('does nothing if `NetworkController.networkConfigurationsByChainId` is not an object', async () => {
42+
const oldStorage = {
43+
meta: { version: oldVersion },
44+
data: {
45+
NetworkController: {
46+
networkConfigurationsByChainId: 'invalidData',
47+
},
48+
},
49+
};
50+
const newStorage = await migrate(oldStorage);
51+
expect(newStorage.data).toStrictEqual(oldStorage.data);
52+
});
53+
54+
it('adds a new network `MegaETH` to `NetworkController.networkConfigurationsByChainId`', async () => {
55+
const oldState = {
56+
meta: { version: oldVersion },
57+
data: {
58+
NetworkController: {
59+
selectedNetworkClientId: 'mainnet',
60+
networksMetadata: {},
61+
networkConfigurationsByChainId: {
62+
'0x1': {
63+
chainId: '0x1',
64+
rpcEndpoints: [
65+
{
66+
networkClientId: 'mainnet',
67+
url: 'https://mainnet.infura.io/v3/{infuraProjectId}',
68+
type: 'infura',
69+
},
70+
],
71+
defaultRpcEndpointIndex: 0,
72+
blockExplorerUrls: ['https://etherscan.io'],
73+
defaultBlockExplorerUrlIndex: 0,
74+
name: 'Ethereum Mainnet',
75+
nativeCurrency: 'ETH',
76+
},
77+
'0xaa36a7': {
78+
chainId: '0xaa36a7',
79+
rpcEndpoints: [
80+
{
81+
networkClientId: 'sepolia',
82+
url: 'https://sepolia.infura.io/v3/{infuraProjectId}',
83+
type: 'infura',
84+
},
85+
],
86+
defaultRpcEndpointIndex: 0,
87+
blockExplorerUrls: ['https://sepolia.etherscan.io'],
88+
defaultBlockExplorerUrlIndex: 0,
89+
name: 'Sepolia',
90+
nativeCurrency: 'SepoliaETH',
91+
},
92+
'0xe705': {
93+
chainId: '0xe705',
94+
rpcEndpoints: [
95+
{
96+
networkClientId: 'linea-sepolia',
97+
url: 'https://linea-sepolia.infura.io/v3/{infuraProjectId}',
98+
type: 'infura',
99+
},
100+
],
101+
defaultRpcEndpointIndex: 0,
102+
blockExplorerUrls: ['https://sepolia.lineascan.build'],
103+
defaultBlockExplorerUrlIndex: 0,
104+
name: 'Linea Sepolia',
105+
nativeCurrency: 'LineaETH',
106+
},
107+
'0xe708': {
108+
chainId: '0xe708',
109+
rpcEndpoints: [
110+
{
111+
networkClientId: 'linea-mainnet',
112+
url: 'https://linea-mainnet.infura.io/v3/{infuraProjectId}',
113+
type: 'infura',
114+
},
115+
],
116+
defaultRpcEndpointIndex: 0,
117+
blockExplorerUrls: ['https://lineascan.build'],
118+
defaultBlockExplorerUrlIndex: 0,
119+
name: 'Linea Mainnet',
120+
nativeCurrency: 'ETH',
121+
},
122+
},
123+
},
124+
},
125+
};
126+
127+
const expectedData = {
128+
NetworkController: {
129+
...oldState.data.NetworkController,
130+
networkConfigurationsByChainId: {
131+
...oldState.data.NetworkController.networkConfigurationsByChainId,
132+
[CHAIN_IDS.MEGAETH_TESTNET]: cloneDeep(
133+
DEFAULT_CUSTOM_TESTNET_MAP[CHAIN_IDS.MEGAETH_TESTNET],
134+
),
135+
},
136+
},
137+
};
138+
139+
const newStorage = await migrate(oldState);
140+
expect(newStorage.data).toStrictEqual(expectedData);
141+
});
142+
143+
it('updates the `MegaETH` network if it has already in `NetworkController.networkConfigurationsByChainId`', async () => {
144+
const oldStorage = {
145+
meta: { version: oldVersion },
146+
data: {
147+
NetworkController: {
148+
selectedNetworkClientId: 'mainnet',
149+
networksMetadata: {},
150+
networkConfigurationsByChainId: {
151+
[CHAIN_IDS.MEGAETH_TESTNET]: {
152+
...cloneDeep(
153+
DEFAULT_CUSTOM_TESTNET_MAP[CHAIN_IDS.MEGAETH_TESTNET],
154+
),
155+
name: 'Some other name',
156+
},
157+
},
158+
},
159+
},
160+
};
161+
162+
const expectedData = {
163+
NetworkController: {
164+
...oldStorage.data.NetworkController,
165+
networkConfigurationsByChainId: {
166+
...oldStorage.data.NetworkController.networkConfigurationsByChainId,
167+
[CHAIN_IDS.MEGAETH_TESTNET]: cloneDeep(
168+
DEFAULT_CUSTOM_TESTNET_MAP[CHAIN_IDS.MEGAETH_TESTNET],
169+
),
170+
},
171+
},
172+
};
173+
174+
const newStorage = await migrate(oldStorage);
175+
expect(newStorage.data).toStrictEqual(expectedData);
176+
});
177+
});
178+
});

app/scripts/migrations/146.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { hasProperty, isObject } from '@metamask/utils';
2+
import { cloneDeep } from 'lodash';
3+
import {
4+
CHAIN_IDS,
5+
DEFAULT_CUSTOM_TESTNET_MAP,
6+
} from '../../../shared/constants/network';
7+
8+
type VersionedData = {
9+
meta: { version: number };
10+
data: Record<string, unknown>;
11+
};
12+
13+
export const version = 146;
14+
15+
/**
16+
* This migration add MegaETH to the network controller
17+
* as a default Testnet.
18+
*
19+
* @param originalVersionedData - Versioned MetaMask extension state, exactly
20+
* what we persist to disk.
21+
* @returns Updated versioned MetaMask extension state.
22+
*/
23+
export async function migrate(originalVersionedData: VersionedData) {
24+
const versionedData = cloneDeep(originalVersionedData);
25+
versionedData.meta.version = version;
26+
versionedData.data = transformState(versionedData.data);
27+
return versionedData;
28+
}
29+
30+
function transformState(state: Record<string, unknown>) {
31+
if (
32+
hasProperty(state, 'NetworkController') &&
33+
isObject(state.NetworkController) &&
34+
isObject(state.NetworkController.networkConfigurationsByChainId)
35+
) {
36+
state.NetworkController.networkConfigurationsByChainId[
37+
CHAIN_IDS.MEGAETH_TESTNET
38+
] = cloneDeep(DEFAULT_CUSTOM_TESTNET_MAP[CHAIN_IDS.MEGAETH_TESTNET]);
39+
}
40+
return state;
41+
}

app/scripts/migrations/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ const migrations = [
171171
require('./143.1'),
172172
require('./144'),
173173
require('./145'),
174+
require('./146'),
174175
];
175176

176177
export default migrations;

0 commit comments

Comments
 (0)