mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-25 03:20:23 +01:00
parent
33f9d6f480
commit
67dbac6b0d
4
app/_locales/en/messages.json
generated
4
app/_locales/en/messages.json
generated
@ -2346,6 +2346,10 @@
|
||||
"message": "Gas fees are $1 relative to the past 72 hours.",
|
||||
"description": "$1 is networks stability value - stable, low, high"
|
||||
},
|
||||
"networkSwitchConnectionError": {
|
||||
"message": "We can't connect to $1",
|
||||
"description": "$1 represents the network name"
|
||||
},
|
||||
"networkURL": {
|
||||
"message": "Network URL"
|
||||
},
|
||||
|
@ -1,9 +1,24 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Button from '../../ui/button';
|
||||
import LoadingScreen from '../../ui/loading-screen';
|
||||
import { SECOND } from '../../../../shared/constants/time';
|
||||
import { NETWORK_TYPES } from '../../../../shared/constants/network';
|
||||
import Popover from '../../ui/popover/popover.component';
|
||||
import {
|
||||
ButtonPrimary,
|
||||
ButtonSecondary,
|
||||
Icon,
|
||||
IconName,
|
||||
IconSize,
|
||||
Text,
|
||||
} from '../../component-library';
|
||||
import {
|
||||
DISPLAY,
|
||||
IconColor,
|
||||
TextAlign,
|
||||
TextVariant,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import Box from '../../ui/box/box';
|
||||
|
||||
export default class LoadingNetworkScreen extends PureComponent {
|
||||
state = {
|
||||
@ -56,63 +71,76 @@ export default class LoadingNetworkScreen extends PureComponent {
|
||||
}
|
||||
};
|
||||
|
||||
renderDeprecatedRpcUrlWarning = () => {
|
||||
const { showNetworkDropdown } = this.props;
|
||||
|
||||
return (
|
||||
<div className="loading-overlay__error-screen">
|
||||
<span className="loading-overlay__emoji">😞</span>
|
||||
<span>{this.context.t('currentRpcUrlDeprecated')}</span>
|
||||
<div className="loading-overlay__error-buttons">
|
||||
<Button
|
||||
type="secondary"
|
||||
onClick={() => {
|
||||
window.clearTimeout(this.cancelCallTimeout);
|
||||
showNetworkDropdown();
|
||||
}}
|
||||
>
|
||||
{this.context.t('switchNetworks')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
renderErrorScreenContent = () => {
|
||||
renderConnectionFailureNotification = (message, showTryAgain = false) => {
|
||||
const { showNetworkDropdown, setProviderArgs, setProviderType } =
|
||||
this.props;
|
||||
|
||||
return (
|
||||
<div className="loading-overlay__error-screen">
|
||||
<span className="loading-overlay__emoji">😞</span>
|
||||
<span>{this.context.t('somethingWentWrong')}</span>
|
||||
<div className="loading-overlay__error-buttons">
|
||||
<Button
|
||||
type="secondary"
|
||||
<Popover
|
||||
onClose={() => {
|
||||
window.clearTimeout(this.cancelCallTimeout);
|
||||
}}
|
||||
centerTitle
|
||||
title={
|
||||
<Icon
|
||||
name={IconName.Danger}
|
||||
size={IconSize.Xl}
|
||||
color={IconColor.warningDefault}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Text
|
||||
variant={TextVariant.bodyLgMedium}
|
||||
textAlign={TextAlign.Center}
|
||||
margin={[0, 4, 4, 4]}
|
||||
>
|
||||
{message}
|
||||
</Text>
|
||||
<Box display={DISPLAY.FLEX} padding={4} gap={2}>
|
||||
<ButtonSecondary
|
||||
onClick={() => {
|
||||
window.clearTimeout(this.cancelCallTimeout);
|
||||
showNetworkDropdown();
|
||||
}}
|
||||
variant={TextVariant.bodySm}
|
||||
block
|
||||
>
|
||||
{this.context.t('switchNetworks')}
|
||||
</Button>
|
||||
</ButtonSecondary>
|
||||
{showTryAgain ? (
|
||||
<ButtonPrimary
|
||||
onClick={() => {
|
||||
this.setState({ showErrorScreen: false });
|
||||
setProviderType(...setProviderArgs);
|
||||
window.clearTimeout(this.cancelCallTimeout);
|
||||
this.cancelCallTimeout = setTimeout(
|
||||
this.cancelCall,
|
||||
this.props.cancelTime || SECOND * 15,
|
||||
);
|
||||
}}
|
||||
variant={TextVariant.bodySm}
|
||||
block
|
||||
>
|
||||
{this.context.t('tryAgain')}
|
||||
</ButtonPrimary>
|
||||
) : null}
|
||||
</Box>
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
this.setState({ showErrorScreen: false });
|
||||
setProviderType(...setProviderArgs);
|
||||
window.clearTimeout(this.cancelCallTimeout);
|
||||
this.cancelCallTimeout = setTimeout(
|
||||
this.cancelCall,
|
||||
this.props.cancelTime || SECOND * 15,
|
||||
);
|
||||
}}
|
||||
>
|
||||
{this.context.t('tryAgain')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
renderDeprecatedRpcUrlWarning = () => {
|
||||
return this.renderConnectionFailureNotification(
|
||||
this.context.t('currentRpcUrlDeprecated'),
|
||||
false,
|
||||
);
|
||||
};
|
||||
|
||||
renderErrorScreenContent = () => {
|
||||
const { providerConfig } = this.props;
|
||||
return this.renderConnectionFailureNotification(
|
||||
this.context.t('networkSwitchConnectionError', [providerConfig.nickname]),
|
||||
true,
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,11 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { NETWORK_TYPES } from '../../../../shared/constants/network';
|
||||
import * as actions from '../../../store/actions';
|
||||
import { getNetworkIdentifier, isNetworkLoading } from '../../../selectors';
|
||||
import {
|
||||
getAllEnabledNetworks,
|
||||
getNetworkIdentifier,
|
||||
isNetworkLoading,
|
||||
} from '../../../selectors';
|
||||
import { getProviderConfig } from '../../../ducks/metamask/metamask';
|
||||
import LoadingNetworkScreen from './loading-network-screen.component';
|
||||
|
||||
@ -21,11 +25,27 @@ const mapStateToProps = (state) => {
|
||||
const isInfuraRpcUrl = rpcUrl && new URL(rpcUrl).host.endsWith('.infura.io');
|
||||
const showDeprecatedRpcUrlWarning = isDeprecatedNetwork && isInfuraRpcUrl;
|
||||
|
||||
// Ensure we have a nickname to provide the user
|
||||
// in case of connection error
|
||||
let networkName = nickname;
|
||||
if (networkName === undefined) {
|
||||
const networks = getAllEnabledNetworks(state);
|
||||
const desiredNetwork = networks.find(
|
||||
(network) => network.chainId === chainId,
|
||||
);
|
||||
if (desiredNetwork) {
|
||||
networkName = desiredNetwork.nickname;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
isNetworkLoading: isNetworkLoading(state),
|
||||
loadingMessage,
|
||||
setProviderArgs,
|
||||
providerConfig,
|
||||
providerConfig: {
|
||||
...providerConfig,
|
||||
nickname: networkName,
|
||||
},
|
||||
providerId: getNetworkIdentifier(state),
|
||||
showDeprecatedRpcUrlWarning,
|
||||
};
|
||||
@ -38,7 +58,12 @@ const mapDispatchToProps = (dispatch) => {
|
||||
},
|
||||
rollbackToPreviousProvider: () =>
|
||||
dispatch(actions.rollbackToPreviousProvider()),
|
||||
showNetworkDropdown: () => dispatch(actions.showNetworkDropdown()),
|
||||
showNetworkDropdown: () => {
|
||||
if (process.env.MULTICHAIN) {
|
||||
return dispatch(actions.toggleNetworkMenu());
|
||||
}
|
||||
return dispatch(actions.showNetworkDropdown());
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -11,12 +11,14 @@ import {
|
||||
setShowTestNetworks,
|
||||
setProviderType,
|
||||
toggleNetworkMenu,
|
||||
upsertNetworkConfiguration,
|
||||
} from '../../../store/actions';
|
||||
import { CHAIN_IDS, TEST_CHAINS } from '../../../../shared/constants/network';
|
||||
import {
|
||||
getShowTestNetworks,
|
||||
getAllEnabledNetworks,
|
||||
getCurrentChainId,
|
||||
getNetworkConfigurations,
|
||||
} from '../../../selectors';
|
||||
import Box from '../../ui/box/box';
|
||||
import ToggleButton from '../../ui/toggle-button';
|
||||
@ -32,6 +34,7 @@ import { MetaMetricsContext } from '../../../contexts/metametrics';
|
||||
import {
|
||||
MetaMetricsEventCategory,
|
||||
MetaMetricsEventName,
|
||||
MetaMetricsNetworkEventSource,
|
||||
} from '../../../../shared/constants/metametrics';
|
||||
|
||||
const UNREMOVABLE_CHAIN_IDS = [CHAIN_IDS.MAINNET, ...TEST_CHAINS];
|
||||
@ -40,6 +43,7 @@ export const NetworkListMenu = ({ onClose }) => {
|
||||
const t = useI18nContext();
|
||||
const networks = useSelector(getAllEnabledNetworks);
|
||||
const showTestNetworks = useSelector(getShowTestNetworks);
|
||||
const networkConfigurations = useSelector(getNetworkConfigurations);
|
||||
const currentChainId = useSelector(getCurrentChainId);
|
||||
const dispatch = useDispatch();
|
||||
const history = useHistory();
|
||||
@ -75,12 +79,34 @@ export const NetworkListMenu = ({ onClose }) => {
|
||||
iconSrc={network?.rpcPrefs?.imageUrl}
|
||||
key={network.id || network.chainId}
|
||||
selected={isCurrentNetwork}
|
||||
onClick={() => {
|
||||
onClick={async () => {
|
||||
dispatch(toggleNetworkMenu());
|
||||
if (network.providerType) {
|
||||
dispatch(setProviderType(network.providerType));
|
||||
} else {
|
||||
dispatch(setActiveNetwork(network.id));
|
||||
// Linea needs to be added as a custom network because
|
||||
// it is not yet supported by Infura. The following lazily
|
||||
// adds Linea to the custom network configurations object
|
||||
let networkId = network.id;
|
||||
if (network.chainId === CHAIN_IDS.LINEA_TESTNET) {
|
||||
const lineaNetworkConfiguration = Object.values(
|
||||
networkConfigurations,
|
||||
).find(
|
||||
({ chainId }) => chainId === CHAIN_IDS.LINEA_TESTNET,
|
||||
);
|
||||
if (lineaNetworkConfiguration) {
|
||||
networkId = lineaNetworkConfiguration.id;
|
||||
} else {
|
||||
networkId = await dispatch(
|
||||
upsertNetworkConfiguration(network, {
|
||||
setActive: true,
|
||||
source:
|
||||
MetaMetricsNetworkEventSource.CustomNetworkForm,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
dispatch(setActiveNetwork(networkId));
|
||||
}
|
||||
trackEvent({
|
||||
event: MetaMetricsEventName.NavNetworkSwitched,
|
||||
|
@ -29,6 +29,8 @@ import {
|
||||
GOERLI_DISPLAY_NAME,
|
||||
ETH_TOKEN_IMAGE_URL,
|
||||
LINEA_TESTNET_DISPLAY_NAME,
|
||||
CURRENCY_SYMBOLS,
|
||||
TEST_NETWORK_TICKER_MAP,
|
||||
} from '../../shared/constants/network';
|
||||
import {
|
||||
WebHIDConnectedStatuses,
|
||||
@ -1180,13 +1182,18 @@ export function getAllNetworks(state) {
|
||||
imageUrl: ETH_TOKEN_IMAGE_URL,
|
||||
},
|
||||
providerType: NETWORK_TYPES.MAINNET,
|
||||
ticker: CURRENCY_SYMBOLS.ETH,
|
||||
});
|
||||
// Custom networks added
|
||||
networks.push(
|
||||
...Object.entries(networkConfigurations)
|
||||
.filter(
|
||||
([, network]) =>
|
||||
!localhostFilter(network) && network.chainId !== CHAIN_IDS.MAINNET,
|
||||
!localhostFilter(network) &&
|
||||
network.chainId !== CHAIN_IDS.MAINNET &&
|
||||
// Linea gets added as a custom network configuration so
|
||||
// we must ignore it here to display in test networks
|
||||
network.chainId !== CHAIN_IDS.LINEA_TESTNET,
|
||||
)
|
||||
.map(([, network]) => network),
|
||||
);
|
||||
@ -1198,18 +1205,20 @@ export function getAllNetworks(state) {
|
||||
nickname: GOERLI_DISPLAY_NAME,
|
||||
rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.GOERLI],
|
||||
providerType: NETWORK_TYPES.GOERLI,
|
||||
ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.GOERLI],
|
||||
},
|
||||
{
|
||||
chainId: CHAIN_IDS.SEPOLIA,
|
||||
nickname: SEPOLIA_DISPLAY_NAME,
|
||||
rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.SEPOLIA],
|
||||
providerType: NETWORK_TYPES.SEPOLIA,
|
||||
ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.SEPOLIA],
|
||||
},
|
||||
{
|
||||
chainId: CHAIN_IDS.LINEA_TESTNET,
|
||||
nickname: LINEA_TESTNET_DISPLAY_NAME,
|
||||
rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.LINEA_TESTNET],
|
||||
provderType: NETWORK_TYPES.LINEA_TESTNET,
|
||||
ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.LINEA_TESTNET],
|
||||
},
|
||||
], // Localhosts
|
||||
...Object.entries(networkConfigurations)
|
||||
|
Loading…
Reference in New Issue
Block a user