Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add new default networks #28006

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions privacy-snapshot.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"api.web3modal.com",
"app.ens.domains",
"arbitrum-mainnet.infura.io",
"avalanche-mainnet.infura.io",
"authentication.api.cx.metamask.io",
"bafkreifvhjdf6ve4jfv6qytqtux5nd4nwnelioeiqx5x2ez5yrgrzk7ypi.ipfs.dweb.link",
"bafybeidxfmwycgzcp4v2togflpqh2gnibuexjy4m4qqwxp7nh3jx5zlh4y.ipfs.dweb.link",
Expand Down
58 changes: 29 additions & 29 deletions test/e2e/tests/network/multi-rpc.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe('MultiRpc:', function (this: Suite) {
json: {
id: '1694444405781',
jsonrpc: '2.0',
result: '0xa4b1',
result: '0xa86a',
},
})),
];
Expand All @@ -37,7 +37,7 @@ describe('MultiRpc:', function (this: Suite) {
fixtures: new FixtureBuilder({ onboarding: true })
.withNetworkController({
providerConfig: {
rpcPrefs: { blockExplorerUrl: 'https://etherscan.io/' },
rpcPrefs: { blockExplorerUrl: 'https://snowtrace.io/' },
},
networkConfigurations: {
networkConfigurationId: {
Expand All @@ -48,20 +48,20 @@ describe('MultiRpc:', function (this: Suite) {
rpcPrefs: { blockExplorerUrl: 'https://etherscan.io/' },
},
'2ce66016-8aab-47df-b27f-318c80865eb0': {
chainId: '0xa4b1',
chainId: '0xa86a',
id: '2ce66016-8aab-47df-b27f-318c80865eb0',
nickname: 'Arbitrum mainnet',
nickname: 'Avalanche mainnet',
rpcPrefs: {},
rpcUrl: 'https://arbitrum-mainnet.infura.io',
ticker: 'ETH',
rpcUrl: 'https://avalanche-mainnet.infura.io',
ticker: 'AVAX',
},
'2ce66016-8aab-47df-b27f-318c80865eb1': {
chainId: '0xa4b1',
chainId: '0xa86a',
id: '2ce66016-8aab-47df-b27f-318c80865eb1',
nickname: 'Arbitrum mainnet 2',
nickname: 'Avalanche mainnet 2',
rpcPrefs: {},
rpcUrl: 'https://responsive-rpc.test/',
ticker: 'ETH',
ticker: 'AVAX',
},
},
selectedNetworkClientId: 'networkConfigurationId',
Expand All @@ -81,7 +81,7 @@ describe('MultiRpc:', function (this: Suite) {

await driver.delay(regularDelayMs);

// complete
// complete onboarding
await driver.clickElement('[data-testid="onboarding-complete-done"]');

// pin extension
Expand All @@ -96,7 +96,7 @@ describe('MultiRpc:', function (this: Suite) {
await driver.clickElement('[data-testid="network-display"]');

await driver.clickElement(
'[data-testid="network-rpc-name-button-0xa4b1"]',
'[data-testid="network-rpc-name-button-0xa86a"]',
);

const menuItems = await driver.findElements('.select-rpc-url__item');
Expand Down Expand Up @@ -341,7 +341,7 @@ describe('MultiRpc:', function (this: Suite) {
json: {
id: '1694444405781',
jsonrpc: '2.0',
result: '0xa4b1',
result: '0xa86a',
},
})),
];
Expand All @@ -351,7 +351,7 @@ describe('MultiRpc:', function (this: Suite) {
fixtures: new FixtureBuilder({ onboarding: true })
.withNetworkController({
providerConfig: {
rpcPrefs: { blockExplorerUrl: 'https://etherscan.io/' },
rpcPrefs: { blockExplorerUrl: 'https://snowtrace.io/' },
},
networkConfigurations: {
networkConfigurationId: {
Expand All @@ -362,20 +362,20 @@ describe('MultiRpc:', function (this: Suite) {
rpcPrefs: { blockExplorerUrl: 'https://etherscan.io/' },
},
'2ce66016-8aab-47df-b27f-318c80865eb0': {
chainId: '0xa4b1',
chainId: '0xa86a',
id: '2ce66016-8aab-47df-b27f-318c80865eb0',
nickname: 'Arbitrum mainnet',
nickname: 'Avalanche mainnet',
rpcPrefs: {},
rpcUrl: 'https://arbitrum-mainnet.infura.io',
ticker: 'ETH',
rpcUrl: 'https://avalanche-mainnet.infura.io',
ticker: 'AVAX',
},
'2ce66016-8aab-47df-b27f-318c80865eb1': {
chainId: '0xa4b1',
chainId: '0xa86a',
id: '2ce66016-8aab-47df-b27f-318c80865eb1',
nickname: 'Arbitrum mainnet 2',
nickname: 'Avalanche mainnet 2',
rpcPrefs: {},
rpcUrl: 'https://responsive-rpc.test/',
ticker: 'ETH',
ticker: 'AVAX',
},
},
selectedNetworkClientId: 'networkConfigurationId',
Expand All @@ -395,7 +395,7 @@ describe('MultiRpc:', function (this: Suite) {

await driver.delay(regularDelayMs);

// go to advanced settigns
// go to advanced settings
await driver.clickElementAndWaitToDisappear({
text: 'Manage default privacy settings',
});
Expand All @@ -406,15 +406,15 @@ describe('MultiRpc:', function (this: Suite) {

// open edit modal
await driver.clickElement({
text: 'arbitrum-mainnet.infura.io',
text: 'avalanche-mainnet.infura.io',
tag: 'p',
});

await driver.clickElement('[data-testid="test-add-rpc-drop-down"]');

await driver.delay(regularDelayMs);
await driver.clickElement({
text: 'Arbitrum mainnet 2',
text: 'Avalanche mainnet 2',
tag: 'button',
});

Expand Down Expand Up @@ -446,14 +446,14 @@ describe('MultiRpc:', function (this: Suite) {

// Validate the network was edited
const networkEdited = await driver.isElementPresent({
text: '“Arbitrum One” was successfully edited!',
text: '“Avalanche Network C-Chain” was successfully edited!',
});
assert.equal(
networkEdited,
true,
'“Arbitrum One” was successfully edited!',
'“Avalanche Network C-Chain” was successfully edited!',
);
// Ensures popover backround doesn't kill test
// Ensures popover background doesn't kill test
await driver.assertElementNotPresent('.popover-bg');

// We need to use clickElementSafe + assertElementNotPresent as sometimes the network dialog doesn't appear, as per this issue (#27870)
Expand All @@ -467,12 +467,12 @@ describe('MultiRpc:', function (this: Suite) {

await driver.clickElement('[data-testid="network-display"]');

const arbitrumRpcUsed = await driver.findElement({
text: 'Arbitrum mainnet 2',
const avalancheRpcUsed = await driver.findElement({
text: 'Avalanche mainnet 2',
tag: 'button',
});

const existRpcUsed = arbitrumRpcUsed !== undefined;
const existRpcUsed = avalancheRpcUsed !== undefined;
assert.equal(existRpcUsed, true, 'Second Rpc is used');
},
);
Expand Down
62 changes: 62 additions & 0 deletions ui/pages/onboarding-flow/welcome/welcome.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useHistory } from 'react-router-dom';
///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask)
import { Carousel } from 'react-responsive-carousel';
///: END:ONLY_INCLUDE_IF
import { CHAIN_IDS } from '@metamask/transaction-controller';
import Mascot from '../../../components/ui/mascot';
import Button from '../../../components/ui/button';
import { Text } from '../../../components/component-library';
Expand All @@ -25,6 +26,8 @@ import {
import {
setFirstTimeFlowType,
setTermsOfUseLastAgreed,
addNetwork,
updateNetworksList,
///: BEGIN:ONLY_INCLUDE_IF(build-mmi)
setParticipateInMetaMetrics,
///: END:ONLY_INCLUDE_IF
Expand All @@ -42,6 +45,8 @@ import {
} from '../../../helpers/constants/routes';
import { getFirstTimeFlowType, getCurrentKeyring } from '../../../selectors';
import { FirstTimeFlowType } from '../../../../shared/constants/onboarding';
import { FEATURED_RPCS } from '../../../../shared/constants/network';
import { getCompletedOnboarding } from '../../../ducks/metamask/metamask';

export default function OnboardingWelcome() {
const t = useI18nContext();
Expand All @@ -54,6 +59,8 @@ export default function OnboardingWelcome() {
const [newAccountCreationInProgress, setNewAccountCreationInProgress] =
useState(false);

const completedOnboarding = useSelector(getCompletedOnboarding);

// Don't allow users to come back to this screen after they
// have already imported or created a wallet
useEffect(() => {
Expand All @@ -72,7 +79,62 @@ export default function OnboardingWelcome() {
history,
firstTimeFlowType,
newAccountCreationInProgress,
dispatch,
]);

useEffect(() => {
const addNetworks = async () => {
if (!completedOnboarding) {
// List of chainIds to add (as hex strings)
const chainIdsToAdd = [
CHAIN_IDS.ARBITRUM,
CHAIN_IDS.BASE,
CHAIN_IDS.BSC,
CHAIN_IDS.OPTIMISM,
CHAIN_IDS.POLYGON,
];

// Define the desired order based on `networkId`
const networkOrder = [
CHAIN_IDS.MAINNET,
CHAIN_IDS.ARBITRUM,
CHAIN_IDS.BASE,
CHAIN_IDS.BSC,
CHAIN_IDS.LINEA_MAINNET,
CHAIN_IDS.OPTIMISM,
CHAIN_IDS.POLYGON,
];

// Filter the FEATURED_RPCS based on the chainIdsToAdd array
const selectedNetworks = FEATURED_RPCS.filter((network) =>
chainIdsToAdd.includes(network.chainId),
);

for (const network of selectedNetworks) {
await dispatch(
addNetwork({
chainId: network.chainId,
blockExplorerUrls: network.blockExplorerUrls,
defaultRpcEndpointIndex: network.defaultRpcEndpointIndex,
defaultBlockExplorerUrlIndex:
network.defaultBlockExplorerUrlIndex,
name: network.name,
nativeCurrency: network.nativeCurrency,
rpcEndpoints: network.rpcEndpoints,
}),
);
salimtb marked this conversation as resolved.
Show resolved Hide resolved
console.log(`Successfully added network: ${network.name}`);
}

await dispatch(updateNetworksList(networkOrder));
}
};

addNetworks().catch((error) => {
console.error('Error adding networks:', error);
});
}, [dispatch, completedOnboarding]);

const trackEvent = useContext(MetaMetricsContext);

const onCreateClick = async () => {
Expand Down
51 changes: 51 additions & 0 deletions ui/pages/onboarding-flow/welcome/welcome.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { renderWithProvider } from '../../../../test/lib/render-helpers';
import {
setFirstTimeFlowType,
setTermsOfUseLastAgreed,
addNetwork,
updateNetworksList,
} from '../../../store/actions';
import {
ONBOARDING_METAMETRICS,
Expand Down Expand Up @@ -35,6 +37,8 @@ jest.mock('../../../store/actions.ts', () => ({
return type;
}),
),
addNetwork: jest.fn(),
updateNetworksList: jest.fn(),
}));

jest.mock('react-router-dom', () => ({
Expand Down Expand Up @@ -122,5 +126,52 @@ describe('Onboarding Welcome Component', () => {
expect(mockHistoryPush).toHaveBeenCalledWith(ONBOARDING_METAMETRICS);
});
});

describe('useEffect for adding networks', () => {
it('should add networks when onboarding is incomplete', async () => {
// Render the component
renderWithProvider(<OnboardingWelcome />, mockStore);

await waitFor(() => {
// Verify addNetwork is called with Arbitrum (or other networks)
expect(addNetwork).toHaveBeenCalledWith({
chainId: '0xa4b1', // Arbitrum's chain ID
blockExplorerUrls: ['https://explorer.arbitrum.io'], // Arbitrum block explorer
defaultRpcEndpointIndex: 0,
defaultBlockExplorerUrlIndex: 0,
name: 'Arbitrum One',
nativeCurrency: 'ETH',
rpcEndpoints: [
{
url: 'https://arbitrum-mainnet.infura.io/v3/undefined',
type: 'custom',
},
],
});
});
});

it('should not add networks when onboarding is completed', async () => {
const mockCompletedOnboardingState = {
...mockState,
metamask: {
...mockState.metamask,
completedOnboarding: true, // Simulate completed onboarding
},
};
const mockStore2 = configureMockStore([thunk])(
mockCompletedOnboardingState,
);

renderWithProvider(<OnboardingWelcome />, mockStore2);

// Wait to ensure the effect runs (or doesn't in this case)
await waitFor(() => {
// Expect that neither addNetwork nor updateNetworksList was called
expect(addNetwork).not.toHaveBeenCalled();
expect(updateNetworksList).not.toHaveBeenCalled();
});
});
});
});
});
4 changes: 4 additions & 0 deletions ui/selectors/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -1803,6 +1803,10 @@ export function getSortedAnnouncementsToShow(state) {
* @returns {{networkId: string}[]}
*/
export function getOrderedNetworksList(state) {
console.log(
'state.metamask.orderedNetworkList ----',
state.metamask.orderedNetworkList,
);
return state.metamask.orderedNetworkList;
}

Expand Down