mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +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.",
|
"message": "Gas fees are $1 relative to the past 72 hours.",
|
||||||
"description": "$1 is networks stability value - stable, low, high"
|
"description": "$1 is networks stability value - stable, low, high"
|
||||||
},
|
},
|
||||||
|
"networkSwitchConnectionError": {
|
||||||
|
"message": "We can't connect to $1",
|
||||||
|
"description": "$1 represents the network name"
|
||||||
|
},
|
||||||
"networkURL": {
|
"networkURL": {
|
||||||
"message": "Network URL"
|
"message": "Network URL"
|
||||||
},
|
},
|
||||||
|
@ -1,9 +1,24 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import Button from '../../ui/button';
|
|
||||||
import LoadingScreen from '../../ui/loading-screen';
|
import LoadingScreen from '../../ui/loading-screen';
|
||||||
import { SECOND } from '../../../../shared/constants/time';
|
import { SECOND } from '../../../../shared/constants/time';
|
||||||
import { NETWORK_TYPES } from '../../../../shared/constants/network';
|
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 {
|
export default class LoadingNetworkScreen extends PureComponent {
|
||||||
state = {
|
state = {
|
||||||
@ -56,63 +71,76 @@ export default class LoadingNetworkScreen extends PureComponent {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
renderDeprecatedRpcUrlWarning = () => {
|
renderConnectionFailureNotification = (message, showTryAgain = false) => {
|
||||||
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 = () => {
|
|
||||||
const { showNetworkDropdown, setProviderArgs, setProviderType } =
|
const { showNetworkDropdown, setProviderArgs, setProviderType } =
|
||||||
this.props;
|
this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="loading-overlay__error-screen">
|
<Popover
|
||||||
<span className="loading-overlay__emoji">😞</span>
|
onClose={() => {
|
||||||
<span>{this.context.t('somethingWentWrong')}</span>
|
window.clearTimeout(this.cancelCallTimeout);
|
||||||
<div className="loading-overlay__error-buttons">
|
}}
|
||||||
<Button
|
centerTitle
|
||||||
type="secondary"
|
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={() => {
|
onClick={() => {
|
||||||
window.clearTimeout(this.cancelCallTimeout);
|
window.clearTimeout(this.cancelCallTimeout);
|
||||||
showNetworkDropdown();
|
showNetworkDropdown();
|
||||||
}}
|
}}
|
||||||
|
variant={TextVariant.bodySm}
|
||||||
|
block
|
||||||
>
|
>
|
||||||
{this.context.t('switchNetworks')}
|
{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
|
renderDeprecatedRpcUrlWarning = () => {
|
||||||
type="primary"
|
return this.renderConnectionFailureNotification(
|
||||||
onClick={() => {
|
this.context.t('currentRpcUrlDeprecated'),
|
||||||
this.setState({ showErrorScreen: false });
|
false,
|
||||||
setProviderType(...setProviderArgs);
|
);
|
||||||
window.clearTimeout(this.cancelCallTimeout);
|
};
|
||||||
this.cancelCallTimeout = setTimeout(
|
|
||||||
this.cancelCall,
|
renderErrorScreenContent = () => {
|
||||||
this.props.cancelTime || SECOND * 15,
|
const { providerConfig } = this.props;
|
||||||
);
|
return this.renderConnectionFailureNotification(
|
||||||
}}
|
this.context.t('networkSwitchConnectionError', [providerConfig.nickname]),
|
||||||
>
|
true,
|
||||||
{this.context.t('tryAgain')}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { NETWORK_TYPES } from '../../../../shared/constants/network';
|
import { NETWORK_TYPES } from '../../../../shared/constants/network';
|
||||||
import * as actions from '../../../store/actions';
|
import * as actions from '../../../store/actions';
|
||||||
import { getNetworkIdentifier, isNetworkLoading } from '../../../selectors';
|
import {
|
||||||
|
getAllEnabledNetworks,
|
||||||
|
getNetworkIdentifier,
|
||||||
|
isNetworkLoading,
|
||||||
|
} from '../../../selectors';
|
||||||
import { getProviderConfig } from '../../../ducks/metamask/metamask';
|
import { getProviderConfig } from '../../../ducks/metamask/metamask';
|
||||||
import LoadingNetworkScreen from './loading-network-screen.component';
|
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 isInfuraRpcUrl = rpcUrl && new URL(rpcUrl).host.endsWith('.infura.io');
|
||||||
const showDeprecatedRpcUrlWarning = isDeprecatedNetwork && isInfuraRpcUrl;
|
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 {
|
return {
|
||||||
isNetworkLoading: isNetworkLoading(state),
|
isNetworkLoading: isNetworkLoading(state),
|
||||||
loadingMessage,
|
loadingMessage,
|
||||||
setProviderArgs,
|
setProviderArgs,
|
||||||
providerConfig,
|
providerConfig: {
|
||||||
|
...providerConfig,
|
||||||
|
nickname: networkName,
|
||||||
|
},
|
||||||
providerId: getNetworkIdentifier(state),
|
providerId: getNetworkIdentifier(state),
|
||||||
showDeprecatedRpcUrlWarning,
|
showDeprecatedRpcUrlWarning,
|
||||||
};
|
};
|
||||||
@ -38,7 +58,12 @@ const mapDispatchToProps = (dispatch) => {
|
|||||||
},
|
},
|
||||||
rollbackToPreviousProvider: () =>
|
rollbackToPreviousProvider: () =>
|
||||||
dispatch(actions.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,
|
setShowTestNetworks,
|
||||||
setProviderType,
|
setProviderType,
|
||||||
toggleNetworkMenu,
|
toggleNetworkMenu,
|
||||||
|
upsertNetworkConfiguration,
|
||||||
} from '../../../store/actions';
|
} from '../../../store/actions';
|
||||||
import { CHAIN_IDS, TEST_CHAINS } from '../../../../shared/constants/network';
|
import { CHAIN_IDS, TEST_CHAINS } from '../../../../shared/constants/network';
|
||||||
import {
|
import {
|
||||||
getShowTestNetworks,
|
getShowTestNetworks,
|
||||||
getAllEnabledNetworks,
|
getAllEnabledNetworks,
|
||||||
getCurrentChainId,
|
getCurrentChainId,
|
||||||
|
getNetworkConfigurations,
|
||||||
} from '../../../selectors';
|
} from '../../../selectors';
|
||||||
import Box from '../../ui/box/box';
|
import Box from '../../ui/box/box';
|
||||||
import ToggleButton from '../../ui/toggle-button';
|
import ToggleButton from '../../ui/toggle-button';
|
||||||
@ -32,6 +34,7 @@ import { MetaMetricsContext } from '../../../contexts/metametrics';
|
|||||||
import {
|
import {
|
||||||
MetaMetricsEventCategory,
|
MetaMetricsEventCategory,
|
||||||
MetaMetricsEventName,
|
MetaMetricsEventName,
|
||||||
|
MetaMetricsNetworkEventSource,
|
||||||
} from '../../../../shared/constants/metametrics';
|
} from '../../../../shared/constants/metametrics';
|
||||||
|
|
||||||
const UNREMOVABLE_CHAIN_IDS = [CHAIN_IDS.MAINNET, ...TEST_CHAINS];
|
const UNREMOVABLE_CHAIN_IDS = [CHAIN_IDS.MAINNET, ...TEST_CHAINS];
|
||||||
@ -40,6 +43,7 @@ export const NetworkListMenu = ({ onClose }) => {
|
|||||||
const t = useI18nContext();
|
const t = useI18nContext();
|
||||||
const networks = useSelector(getAllEnabledNetworks);
|
const networks = useSelector(getAllEnabledNetworks);
|
||||||
const showTestNetworks = useSelector(getShowTestNetworks);
|
const showTestNetworks = useSelector(getShowTestNetworks);
|
||||||
|
const networkConfigurations = useSelector(getNetworkConfigurations);
|
||||||
const currentChainId = useSelector(getCurrentChainId);
|
const currentChainId = useSelector(getCurrentChainId);
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
@ -75,12 +79,34 @@ export const NetworkListMenu = ({ onClose }) => {
|
|||||||
iconSrc={network?.rpcPrefs?.imageUrl}
|
iconSrc={network?.rpcPrefs?.imageUrl}
|
||||||
key={network.id || network.chainId}
|
key={network.id || network.chainId}
|
||||||
selected={isCurrentNetwork}
|
selected={isCurrentNetwork}
|
||||||
onClick={() => {
|
onClick={async () => {
|
||||||
dispatch(toggleNetworkMenu());
|
dispatch(toggleNetworkMenu());
|
||||||
if (network.providerType) {
|
if (network.providerType) {
|
||||||
dispatch(setProviderType(network.providerType));
|
dispatch(setProviderType(network.providerType));
|
||||||
} else {
|
} 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({
|
trackEvent({
|
||||||
event: MetaMetricsEventName.NavNetworkSwitched,
|
event: MetaMetricsEventName.NavNetworkSwitched,
|
||||||
|
@ -29,6 +29,8 @@ import {
|
|||||||
GOERLI_DISPLAY_NAME,
|
GOERLI_DISPLAY_NAME,
|
||||||
ETH_TOKEN_IMAGE_URL,
|
ETH_TOKEN_IMAGE_URL,
|
||||||
LINEA_TESTNET_DISPLAY_NAME,
|
LINEA_TESTNET_DISPLAY_NAME,
|
||||||
|
CURRENCY_SYMBOLS,
|
||||||
|
TEST_NETWORK_TICKER_MAP,
|
||||||
} from '../../shared/constants/network';
|
} from '../../shared/constants/network';
|
||||||
import {
|
import {
|
||||||
WebHIDConnectedStatuses,
|
WebHIDConnectedStatuses,
|
||||||
@ -1180,13 +1182,18 @@ export function getAllNetworks(state) {
|
|||||||
imageUrl: ETH_TOKEN_IMAGE_URL,
|
imageUrl: ETH_TOKEN_IMAGE_URL,
|
||||||
},
|
},
|
||||||
providerType: NETWORK_TYPES.MAINNET,
|
providerType: NETWORK_TYPES.MAINNET,
|
||||||
|
ticker: CURRENCY_SYMBOLS.ETH,
|
||||||
});
|
});
|
||||||
// Custom networks added
|
// Custom networks added
|
||||||
networks.push(
|
networks.push(
|
||||||
...Object.entries(networkConfigurations)
|
...Object.entries(networkConfigurations)
|
||||||
.filter(
|
.filter(
|
||||||
([, network]) =>
|
([, 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),
|
.map(([, network]) => network),
|
||||||
);
|
);
|
||||||
@ -1198,18 +1205,20 @@ export function getAllNetworks(state) {
|
|||||||
nickname: GOERLI_DISPLAY_NAME,
|
nickname: GOERLI_DISPLAY_NAME,
|
||||||
rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.GOERLI],
|
rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.GOERLI],
|
||||||
providerType: NETWORK_TYPES.GOERLI,
|
providerType: NETWORK_TYPES.GOERLI,
|
||||||
|
ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.GOERLI],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
chainId: CHAIN_IDS.SEPOLIA,
|
chainId: CHAIN_IDS.SEPOLIA,
|
||||||
nickname: SEPOLIA_DISPLAY_NAME,
|
nickname: SEPOLIA_DISPLAY_NAME,
|
||||||
rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.SEPOLIA],
|
rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.SEPOLIA],
|
||||||
providerType: NETWORK_TYPES.SEPOLIA,
|
providerType: NETWORK_TYPES.SEPOLIA,
|
||||||
|
ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.SEPOLIA],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
chainId: CHAIN_IDS.LINEA_TESTNET,
|
chainId: CHAIN_IDS.LINEA_TESTNET,
|
||||||
nickname: LINEA_TESTNET_DISPLAY_NAME,
|
nickname: LINEA_TESTNET_DISPLAY_NAME,
|
||||||
rpcUrl: CHAIN_ID_TO_RPC_URL_MAP[CHAIN_IDS.LINEA_TESTNET],
|
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
|
], // Localhosts
|
||||||
...Object.entries(networkConfigurations)
|
...Object.entries(networkConfigurations)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user