Repository: MetaMask/metamask-mobile (2025-07-21T11:07:43Z)

Issue:
[Bug]: Base Mainnet displayed as Private Network in the network picker
### Describe the bug

Base Mainnet is displayed as `Private Network` in the network picker.

This issue was initially noticed in this [PR](https://github.com/MetaMask/metamask-mobile/pull/16349#issuecomment-2976651943), the fix for [this issue](https://github.com/MetaMask/metamask-mobile/issues/15664) 



### Expected behavior

Network name to be displayed as Base Mainnet

### Screenshots/Recordings

https://github.com/user-attachments/assets/86504d55-1b2c-456a-831a-c1d54bc60e5e

### Steps to reproduce

1. Switch to Base Mainnet
2. Switch to Current Network in the network picker
3. Notice network name

### Error messages or log output

```shell

```

### Detection stage

During release testing

### Version

7.50.0

### Build type

None

### Device

Pixel 6 Pro

### Operating system

Android

### Additional context

_No response_

### Severity

_No response_


Discussion:
Same in 7.51.0:

https://github.com/user-attachments/assets/70c57f91-f80e-4f4e-aaaa-6130d94ac087



Patch:
diff --git a/app/components/UI/ImageIcon/index.tsx b/app/components/UI/ImageIcon/index.tsx
index 34826c50dbd2..279947dfdbe4 100644
--- a/app/components/UI/ImageIcon/index.tsx
+++ b/app/components/UI/ImageIcon/index.tsx
@@ -1,9 +1,9 @@
-import { Image } from 'react-native';
+import { Image, type ImageSourcePropType } from 'react-native';
 import React from 'react';
 import images from 'images/image-icons';
 
 interface ImageIconPropTypes {
-  image: string;
+  image: string | ImageSourcePropType;
   // TODO: Replace "any" with type
   // eslint-disable-next-line @typescript-eslint/no-explicit-any
   style: any;
@@ -13,7 +13,14 @@ const ImageIcon = (props: ImageIconPropTypes) => {
   const { image, style } = props;
 
   if (!image) return null;
-  const source = images[image];
+
+  let source: ImageSourcePropType | undefined;
+  if (typeof image === 'string') {
+    source = images[image];
+  } else {
+    source = image;
+  }
+
   if (!source) {
     return null;
   }
diff --git a/app/components/Views/Settings/NetworksSettings/index.js b/app/components/Views/Settings/NetworksSettings/index.js
index 53cbcee5027e..725896dcaa98 100644
--- a/app/components/Views/Settings/NetworksSettings/index.js
+++ b/app/components/Views/Settings/NetworksSettings/index.js
@@ -15,9 +15,10 @@ import { getNavigationOptionsTitle } from '../../../UI/Navbar';
 import { strings } from '../../../../../locales/i18n';
 import Networks, {
   getAllNetworks,
+  getMainnetNetworks,
+  getTestNetworks,
   getNetworkImageSource,
-  isDefaultMainnet,
-  isLineaMainnet,
+  isMainnetNetwork,
   isMainNet,
   isTestNet,
 } from '../../../../util/networks';
@@ -181,8 +182,6 @@ class NetworksSettings extends PureComponent {
     this.updateNavBar();
   };
 
-  getOtherNetworks = () => getAllNetworks().slice(2);
-
   onNetworkPress = (networkTypeOrRpcUrl) => {
     const { navigation } = this.props;
     navigation.navigate(Routes.ADD_NETWORK, {
@@ -263,62 +262,54 @@ class NetworksSettings extends PureComponent {
     const styles = createStyles(colors);
     return (
       <View key={`network-${networkTypeOrRpcUrl}`}>
-        {
-          // Do not change. This logic must check for 'mainnet' and is used for rendering the out of the box mainnet when searching.
-          isDefaultMainnet(networkTypeOrRpcUrl) ? (
-            this.renderMainnet()
-          ) : isLineaMainnet(networkTypeOrRpcUrl) ? (
-            this.renderLineaMainnet()
-          ) : (
-            <TouchableOpacity
-              key={`network-${i}`}
-              onPress={() => this.onNetworkPress(networkTypeOrRpcUrl)}
-              onLongPress={() =>
-                isCustomRPC && this.showRemoveMenu(networkTypeOrRpcUrl)
-              }
-            >
-              <View style={styles.network}>
-                {isCustomRPC ? (
-                  <AvatarNetwork
-                    variant={AvatarVariant.Network}
-                    name={name}
-                    imageSource={image}
-                    style={styles.networkIcon}
-                    size={AvatarSize.Xs}
-                  />
-                ) : null}
-                {!isCustomRPC &&
-                  (image ? (
-                    <ImageIcons
-                      image={networkTypeOrRpcUrl.toUpperCase()}
-                      style={styles.networkIcon}
-                    />
-                  ) : (
-                    <View
-                      style={[styles.networkIcon, { backgroundColor: color }]}
-                    >
-                      <Text style={styles.text}>{name[0]}</Text>
-                    </View>
-                  ))}
-                <Text style={styles.networkLabel}>{name}</Text>
-                {!isCustomRPC && (
-                  <FontAwesome
-                    name="lock"
-                    size={20}
-                    color={colors.icon.default}
-                    style={styles.icon}
-                  />
-                )}
-              </View>
-            </TouchableOpacity>
-          )
-        }
+        {isMainnetNetwork(networkTypeOrRpcUrl) ? (
+          this.renderMainnetNetworks(networkTypeOrRpcUrl)
+        ) : (
+          <TouchableOpacity
+            key={`network-${i}`}
+            onPress={() => this.onNetworkPress(networkTypeOrRpcUrl)}
+            onLongPress={() =>
+              isCustomRPC && this.showRemoveMenu(networkTypeOrRpcUrl)
+            }
+          >
+            <View style={styles.network}>
+              {isCustomRPC ? (
+                <AvatarNetwork
+                  variant={AvatarVariant.Network}
+                  name={name}
+                  imageSource={image}
+                  style={styles.networkIcon}
+                  size={AvatarSize.Xs}
+                />
+              ) : null}
+              {!isCustomRPC &&
+                (image ? (
+                  <ImageIcons image={image} style={styles.networkIcon} />
+                ) : (
+                  <View
+                    style={[styles.networkIcon, { backgroundColor: color }]}
+                  >
+                    <Text style={styles.text}>{name[0]}</Text>
+                  </View>
+                ))}
+              <Text style={styles.networkLabel}>{name}</Text>
+              {!isCustomRPC && (
+                <FontAwesome
+                  name="lock"
+                  size={20}
+                  color={colors.icon.default}
+                  style={styles.icon}
+                />
+              )}
+            </View>
+          </TouchableOpacity>
+        )}
       </View>
     );
   }
 
-  renderOtherNetworks() {
-    return this.getOtherNetworks().map((networkType, i) => {
+  renderTestNetworks() {
+    return getTestNetworks().map((networkType, i) => {
       const { name, imageSource, color } = Networks[networkType];
       return this.networkElement(
         name,
@@ -331,7 +322,11 @@ class NetworksSettings extends PureComponent {
     });
   }
 
-  renderRpcNetworks = () => {
+  /**
+   *
+   * @param {string[]} excludedChainIds
+   */
+  renderRpcNetworks = (excludedChainIds) => {
     const { networkConfigurations } = this.props;
     return Object.values(networkConfigurations).map(
       (
@@ -342,8 +337,7 @@ class NetworksSettings extends PureComponent {
           !chainId ||
           isTestNet(chainId) ||
           isMainNet(chainId) ||
-          chainId === CHAIN_IDS.LINEA_MAINNET ||
-          chainId === CHAIN_IDS.GOERLI ||
+          excludedChainIds.includes(chainId) ||
           isNonEvmChainId(chainId)
         ) {
           return null;
@@ -359,15 +353,8 @@ class NetworksSettings extends PureComponent {
 
   renderRpcNetworksView = () => {
     const { networkConfigurations } = this.props;
-    // Define the chainIds to exclude (Mainnet and Linea)
-    const excludedChainIds = [
-      CHAIN_IDS.MAINNET,
-      CHAIN_IDS.LINEA_MAINNET,
-      CHAIN_IDS.GOERLI,
-      CHAIN_IDS.LINEA_GOERLI,
-      CHAIN_IDS.SEPOLIA,
-      CHAIN_IDS.LINEA_SEPOLIA,
-    ];
+    // Define the chainIds to exclude (from our predefined networks list)
+    const excludedChainIds = getAllNetworks().map((n) => Networks[n].chainId);
 
     const filteredChain = Object.keys(networkConfigurations).reduce(
       (filtered, key) => {
@@ -390,67 +377,55 @@ class NetworksSettings extends PureComponent {
           <Text style={styles.sectionLabel}>
             {strings('app_settings.custom_network_name')}
           </Text>
-          {this.renderRpcNetworks()}
+          {this.renderRpcNetworks(excludedChainIds)}
         </View>
       );
     }
   };
 
-  renderMainnet() {
-    const { name: mainnetName } = Networks.mainnet;
+  /**
+   * @param {string | undefined} mainnetNetwork - used to render a specific mainnet network
+   */
+  renderMainnetNetworks(mainnetNetwork) {
+    const networkKeys = mainnetNetwork
+      ? [mainnetNetwork]
+      : getMainnetNetworks();
+    const mainnetNetworks = networkKeys
+      .map((n) => Networks[n])
+      .filter((n) => Boolean(n));
     const colors = this.context.colors || mockTheme.colors;
     const styles = createStyles(colors);
-
     return (
-      <View style={styles.mainnetHeader}>
-        <TouchableOpacity
-          style={styles.network}
-          key={`network-${MAINNET}`}
-          onPress={() => this.onNetworkPress(MAINNET)}
-        >
-          <View style={styles.networkWrapper}>
-            <ImageIcons image="ETHEREUM" style={styles.networkIcon} />
-            <View style={styles.networkInfo}>
-              <Text style={styles.networkLabel}>{mainnetName}</Text>
-            </View>
-          </View>
-          <FontAwesome
-            name="lock"
-            size={20}
-            color={colors.icon.default}
-            style={styles.icon}
-          />
-        </TouchableOpacity>
-      </View>
-    );
-  }
-
-  renderLineaMainnet() {
-    const { name: lineaMainnetName } = Networks['linea-mainnet'];
-    const colors = this.context.colors || mockTheme.colors;
-    const styles = createStyles(colors);
-
-    return (
-      <View style={styles.mainnetHeader}>
-        <TouchableOpacity
-          style={styles.network}
-          key={`network-${LINEA_MAINNET}`}
-          onPress={() => this.onNetworkPress(LINEA_MAINNET)}
-        >
-          <View style={styles.networkWrapper}>
-            <ImageIcons image="LINEA-MAINNET" style={styles.networkIcon} />
-            <View style={styles.networkInfo}>
-              <Text style={styles.networkLabel}>{lineaMainnetName}</Text>
-            </View>
+      <>
+        {mainnetNetworks.map((network) => (
+          <View
+            style={styles.mainnetHeader}
+            key={`mainnet-network-${network.chainId}`}
+          >
+            <TouchableOpacity
+              style={styles.network}
+              key={`network-${MAINNET}`}
+              onPress={() => this.onNetworkPress(MAINNET)}
+            >
+              <View style={styles.networkWrapper}>
+                <ImageIcons
+                  image={network.imageSource}
+                  style={styles.networkIcon}
+                />
+                <View style={styles.networkInfo}>
+                  <Text style={styles.networkLabel}>{network.name}</Text>
+                </View>
+              </View>
+              <FontAwesome
+                name="lock"
+                size={20}
+                color={colors.icon.default}
+                style={styles.icon}
+              />
+            </TouchableOpacity>
           </View>
-          <FontAwesome
-            name="lock"
-            size={20}
-            color={colors.icon.default}
-            style={styles.icon}
-          />
-        </TouchableOpacity>
-      </View>
+        ))}
+      </>
     );
   }
 
@@ -589,8 +564,7 @@ class NetworksSettings extends PureComponent {
               <Text style={styles.sectionLabel}>
                 {strings('app_settings.mainnet')}
               </Text>
-              {this.renderMainnet()}
-              {this.renderLineaMainnet()}
+              {this.renderMainnetNetworks()}
               {
                 ///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps)
                 this.renderSolanaMainnet()
@@ -600,7 +574,7 @@ class NetworksSettings extends PureComponent {
               <Text style={styles.sectionLabel}>
                 {strings('app_settings.test_network_name')}
               </Text>
-              {this.renderOtherNetworks()}
+              {this.renderTestNetworks()}
             </>
           )}
         </ScrollView>
diff --git a/app/constants/urls.ts b/app/constants/urls.ts
index 79665a0a740c..f1f1f8043573 100644
--- a/app/constants/urls.ts
+++ b/app/constants/urls.ts
@@ -48,7 +48,7 @@ export const LINEA_SEPOLIA_BLOCK_EXPLORER = 'https://sepolia.lineascan.build';
 export const LINEA_MAINNET_BLOCK_EXPLORER = 'https://lineascan.build';
 export const MAINNET_BLOCK_EXPLORER = 'https://etherscan.io';
 export const SEPOLIA_BLOCK_EXPLORER = 'https://sepolia.etherscan.io';
-export const BASE_MAINNET_BLOCK_EXPLORER_URL = 'https://basescan.org';
+export const BASE_MAINNET_BLOCK_EXPLORER = 'https://basescan.org';
 
 // Rpcs
 export const MAINNET_DEFAULT_RPC_URL = `https://mainnet.infura.io/v3/${infuraProjectId}`;
diff --git a/app/util/etherscan.js b/app/util/etherscan.js
index 1bef534a5902..1f1fa7b9adfa 100644
--- a/app/util/etherscan.js
+++ b/app/util/etherscan.js
@@ -1,5 +1,5 @@
 import {
-  BASE_MAINNET_BLOCK_EXPLORER_URL,
+  BASE_MAINNET_BLOCK_EXPLORER,
   LINEA_GOERLI_BLOCK_EXPLORER,
   LINEA_MAINNET_BLOCK_EXPLORER,
   LINEA_SEPOLIA_BLOCK_EXPLORER,
@@ -52,7 +52,7 @@ export function getEtherscanBaseUrl(networkType) {
   if (networkType === LINEA_GOERLI) return LINEA_GOERLI_BLOCK_EXPLORER;
   if (networkType === LINEA_SEPOLIA) return LINEA_SEPOLIA_BLOCK_EXPLORER;
   if (networkType === LINEA_MAINNET) return LINEA_MAINNET_BLOCK_EXPLORER;
-  if (networkType === BASE_MAINNET) return BASE_MAINNET_BLOCK_EXPLORER_URL;
+  if (networkType === BASE_MAINNET) return BASE_MAINNET_BLOCK_EXPLORER;
   if (networkType === SEPOLIA) return SEPOLIA_BLOCK_EXPLORER;
   const subdomain =
     networkType.toLowerCase() === MAINNET
diff --git a/app/util/networks/index.js b/app/util/networks/index.js
index 3fc03eac1465..0b3cd1605eb0 100644
--- a/app/util/networks/index.js
+++ b/app/util/networks/index.js
@@ -10,6 +10,7 @@ import {
   LINEA_SEPOLIA,
   MEGAETH_TESTNET,
   MONAD_TESTNET,
+  BASE_MAINNET,
 } from '../../../app/constants/network';
 import { NetworkSwitchErrorType } from '../../../app/constants/error';
 import {
@@ -30,6 +31,7 @@ const lineaTestnetLogo = require('../../images/linea-testnet-logo.png');
 const lineaMainnetLogo = require('../../images/linea-mainnet-logo.png');
 const megaEthTestnetLogo = require('../../images/megaeth-testnet-logo.png');
 const monadTestnetLogo = require('../../images/monad-testnet-logo.png');
+const baseMainnetLogo = require('../../images/base.png');
 
 /* eslint-enable */
 import {
@@ -51,6 +53,7 @@ import {
   MAINNET_BLOCK_EXPLORER,
   SEPOLIA_BLOCK_EXPLORER,
   SEPOLIA_FAUCET,
+  BASE_MAINNET_BLOCK_EXPLORER,
 } from '../../constants/urls';
 import { isNonEvmChainId } from '../../core/Multichain/utils';
 import { SolScope } from '@metamask/keyring-api';
@@ -87,6 +90,7 @@ export const NetworkList = {
     networkType: 'mainnet',
     imageSource: ethLogo,
     blockExplorerUrl: MAINNET_BLOCK_EXPLORER,
+    isTestNet: false,
   },
   [LINEA_MAINNET]: {
     name: 'Linea Main Network',
@@ -100,6 +104,21 @@ export const NetworkList = {
     networkType: 'linea-mainnet',
     imageSource: lineaMainnetLogo,
     blockExplorerUrl: LINEA_MAINNET_BLOCK_EXPLORER,
+    isTestNet: false,
+  },
+  [BASE_MAINNET]: {
+    name: 'Base Main Network',
+    shortName: 'Base',
+    networkId: 8453,
+    chainId: toHex('8453'),
+    ticker: 'ETH',
+    // Third party color
+    // eslint-disable-next-line @metamask/design-tokens/color-no-hex
+    color: '#0052FE',
+    networkType: 'base-mainnet',
+    imageSource: baseMainnetLogo,
+    blockExplorerUrl: BASE_MAINNET_BLOCK_EXPLORER,
+    isTestNet: false,
   },
   [SEPOLIA]: {
     name: 'Sepolia',
@@ -113,6 +132,7 @@ export const NetworkList = {
     networkType: 'sepolia',
     imageSource: sepoliaLogo,
     blockExplorerUrl: SEPOLIA_BLOCK_EXPLORER,
+    isTestNet: true,
   },
   [LINEA_SEPOLIA]: {
     name: 'Linea Sepolia',
@@ -126,6 +146,7 @@ export const NetworkList = {
     networkType: 'linea-sepolia',
     imageSource: lineaTestnetLogo,
     blockExplorerUrl: LINEA_SEPOLIA_BLOCK_EXPLORER,
+    isTestNet: true,
   },
   [MEGAETH_TESTNET]: {
     name: 'Mega Testnet',
@@ -139,6 +160,7 @@ export const NetworkList = {
     networkType: 'megaeth-testnet',
     imageSource: megaEthTestnetLogo,
     blockExplorerUrl: BlockExplorerUrl['megaeth-testnet'],
+    isTestNet: true,
   },
   [MONAD_TESTNET]: {
     name: 'Monad Testnet',
@@ -152,6 +174,7 @@ export const NetworkList = {
     networkType: 'monad-testnet',
     imageSource: monadTestnetLogo,
     blockExplorerUrl: BlockExplorerUrl['monad-testnet'],
+    isTestNet: true,
   },
   [RPC]: {
     name: 'Private Network',
@@ -187,6 +210,15 @@ export default NetworkList;
 export const getAllNetworks = () =>
   NetworkListKeys.filter((name) => name !== RPC);
 
+export const getMainnetNetworks = () =>
+  getAllNetworks().filter((name) => !NetworkList[name].isTestNet);
+
+export const getTestNetworks = () =>
+  getAllNetworks().filter((name) => NetworkList[name].isTestNet);
+
+export const isMainnetNetwork = (networkType) =>
+  getMainnetNetworks().includes(networkType);
+
 /**
  * Checks if network is default mainnet.
  *


Test patch:
diff --git a/app/components/Views/Settings/NetworksSettings/__snapshots__/index.test.tsx.snap b/app/components/Views/Settings/NetworksSettings/__snapshots__/index.test.tsx.snap
index 2d498c38624b..f52eeb3efce5 100644
--- a/app/components/Views/Settings/NetworksSettings/__snapshots__/index.test.tsx.snap
+++ b/app/components/Views/Settings/NetworksSettings/__snapshots__/index.test.tsx.snap
@@ -607,14 +607,12 @@ exports[`NetworksSettings should render correctly 1`] = `
                           </View>
                           <View>
                             <TouchableOpacity
-                              disabled={true}
                               onPress={[Function]}
                               style={
                                 {
                                   "alignItems": "center",
                                   "flex": 1,
                                   "flexDirection": "row",
-                                  "opacity": 0.5,
                                   "paddingVertical": 12,
                                 }
                               }
@@ -651,7 +649,7 @@ exports[`NetworksSettings should render correctly 1`] = `
                                       }
                                     }
                                   >
-                                    Solana
+                                    Base Main Network
                                   </Text>
                                 </View>
                               </View>
@@ -680,66 +678,42 @@ exports[`NetworksSettings should render correctly 1`] = `
                               </Text>
                             </TouchableOpacity>
                           </View>
-                          <View
-                            testID="custom-networks-list"
-                          >
-                            <Text
+                          <View>
+                            <TouchableOpacity
+                              disabled={true}
+                              onPress={[Function]}
                               style={
                                 {
-                                  "color": "#121314",
-                                  "fontFamily": "CentraNo1-Bold",
-                                  "fontSize": 14,
-                                  "fontWeight": "600",
+                                  "alignItems": "center",
+                                  "flex": 1,
+                                  "flexDirection": "row",
+                                  "opacity": 0.5,
                                   "paddingVertical": 12,
                                 }
                               }
                             >
-                              Custom networks
-                            </Text>
-                            <View>
-                              <TouchableOpacity
-                                onLongPress={[Function]}
-                                onPress={[Function]}
+                              <View
+                                style={
+                                  {
+                                    "alignItems": "center",
+                                    "flex": 0,
+                                    "flexDirection": "row",
+                                  }
+                                }
                               >
-                                <View
+                                <Image
+                                  source={1}
                                   style={
                                     {
-                                      "alignItems": "center",
-                                      "flex": 1,
-                                      "flexDirection": "row",
-                                      "paddingVertical": 12,
+                                      "borderRadius": 10,
+                                      "height": 20,
+                                      "marginRight": 16,
+                                      "marginTop": 2,
+                                      "width": 20,
                                     }
                                   }
-                                >
-                                  <View
-                                    style={
-                                      {
-                                        "alignItems": "center",
-                                        "backgroundColor": "#ffffff",
-                                        "borderRadius": 10,
-                                        "height": 20,
-                                        "justifyContent": "center",
-                                        "marginRight": 16,
-                                        "marginTop": 2,
-                                        "overflow": "hidden",
-                                        "width": 20,
-                                      }
-                                    }
-                                    variant="Network"
-                                  >
-                                    <Image
-                                      onError={[Function]}
-                                      resizeMode="contain"
-                                      source={1}
-                                      style={
-                                        {
-                                          "height": 16,
-                                          "width": 16,
-                                        }
-                                      }
-                                      testID="network-avatar-image"
-                                    />
-                                  </View>
+                                />
+                                <View>
                                   <Text
                                     style={
                                       {
@@ -750,11 +724,34 @@ exports[`NetworksSettings should render correctly 1`] = `
                                       }
                                     }
                                   >
-                                    Base Mainnet
+                                    Solana
                                   </Text>
                                 </View>
-                              </TouchableOpacity>
-                            </View>
+                              </View>
+                              <Text
+                                allowFontScaling={false}
+                                selectable={false}
+                                style={
+                                  [
+                                    {
+                                      "color": "#121314",
+                                      "fontSize": 20,
+                                    },
+                                    {
+                                      "marginLeft": 8,
+                                    },
+                                    {
+                                      "fontFamily": "FontAwesome",
+                                      "fontStyle": "normal",
+                                      "fontWeight": "normal",
+                                    },
+                                    {},
+                                  ]
+                                }
+                              >
+                                
+                              </Text>
+                            </TouchableOpacity>
                           </View>
                           <Text
                             style={
diff --git a/app/util/networks/index.test.ts b/app/util/networks/index.test.ts
index d4bcdc6ce198..d069941433e8 100644
--- a/app/util/networks/index.test.ts
+++ b/app/util/networks/index.test.ts
@@ -31,6 +31,7 @@ import {
   LINEA_SEPOLIA,
   MEGAETH_TESTNET,
   MONAD_TESTNET,
+  BASE_MAINNET,
 } from '../../../app/constants/network';
 import { NetworkSwitchErrorType } from '../../../app/constants/error';
 import Engine from './../../core/Engine';
@@ -120,6 +121,7 @@ describe('network-utils', () => {
       expect(allNetworks).toStrictEqual([
         MAINNET,
         LINEA_MAINNET,
+        BASE_MAINNET,
         SEPOLIA,
         LINEA_SEPOLIA,
         MEGAETH_TESTNET,