Skip to content

Commit

Permalink
merge: upgrade network controller to v21
Browse files Browse the repository at this point in the history
  • Loading branch information
salimtb committed Oct 9, 2024
1 parent ea3948c commit 6f2c53d
Show file tree
Hide file tree
Showing 66 changed files with 4,706 additions and 3,905 deletions.
23 changes: 9 additions & 14 deletions app/components/UI/AccountInfoCard/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
MOCK_ADDRESS_1,
} from '../../../util/test/accountsControllerTestUtils';
import { RootState } from '../../../reducers';
import { RpcEndpointType } from '@metamask/network-controller';
import { mockNetworkState } from '../../../util/test/network';

jest.mock('../../../core/Engine', () => ({
resetState: jest.fn(),
Expand Down Expand Up @@ -48,20 +50,13 @@ const mockInitialState: DeepPartial<RootState> = {
},
},
NetworkController: {
selectedNetworkClientId: 'sepolia',
networksMetadata: {},
networkConfigurations: {
sepolia: {
id: 'sepolia',
rpcUrl: 'http://localhost/v3/',
chainId: '0xaa36a7',
ticker: 'ETH',
nickname: 'sepolia',
rpcPrefs: {
blockExplorerUrl: 'https://etherscan.com',
},
},
},
...mockNetworkState({
chainId: '0xaa36a7',
id: 'mainnet',
nickname: 'Sepolia',
ticker: 'SepoliaETH',
type: RpcEndpointType.Infura,
}),
},
TokenBalancesController: {
contractBalances: {},
Expand Down
177 changes: 144 additions & 33 deletions app/components/UI/NetworkModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ import { useMetrics } from '../../../components/hooks/useMetrics';
import { toHex } from '@metamask/controller-utils';
import { rpcIdentifierUtility } from '../../../components/hooks/useSafeChains';
import Logger from '../../../util/Logger';
import { selectNetworkConfigurations } from '../../../selectors/networkController';
import {
NetworkConfiguration,
RpcEndpointType,
AddNetworkFields,
} from '@metamask/network-controller';

export interface SafeChain {
chainId: string;
Expand Down Expand Up @@ -162,6 +168,10 @@ const NetworkModals = (props: NetworkProps) => {
selectUseSafeChainsListValidation,
);

const networkConfigurationByChainId = useSelector(
selectNetworkConfigurations,
);

const customNetworkInformation = {
chainId,
blockExplorerUrl,
Expand Down Expand Up @@ -189,52 +199,153 @@ const NetworkModals = (props: NetworkProps) => {
checkNetwork();
}, [checkNetwork]);

const closeModal = () => {
const closeModal = async () => {
const { NetworkController } = Engine.context;
const url = new URLPARSE(rpcUrl);
!isPrivateConnection(url.hostname) && url.set('protocol', 'https:');
NetworkController.upsertNetworkConfiguration(
{
rpcUrl: url.href,

const existingNetwork = networkConfigurationByChainId[chainId];

if (existingNetwork) {
const updatedNetwork = await NetworkController.updateNetwork(
existingNetwork.chainId,
existingNetwork,
existingNetwork.chainId === chainId
? {
replacementSelectedRpcEndpointIndex:
existingNetwork.defaultRpcEndpointIndex,
}
: undefined,
);

const { networkClientId } =
updatedNetwork?.rpcEndpoints?.[
updatedNetwork.defaultRpcEndpointIndex
] ?? {};

await NetworkController.setActiveNetwork(networkClientId);
} else {
const addedNetwork = await NetworkController.addNetwork({
chainId,
ticker,
nickname,
rpcPrefs: { blockExplorerUrl },
},
{
// Metrics-related properties required, but the metric event is a no-op
// TODO: Use events for controller metric events
referrer: 'ignored',
source: 'ignored',
},
);
blockExplorerUrls: [blockExplorerUrl],
defaultRpcEndpointIndex: 0,
defaultBlockExplorerUrlIndex: 0,
name: nickname,
nativeCurrency: ticker,
rpcEndpoints: [
{
url: rpcUrl,
name: nickname,
type: RpcEndpointType.Custom,
},
],
});

const { networkClientId } =
addedNetwork?.rpcEndpoints?.[addedNetwork.defaultRpcEndpointIndex] ??
{};

await NetworkController.setActiveNetwork(networkClientId);
}
onClose();
};

const switchNetwork = () => {
const handleExistingNetwork = async (
existingNetwork: NetworkConfiguration,
networkId: string,
) => {
const { NetworkController } = Engine.context;
const updatedNetwork = await NetworkController.updateNetwork(
existingNetwork.chainId,
existingNetwork,
existingNetwork.chainId === networkId
? {
replacementSelectedRpcEndpointIndex:
existingNetwork.defaultRpcEndpointIndex,
}
: undefined,
);

const { networkClientId } =
updatedNetwork?.rpcEndpoints?.[updatedNetwork.defaultRpcEndpointIndex] ??
{};

await NetworkController.setActiveNetwork(networkClientId);
};

const handleNewNetwork = async (
networkId: `0x${string}`,
networkRpcUrl: string,
name: string,
nativeCurrency: string,
networkBlockExplorerUrl: string,
) => {
const { NetworkController } = Engine.context;
const networkConfig = {
chainId: networkId,
blockExplorerUrls: networkBlockExplorerUrl
? [networkBlockExplorerUrl]
: [],
defaultRpcEndpointIndex: 0,
defaultBlockExplorerUrlIndex: blockExplorerUrl ? 0 : undefined,
name,
nativeCurrency,
rpcEndpoints: [
{
url: networkRpcUrl,
name,
type: RpcEndpointType.Custom,
},
],
} as AddNetworkFields;

return NetworkController.addNetwork(networkConfig);
};

const handleNavigation = (
onSwitchNetwork: () => void,
networkSwitchPopToWallet: boolean,
) => {
if (onSwitchNetwork) {
onSwitchNetwork();
} else {
networkSwitchPopToWallet
? navigation.navigate('WalletView')
: navigation.goBack();
}
};

const switchNetwork = async () => {
const { NetworkController, CurrencyRateController } = Engine.context;
const url = new URLPARSE(rpcUrl);
const existingNetwork = networkConfigurationByChainId[chainId];

CurrencyRateController.updateExchangeRate(ticker);
!isPrivateConnection(url.hostname) && url.set('protocol', 'https:');
NetworkController.upsertNetworkConfiguration(
{
rpcUrl: url.href,

if (!isPrivateConnection(url.hostname)) {
url.set('protocol', 'https:');
}

if (existingNetwork) {
await handleExistingNetwork(existingNetwork, chainId);
} else {
const addedNetwork = await handleNewNetwork(
chainId,
ticker,
rpcUrl,
nickname,
rpcPrefs: { blockExplorerUrl },
},
{
setActive: true,
// Metrics-related properties required, but the metric event is a no-op
// TODO: Use events for controller metric events
referrer: 'ignored',
source: 'ignored',
},
);
closeModal();
ticker,
blockExplorerUrl,
);
const { networkClientId } =
addedNetwork?.rpcEndpoints?.[addedNetwork.defaultRpcEndpointIndex] ??
{};

NetworkController.setActiveNetwork(networkClientId);
}
onClose();

if (onNetworkSwitch) {
onNetworkSwitch();
handleNavigation(onNetworkSwitch, shouldNetworkSwitchPopToWallet);
} else {
shouldNetworkSwitchPopToWallet
? navigation.navigate('WalletView')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ function render(Component: React.ComponentType, chainId?: `0x${string}`) {
chainId: '0x89',
id: 'networkId1',
nickname: 'Polygon Mainnet',
ticker: 'MATIC',
ticker: 'POL',
},
),
},
Expand Down
18 changes: 12 additions & 6 deletions app/components/UI/Ramp/Views/NetworkSwitcher/NetworkSwitcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,16 +154,22 @@ function NetworkSwitcher() {
const switchNetwork = useCallback(
(networkConfiguration) => {
const { CurrencyRateController, NetworkController } = Engine.context;
const entry = Object.entries(networkConfigurations).find(
([_a, { chainId }]) => chainId === networkConfiguration.chainId,
const config = Object.values(networkConfigurations).find(
({ chainId }) => chainId === networkConfiguration.chainId,
);

if (entry) {
const [networkConfigurationId] = entry;
const { ticker } = networkConfiguration;
if (config) {
const {
nativeCurrency: ticker,
rpcEndpoints,
defaultRpcEndpointIndex,
} = config;

const { networkClientId } =
rpcEndpoints?.[defaultRpcEndpointIndex] ?? {};

CurrencyRateController.updateExchangeRate(ticker);
NetworkController.setActiveNetwork(networkConfigurationId);
NetworkController.setActiveNetwork(networkClientId);
navigateToGetStarted();
}
},
Expand Down
20 changes: 11 additions & 9 deletions app/components/UI/ReceiveRequest/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import { cloneDeep } from 'lodash';
import { RpcEndpointType } from '@metamask/network-controller';
import ReceiveRequest from './';
import { renderScreen } from '../../../util/test/renderWithProvider';
import { backgroundState } from '../../../util/test/initial-root-state';
import { MOCK_ACCOUNTS_CONTROLLER_STATE } from '../../../util/test/accountsControllerTestUtils';
import { mockNetworkState } from '../../../util/test/network';

const initialState = {
engine: {
backgroundState: {
...backgroundState,
NetworkController: {
providerConfig: {
type: 'mainnet',
chainId: '0x1',
...mockNetworkState({
id: 'mainnet',
nickname: 'Ethereum',
ticker: 'ETH',
},
chainId: '0x1',
type: RpcEndpointType.Infura,
}),
},
AccountsController: MOCK_ACCOUNTS_CONTROLLER_STATE,
},
Expand Down Expand Up @@ -47,20 +51,19 @@ describe('ReceiveRequest', () => {
const { toJSON } = renderScreen(
ReceiveRequest,
{ name: 'ReceiveRequest' },
// @ts-expect-error initialBackgroundState throws error
{ state: initialState },
);
expect(toJSON()).toMatchSnapshot();
});

it('render with different ticker matches snapshot', () => {
const state = cloneDeep(initialState);
state.engine.backgroundState.NetworkController.providerConfig.ticker =
'DIFF';
state.engine.backgroundState.NetworkController.networkConfigurationsByChainId[
'0x1'
].nativeCurrency = 'DIFF';
const { toJSON } = renderScreen(
ReceiveRequest,
{ name: 'ReceiveRequest' },
// @ts-expect-error initialBackgroundState throws error
{ state },
);
expect(toJSON()).toMatchSnapshot();
Expand All @@ -74,7 +77,6 @@ describe('ReceiveRequest', () => {
const { toJSON } = renderScreen(
ReceiveRequest,
{ name: 'ReceiveRequest' },
// @ts-expect-error initialBackgroundState throws error
{ state },
);
expect(toJSON()).toMatchSnapshot();
Expand Down
4 changes: 2 additions & 2 deletions app/components/Views/AssetDetails/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import { useMetrics } from '../../../components/hooks/useMetrics';
import { RootState } from 'app/reducers';
import { Colors } from '../../../util/theme/models';
import { Hex } from '@metamask/utils';
import { RpcEndpointType } from '@metamask/network-controller';

const createStyles = (colors: Colors) =>
StyleSheet.create({
Expand Down Expand Up @@ -138,8 +139,7 @@ const AssetDetails = (props: Props) => {
* removes goerli from provider config types
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(Networks as any)[providerConfig.type]?.name ||
{ ...Networks.rpc, color: null }.name;
(Networks as any)[providerConfig?.type ?? RpcEndpointType.Custom];
}
return name;
};
Expand Down
Loading

0 comments on commit 6f2c53d

Please sign in to comment.