1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-10-22 11:22:43 +02:00

Fix #19941 - Correctly show network name and selection when chainIds collide (#19947)

This commit is contained in:
David Walsh 2023-07-13 13:29:53 -05:00 committed by Dan J Miller
parent 710101991c
commit 6c04d76502
10 changed files with 95 additions and 17 deletions

View File

@ -115,13 +115,22 @@
"type": "rpc", "type": "rpc",
"chainId": "0x5", "chainId": "0x5",
"ticker": "ETH", "ticker": "ETH",
"id": "testNetworkConfigurationId" "id": "chain5"
}, },
"networkConfigurations": { "networkConfigurations": {
"testNetworkConfigurationId": { "testNetworkConfigurationId": {
"rpcUrl": "https://testrpc.com", "rpcUrl": "https://testrpc.com",
"chainId": "0x1", "chainId": "0x1",
"nickname": "Custom Mainnet RPC" "nickname": "Custom Mainnet RPC",
"type": "rpc",
"id": "testNetworkConfigurationId"
},
"chain5": {
"type": "rpc",
"chainId": "0x5",
"ticker": "ETH",
"nickname": "Chain 5",
"id": "chain5"
} }
}, },
"keyrings": [ "keyrings": [

View File

@ -215,6 +215,7 @@ function defaultFixture() {
rpcUrl: 'http://localhost:8545', rpcUrl: 'http://localhost:8545',
ticker: 'ETH', ticker: 'ETH',
type: 'rpc', type: 'rpc',
id: 'networkConfigurationId',
}, },
networkConfigurations: { networkConfigurations: {
networkConfigurationId: { networkConfigurationId: {
@ -346,6 +347,7 @@ function onboardingFixture() {
rpcUrl: 'http://localhost:8545', rpcUrl: 'http://localhost:8545',
chainId: CHAIN_IDS.LOCALHOST, chainId: CHAIN_IDS.LOCALHOST,
nickname: 'Localhost 8545', nickname: 'Localhost 8545',
id: 'networkConfigurationId',
}, },
networkConfigurations: { networkConfigurations: {
networkConfigurationId: { networkConfigurationId: {
@ -355,6 +357,7 @@ function onboardingFixture() {
rpcUrl: 'http://localhost:8545', rpcUrl: 'http://localhost:8545',
ticker: 'ETH', ticker: 'ETH',
networkConfigurationId: 'networkConfigurationId', networkConfigurationId: 'networkConfigurationId',
type: 'rpc',
}, },
}, },
}, },

View File

@ -196,19 +196,21 @@ describe('Stores custom RPC history', function () {
fixtures: new FixtureBuilder() fixtures: new FixtureBuilder()
.withNetworkController({ .withNetworkController({
networkConfigurations: { networkConfigurations: {
networkConfigurationId: { networkConfigurationIdOne: {
rpcUrl: 'http://127.0.0.1:8545/1', rpcUrl: 'http://127.0.0.1:8545/1',
chainId: '0x539', chainId: '0x539',
ticker: 'ETH', ticker: 'ETH',
nickname: 'http://127.0.0.1:8545/1', nickname: 'http://127.0.0.1:8545/1',
rpcPrefs: {}, rpcPrefs: {},
type: 'rpc',
}, },
networkConfigurationId2: { networkConfigurationIdTwo: {
rpcUrl: 'http://127.0.0.1:8545/2', rpcUrl: 'http://127.0.0.1:8545/2',
chainId: '0x539', chainId: '0x539',
ticker: 'ETH', ticker: 'ETH',
nickname: 'http://127.0.0.1:8545/2', nickname: 'http://127.0.0.1:8545/2',
rpcPrefs: {}, rpcPrefs: {},
type: 'rpc',
}, },
}, },
}) })
@ -248,14 +250,14 @@ describe('Stores custom RPC history', function () {
fixtures: new FixtureBuilder() fixtures: new FixtureBuilder()
.withNetworkController({ .withNetworkController({
networkConfigurations: { networkConfigurations: {
networkConfigurationId: { networkConfigurationIdOne: {
rpcUrl: 'http://127.0.0.1:8545/1', rpcUrl: 'http://127.0.0.1:8545/1',
chainId: '0x539', chainId: '0x539',
ticker: 'ETH', ticker: 'ETH',
nickname: 'http://127.0.0.1:8545/1', nickname: 'http://127.0.0.1:8545/1',
rpcPrefs: {}, rpcPrefs: {},
}, },
networkConfigurationId2: { networkConfigurationIdTwo: {
rpcUrl: 'http://127.0.0.1:8545/2', rpcUrl: 'http://127.0.0.1:8545/2',
chainId: '0x539', chainId: '0x539',
ticker: 'ETH', ticker: 'ETH',

View File

@ -66,7 +66,7 @@ exports[`NFT Details should match minimal props and state snapshot 1`] = `
class="box mm-text mm-avatar-base mm-avatar-base--size-sm mm-avatar-network nft-item__network-badge mm-text--body-sm mm-text--text-transform-uppercase box--display-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-text-default box--background-color-background-alternative box--rounded-full box--border-color-background-default box--border-width-2 box--border-style-solid" class="box mm-text mm-avatar-base mm-avatar-base--size-sm mm-avatar-network nft-item__network-badge mm-text--body-sm mm-text--text-transform-uppercase box--display-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-text-default box--background-color-background-alternative box--rounded-full box--border-color-background-default box--border-width-2 box--border-style-solid"
data-testid="nft-network-badge" data-testid="nft-network-badge"
> >
G C
</div> </div>
</div> </div>
</div> </div>

View File

@ -13,6 +13,12 @@ import {
removeAndIgnoreNft, removeAndIgnoreNft,
setRemoveNftMessage, setRemoveNftMessage,
} from '../../../store/actions'; } from '../../../store/actions';
import {
CHAIN_IDS,
CURRENCY_SYMBOLS,
MAINNET_DISPLAY_NAME,
NETWORK_TYPES,
} from '../../../../shared/constants/network';
import NftDetails from './nft-details'; import NftDetails from './nft-details';
jest.mock('copy-to-clipboard'); jest.mock('copy-to-clipboard');
@ -172,7 +178,10 @@ describe('NFT Details', () => {
metamask: { metamask: {
...mockState.metamask, ...mockState.metamask,
providerConfig: { providerConfig: {
chainId: '0x1', chainId: CHAIN_IDS.MAINNET,
type: NETWORK_TYPES.MAINNET,
ticker: CURRENCY_SYMBOLS.ETH,
nickname: MAINNET_DISPLAY_NAME,
}, },
}, },
}; };
@ -203,12 +212,16 @@ describe('NFT Details', () => {
...mockState.metamask, ...mockState.metamask,
providerConfig: { providerConfig: {
chainId: '0x89', chainId: '0x89',
type: 'rpc',
id: 'custom-mainnet',
}, },
networkConfigurations: { networkConfigurations: {
testNetworkConfigurationId: { testNetworkConfigurationId: {
rpcUrl: 'https://testrpc.com', rpcUrl: 'https://testrpc.com',
chainId: '0x89', chainId: '0x89',
nickname: 'Custom Mainnet RPC', nickname: 'Custom Mainnet RPC',
type: 'rpc',
id: 'custom-mainnet',
}, },
}, },
}, },
@ -239,7 +252,8 @@ describe('NFT Details', () => {
metamask: { metamask: {
...mockState.metamask, ...mockState.metamask,
providerConfig: { providerConfig: {
chainId: '0xaa36a7', chainId: CHAIN_IDS.SEPOLIA,
type: NETWORK_TYPES.SEPOLIA,
}, },
}, },
}; };

View File

@ -214,12 +214,12 @@ exports[`App Header should match snapshot 1`] = `
<div <div
class="box mm-text mm-avatar-base mm-avatar-base--size-xs mm-avatar-network mm-picker-network__avatar-network mm-text--body-xs mm-text--text-transform-uppercase box--display-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-text-default box--background-color-background-alternative box--rounded-full box--border-color-transparent box--border-style-solid box--border-width-1" class="box mm-text mm-avatar-base mm-avatar-base--size-xs mm-avatar-network mm-picker-network__avatar-network mm-text--body-xs mm-text--text-transform-uppercase box--display-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-text-default box--background-color-background-alternative box--rounded-full box--border-color-transparent box--border-style-solid box--border-width-1"
> >
G C
</div> </div>
<p <p
class="box mm-text mm-text--body-sm mm-text--ellipsis box--flex-direction-row box--color-text-default" class="box mm-text mm-text--body-sm mm-text--ellipsis box--flex-direction-row box--color-text-default"
> >
Goerli Chain 5
</p> </p>
<span <span
class="box mm-picker-network__arrow-down-icon mm-icon mm-icon--size-xs box--display-inline-block box--flex-direction-row box--color-icon-default" class="box mm-picker-network__arrow-down-icon mm-icon mm-icon--size-xs box--display-inline-block box--flex-direction-row box--color-icon-default"

View File

@ -17,6 +17,7 @@ import {
getShowTestNetworks, getShowTestNetworks,
getAllEnabledNetworks, getAllEnabledNetworks,
getCurrentChainId, getCurrentChainId,
getCurrentNetwork,
} 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';
@ -53,6 +54,9 @@ export const NetworkListMenu = ({ onClose }) => {
const networks = useSelector(getAllEnabledNetworks); const networks = useSelector(getAllEnabledNetworks);
const showTestNetworks = useSelector(getShowTestNetworks); const showTestNetworks = useSelector(getShowTestNetworks);
const currentChainId = useSelector(getCurrentChainId); const currentChainId = useSelector(getCurrentChainId);
const currentNetwork = useSelector(getCurrentNetwork);
const dispatch = useDispatch(); const dispatch = useDispatch();
const history = useHistory(); const history = useHistory();
const trackEvent = useContext(MetaMetricsContext); const trackEvent = useContext(MetaMetricsContext);
@ -91,7 +95,7 @@ export const NetworkListMenu = ({ onClose }) => {
) { ) {
return null; return null;
} }
const isCurrentNetwork = currentChainId === network.chainId; const isCurrentNetwork = currentNetwork.id === network.id;
const canDeleteNetwork = const canDeleteNetwork =
!isCurrentNetwork && !isCurrentNetwork &&
!UNREMOVABLE_CHAIN_IDS.includes(network.chainId); !UNREMOVABLE_CHAIN_IDS.includes(network.chainId);

View File

@ -1170,9 +1170,13 @@ export function getNetworkConfigurations(state) {
export function getCurrentNetwork(state) { export function getCurrentNetwork(state) {
const allNetworks = getAllNetworks(state); const allNetworks = getAllNetworks(state);
const currentChainId = getCurrentChainId(state); const providerConfig = getProviderConfig(state);
return allNetworks.find((network) => network.chainId === currentChainId); const filter =
providerConfig.type === 'rpc'
? (network) => network.id === providerConfig.id
: (network) => network.id === providerConfig.type;
return allNetworks.find(filter);
} }
export function getAllEnabledNetworks(state) { export function getAllEnabledNetworks(state) {
@ -1200,6 +1204,7 @@ export function getAllNetworks(state) {
}, },
providerType: NETWORK_TYPES.MAINNET, providerType: NETWORK_TYPES.MAINNET,
ticker: CURRENCY_SYMBOLS.ETH, ticker: CURRENCY_SYMBOLS.ETH,
id: NETWORK_TYPES.MAINNET,
}, },
{ {
chainId: CHAIN_IDS.LINEA_MAINNET, chainId: CHAIN_IDS.LINEA_MAINNET,
@ -1210,6 +1215,7 @@ export function getAllNetworks(state) {
}, },
providerType: NETWORK_TYPES.LINEA_MAINNET, providerType: NETWORK_TYPES.LINEA_MAINNET,
ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.LINEA_MAINNET], ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.LINEA_MAINNET],
id: NETWORK_TYPES.LINEA_MAINNET,
}, },
// Custom networks added by the user // Custom networks added by the user
...Object.values(networkConfigurations).filter( ...Object.values(networkConfigurations).filter(
@ -1222,6 +1228,7 @@ export function getAllNetworks(state) {
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], ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.GOERLI],
id: NETWORK_TYPES.GOERLI,
}, },
{ {
chainId: CHAIN_IDS.SEPOLIA, chainId: CHAIN_IDS.SEPOLIA,
@ -1229,6 +1236,7 @@ export function getAllNetworks(state) {
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], ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.SEPOLIA],
id: NETWORK_TYPES.SEPOLIA,
}, },
{ {
chainId: CHAIN_IDS.LINEA_GOERLI, chainId: CHAIN_IDS.LINEA_GOERLI,
@ -1239,6 +1247,7 @@ export function getAllNetworks(state) {
}, },
providerType: NETWORK_TYPES.LINEA_GOERLI, providerType: NETWORK_TYPES.LINEA_GOERLI,
ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.LINEA_GOERLI], ticker: TEST_NETWORK_TICKER_MAP[NETWORK_TYPES.LINEA_GOERLI],
id: NETWORK_TYPES.LINEA_GOERLI,
}, },
// Localhosts // Localhosts
...Object.values(networkConfigurations).filter( ...Object.values(networkConfigurations).filter(

View File

@ -316,6 +316,46 @@ describe('Selectors', () => {
}); });
}); });
describe('#getCurrentNetwork', () => {
it('returns the correct custom network when there is a chainId collision', () => {
const modifiedMockState = {
...mockState,
metamask: {
...mockState.metamask,
providerConfig: {
...mockState.metamask.networkConfigurations
.testNetworkConfigurationId,
// 0x1 would collide with Ethereum Mainnet
chainId: '0x1',
// type of "rpc" signals custom network
type: 'rpc',
},
},
};
const currentNetwork = selectors.getCurrentNetwork(modifiedMockState);
expect(currentNetwork.nickname).toBe('Custom Mainnet RPC');
expect(currentNetwork.chainId).toBe('0x1');
});
it('returns the correct mainnet network when there is a chainId collision', () => {
const modifiedMockState = {
...mockState,
metamask: {
...mockState.metamask,
providerConfig: {
...mockState.metamask.providerConfig,
chainId: '0x1',
// Changing type to 'mainnet' represents Ethereum Mainnet
type: 'mainnet',
},
},
};
const currentNetwork = selectors.getCurrentNetwork(modifiedMockState);
expect(currentNetwork.nickname).toBe('Ethereum Mainnet');
});
});
describe('#getAllEnabledNetworks', () => { describe('#getAllEnabledNetworks', () => {
it('returns only MainNet with showTestNetworks off', () => { it('returns only MainNet with showTestNetworks off', () => {
const networks = selectors.getAllEnabledNetworks({ const networks = selectors.getAllEnabledNetworks({

View File

@ -19,12 +19,9 @@ import { PayloadAction } from '@reduxjs/toolkit';
import { GasFeeController } from '@metamask/gas-fee-controller'; import { GasFeeController } from '@metamask/gas-fee-controller';
import { PermissionsRequest } from '@metamask/permission-controller'; import { PermissionsRequest } from '@metamask/permission-controller';
import { NonEmptyArray } from '@metamask/controller-utils'; import { NonEmptyArray } from '@metamask/controller-utils';
<<<<<<< HEAD
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps) ///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
import { HandlerType } from '@metamask/snaps-utils'; import { HandlerType } from '@metamask/snaps-utils';
///: END:ONLY_INCLUDE_IN ///: END:ONLY_INCLUDE_IN
=======
>>>>>>> master
import { getMethodDataAsync } from '../helpers/utils/transactions.util'; import { getMethodDataAsync } from '../helpers/utils/transactions.util';
import switchDirection from '../../shared/lib/switch-direction'; import switchDirection from '../../shared/lib/switch-direction';
import { import {