mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-22 09:23:21 +01:00
feat: add new linea mainnet network (#19326)
* feat: add new linea mainnet network * fix: removed unused condition + lint code * fix: update tests + fix network tab issue * feat: add feature toggle for linea mainnet * fix: add feature toggle for linea mainnet * feat: add linea mainnet logo * update @metamask/eth-json-rpc-infura package to support linea networks * update linea mainnet block explorer url * fix: refactor linea mainnet feature toggle * fix: update linea mainnet chain id and rpc url * fix: update settings-search unit test * fix: update linea mainnet feature flag * fix: remove useless async function keyword for linea mainnet feature flag
This commit is contained in:
parent
70d86ee67c
commit
e4923399a9
6
app/_locales/en/messages.json
generated
6
app/_locales/en/messages.json
generated
@ -805,6 +805,9 @@
|
||||
"connectingToLineaGoerli": {
|
||||
"message": "Connecting to Linea Goerli test network"
|
||||
},
|
||||
"connectingToLineaMainnet": {
|
||||
"message": "Connecting to Linea Mainnet"
|
||||
},
|
||||
"connectingToMainnet": {
|
||||
"message": "Connecting to Ethereum Mainnet"
|
||||
},
|
||||
@ -2138,6 +2141,9 @@
|
||||
"lineaGoerli": {
|
||||
"message": "Linea Goerli test network"
|
||||
},
|
||||
"lineaMainnet": {
|
||||
"message": "Linea Mainnet"
|
||||
},
|
||||
"link": {
|
||||
"message": "Link"
|
||||
},
|
||||
|
BIN
app/images/linea-logo-mainnet.png
Normal file
BIN
app/images/linea-logo-mainnet.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
@ -6,6 +6,7 @@ import { setDashboardCookie } from '@metamask-institutional/portfolio-dashboard'
|
||||
import { IPFS_DEFAULT_GATEWAY_URL } from '../../../shared/constants/network';
|
||||
import { LedgerTransportTypes } from '../../../shared/constants/hardware-wallets';
|
||||
import { ThemeType } from '../../../shared/constants/preferences';
|
||||
import { shouldShowLineaMainnet } from '../../../shared/modules/network.utils';
|
||||
|
||||
export default class PreferencesController {
|
||||
/**
|
||||
@ -69,6 +70,7 @@ export default class PreferencesController {
|
||||
: LedgerTransportTypes.u2f,
|
||||
transactionSecurityCheckEnabled: false,
|
||||
theme: ThemeType.os,
|
||||
isLineaMainnetReleased: false,
|
||||
...opts.initState,
|
||||
};
|
||||
|
||||
@ -92,6 +94,8 @@ export default class PreferencesController {
|
||||
global.setPreference = (key, value) => {
|
||||
return this.setFeatureFlag(key, value);
|
||||
};
|
||||
|
||||
this._showShouldLineaMainnetNetwork();
|
||||
}
|
||||
// PUBLIC METHODS
|
||||
|
||||
@ -574,4 +578,12 @@ export default class PreferencesController {
|
||||
|
||||
this.store.updateState({ infuraBlocked: isBlocked });
|
||||
}
|
||||
|
||||
/**
|
||||
* A method to check is the linea mainnet network should be displayed
|
||||
*/
|
||||
_showShouldLineaMainnetNetwork() {
|
||||
const showLineaMainnet = shouldShowLineaMainnet();
|
||||
this.store.updateState({ isLineaMainnetReleased: showLineaMainnet });
|
||||
}
|
||||
}
|
||||
|
@ -280,7 +280,8 @@ export default class TransactionController extends EventEmitter {
|
||||
if (
|
||||
type !== NETWORK_TYPES.RPC &&
|
||||
type !== NETWORK_TYPES.SEPOLIA &&
|
||||
type !== NETWORK_TYPES.LINEA_GOERLI
|
||||
type !== NETWORK_TYPES.LINEA_GOERLI &&
|
||||
type !== NETWORK_TYPES.LINEA_MAINNET
|
||||
) {
|
||||
return new Common({
|
||||
chain: type,
|
||||
|
@ -305,7 +305,8 @@
|
||||
"mainnet": "ok",
|
||||
"goerli": "ok",
|
||||
"sepolia": "ok",
|
||||
"lineaGoerli": "ok"
|
||||
"lineaGoerli": "ok",
|
||||
"lineaMainnet": "ok"
|
||||
}
|
||||
},
|
||||
"send": {
|
||||
|
@ -96,6 +96,7 @@ export const NETWORK_TYPES = {
|
||||
RPC: 'rpc',
|
||||
SEPOLIA: 'sepolia',
|
||||
LINEA_GOERLI: 'linea-goerli',
|
||||
LINEA_MAINNET: 'linea-mainnet',
|
||||
} as const;
|
||||
|
||||
/**
|
||||
@ -122,6 +123,7 @@ export const NETWORK_IDS = {
|
||||
LOCALHOST: '1337',
|
||||
SEPOLIA: '11155111',
|
||||
LINEA_GOERLI: '59140',
|
||||
LINEA_MAINNET: '59144',
|
||||
} as const;
|
||||
|
||||
/**
|
||||
@ -148,6 +150,7 @@ export const CHAIN_IDS = {
|
||||
PALM: '0x2a15c308d',
|
||||
SEPOLIA: '0xaa36a7',
|
||||
LINEA_GOERLI: '0xe704',
|
||||
LINEA_MAINNET: '0xe708',
|
||||
AURORA: '0x4e454152',
|
||||
MOONBEAM: '0x504',
|
||||
MOONBEAM_TESTNET: '0x507',
|
||||
@ -165,6 +168,7 @@ export const MAINNET_DISPLAY_NAME = 'Ethereum Mainnet';
|
||||
export const GOERLI_DISPLAY_NAME = 'Goerli';
|
||||
export const SEPOLIA_DISPLAY_NAME = 'Sepolia';
|
||||
export const LINEA_GOERLI_DISPLAY_NAME = 'Linea Goerli';
|
||||
export const LINEA_MAINNET_DISPLAY_NAME = 'Linea Mainnet';
|
||||
export const LOCALHOST_DISPLAY_NAME = 'Localhost 8545';
|
||||
export const BSC_DISPLAY_NAME = 'Binance Smart Chain';
|
||||
export const POLYGON_DISPLAY_NAME = 'Polygon';
|
||||
@ -197,6 +201,9 @@ export const SEPOLIA_RPC_URL = getRpcUrl({ network: NETWORK_TYPES.SEPOLIA });
|
||||
export const LINEA_GOERLI_RPC_URL = getRpcUrl({
|
||||
network: NETWORK_TYPES.LINEA_GOERLI,
|
||||
});
|
||||
export const LINEA_MAINNET_RPC_URL = getRpcUrl({
|
||||
network: NETWORK_TYPES.LINEA_MAINNET,
|
||||
});
|
||||
export const LOCALHOST_RPC_URL = 'http://localhost:8545';
|
||||
|
||||
/**
|
||||
@ -230,6 +237,7 @@ export const CURRENCY_SYMBOLS = {
|
||||
|
||||
export const ETH_TOKEN_IMAGE_URL = './images/eth_logo.png';
|
||||
export const LINEA_GOERLI_TOKEN_IMAGE_URL = './images/linea-logo-testnet.png';
|
||||
export const LINEA_MAINNET_TOKEN_IMAGE_URL = './images/linea-logo-mainnet.png';
|
||||
export const TEST_ETH_TOKEN_IMAGE_URL = './images/black-eth-logo.svg';
|
||||
export const BNB_TOKEN_IMAGE_URL = './images/bnb.png';
|
||||
export const MATIC_TOKEN_IMAGE_URL = './images/matic-token.png';
|
||||
@ -247,6 +255,7 @@ export const INFURA_PROVIDER_TYPES = [
|
||||
NETWORK_TYPES.GOERLI,
|
||||
NETWORK_TYPES.SEPOLIA,
|
||||
NETWORK_TYPES.LINEA_GOERLI,
|
||||
NETWORK_TYPES.LINEA_MAINNET,
|
||||
] as const;
|
||||
|
||||
export const TEST_CHAINS = [
|
||||
@ -260,7 +269,10 @@ const typedCapitalize = <K extends string>(k: K): Capitalize<K> =>
|
||||
capitalize(k) as Capitalize<typeof k>;
|
||||
|
||||
export const TEST_NETWORK_TICKER_MAP: {
|
||||
[K in Exclude<NetworkType, 'localhost' | 'mainnet' | 'rpc'>]: string;
|
||||
[K in Exclude<
|
||||
NetworkType,
|
||||
'localhost' | 'mainnet' | 'rpc' | 'linea-mainnet'
|
||||
>]: string;
|
||||
} = {
|
||||
[NETWORK_TYPES.GOERLI]: `${typedCapitalize(NETWORK_TYPES.GOERLI)}${
|
||||
CURRENCY_SYMBOLS.ETH
|
||||
@ -298,6 +310,11 @@ export const BUILT_IN_NETWORKS = {
|
||||
chainId: CHAIN_IDS.MAINNET,
|
||||
blockExplorerUrl: `https://etherscan.io`,
|
||||
},
|
||||
[NETWORK_TYPES.LINEA_MAINNET]: {
|
||||
networkId: NETWORK_IDS.LINEA_MAINNET,
|
||||
chainId: CHAIN_IDS.LINEA_MAINNET,
|
||||
blockExplorerUrl: 'https://lineascan.build',
|
||||
},
|
||||
[NETWORK_TYPES.LOCALHOST]: {
|
||||
networkId: NETWORK_IDS.LOCALHOST,
|
||||
chainId: CHAIN_IDS.LOCALHOST,
|
||||
@ -316,18 +333,21 @@ export const NETWORK_TO_NAME_MAP = {
|
||||
[NETWORK_TYPES.GOERLI]: GOERLI_DISPLAY_NAME,
|
||||
[NETWORK_TYPES.SEPOLIA]: SEPOLIA_DISPLAY_NAME,
|
||||
[NETWORK_TYPES.LINEA_GOERLI]: LINEA_GOERLI_DISPLAY_NAME,
|
||||
[NETWORK_TYPES.LINEA_MAINNET]: LINEA_MAINNET_DISPLAY_NAME,
|
||||
[NETWORK_TYPES.LOCALHOST]: LOCALHOST_DISPLAY_NAME,
|
||||
|
||||
[NETWORK_IDS.GOERLI]: GOERLI_DISPLAY_NAME,
|
||||
[NETWORK_IDS.SEPOLIA]: SEPOLIA_DISPLAY_NAME,
|
||||
[NETWORK_IDS.LINEA_GOERLI]: LINEA_GOERLI_DISPLAY_NAME,
|
||||
[NETWORK_IDS.MAINNET]: MAINNET_DISPLAY_NAME,
|
||||
[NETWORK_IDS.LINEA_MAINNET]: LINEA_MAINNET_DISPLAY_NAME,
|
||||
[NETWORK_IDS.LOCALHOST]: LOCALHOST_DISPLAY_NAME,
|
||||
|
||||
[CHAIN_IDS.GOERLI]: GOERLI_DISPLAY_NAME,
|
||||
[CHAIN_IDS.SEPOLIA]: SEPOLIA_DISPLAY_NAME,
|
||||
[CHAIN_IDS.LINEA_GOERLI]: LINEA_GOERLI_DISPLAY_NAME,
|
||||
[CHAIN_IDS.MAINNET]: MAINNET_DISPLAY_NAME,
|
||||
[CHAIN_IDS.LINEA_MAINNET]: LINEA_MAINNET_DISPLAY_NAME,
|
||||
[CHAIN_IDS.LOCALHOST]: LOCALHOST_DISPLAY_NAME,
|
||||
} as const;
|
||||
|
||||
@ -336,6 +356,7 @@ export const CHAIN_ID_TO_TYPE_MAP = {
|
||||
[CHAIN_IDS.GOERLI]: NETWORK_TYPES.GOERLI,
|
||||
[CHAIN_IDS.SEPOLIA]: NETWORK_TYPES.SEPOLIA,
|
||||
[CHAIN_IDS.LINEA_GOERLI]: NETWORK_TYPES.LINEA_GOERLI,
|
||||
[CHAIN_IDS.LINEA_MAINNET]: NETWORK_TYPES.LINEA_MAINNET,
|
||||
[CHAIN_IDS.LOCALHOST]: NETWORK_TYPES.LOCALHOST,
|
||||
} as const;
|
||||
|
||||
@ -344,12 +365,14 @@ export const CHAIN_ID_TO_RPC_URL_MAP = {
|
||||
[CHAIN_IDS.SEPOLIA]: SEPOLIA_RPC_URL,
|
||||
[CHAIN_IDS.LINEA_GOERLI]: LINEA_GOERLI_RPC_URL,
|
||||
[CHAIN_IDS.MAINNET]: MAINNET_RPC_URL,
|
||||
[CHAIN_IDS.LINEA_MAINNET]: LINEA_MAINNET_RPC_URL,
|
||||
[CHAIN_IDS.LOCALHOST]: LOCALHOST_RPC_URL,
|
||||
} as const;
|
||||
|
||||
export const CHAIN_ID_TO_NETWORK_IMAGE_URL_MAP = {
|
||||
[CHAIN_IDS.MAINNET]: ETH_TOKEN_IMAGE_URL,
|
||||
[CHAIN_IDS.LINEA_GOERLI]: LINEA_GOERLI_TOKEN_IMAGE_URL,
|
||||
[CHAIN_IDS.LINEA_MAINNET]: LINEA_MAINNET_TOKEN_IMAGE_URL,
|
||||
[CHAIN_IDS.AVALANCHE]: AVAX_TOKEN_IMAGE_URL,
|
||||
[CHAIN_IDS.BSC]: BNB_TOKEN_IMAGE_URL,
|
||||
[CHAIN_IDS.POLYGON]: MATIC_TOKEN_IMAGE_URL,
|
||||
@ -367,6 +390,7 @@ export const NETWORK_ID_TO_ETHERS_NETWORK_NAME_MAP = {
|
||||
[NETWORK_IDS.SEPOLIA]: NETWORK_TYPES.SEPOLIA,
|
||||
[NETWORK_IDS.LINEA_GOERLI]: NETWORK_TYPES.LINEA_GOERLI,
|
||||
[NETWORK_IDS.MAINNET]: NETWORK_NAMES.HOMESTEAD,
|
||||
[NETWORK_IDS.LINEA_MAINNET]: NETWORK_TYPES.LINEA_MAINNET,
|
||||
} as const;
|
||||
|
||||
export const CHAIN_ID_TO_NETWORK_ID_MAP = {
|
||||
@ -374,6 +398,7 @@ export const CHAIN_ID_TO_NETWORK_ID_MAP = {
|
||||
[CHAIN_IDS.GOERLI]: NETWORK_IDS.GOERLI,
|
||||
[CHAIN_IDS.SEPOLIA]: NETWORK_IDS.SEPOLIA,
|
||||
[CHAIN_IDS.LINEA_GOERLI]: NETWORK_IDS.LINEA_GOERLI,
|
||||
[CHAIN_IDS.LINEA_MAINNET]: NETWORK_IDS.LINEA_MAINNET,
|
||||
[CHAIN_IDS.LOCALHOST]: NETWORK_IDS.LOCALHOST,
|
||||
} as const;
|
||||
|
||||
@ -420,6 +445,11 @@ export const ETHERSCAN_SUPPORTED_NETWORKS = {
|
||||
subdomain: 'goerli',
|
||||
networkId: CHAIN_ID_TO_NETWORK_ID_MAP[CHAIN_IDS.LINEA_GOERLI],
|
||||
},
|
||||
[CHAIN_IDS.LINEA_MAINNET]: {
|
||||
domain: 'lineascan.build',
|
||||
subdomain: defaultEtherscanSubdomainPrefix,
|
||||
networkId: CHAIN_ID_TO_NETWORK_ID_MAP[CHAIN_IDS.LINEA_MAINNET],
|
||||
},
|
||||
[CHAIN_IDS.BSC]: {
|
||||
domain: 'bscscan.com',
|
||||
subdomain: defaultEtherscanSubdomainPrefix,
|
||||
@ -519,6 +549,7 @@ export const BUYABLE_CHAINS_MAP: {
|
||||
| typeof CHAIN_IDS.FANTOM_TESTNET
|
||||
| typeof CHAIN_IDS.MOONBEAM_TESTNET
|
||||
| typeof CHAIN_IDS.LINEA_GOERLI
|
||||
| typeof CHAIN_IDS.LINEA_MAINNET
|
||||
| typeof CHAIN_IDS.GOERLI
|
||||
>]: BuyableChainSettings;
|
||||
} = {
|
||||
|
@ -56,3 +56,7 @@ export function isTokenDetectionEnabledForNetwork(chainId: string | undefined) {
|
||||
function isSafeInteger(value: unknown): value is number {
|
||||
return Number.isSafeInteger(value);
|
||||
}
|
||||
|
||||
export function shouldShowLineaMainnet(): boolean {
|
||||
return new Date().getTime() > Date.UTC(2023, 6, 11, 18);
|
||||
}
|
||||
|
@ -161,6 +161,7 @@ function defaultFixture() {
|
||||
trezorModel: null,
|
||||
usedNetworks: {
|
||||
[CHAIN_IDS.MAINNET]: true,
|
||||
[CHAIN_IDS.LINEA_MAINNET]: true,
|
||||
[CHAIN_IDS.GOERLI]: true,
|
||||
[CHAIN_IDS.LOCALHOST]: true,
|
||||
},
|
||||
@ -187,6 +188,7 @@ function defaultFixture() {
|
||||
incomingTransactions: {},
|
||||
incomingTxLastFetchedBlockByChainId: {
|
||||
[CHAIN_IDS.MAINNET]: null,
|
||||
[CHAIN_IDS.LINEA_MAINNET]: null,
|
||||
[CHAIN_IDS.GOERLI]: null,
|
||||
[CHAIN_IDS.SEPOLIA]: null,
|
||||
[CHAIN_IDS.LINEA_GOERLI]: null,
|
||||
@ -329,6 +331,7 @@ function onboardingFixture() {
|
||||
trezorModel: null,
|
||||
usedNetworks: {
|
||||
[CHAIN_IDS.MAINNET]: true,
|
||||
[CHAIN_IDS.LINEA_MAINNET]: true,
|
||||
[CHAIN_IDS.GOERLI]: true,
|
||||
[CHAIN_IDS.LOCALHOST]: true,
|
||||
},
|
||||
|
@ -66,6 +66,8 @@ export default class LoadingNetworkScreen extends PureComponent {
|
||||
return t('connectingToSepolia');
|
||||
case NETWORK_TYPES.LINEA_GOERLI:
|
||||
return t('connectingToLineaGoerli');
|
||||
case NETWORK_TYPES.LINEA_MAINNET:
|
||||
return t('connectingToLineaMainnet');
|
||||
default:
|
||||
return t('connectingTo', [providerId]);
|
||||
}
|
||||
|
@ -62,6 +62,9 @@ function renderBackgroundColor(color) {
|
||||
case Color.lineaGoerliInverse:
|
||||
bgColor = BackgroundColor.lineaGoerli;
|
||||
break;
|
||||
case Color.lineaMainnetInverse:
|
||||
bgColor = BackgroundColor.lineaMainnet;
|
||||
break;
|
||||
default:
|
||||
bgColor = null;
|
||||
break;
|
||||
|
@ -37,9 +37,16 @@ import {
|
||||
MetaMetricsEventCategory,
|
||||
MetaMetricsEventName,
|
||||
} from '../../../../shared/constants/metametrics';
|
||||
import { getCompletedOnboarding } from '../../../ducks/metamask/metamask';
|
||||
import {
|
||||
getCompletedOnboarding,
|
||||
isLineaMainnetNetworkReleased,
|
||||
} from '../../../ducks/metamask/metamask';
|
||||
|
||||
const UNREMOVABLE_CHAIN_IDS = [CHAIN_IDS.MAINNET, ...TEST_CHAINS];
|
||||
const UNREMOVABLE_CHAIN_IDS = [
|
||||
CHAIN_IDS.MAINNET,
|
||||
CHAIN_IDS.LINEA_MAINNET,
|
||||
...TEST_CHAINS,
|
||||
];
|
||||
|
||||
export const NetworkListMenu = ({ onClose }) => {
|
||||
const t = useI18nContext();
|
||||
@ -58,6 +65,8 @@ export const NetworkListMenu = ({ onClose }) => {
|
||||
|
||||
const completedOnboarding = useSelector(getCompletedOnboarding);
|
||||
|
||||
const lineaMainnetReleased = useSelector(isLineaMainnetNetworkReleased);
|
||||
|
||||
useEffect(() => {
|
||||
if (showTestNetworks && !showTestNetworksRef.current) {
|
||||
// Scroll to the bottom of the list
|
||||
@ -76,6 +85,12 @@ export const NetworkListMenu = ({ onClose }) => {
|
||||
<>
|
||||
<Box className="multichain-network-list-menu" ref={networkListRef}>
|
||||
{networks.map((network, index) => {
|
||||
if (
|
||||
!lineaMainnetReleased &&
|
||||
network.providerType === 'linea-mainnet'
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
const isCurrentNetwork = currentChainId === network.chainId;
|
||||
const canDeleteNetwork =
|
||||
!isCurrentNetwork &&
|
||||
|
@ -26,6 +26,7 @@ import Chip from '../chip/chip';
|
||||
import { setFirstTimeUsedNetwork } from '../../../store/actions';
|
||||
import { NETWORK_TYPES } from '../../../../shared/constants/network';
|
||||
import { Icon, IconName, Text } from '../../component-library';
|
||||
import { getNetworkLabelKey } from '../../../helpers/utils/i18n-helper';
|
||||
|
||||
const NewNetworkInfo = () => {
|
||||
const t = useContext(I18nContext);
|
||||
@ -95,7 +96,7 @@ const NewNetworkInfo = () => {
|
||||
label={
|
||||
providerConfig.type === NETWORK_TYPES.RPC
|
||||
? providerConfig.nickname ?? t('privateNetwork')
|
||||
: t(providerConfig.type)
|
||||
: t(getNetworkLabelKey(providerConfig.type))
|
||||
}
|
||||
labelProps={{
|
||||
color: Color.textDefault,
|
||||
|
@ -35,6 +35,8 @@ export const ValidColors = [
|
||||
Color.sepoliaInverse,
|
||||
Color.lineaGoerli,
|
||||
Color.lineaGoerliInverse,
|
||||
Color.lineaMainnet,
|
||||
Color.lineaMainnetInverse,
|
||||
];
|
||||
|
||||
export const ValidTags = [
|
||||
|
@ -43,6 +43,8 @@ $color-map: (
|
||||
'sepolia-inverse': --color-network-sepolia-inverse,
|
||||
'linea-goerli': --color-network-linea-goerli-default,
|
||||
'linea-goerli-inverse': --color-network-linea-goerli-inverse,
|
||||
'linea-mainnet': --color-network-linea-mainnet-default,
|
||||
'linea-mainnet-inverse': --color-network-linea-mainnet-inverse,
|
||||
'localhost': --color-network-localhost-default,
|
||||
'transparent': --transparent,
|
||||
'flask-purple': --color-flask-default,
|
||||
|
@ -4,8 +4,10 @@
|
||||
--mainnet: #29b6af;
|
||||
--inherit: inherit;
|
||||
--transparent: transparent;
|
||||
--color-network-linea-goerli-default: #000;
|
||||
--color-network-linea-goerli-default: #61dfff;
|
||||
--color-network-linea-goerli-inverse: #fcfcfc;
|
||||
--color-network-linea-mainnet-default: #121212;
|
||||
--color-network-linea-mainnet-inverse: #fcfcfc;
|
||||
// DO NOT CHANGE
|
||||
// Required for the QR reader to work properly
|
||||
--qr-code-white-background: #fff;
|
||||
|
@ -426,3 +426,7 @@ export function doesUserHaveALedgerAccount(state) {
|
||||
return kr.type === KeyringType.ledger;
|
||||
});
|
||||
}
|
||||
|
||||
export function isLineaMainnetNetworkReleased(state) {
|
||||
return state.metamask.isLineaMainnetReleased;
|
||||
}
|
||||
|
@ -48,6 +48,8 @@ export enum Color {
|
||||
sepolia = 'sepolia',
|
||||
lineaGoerli = 'linea-goerli',
|
||||
lineaGoerliInverse = 'linea-goerli-inverse',
|
||||
lineaMainnet = 'linea-mainnet',
|
||||
lineaMainnetInverse = 'linea-mainnet-inverse',
|
||||
transparent = 'transparent',
|
||||
localhost = 'localhost',
|
||||
inherit = 'inherit',
|
||||
@ -78,6 +80,7 @@ export enum BackgroundColor {
|
||||
goerli = 'goerli',
|
||||
sepolia = 'sepolia',
|
||||
lineaGoerli = 'linea-goerli',
|
||||
lineaMainnet = 'linea-mainnet',
|
||||
transparent = 'transparent',
|
||||
localhost = 'localhost',
|
||||
}
|
||||
@ -104,6 +107,7 @@ export enum BorderColor {
|
||||
goerli = 'goerli',
|
||||
sepolia = 'sepolia',
|
||||
lineaGoerli = 'linea-goerli',
|
||||
lineaMainnet = 'linea-mainnet',
|
||||
transparent = 'transparent',
|
||||
localhost = 'localhost',
|
||||
backgroundDefault = 'background-default', // exception for border color when element is meant to look "cut out"
|
||||
@ -129,6 +133,8 @@ export enum TextColor {
|
||||
sepolia = 'sepolia',
|
||||
lineaGoerli = 'linea-goerli',
|
||||
lineaGoerliInverse = 'linea-goerli-inverse',
|
||||
lineaMainnet = 'linea-mainnet',
|
||||
lineaMainnetInverse = 'linea-mainnet-inverse',
|
||||
goerliInverse = 'goerli-inverse',
|
||||
sepoliaInverse = 'sepolia-inverse',
|
||||
transparent = 'transparent',
|
||||
@ -154,6 +160,8 @@ export enum IconColor {
|
||||
sepolia = 'sepolia',
|
||||
lineaGoerli = 'linea-goerli',
|
||||
lineaGoerliInverse = 'linea-goerli-inverse',
|
||||
lineaMainnet = 'linea-mainnet',
|
||||
lineaMainnetInverse = 'linea-mainnet-inverse',
|
||||
goerliInverse = 'goerli-inverse',
|
||||
sepoliaInverse = 'sepolia-inverse',
|
||||
}
|
||||
|
@ -226,6 +226,13 @@ export const SETTINGS_CONSTANTS = [
|
||||
route: `${NETWORKS_ROUTE}#networks-mainnet`,
|
||||
icon: 'fa fa-plug',
|
||||
},
|
||||
{
|
||||
tabMessage: (t) => t('networks'),
|
||||
sectionMessage: (t) => t('lineaMainnet'),
|
||||
descriptionMessage: (t) => t('lineaMainnet'),
|
||||
route: `${NETWORKS_ROUTE}#networks-linea-mainnet`,
|
||||
icon: 'fa fa-plug',
|
||||
},
|
||||
{
|
||||
tabMessage: (t) => t('networks'),
|
||||
sectionMessage: (t) => t('goerli'),
|
||||
|
@ -171,5 +171,8 @@ export function getNetworkLabelKey(network: string): string {
|
||||
if (network === NETWORK_TYPES.LINEA_GOERLI) {
|
||||
return 'lineaGoerli';
|
||||
}
|
||||
if (network === NETWORK_TYPES.LINEA_MAINNET) {
|
||||
return 'lineaMainnet';
|
||||
}
|
||||
return network;
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ describe('Settings Search Utils', () => {
|
||||
});
|
||||
|
||||
it('should get good network section number', () => {
|
||||
expect(getNumberOfSettingsInSection(t, t('networks'))).toStrictEqual(5);
|
||||
expect(getNumberOfSettingsInSection(t, t('networks'))).toStrictEqual(6);
|
||||
});
|
||||
|
||||
it('should get good experimental section number', () => {
|
||||
|
@ -62,6 +62,7 @@ export function isDefaultMetaMaskChain(chainId) {
|
||||
if (
|
||||
!chainId ||
|
||||
chainId === CHAIN_IDS.MAINNET ||
|
||||
chainId === CHAIN_IDS.LINEA_MAINNET ||
|
||||
chainId === CHAIN_IDS.GOERLI ||
|
||||
chainId === CHAIN_IDS.SEPOLIA ||
|
||||
chainId === CHAIN_IDS.LINEA_GOERLI ||
|
||||
|
@ -426,7 +426,9 @@ export default class ConfirmApproveContent extends Component {
|
||||
this.props;
|
||||
const useBlockExplorer =
|
||||
rpcPrefs?.blockExplorerUrl ||
|
||||
[...TEST_CHAINS, CHAIN_IDS.MAINNET].includes(chainId);
|
||||
[...TEST_CHAINS, CHAIN_IDS.MAINNET, CHAIN_IDS.LINEA_MAINNET].includes(
|
||||
chainId,
|
||||
);
|
||||
|
||||
const titleTokenDescription = this.getTokenName();
|
||||
const tokenIdWrapped = tokenId ? ` (#${tokenId})` : '';
|
||||
|
@ -64,7 +64,9 @@ export default function ConfirmTokenTransactionBase({
|
||||
const getTitleTokenDescription = (renderType) => {
|
||||
const useBlockExplorer =
|
||||
rpcPrefs?.blockExplorerUrl ||
|
||||
[...TEST_CHAINS, CHAIN_IDS.MAINNET].includes(chainId);
|
||||
[...TEST_CHAINS, CHAIN_IDS.MAINNET, CHAIN_IDS.LINEA_MAINNET].includes(
|
||||
chainId,
|
||||
);
|
||||
|
||||
const nftCollection = nftCollections.find(
|
||||
(collection) =>
|
||||
|
@ -601,6 +601,8 @@ export default class Routes extends Component {
|
||||
return t('connectingToSepolia');
|
||||
case NETWORK_TYPES.LINEA_GOERLI:
|
||||
return t('connectingToLineaGoerli');
|
||||
case NETWORK_TYPES.LINEA_MAINNET:
|
||||
return t('connectingToLineaMainnet');
|
||||
default:
|
||||
return t('connectingTo', [providerId]);
|
||||
}
|
||||
|
@ -97,13 +97,13 @@ const NetworksListItem = ({
|
||||
<UrlIcon
|
||||
className="networks-tab__content__icon-with-fallback"
|
||||
fallbackClassName="networks-tab__content__icon-with-fallback"
|
||||
name={label}
|
||||
name={label || getNetworkLabelKey(labelKey)}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
{network.isATestNetwork && network.chainId !== CHAIN_IDS.LINEA_GOERLI && (
|
||||
<UrlIcon
|
||||
name={label || labelKey}
|
||||
name={label || getNetworkLabelKey(labelKey)}
|
||||
fallbackClassName={classnames(
|
||||
'networks-tab__content__icon-with-fallback',
|
||||
{
|
||||
|
@ -45,7 +45,7 @@ const defaultNetworksData = [
|
||||
},
|
||||
{
|
||||
labelKey: NETWORK_TYPES.LINEA_GOERLI,
|
||||
iconColor: '#234FD5',
|
||||
iconColor: '#61dfff',
|
||||
providerType: NETWORK_TYPES.LINEA_GOERLI,
|
||||
rpcUrl: getRpcUrl({
|
||||
network: NETWORK_TYPES.LINEA_GOERLI,
|
||||
@ -55,6 +55,18 @@ const defaultNetworksData = [
|
||||
ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.LINEA_GOERLI],
|
||||
blockExplorerUrl: 'https://goerli.lineascan.build',
|
||||
},
|
||||
{
|
||||
labelKey: NETWORK_TYPES.LINEA_MAINNET,
|
||||
iconColor: '#121212',
|
||||
providerType: NETWORK_TYPES.LINEA_MAINNET,
|
||||
rpcUrl: getRpcUrl({
|
||||
network: NETWORK_TYPES.LINEA_MAINNET,
|
||||
excludeProjectId: true,
|
||||
}),
|
||||
chainId: CHAIN_IDS.LINEA_MAINNET,
|
||||
ticker: CURRENCY_SYMBOLS.ETH,
|
||||
blockExplorerUrl: 'https://lineascan.build',
|
||||
},
|
||||
];
|
||||
|
||||
export { defaultNetworksData };
|
||||
|
@ -18,10 +18,14 @@ import {
|
||||
getNetworkConfigurations,
|
||||
getNetworksTabSelectedNetworkConfigurationId,
|
||||
} from '../../../selectors';
|
||||
import { getProviderConfig } from '../../../ducks/metamask/metamask';
|
||||
import {
|
||||
getProviderConfig,
|
||||
isLineaMainnetNetworkReleased,
|
||||
} from '../../../ducks/metamask/metamask';
|
||||
import {
|
||||
NETWORK_TYPES,
|
||||
TEST_CHAINS,
|
||||
BUILT_IN_NETWORKS,
|
||||
} from '../../../../shared/constants/network';
|
||||
import { defaultNetworksData } from './networks-tab.constants';
|
||||
import NetworksTabContent from './networks-tab-content';
|
||||
@ -52,6 +56,7 @@ const NetworksTab = ({ addNewNetwork }) => {
|
||||
const networksTabSelectedNetworkConfigurationId = useSelector(
|
||||
getNetworksTabSelectedNetworkConfigurationId,
|
||||
);
|
||||
const isLineaMainnetReleased = useSelector(isLineaMainnetNetworkReleased);
|
||||
|
||||
const networkConfigurationsList = Object.entries(networkConfigurations).map(
|
||||
([networkConfigurationId, networkConfiguration]) => {
|
||||
@ -69,8 +74,14 @@ const NetworksTab = ({ addNewNetwork }) => {
|
||||
},
|
||||
);
|
||||
|
||||
const networksToRender = [...defaultNetworks, ...networkConfigurationsList];
|
||||
|
||||
let networksToRender = [...defaultNetworks, ...networkConfigurationsList];
|
||||
if (!isLineaMainnetReleased) {
|
||||
networksToRender = networksToRender.filter(
|
||||
(network) =>
|
||||
network.chainId !==
|
||||
BUILT_IN_NETWORKS[NETWORK_TYPES.LINEA_MAINNET].chainId,
|
||||
);
|
||||
}
|
||||
let selectedNetwork =
|
||||
networksToRender.find(
|
||||
(network) =>
|
||||
|
@ -34,6 +34,8 @@ import {
|
||||
CURRENCY_SYMBOLS,
|
||||
TEST_NETWORK_TICKER_MAP,
|
||||
LINEA_GOERLI_TOKEN_IMAGE_URL,
|
||||
LINEA_MAINNET_TOKEN_IMAGE_URL,
|
||||
LINEA_MAINNET_DISPLAY_NAME,
|
||||
} from '../../shared/constants/network';
|
||||
import {
|
||||
WebHIDConnectedStatuses,
|
||||
@ -1198,6 +1200,16 @@ export function getAllNetworks(state) {
|
||||
providerType: NETWORK_TYPES.MAINNET,
|
||||
ticker: CURRENCY_SYMBOLS.ETH,
|
||||
},
|
||||
{
|
||||
chainId: CHAIN_IDS.LINEA_MAINNET,
|
||||
nickname: LINEA_MAINNET_DISPLAY_NAME,
|
||||
rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.LINEA_MAINNET],
|
||||
rpcPrefs: {
|
||||
imageUrl: LINEA_MAINNET_TOKEN_IMAGE_URL,
|
||||
},
|
||||
providerType: NETWORK_TYPES.LINEA_MAINNET,
|
||||
ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.LINEA_MAINNET],
|
||||
},
|
||||
// Custom networks added by the user
|
||||
...Object.values(networkConfigurations).filter(
|
||||
({ chainId }) => ![CHAIN_IDS.LOCALHOST].includes(chainId),
|
||||
|
@ -7,6 +7,14 @@ import {
|
||||
} from '../../shared/constants/network';
|
||||
import * as selectors from './selectors';
|
||||
|
||||
jest.mock('../../shared/modules/network.utils', () => {
|
||||
const actual = jest.requireActual('../../shared/modules/network.utils');
|
||||
return {
|
||||
...actual,
|
||||
shouldShowLineaMainnet: jest.fn().mockResolvedValue(true),
|
||||
};
|
||||
});
|
||||
|
||||
describe('Selectors', () => {
|
||||
describe('#getSelectedAddress', () => {
|
||||
it('returns undefined if selectedAddress is undefined', () => {
|
||||
@ -317,7 +325,7 @@ describe('Selectors', () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(networks).toHaveLength(1);
|
||||
expect(networks).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('returns networks with showTestNetworks on', () => {
|
||||
@ -328,7 +336,7 @@ describe('Selectors', () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(networks.length).toBeGreaterThan(1);
|
||||
expect(networks.length).toBeGreaterThan(2);
|
||||
});
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user