Skip to content

Commit

Permalink
move getProviderConfig out of ducks/metamask.js to `selectors/net…
Browse files Browse the repository at this point in the history
…works.ts`

`getProviderConfig` is so widely used in the codebase, and makes use of multiple selectors itself, it makes it very complicated to untangle. I've put it in its own file just to, hopefully temporarily, simplify untangling other circular dependency issues.
  • Loading branch information
davidmurdoch committed Oct 9, 2024
1 parent 77bdf73 commit 6f8db43
Show file tree
Hide file tree
Showing 55 changed files with 386 additions and 242 deletions.
2 changes: 1 addition & 1 deletion app/scripts/lib/ppom/ppom-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export async function isChainSupported(chainId: Hex): Promise<boolean> {
`Error fetching supported chains from security alerts API`,
);
}
return supportedChainIds.includes(chainId);
return supportedChainIds.includes(chainId as Hex);
}

function normalizePPOMRequest(
Expand Down
4 changes: 2 additions & 2 deletions app/scripts/metamask-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,10 +227,10 @@ import {
} from '../../shared/lib/transactions-controller-utils';
// TODO: Remove restricted import
// eslint-disable-next-line import/no-restricted-paths
import { getCurrentChainId } from '../../ui/selectors';
import { getCurrentChainId } from '../../ui/selectors/selectors';
// TODO: Remove restricted import
// eslint-disable-next-line import/no-restricted-paths
import { getProviderConfig } from '../../ui/ducks/metamask/metamask';
import { getProviderConfig } from '../../ui/selectors/networks';
import { endTrace, trace } from '../../shared/lib/trace';
import { BalancesController as MultichainBalancesController } from './lib/accounts/BalancesController';
import {
Expand Down
2 changes: 2 additions & 0 deletions shared/constants/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export const ALLOWED_BRIDGE_CHAIN_IDS = [
CHAIN_IDS.BASE,
];

export type AllowedBridgeChainIds = (typeof ALLOWED_BRIDGE_CHAIN_IDS)[number];

export const BRIDGE_DEV_API_BASE_URL = 'https://bridge.dev-api.cx.metamask.io';
export const BRIDGE_PROD_API_BASE_URL = 'https://bridge.api.cx.metamask.io';
export const BRIDGE_API_BASE_URL = process.env.BRIDGE_USE_DEV_APIS
Expand Down
2 changes: 2 additions & 0 deletions shared/constants/multichain/networks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export type MultichainProviderConfig = ProviderConfigWithImageUrl & {
isAddressCompatible: (address: string) => boolean;
};

export type MultichainNetworkIds = `${MultichainNetworks}`;

export enum MultichainNetworks {
BITCOIN = 'bip122:000000000019d6689c085ae165831e93',
BITCOIN_TESTNET = 'bip122:000000000933ea01ad0ee984209779ba',
Expand Down
2 changes: 2 additions & 0 deletions shared/constants/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ export const NETWORK_TYPES = {
LINEA_MAINNET: 'linea-mainnet',
} as const;

export type NetworkTypes = (typeof NETWORK_TYPES)[keyof typeof NETWORK_TYPES];

/**
* An object containing shortcut names for any non-builtin network. We need
* this to be able to differentiate between networks that require custom
Expand Down
14 changes: 7 additions & 7 deletions shared/modules/selectors/smart-transactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ import {
} from '../../../ui/selectors/selectors'; // TODO: Migrate shared selectors to this file.
import { isProduction } from '../environment';

// TODO: Remove restricted import
// TODO: Remove restricted imports
// eslint-disable-next-line import/no-restricted-paths
import { MultichainState } from '../../../ui/selectors/multichain';
// eslint-disable-next-line import/no-restricted-paths
import { NetworkState } from '../../../ui/selectors/networks';

type SmartTransactionsMetaMaskState = {
metamask: {
Expand Down Expand Up @@ -69,9 +71,7 @@ export const getCurrentChainSupportsSmartTransactions = (
return getAllowedSmartTransactionsChainIds().includes(chainId);
};

const getIsAllowedRpcUrlForSmartTransactions = (
state: SmartTransactionsMetaMaskState,
) => {
const getIsAllowedRpcUrlForSmartTransactions = (state: NetworkState) => {
const chainId = getCurrentChainId(state);
if (!isProduction() || SKIP_STX_RPC_URL_CHECK_CHAIN_IDS.includes(chainId)) {
// Allow any STX RPC URL in development and testing environments or for specific chain IDs.
Expand Down Expand Up @@ -100,7 +100,7 @@ const hasNonZeroBalance = (state: SmartTransactionsMetaMaskState) => {
};

export const getIsSmartTransactionsOptInModalAvailable = (
state: SmartTransactionsMetaMaskState,
state: SmartTransactionsMetaMaskState & NetworkState,
) => {
return (
getCurrentChainSupportsSmartTransactions(state) &&
Expand All @@ -111,7 +111,7 @@ export const getIsSmartTransactionsOptInModalAvailable = (
};

export const getSmartTransactionsEnabled = (
state: SmartTransactionsMetaMaskState,
state: SmartTransactionsMetaMaskState & NetworkState,
): boolean => {
const supportedAccount = accountSupportsSmartTx(state);
// TODO: Create a new proxy service only for MM feature flags.
Expand All @@ -130,7 +130,7 @@ export const getSmartTransactionsEnabled = (
};

export const getIsSmartTransaction = (
state: SmartTransactionsMetaMaskState,
state: SmartTransactionsMetaMaskState & NetworkState,
): boolean => {
const smartTransactionsOptInStatus = getSmartTransactionsOptInStatus(state);
const smartTransactionsEnabled = getSmartTransactionsEnabled(state);
Expand Down
15 changes: 13 additions & 2 deletions test/data/mock-state.json
Original file line number Diff line number Diff line change
Expand Up @@ -387,26 +387,30 @@
"name": "Custom Mainnet RPC",
"nativeCurrency": "ETH",
"defaultRpcEndpointIndex": 0,
"ticker": "ETH",
"rpcEndpoints": [
{
"type": "custom",
"url": "https://testrpc.com",
"networkClientId": "testNetworkConfigurationId"
}
]
],
"blockExplorerUrls": []
},
"0x5": {
"chainId": "0x5",
"name": "Goerli",
"nativeCurrency": "ETH",
"defaultRpcEndpointIndex": 0,
"ticker": "ETH",
"rpcEndpoints": [
{
"type": "custom",
"url": "https://goerli.com",
"networkClientId": "goerli"
}
]
],
"blockExplorerUrls": []
}
},
"internalAccounts": {
Expand All @@ -415,6 +419,7 @@
"address": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
"id": "cf8dace4-9439-4bd4-b3a8-88c821c8fcb3",
"metadata": {
"importTime": 0,
"name": "Test Account",
"keyring": {
"type": "HD Key Tree"
Expand All @@ -434,6 +439,7 @@
"address": "0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b",
"id": "07c2cfec-36c9-46c4-8115-3836d3ac9047",
"metadata": {
"importTime": 0,
"name": "Test Account 2",
"keyring": {
"type": "HD Key Tree"
Expand All @@ -453,6 +459,7 @@
"address": "0xc42edfcc21ed14dda456aa0756c153f7985d8813",
"id": "15e69915-2a1a-4019-93b3-916e11fd432f",
"metadata": {
"importTime": 0,
"name": "Ledger Hardware 2",
"keyring": {
"type": "Ledger Hardware"
Expand All @@ -472,6 +479,7 @@
"address": "0xeb9e64b93097bc15f01f13eae97015c57ab64823",
"id": "784225f4-d30b-4e77-a900-c8bbce735b88",
"metadata": {
"importTime": 0,
"name": "Test Account 3",
"keyring": {
"type": "HD Key Tree"
Expand All @@ -491,6 +499,7 @@
"address": "0xca8f1F0245530118D0cf14a06b01Daf8f76Cf281",
"id": "694225f4-d30b-4e77-a900-c8bbce735b42",
"metadata": {
"importTime": 0,
"name": "Test Account 4",
"keyring": {
"type": "Custody test"
Expand All @@ -510,11 +519,13 @@
"address": "0xb552685e3d2790efd64a175b00d51f02cdafee5d",
"id": "c3deeb99-ba0d-4a4e-a0aa-033fc1f79ae3",
"metadata": {
"importTime": 0,
"name": "Snap Account 1",
"keyring": {
"type": "Snap Keyring"
},
"snap": {
"enabled": true,
"id": "snap-id",
"name": "snap-name"
}
Expand Down
4 changes: 2 additions & 2 deletions test/stub/networks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const mockNetworkStateOld = (
blockExplorerUrl?: string;
metadata?: NetworkMetadata;
}[]
) => {
): NetworkState => {
const networkConfigurations = networks.map((network) => ({
id: network.id ?? uuidv4(),
chainId: network.chainId,
Expand Down Expand Up @@ -64,7 +64,7 @@ export const mockNetworkStateOld = (

return {
selectedNetworkClientId: networkConfigurations[0].id,
networkConfigurations: networkConfigurations.reduce(
networkConfigurationsByChainId: networkConfigurations.reduce(
(acc, network) => ({ ...acc, [network.id]: network }),
{},
),
Expand Down
6 changes: 2 additions & 4 deletions ui/components/app/currency-input/currency-input.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ import { Box } from '../../component-library';
import { BlockSize } from '../../../helpers/constants/design-system';
import UnitInput from '../../ui/unit-input';
import CurrencyDisplay from '../../ui/currency-display';
import {
getNativeCurrency,
getProviderConfig,
} from '../../../ducks/metamask/metamask';
import { getNativeCurrency } from '../../../ducks/metamask/metamask';
import { getProviderConfig } from '../../../selectors/networks';
import {
getCurrentChainId,
getCurrentCurrency,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
getNetworkIdentifier,
isNetworkLoading,
} from '../../../selectors';
import { getProviderConfig } from '../../../ducks/metamask/metamask';
import { getProviderConfig } from '../../../selectors/networks';
import LoadingNetworkScreen from './loading-network-screen.component';

const DEPRECATED_TEST_NET_CHAINIDS = ['0x3', '0x2a', '0x4'];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React, { useContext } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { getBlockExplorerLink } from '@metamask/etherscan-link';
import { type TransactionMeta } from '@metamask/transaction-controller';
import { type NetworkClientConfiguration } from '@metamask/network-controller';
import {
getRpcPrefsForCurrentProvider,
getTransaction,
Expand Down Expand Up @@ -38,19 +37,15 @@ export default function TransactionAlreadyConfirmed() {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(getTransaction as any)(state, originalTransactionId),
);
const rpcPrefs: NetworkClientConfiguration = useSelector(
getRpcPrefsForCurrentProvider,
);
const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider);

const viewTransaction = () => {
// TODO: Fix getBlockExplorerLink arguments compatible with the actual controller types
const blockExplorerLink = getBlockExplorerLink(
// TODO: Replace `any` with type
// eslint-disable-next-line @typescript-eslint/no-explicit-any
transaction as any,
// TODO: Replace `any` with type
// eslint-disable-next-line @typescript-eslint/no-explicit-any
rpcPrefs as any,
rpcPrefs,
);
global.platform.openTab({
url: blockExplorerLink,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
getCustodyAccountDetails,
getIsCustodianSupportedChain,
} from '../../../selectors/institutional/selectors';
import { getProviderConfig } from '../../../ducks/metamask/metamask';
import { getProviderConfig } from '../../../selectors/networks';
///: END:ONLY_INCLUDE_IF
import SelectedAccount from './selected-account.component';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,13 @@ import {
import { getSelectedAccountCachedBalance } from '../../../selectors';
import { getIsCustodianSupportedChain } from '../../../selectors/institutional/selectors';
import { useI18nContext } from '../../../hooks/useI18nContext';
import { getProviderConfig } from '../../../ducks/metamask/metamask';
import { getProviderConfig } from '../../../selectors/networks';
import { Icon, IconName, IconSize, Box, Text } from '../../component-library';

const WrongNetworkNotification: React.FC = () => {
const t = useI18nContext();
const providerConfig = useSelector<
object,
{ nickname?: string; type: string } | undefined
>(getProviderConfig);
const balance = useSelector(getSelectedAccountCachedBalance);
const providerConfig = useSelector(getProviderConfig);
const balance = useSelector<string | null>(getSelectedAccountCachedBalance);

const isCustodianSupportedChain = useSelector(getIsCustodianSupportedChain);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
getIsCustodianSupportedChain,
getCustodianIconForAddress,
} from '../../../selectors/institutional/selectors';
import { getProviderConfig } from '../../../ducks/metamask/metamask';
import { getProviderConfig } from '../../../selectors/networks';
///: END:ONLY_INCLUDE_IF
import { ButtonBase, IconName, Box } from '../../component-library';
import {
Expand Down
2 changes: 1 addition & 1 deletion ui/components/ui/new-network-info/new-network-info.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useSelector } from 'react-redux';
import { TOKEN_API_METASWAP_CODEFI_URL } from '../../../../shared/constants/tokens';
import fetchWithCache from '../../../../shared/lib/fetch-with-cache';
import { I18nContext } from '../../../contexts/i18n';
import { getProviderConfig } from '../../../ducks/metamask/metamask';
import { getProviderConfig } from '../../../selectors/networks';
import {
AlignItems,
BackgroundColor,
Expand Down
2 changes: 1 addition & 1 deletion ui/ducks/bridge/selectors.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createBridgeMockStore } from '../../../test/jest/mock-store';
import { CHAIN_IDS, FEATURED_RPCS } from '../../../shared/constants/network';
import { ALLOWED_BRIDGE_CHAIN_IDS } from '../../../shared/constants/bridge';
import { getProviderConfig } from '../metamask/metamask';
import { getProviderConfig } from '../../selectors/networks';
import { mockNetworkState } from '../../../test/stub/networks';
import {
getAllBridgeableNetworks,
Expand Down
7 changes: 3 additions & 4 deletions ui/ducks/bridge/selectors.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { NetworkState } from '@metamask/network-controller';
import { uniqBy } from 'lodash';
import {
getIsBridgeEnabled,
Expand All @@ -13,12 +12,12 @@ import {
} from '../../../app/scripts/controllers/bridge/types';
import { FEATURED_RPCS } from '../../../shared/constants/network';
import { createDeepEqualSelector } from '../../selectors/util';
import { getProviderConfig } from '../metamask/metamask';
import { NetworkState, getProviderConfig } from '../../selectors/networks';
import { BridgeState } from './bridge';

// TODO add swaps state
type BridgeAppState = {
metamask: NetworkState & { bridgeState: BridgeControllerState } & {
type BridgeAppState = NetworkState & {
metamask: { bridgeState: BridgeControllerState } & {
useExternalServices: boolean;
};
bridge: BridgeState;
Expand Down
43 changes: 4 additions & 39 deletions ui/ducks/metamask/metamask.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { addHexPrefix, isHexString } from 'ethereumjs-util';
import { createSelector } from 'reselect';
import { mergeGasFeeEstimates } from '@metamask/transaction-controller';
import { RpcEndpointType } from '@metamask/network-controller';
import { AlertTypes } from '../../../shared/constants/alerts';
import {
GasEstimateTypes,
Expand All @@ -16,9 +15,11 @@ import {
accountsWithSendEtherInfoSelector,
checkNetworkAndAccountSupports1559,
getAddressBook,
getSelectedNetworkClientId,
getNetworkConfigurationsByChainId,
} from '../../selectors/selectors';
import {
getProviderConfig,
getSelectedNetworkClientId,
} from '../../selectors/networks';
import { getSelectedInternalAccount } from '../../selectors/accounts';
import * as actionConstants from '../../store/actionConstants';
import { updateTransactionGasFees } from '../../store/actions';
Expand Down Expand Up @@ -274,42 +275,6 @@ export function updateGasFees({

export const getAlertEnabledness = (state) => state.metamask.alertEnabledness;

/**
* Get the provider configuration for the current selected network.
*
* @param {object} state - Redux state object.
*/
export const getProviderConfig = createSelector(
(state) => getNetworkConfigurationsByChainId(state),
(state) => getSelectedNetworkClientId(state),
(networkConfigurationsByChainId, selectedNetworkClientId) => {
for (const network of Object.values(networkConfigurationsByChainId)) {
for (const rpcEndpoint of network.rpcEndpoints) {
if (rpcEndpoint.networkClientId === selectedNetworkClientId) {
const blockExplorerUrl =
network.blockExplorerUrls?.[network.defaultBlockExplorerUrlIndex];

return {
chainId: network.chainId,
ticker: network.nativeCurrency,
rpcPrefs: { ...(blockExplorerUrl && { blockExplorerUrl }) },
type:
rpcEndpoint.type === RpcEndpointType.Custom
? 'rpc'
: rpcEndpoint.networkClientId,
...(rpcEndpoint.type === RpcEndpointType.Custom && {
id: rpcEndpoint.networkClientId,
nickname: network.name,
rpcUrl: rpcEndpoint.url,
}),
};
}
}
}
return undefined; // should not be reachable
},
);

export const getUnconnectedAccountAlertEnabledness = (state) =>
getAlertEnabledness(state)[AlertTypes.unconnectedAccount];

Expand Down
Loading

0 comments on commit 6f8db43

Please sign in to comment.