1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Privacy - Show default selected network after a custom network has been added during onboarding (#16789)

* Privacy - Allow users to set a custom RPC from the onboarding process (#16767)

* Privacy - Allow adding custom IPFS from onboarding (#16782)

* Privacy - Show default selected network after a custom network has been added during onboarding

* WIP: Show dropdown list of networks

* Add network switcher to the onboarding advanced privacy screen

* Fix duplicate imports

* Provide default for networks

* Update ui/helpers/utils/ipfs.js

Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com>

* Fix lint

* Remove unwanted changes

* Fix lint

Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com>
This commit is contained in:
David Walsh 2022-12-08 10:42:23 -06:00 committed by GitHub
parent 6d1170f06c
commit 43c278d813
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 279 additions and 36 deletions

View File

@ -2583,6 +2583,27 @@
"on": { "on": {
"message": "On" "message": "On"
}, },
"onboardingAdvancedPrivacyIPFSDescription": {
"message": "The IPFS gateway makes it possible to access and view data hosted by third parties. You can add a custom IPFS gateway or continue using the default."
},
"onboardingAdvancedPrivacyIPFSInvalid": {
"message": "Please enter a valid URL"
},
"onboardingAdvancedPrivacyIPFSTitle": {
"message": "Add custom IPFS Gateway"
},
"onboardingAdvancedPrivacyIPFSValid": {
"message": "IPFS gateway URL is valid"
},
"onboardingAdvancedPrivacyNetworkButton": {
"message": "Add custom network"
},
"onboardingAdvancedPrivacyNetworkDescription": {
"message": "We use Infura as our remote procedure call (RPC) provider to offer the most reliable and private access to Ethereum data we can. You can choose your own RPC, but remember that any RPC will receive your IP address and Ethereum wallet to make transactions. Read our $1 to learn more about how Infura handles data."
},
"onboardingAdvancedPrivacyNetworkTitle": {
"message": "Choose your network"
},
"onboardingCreateWallet": { "onboardingCreateWallet": {
"message": "Create a new wallet" "message": "Create a new wallet"
}, },
@ -2617,6 +2638,9 @@
"onboardingMetametricsInfuraTermsPolicyLink": { "onboardingMetametricsInfuraTermsPolicyLink": {
"message": "here" "message": "here"
}, },
"onboardingMetametricsModalTitle": {
"message": "Add custom network"
},
"onboardingMetametricsNeverCollect": { "onboardingMetametricsNeverCollect": {
"message": "$1 collect information we dont need to provide the service (such as keys, addresses, transaction hashes, or balances)", "message": "$1 collect information we dont need to provide the service (such as keys, addresses, transaction hashes, or balances)",
"description": "$1 represents `onboardingMetametricsNeverEmphasis`" "description": "$1 represents `onboardingMetametricsNeverEmphasis`"

View File

@ -101,6 +101,9 @@ class NetworkDropdown extends Component {
showTestnetMessageInDropdown: PropTypes.bool.isRequired, showTestnetMessageInDropdown: PropTypes.bool.isRequired,
hideTestNetMessage: PropTypes.func.isRequired, hideTestNetMessage: PropTypes.func.isRequired,
history: PropTypes.object, history: PropTypes.object,
dropdownStyles: PropTypes.object,
hideElementsForOnboarding: PropTypes.bool,
onAddClick: PropTypes.func,
}; };
handleClick(newProviderType) { handleClick(newProviderType) {
@ -122,16 +125,21 @@ class NetworkDropdown extends Component {
} }
renderAddCustomButton() { renderAddCustomButton() {
const { onAddClick } = this.props;
return ( return (
<div className="network__add-network-button"> <div className="network__add-network-button">
<Button <Button
type="secondary" type="secondary"
onClick={() => { onClick={() => {
if (onAddClick) {
onAddClick();
} else {
getEnvironmentType() === ENVIRONMENT_TYPE_POPUP getEnvironmentType() === ENVIRONMENT_TYPE_POPUP
? global.platform.openExtensionInBrowser( ? global.platform.openExtensionInBrowser(
ADD_POPULAR_CUSTOM_NETWORK, ADD_POPULAR_CUSTOM_NETWORK,
) )
: this.props.history.push(ADD_POPULAR_CUSTOM_NETWORK); : this.props.history.push(ADD_POPULAR_CUSTOM_NETWORK);
}
this.props.hideNetworkDropdown(); this.props.hideNetworkDropdown();
}} }}
> >
@ -263,6 +271,7 @@ class NetworkDropdown extends Component {
render() { render() {
const { const {
history, history,
hideElementsForOnboarding,
hideNetworkDropdown, hideNetworkDropdown,
shouldShowTestNetworks, shouldShowTestNetworks,
showTestnetMessageInDropdown, showTestnetMessageInDropdown,
@ -294,20 +303,26 @@ class NetworkDropdown extends Component {
}} }}
containerClassName="network-droppo" containerClassName="network-droppo"
zIndex={55} zIndex={55}
style={{ style={
this.props.dropdownStyles || {
position: 'absolute', position: 'absolute',
top: '58px', top: '58px',
width: '309px', width: '309px',
zIndex: '55px', zIndex: '55',
}} }
}
innerStyle={{ innerStyle={{
padding: '16px 0', padding: '16px 0',
}} }}
> >
<div className="network-dropdown-header"> <div className="network-dropdown-header">
{hideElementsForOnboarding ? null : (
<div className="network-dropdown-title">{t('networks')}</div> <div className="network-dropdown-title">{t('networks')}</div>
)}
{hideElementsForOnboarding ? null : (
<div className="network-dropdown-divider" /> <div className="network-dropdown-divider" />
{showTestnetMessageInDropdown ? ( )}
{showTestnetMessageInDropdown && !hideElementsForOnboarding ? (
<div className="network-dropdown-content"> <div className="network-dropdown-content">
{t('toggleTestNetworks', [ {t('toggleTestNetworks', [
<a <a

View File

@ -8,6 +8,7 @@ import { getEnvironmentType } from '../../../../app/scripts/lib/util';
import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app'; import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app';
// Modal Components // Modal Components
import AddNetworkModal from '../../../pages/onboarding-flow/add-network-modal';
import AccountDetailsModal from './account-details-modal'; import AccountDetailsModal from './account-details-modal';
import ExportPrivateKeyModal from './export-private-key-modal'; import ExportPrivateKeyModal from './export-private-key-modal';
import HideTokenConfirmationModal from './hide-token-confirmation-modal'; import HideTokenConfirmationModal from './hide-token-confirmation-modal';
@ -76,6 +77,10 @@ const accountModalStyle = {
}; };
const MODALS = { const MODALS = {
ONBOARDING_ADD_NETWORK: {
contents: <AddNetworkModal />,
...accountModalStyle,
},
NEW_ACCOUNT: { NEW_ACCOUNT: {
contents: <NewAccountModal />, contents: <NewAccountModal />,
mobileModalStyle: { mobileModalStyle: {

3
ui/helpers/utils/ipfs.js Normal file
View File

@ -0,0 +1,3 @@
export function addUrlProtocolPrefix(urlString) {
return urlString.match(/^https?:\/\//u) ? urlString : `https://${urlString}`;
}

View File

@ -0,0 +1,43 @@
import React from 'react';
import { useDispatch } from 'react-redux';
import { useI18nContext } from '../../../hooks/useI18nContext';
import { hideModal } from '../../../store/actions';
import Typography from '../../../components/ui/typography/typography';
import Box from '../../../components/ui/box/box';
import {
TEXT_ALIGN,
TYPOGRAPHY,
FONT_WEIGHT,
} from '../../../helpers/constants/design-system';
import NetworksForm from '../../settings/networks-tab/networks-form/networks-form';
export default function AddNetworkModal() {
const dispatch = useDispatch();
const t = useI18nContext();
const closeCallback = () =>
dispatch(hideModal({ name: 'ONBOARDING_ADD_NETWORK' }));
return (
<>
<Box paddingTop={4}>
<Typography
variant={TYPOGRAPHY.H4}
align={TEXT_ALIGN.CENTER}
fontWeight={FONT_WEIGHT.BOLD}
>
{t('onboardingMetametricsModalTitle')}
</Typography>
</Box>
<NetworksForm
addNewNetwork
networksToRender={[]}
cancelCallback={closeCallback}
submitCallback={closeCallback}
/>
</>
);
}

View File

@ -56,6 +56,15 @@
} }
} }
&__network {
position: relative;
.dropdown-menu-item {
font-size: 14px !important;
padding: 8px !important;
}
}
& button { & button {
max-width: 50%; max-width: 50%;
padding: 15px; padding: 15px;

View File

@ -1,22 +1,32 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { useHistory } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import { useHistory } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import Box from '../../../components/ui/box/box';
import Button from '../../../components/ui/button'; import Button from '../../../components/ui/button';
import Typography from '../../../components/ui/typography'; import Typography from '../../../components/ui/typography';
import { import {
COLORS,
FONT_WEIGHT, FONT_WEIGHT,
TYPOGRAPHY, TYPOGRAPHY,
} from '../../../helpers/constants/design-system'; } from '../../../helpers/constants/design-system';
import { useI18nContext } from '../../../hooks/useI18nContext'; import { useI18nContext } from '../../../hooks/useI18nContext';
import { addUrlProtocolPrefix } from '../../../helpers/utils/ipfs';
import { import {
setCompletedOnboarding, setCompletedOnboarding,
setFeatureFlag, setFeatureFlag,
setUseMultiAccountBalanceChecker, setUseMultiAccountBalanceChecker,
setUsePhishDetect, setUsePhishDetect,
setUseTokenDetection, setUseTokenDetection,
showModal,
setIpfsGateway,
showNetworkDropdown,
} from '../../../store/actions'; } from '../../../store/actions';
import { ONBOARDING_PIN_EXTENSION_ROUTE } from '../../../helpers/constants/routes'; import { ONBOARDING_PIN_EXTENSION_ROUTE } from '../../../helpers/constants/routes';
import { Icon, TextField } from '../../../components/component-library';
import NetworkDropdown from '../../../components/app/dropdowns/network-dropdown';
import NetworkDisplay from '../../../components/app/network-display/network-display';
import { Setting } from './setting'; import { Setting } from './setting';
export default function PrivacySettings() { export default function PrivacySettings() {
@ -31,6 +41,12 @@ export default function PrivacySettings() {
isMultiAccountBalanceCheckerEnabled, isMultiAccountBalanceCheckerEnabled,
setMultiAccountBalanceCheckerEnabled, setMultiAccountBalanceCheckerEnabled,
] = useState(true); ] = useState(true);
const [ipfsURL, setIPFSURL] = useState('');
const [ipfsError, setIPFSError] = useState(null);
const networks = useSelector(
(state) => state.metamask.frequentRpcListDetail || [],
);
const handleSubmit = () => { const handleSubmit = () => {
dispatch( dispatch(
@ -42,9 +58,28 @@ export default function PrivacySettings() {
setUseMultiAccountBalanceChecker(isMultiAccountBalanceCheckerEnabled), setUseMultiAccountBalanceChecker(isMultiAccountBalanceCheckerEnabled),
); );
dispatch(setCompletedOnboarding()); dispatch(setCompletedOnboarding());
if (ipfsURL && !ipfsError) {
const { host } = new URL(addUrlProtocolPrefix(ipfsURL));
dispatch(setIpfsGateway(host));
}
history.push(ONBOARDING_PIN_EXTENSION_ROUTE); history.push(ONBOARDING_PIN_EXTENSION_ROUTE);
}; };
const handleIPFSChange = (url) => {
setIPFSURL(url);
try {
const { host } = new URL(addUrlProtocolPrefix(url));
if (!host || host === 'gateway.ipfs.io') {
throw new Error();
}
setIPFSError(null);
} catch (error) {
setIPFSError(t('onboardingAdvancedPrivacyIPFSInvalid'));
}
};
return ( return (
<> <>
<div className="privacy-settings" data-testid="privacy-settings"> <div className="privacy-settings" data-testid="privacy-settings">
@ -118,6 +153,94 @@ export default function PrivacySettings() {
title={t('useMultiAccountBalanceChecker')} title={t('useMultiAccountBalanceChecker')}
description={t('useMultiAccountBalanceCheckerDescription')} description={t('useMultiAccountBalanceCheckerDescription')}
/> />
<Setting
title={t('onboardingAdvancedPrivacyNetworkTitle')}
showToggle={false}
description={
<>
{t('onboardingAdvancedPrivacyNetworkDescription', [
<a
href="https://consensys.net/privacy-policy/"
key="link"
target="_blank"
rel="noopener noreferrer"
>
{t('privacyMsg')}
</a>,
])}
<Box paddingTop={2}>
{networks.length > 1 ? (
<div className="privacy-settings__network">
<>
<NetworkDisplay
onClick={() => dispatch(showNetworkDropdown())}
/>
<NetworkDropdown
hideElementsForOnboarding
dropdownStyles={{
position: 'absolute',
top: '40px',
left: '0',
width: '309px',
zIndex: '55',
}}
onAddClick={() => {
dispatch(
showModal({ name: 'ONBOARDING_ADD_NETWORK' }),
);
}}
/>
</>
</div>
) : null}
{networks.length === 1 ? (
<Button
type="secondary"
rounded
large
onClick={(e) => {
e.preventDefault();
dispatch(showModal({ name: 'ONBOARDING_ADD_NETWORK' }));
}}
icon={<Icon name="add-outline" marginRight={2} />}
>
{t('onboardingAdvancedPrivacyNetworkButton')}
</Button>
) : null}
</Box>
</>
}
/>
<Setting
title={t('onboardingAdvancedPrivacyIPFSTitle')}
showToggle={false}
description={
<>
{t('onboardingAdvancedPrivacyIPFSDescription')}
<Box paddingTop={2}>
<TextField
style={{ width: '100%' }}
onChange={(e) => {
handleIPFSChange(e.target.value);
}}
/>
{ipfsURL ? (
<Typography
variant={TYPOGRAPHY.H7}
color={
ipfsError
? COLORS.ERROR_DEFAULT
: COLORS.SUCCESS_DEFAULT
}
>
{ipfsError || t('onboardingAdvancedPrivacyIPFSValid')}
</Typography>
) : null}
</Box>
</>
}
/>
</div> </div>
<Button type="primary" rounded onClick={handleSubmit}> <Button type="primary" rounded onClick={handleSubmit}>
{t('done')} {t('done')}

View File

@ -11,6 +11,7 @@ import PrivacySettings from './privacy-settings';
describe('Privacy Settings Onboarding View', () => { describe('Privacy Settings Onboarding View', () => {
const mockStore = { const mockStore = {
metamask: { metamask: {
frequentRpcListDetail: [],
provider: { provider: {
type: 'test', type: 'test',
}, },

View File

@ -9,7 +9,13 @@ import {
FONT_WEIGHT, FONT_WEIGHT,
} from '../../../helpers/constants/design-system'; } from '../../../helpers/constants/design-system';
export const Setting = ({ value, setValue, title, description }) => { export const Setting = ({
value,
setValue,
title,
description,
showToggle = true,
}) => {
return ( return (
<Box justifyContent={JUSTIFY_CONTENT.CENTER} margin={3}> <Box justifyContent={JUSTIFY_CONTENT.CENTER} margin={3}>
<div className="privacy-settings__setting"> <div className="privacy-settings__setting">
@ -18,9 +24,11 @@ export const Setting = ({ value, setValue, title, description }) => {
</Typography> </Typography>
<Typography variant={TYPOGRAPHY.H6}>{description}</Typography> <Typography variant={TYPOGRAPHY.H6}>{description}</Typography>
</div> </div>
{showToggle ? (
<div className="privacy-settings__setting__toggle"> <div className="privacy-settings__setting__toggle">
<ToggleButton value={value} onToggle={(val) => setValue(!val)} /> <ToggleButton value={value} onToggle={(val) => setValue(!val)} />
</div> </div>
) : null}
</Box> </Box>
); );
}; };
@ -30,4 +38,5 @@ Setting.propTypes = {
setValue: PropTypes.func, setValue: PropTypes.func,
title: PropTypes.string, title: PropTypes.string,
description: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), description: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
showToggle: PropTypes.bool,
}; };

View File

@ -115,6 +115,7 @@ export default class Routes extends Component {
portfolioTooltipIsBeingShown: PropTypes.bool, portfolioTooltipIsBeingShown: PropTypes.bool,
forgottenPassword: PropTypes.bool, forgottenPassword: PropTypes.bool,
isCurrentProviderCustom: PropTypes.bool, isCurrentProviderCustom: PropTypes.bool,
completedOnboarding: PropTypes.bool,
}; };
static contextTypes = { static contextTypes = {
@ -379,6 +380,7 @@ export default class Routes extends Component {
shouldShowSeedPhraseReminder, shouldShowSeedPhraseReminder,
portfolioTooltipIsBeingShown, portfolioTooltipIsBeingShown,
isCurrentProviderCustom, isCurrentProviderCustom,
completedOnboarding,
} = this.props; } = this.props;
const loadMessage = const loadMessage =
loadingMessage || isNetworkLoading loadingMessage || isNetworkLoading
@ -391,6 +393,7 @@ export default class Routes extends Component {
!isTestNet && !isTestNet &&
!isNetworkUsed && !isNetworkUsed &&
!isCurrentProviderCustom && !isCurrentProviderCustom &&
completedOnboarding &&
allAccountsOnNetworkAreEmpty; allAccountsOnNetworkAreEmpty;
const windowType = getEnvironmentType(); const windowType = getEnvironmentType();
@ -436,7 +439,7 @@ export default class Routes extends Component {
{process.env.ONBOARDING_V2 && this.showOnboardingHeader() && ( {process.env.ONBOARDING_V2 && this.showOnboardingHeader() && (
<OnboardingAppHeader /> <OnboardingAppHeader />
)} )}
<NetworkDropdown /> {completedOnboarding ? <NetworkDropdown /> : null}
<AccountMenu /> <AccountMenu />
<div className="main-container-wrapper"> <div className="main-container-wrapper">
{isLoading ? <Loading loadingMessage={loadMessage} /> : null} {isLoading ? <Loading loadingMessage={loadMessage} /> : null}

View File

@ -29,6 +29,7 @@ function mapStateToProps(state) {
const { appState } = state; const { appState } = state;
const { alertOpen, alertMessage, isLoading, loadingMessage } = appState; const { alertOpen, alertMessage, isLoading, loadingMessage } = appState;
const { autoLockTimeLimit = 0 } = getPreferences(state); const { autoLockTimeLimit = 0 } = getPreferences(state);
const { completedOnboarding } = state.metamask;
return { return {
alertOpen, alertOpen,
@ -55,6 +56,7 @@ function mapStateToProps(state) {
portfolioTooltipIsBeingShown: getShowPortfolioTooltip(state), portfolioTooltipIsBeingShown: getShowPortfolioTooltip(state),
forgottenPassword: state.metamask.forgottenPassword, forgottenPassword: state.metamask.forgottenPassword,
isCurrentProviderCustom: isCurrentProviderCustom(state), isCurrentProviderCustom: isCurrentProviderCustom(state),
completedOnboarding,
}; };
} }

View File

@ -14,6 +14,7 @@ import {
getNumberOfSettingsInSection, getNumberOfSettingsInSection,
handleSettingsRefs, handleSettingsRefs,
} from '../../../helpers/utils/settings-search'; } from '../../../helpers/utils/settings-search';
import { addUrlProtocolPrefix } from '../../../helpers/utils/ipfs';
import { import {
LEDGER_TRANSPORT_TYPES, LEDGER_TRANSPORT_TYPES,
@ -842,10 +843,3 @@ export default class AdvancedTab extends PureComponent {
); );
} }
} }
function addUrlProtocolPrefix(urlString) {
if (!urlString.match(/(^http:\/\/)|(^https:\/\/)/u)) {
return `https://${urlString}`;
}
return urlString;
}

View File

@ -5,7 +5,6 @@ import React, {
useRef, useRef,
useState, useState,
} from 'react'; } from 'react';
import { useHistory } from 'react-router-dom';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import validUrl from 'valid-url'; import validUrl from 'valid-url';
@ -29,10 +28,6 @@ import {
showModal, showModal,
setNewNetworkAdded, setNewNetworkAdded,
} from '../../../../store/actions'; } from '../../../../store/actions';
import {
DEFAULT_ROUTE,
NETWORKS_ROUTE,
} from '../../../../helpers/constants/routes';
import fetchWithCache from '../../../../../shared/lib/fetch-with-cache'; import fetchWithCache from '../../../../../shared/lib/fetch-with-cache';
import { usePrevious } from '../../../../hooks/usePrevious'; import { usePrevious } from '../../../../hooks/usePrevious';
import { MetaMetricsContext } from '../../../../contexts/metametrics'; import { MetaMetricsContext } from '../../../../contexts/metametrics';
@ -86,10 +81,11 @@ const NetworksForm = ({
isCurrentRpcTarget, isCurrentRpcTarget,
networksToRender, networksToRender,
selectedNetwork, selectedNetwork,
cancelCallback,
submitCallback,
}) => { }) => {
const t = useI18nContext(); const t = useI18nContext();
const trackEvent = useContext(MetaMetricsContext); const trackEvent = useContext(MetaMetricsContext);
const history = useHistory();
const dispatch = useDispatch(); const dispatch = useDispatch();
const { label, labelKey, viewOnly, rpcPrefs } = selectedNetwork; const { label, labelKey, viewOnly, rpcPrefs } = selectedNetwork;
const selectedNetworkName = label || (labelKey && t(labelKey)); const selectedNetworkName = label || (labelKey && t(labelKey));
@ -544,7 +540,8 @@ const NetworksForm = ({
}, },
}); });
dispatch(setNewNetworkAdded(networkName)); dispatch(setNewNetworkAdded(networkName));
history.push(DEFAULT_ROUTE);
submitCallback?.();
} }
} catch (error) { } catch (error) {
setIsSubmitting(false); setIsSubmitting(false);
@ -555,7 +552,7 @@ const NetworksForm = ({
const onCancel = () => { const onCancel = () => {
if (addNewNetwork) { if (addNewNetwork) {
dispatch(setSelectedSettingsRpcUrl('')); dispatch(setSelectedSettingsRpcUrl(''));
history.push(NETWORKS_ROUTE); cancelCallback?.();
} else { } else {
resetForm(); resetForm();
} }
@ -709,6 +706,8 @@ NetworksForm.propTypes = {
isCurrentRpcTarget: PropTypes.bool, isCurrentRpcTarget: PropTypes.bool,
networksToRender: PropTypes.array.isRequired, networksToRender: PropTypes.array.isRequired,
selectedNetwork: PropTypes.object, selectedNetwork: PropTypes.object,
cancelCallback: PropTypes.func,
submitCallback: PropTypes.func,
}; };
NetworksForm.defaultProps = { NetworksForm.defaultProps = {

View File

@ -1,10 +1,16 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { useHistory } from 'react-router-dom';
import NetworksForm from '../networks-form'; import NetworksForm from '../networks-form';
import NetworksList from '../networks-list'; import NetworksList from '../networks-list';
import { getProvider } from '../../../../selectors'; import { getProvider } from '../../../../selectors';
import {
DEFAULT_ROUTE,
NETWORKS_ROUTE,
} from '../../../../helpers/constants/routes';
const NetworksTabContent = ({ const NetworksTabContent = ({
networkDefaultedToProvider, networkDefaultedToProvider,
networkIsSelected, networkIsSelected,
@ -13,6 +19,7 @@ const NetworksTabContent = ({
shouldRenderNetworkForm, shouldRenderNetworkForm,
}) => { }) => {
const provider = useSelector(getProvider); const provider = useSelector(getProvider);
const history = useHistory();
return ( return (
<> <>
@ -27,6 +34,8 @@ const NetworksTabContent = ({
isCurrentRpcTarget={provider.rpcUrl === selectedNetwork.rpcUrl} isCurrentRpcTarget={provider.rpcUrl === selectedNetwork.rpcUrl}
networksToRender={networksToRender} networksToRender={networksToRender}
selectedNetwork={selectedNetwork} selectedNetwork={selectedNetwork}
submitCallback={() => history.push(DEFAULT_ROUTE)}
cancelCallback={() => history.push(NETWORKS_ROUTE)}
/> />
) : null} ) : null}
</> </>

View File

@ -7,6 +7,8 @@ import { useI18nContext } from '../../../hooks/useI18nContext';
import { import {
ADD_POPULAR_CUSTOM_NETWORK, ADD_POPULAR_CUSTOM_NETWORK,
NETWORKS_FORM_ROUTE, NETWORKS_FORM_ROUTE,
DEFAULT_ROUTE,
NETWORKS_ROUTE,
} from '../../../helpers/constants/routes'; } from '../../../helpers/constants/routes';
import { setSelectedSettingsRpcUrl } from '../../../store/actions'; import { setSelectedSettingsRpcUrl } from '../../../store/actions';
import Button from '../../../components/ui/button'; import Button from '../../../components/ui/button';
@ -106,6 +108,8 @@ const NetworksTab = ({ addNewNetwork }) => {
<NetworksForm <NetworksForm
networksToRender={networksToRender} networksToRender={networksToRender}
addNewNetwork={addNewNetwork} addNewNetwork={addNewNetwork}
submitCallback={() => history.push(DEFAULT_ROUTE)}
cancelCallback={() => history.push(NETWORKS_ROUTE)}
/> />
) : ( ) : (
<> <>