import { ethErrors } from 'eth-rpc-errors'; import React from 'react'; import { infuraProjectId } from '../../../../shared/constants/network'; import { Severity, TypographyVariant, TextAlign, Display, FlexDirection, AlignItems, JustifyContent, BackgroundColor, } from '../../../helpers/constants/design-system'; import { DEFAULT_ROUTE } from '../../../helpers/constants/routes'; import ZENDESK_URLS from '../../../helpers/constants/zendesk-url'; import fetchWithCache from '../../../../shared/lib/fetch-with-cache'; import { jsonRpcRequest } from '../../../../shared/modules/rpc.utils'; const UNRECOGNIZED_CHAIN = { id: 'UNRECOGNIZED_CHAIN', severity: Severity.Warning, content: { element: 'span', children: { element: 'MetaMaskTranslation', props: { translationKey: 'unrecognizedChain', }, }, }, }; const MISMATCHED_CHAIN_RECOMMENDATION = { id: 'MISMATCHED_CHAIN_RECOMMENDATION', severity: Severity.Warning, content: { element: 'span', children: { element: 'MetaMaskTranslation', props: { translationKey: 'mismatchedChainRecommendation', variables: [ { element: 'a', key: 'mismatchedChainLink', props: { href: ZENDESK_URLS.VERIFY_CUSTOM_NETWORK, target: '__blank', tabIndex: 0, }, children: { element: 'MetaMaskTranslation', props: { translationKey: 'mismatchedChainLinkText', }, }, }, ], }, }, }, }; const MISMATCHED_NETWORK_NAME = { id: 'MISMATCHED_NETWORK_NAME', severity: Severity.Warning, content: { element: 'span', children: { element: 'MetaMaskTranslation', props: { translationKey: 'mismatchedNetworkName', }, }, }, }; const MISMATCHED_NETWORK_SYMBOL = { id: 'MISMATCHED_NETWORK_SYMBOL', severity: Severity.Danger, content: { element: 'span', children: { element: 'MetaMaskTranslation', props: { translationKey: 'mismatchedNetworkSymbol', }, }, }, }; const MISMATCHED_NETWORK_RPC = { id: 'MISMATCHED_NETWORK_RPC', severity: Severity.Danger, content: { element: 'span', children: { element: 'MetaMaskTranslation', props: { translationKey: 'mismatchedRpcUrl', }, }, }, }; const MISMATCHED_NETWORK_RPC_CHAIN_ID = { id: 'MISMATCHED_NETWORK_RPC_CHAIN_ID', severity: Severity.Danger, content: { element: 'span', children: { element: 'MetaMaskTranslation', props: { translationKey: 'mismatchedRpcChainId', }, }, }, }; const ERROR_CONNECTING_TO_RPC = { id: 'ERROR_CONNECTING_TO_RPC', severity: Severity.Danger, content: { element: 'span', children: { element: 'MetaMaskTranslation', props: { translationKey: 'errorWhileConnectingToRPC', }, }, }, }; async function getAlerts(pendingApproval) { const alerts = []; const safeChainsList = (await fetchWithCache('https://chainid.network/chains.json')) || []; const matchedChain = safeChainsList.find( (chain) => chain.chainId === parseInt(pendingApproval.requestData.chainId, 16), ); const originIsMetaMask = pendingApproval.origin === 'metamask'; if (originIsMetaMask && Boolean(matchedChain)) { return []; } if (matchedChain) { if ( matchedChain.name.toLowerCase() !== pendingApproval.requestData.chainName.toLowerCase() ) { alerts.push(MISMATCHED_NETWORK_NAME); } if ( matchedChain.nativeCurrency?.symbol !== pendingApproval.requestData.ticker ) { alerts.push(MISMATCHED_NETWORK_SYMBOL); } const { origin } = new URL(pendingApproval.requestData.rpcUrl); if (!matchedChain.rpc.map((rpc) => new URL(rpc).origin).includes(origin)) { alerts.push(MISMATCHED_NETWORK_RPC); } } if (!matchedChain) { alerts.push(UNRECOGNIZED_CHAIN); } if (alerts.length) { alerts.push(MISMATCHED_CHAIN_RECOMMENDATION); } return alerts; } function getState(pendingApproval) { if (parseInt(pendingApproval.requestData.chainId, 16) === 1) { return { useWarningModal: true }; } return {}; } function getValues(pendingApproval, t, actions, history) { const originIsMetaMask = pendingApproval.origin === 'metamask'; const customRpcUrl = pendingApproval.requestData.rpcUrl; return { content: [ { hide: !originIsMetaMask, element: 'Box', key: 'network-box', props: { textAlign: TextAlign.Center, display: Display.Flex, justifyContent: JustifyContent.center, marginTop: 4, marginBottom: 2, }, children: [ { element: 'Chip', key: 'network-chip', props: { label: pendingApproval.requestData.chainName, backgroundColor: BackgroundColor.backgroundAlternative, leftIconUrl: pendingApproval.requestData.imageUrl, }, }, ], }, { element: 'Typography', key: 'title', children: originIsMetaMask ? t('wantToAddThisNetwork') : t('addEthereumChainConfirmationTitle'), props: { variant: TypographyVariant.H3, align: 'center', fontWeight: 'bold', boxProps: { margin: [0, 0, 4], }, }, }, { element: 'Typography', key: 'description', children: t('addEthereumChainConfirmationDescription'), props: { variant: TypographyVariant.H7, align: 'center', boxProps: { margin: originIsMetaMask ? [0, 8, 4] : [0, 0, 4], }, }, }, { element: 'Typography', key: 'only-add-networks-you-trust', children: [ { element: 'b', key: 'bolded-text', props: { style: { display: originIsMetaMask && '-webkit-box' }, }, children: [ `${t('addEthereumChainConfirmationRisks')} `, { hide: !originIsMetaMask, element: 'Tooltip', key: 'tooltip-info', props: { position: 'bottom', interactive: true, trigger: 'mouseenter', html: (