From 43317f9a766e8475708eeeb204698c3734d183c9 Mon Sep 17 00:00:00 2001 From: Matthew Walsh Date: Tue, 5 Nov 2024 16:00:45 +0000 Subject: [PATCH] Remove additional selector usages --- .eslintrc.js | 21 +++++++++----- .../advanced-gas-fee-defaults.js | 8 +++-- .../advanced-gas-fee-defaults.test.js | 4 ++- .../confirm-page-container.component.js | 12 +++++--- .../confirm-page-container.container.js | 3 -- .../approve-static-simulation.tsx | 1 + .../confirm/info/approve/approve.tsx | 1 + .../edit-spending-cap-modal.tsx | 1 + .../approve/spending-cap/spending-cap.tsx | 1 + .../confirm/info/hooks/use-token-values.ts | 1 + .../nft-send-heading/nft-send-heading.tsx | 2 ++ .../title/hooks/useCurrentSpendingCap.ts | 8 ++++- .../confirm-token-transaction-base.js | 7 +++-- .../confirm-token-transaction-switch.js | 4 ++- .../confirmations/hooks/useAssetDetails.js | 13 +++++++-- .../token-allowance/token-allowance.js | 14 ++++++--- ui/selectors/selectors.js | 29 +++++++++++++++++++ 17 files changed, 102 insertions(+), 28 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index bf001c58bc49..4aa9ef688592 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -478,13 +478,20 @@ module.exports = { 'no-restricted-syntax': [ 'error', { - selector: - 'ImportSpecifier[imported.name=/' + - '(getCurrentChainId)|' + - '(getNativeCurrency)|' + - '(getProviderConfig)|' + - '(getRpcPrefsForCurrentProvider)|' + - '(getConversionRate)/]', + selector: `ImportSpecifier[imported.name=/${[ + 'getConversionRate', + 'getCurrentChainId', + 'getNativeCurrency', + 'getNetworkIdentifier', + 'getNftContracts', + 'getNfts', + 'getProviderConfig', + 'getRpcPrefsForCurrentProvider', + 'getUSDConversionRate', + 'isCurrentProviderCustom', + ] + .map((method) => `(${method})`) + .join('|')}/]`, message: 'Avoid using global network selectors in confirmations', }, ], diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.js index 33d4ebd45c5f..106984363699 100644 --- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.js +++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.js @@ -11,7 +11,7 @@ import { } from '../../../../../helpers/constants/design-system'; import { getAdvancedGasFeeValues, - getNetworkIdentifier, + selectNetworkIdentifierByChainId, } from '../../../../../selectors'; import { setAdvancedGasFee } from '../../../../../store/actions'; import { useGasFeeContext } from '../../../../../contexts/gasFee'; @@ -34,10 +34,14 @@ const AdvancedGasFeeDefaults = () => { 10, ).toString(); const advancedGasFeeValues = useSelector(getAdvancedGasFeeValues); - const networkIdentifier = useSelector(getNetworkIdentifier); const { updateTransactionEventFragment } = useTransactionEventFragment(); const { editGasMode, transaction } = useGasFeeContext(); const { chainId } = transaction; + + const networkIdentifier = useSelector((state) => + selectNetworkIdentifierByChainId(state, chainId), + ); + const [isDefaultSettingsSelected, setDefaultSettingsSelected] = useState( Boolean(advancedGasFeeValues) && advancedGasFeeValues.maxBaseFee === maxBaseFee && diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.test.js index 5e330a8b90c7..07c7fc8faaab 100644 --- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.test.js +++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.test.js @@ -21,6 +21,7 @@ import { mockNetworkState } from '../../../../../../test/stub/networks'; import AdvancedGasFeeDefaults from './advanced-gas-fee-defaults'; const TEXT_SELECTOR = 'Save these values as my default for the Goerli network.'; +const CHAIN_ID_MOCK = CHAIN_IDS.GOERLI; jest.mock('../../../../../store/actions', () => ({ gasFeeStartPollingByNetworkClientId: jest @@ -43,7 +44,7 @@ const render = async (defaultGasParams, contextParams) => { metamask: { ...mockState.metamask, ...defaultGasParams, - ...mockNetworkState({ chainId: CHAIN_IDS.GOERLI }), + ...mockNetworkState({ chainId: CHAIN_ID_MOCK }), accounts: { [mockSelectedInternalAccount.address]: { address: mockSelectedInternalAccount.address, @@ -71,6 +72,7 @@ const render = async (defaultGasParams, contextParams) => { (result = renderWithProvider( { useState(false); const isBuyableChain = useSelector(getIsNativeTokenBuyable); const contact = useSelector((state) => getAddressBookEntry(state, toAddress)); - const networkIdentifier = useSelector(getNetworkIdentifier); const defaultToken = useSelector(getSwapsDefaultToken); const accountBalance = defaultToken.string; const internalAccounts = useSelector(getInternalAccounts); @@ -139,8 +138,13 @@ const ConfirmPageContainer = (props) => { const shouldDisplayWarning = contentComponent && disabled && (errorKey || errorMessage); - const networkName = - NETWORK_TO_NAME_MAP[currentTransaction.chainId] || networkIdentifier; + const { chainId } = currentTransaction; + + const networkIdentifier = useSelector((state) => + selectNetworkIdentifierByChainId(state, chainId), + ); + + const networkName = NETWORK_TO_NAME_MAP[chainId] || networkIdentifier; const fetchCollectionBalance = useCallback(async () => { const tokenBalance = await fetchTokenBalance( diff --git a/ui/pages/confirmations/components/confirm-page-container/confirm-page-container.container.js b/ui/pages/confirmations/components/confirm-page-container/confirm-page-container.container.js index db07ad4117e7..23eaa43d44ab 100644 --- a/ui/pages/confirmations/components/confirm-page-container/confirm-page-container.container.js +++ b/ui/pages/confirmations/components/confirm-page-container/confirm-page-container.container.js @@ -1,7 +1,6 @@ import { connect } from 'react-redux'; import { getAddressBookEntry, - getNetworkIdentifier, getSwapsDefaultToken, getMetadataContractName, getAccountName, @@ -12,7 +11,6 @@ import ConfirmPageContainer from './confirm-page-container.component'; function mapStateToProps(state, ownProps) { const to = ownProps.toAddress; const contact = getAddressBookEntry(state, to); - const networkIdentifier = getNetworkIdentifier(state); const defaultToken = getSwapsDefaultToken(state); const accountBalance = defaultToken.string; const internalAccounts = getInternalAccounts(state); @@ -26,7 +24,6 @@ function mapStateToProps(state, ownProps) { toMetadataName, recipientIsOwnedAccount: Boolean(ownedAccountName), to, - networkIdentifier, accountBalance, }; } diff --git a/ui/pages/confirmations/components/confirm/info/approve/approve-static-simulation/approve-static-simulation.tsx b/ui/pages/confirmations/components/confirm/info/approve/approve-static-simulation/approve-static-simulation.tsx index f1117e2a22b2..eab973d0a37c 100644 --- a/ui/pages/confirmations/components/confirm/info/approve/approve-static-simulation/approve-static-simulation.tsx +++ b/ui/pages/confirmations/components/confirm/info/approve/approve-static-simulation/approve-static-simulation.tsx @@ -33,6 +33,7 @@ export const ApproveStaticSimulation = () => { transactionMeta?.txParams?.to, transactionMeta?.txParams?.from, transactionMeta?.txParams?.data, + transactionMeta?.chainId, ); const decimals = initialDecimals || '0'; diff --git a/ui/pages/confirmations/components/confirm/info/approve/approve.tsx b/ui/pages/confirmations/components/confirm/info/approve/approve.tsx index fed03a75e17e..8f4ec8db31d7 100644 --- a/ui/pages/confirmations/components/confirm/info/approve/approve.tsx +++ b/ui/pages/confirmations/components/confirm/info/approve/approve.tsx @@ -31,6 +31,7 @@ const ApproveInfo = () => { transactionMeta.txParams.to, transactionMeta.txParams.from, transactionMeta.txParams.data, + transactionMeta.chainId, ); const { spendingCap, pending } = useApproveTokenSimulation( diff --git a/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.tsx b/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.tsx index f908333e4f25..0b08bbe13068 100644 --- a/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.tsx +++ b/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.tsx @@ -55,6 +55,7 @@ export const EditSpendingCapModal = ({ transactionMeta.txParams.to, transactionMeta.txParams.from, transactionMeta.txParams.data, + transactionMeta.chainId, ); const accountBalance = calcTokenAmount( diff --git a/ui/pages/confirmations/components/confirm/info/approve/spending-cap/spending-cap.tsx b/ui/pages/confirmations/components/confirm/info/approve/spending-cap/spending-cap.tsx index 2ebd9d8e7e4e..afe43e6f9e72 100644 --- a/ui/pages/confirmations/components/confirm/info/approve/spending-cap/spending-cap.tsx +++ b/ui/pages/confirmations/components/confirm/info/approve/spending-cap/spending-cap.tsx @@ -89,6 +89,7 @@ export const SpendingCap = ({ transactionMeta.txParams.to, transactionMeta.txParams.from, transactionMeta.txParams.data, + transactionMeta.chainId, ); const accountBalance = calcTokenAmount( diff --git a/ui/pages/confirmations/components/confirm/info/hooks/use-token-values.ts b/ui/pages/confirmations/components/confirm/info/hooks/use-token-values.ts index f416282ee4ef..087a17c473c6 100644 --- a/ui/pages/confirmations/components/confirm/info/hooks/use-token-values.ts +++ b/ui/pages/confirmations/components/confirm/info/hooks/use-token-values.ts @@ -17,6 +17,7 @@ export const useTokenValues = (transactionMeta: TransactionMeta) => { transactionMeta.txParams.to, transactionMeta.txParams.from, transactionMeta.txParams.data, + transactionMeta.chainId, ); const decodedResponse = useDecodedTransactionData(); diff --git a/ui/pages/confirmations/components/confirm/info/shared/nft-send-heading/nft-send-heading.tsx b/ui/pages/confirmations/components/confirm/info/shared/nft-send-heading/nft-send-heading.tsx index 006613e206c9..2f36d10ce42c 100644 --- a/ui/pages/confirmations/components/confirm/info/shared/nft-send-heading/nft-send-heading.tsx +++ b/ui/pages/confirmations/components/confirm/info/shared/nft-send-heading/nft-send-heading.tsx @@ -24,11 +24,13 @@ const NFTSendHeading = () => { const tokenAddress = transactionMeta.txParams.to; const userAddress = transactionMeta.txParams.from; const { data } = transactionMeta.txParams; + const { chainId } = transactionMeta; const { assetName, tokenImage, tokenId } = useAssetDetails( tokenAddress, userAddress, data, + chainId, ); const TokenImage = ; diff --git a/ui/pages/confirmations/components/confirm/title/hooks/useCurrentSpendingCap.ts b/ui/pages/confirmations/components/confirm/title/hooks/useCurrentSpendingCap.ts index 5f588a971561..b50948259734 100644 --- a/ui/pages/confirmations/components/confirm/title/hooks/useCurrentSpendingCap.ts +++ b/ui/pages/confirmations/components/confirm/title/hooks/useCurrentSpendingCap.ts @@ -32,8 +32,14 @@ export function useCurrentSpendingCap(currentConfirmation: Confirmation) { const txParamsData = isTxWithSpendingCap ? currentConfirmation.txParams.data : null; + const chainId = isTxWithSpendingCap ? currentConfirmation.chainId : null; - const { decimals } = useAssetDetails(txParamsTo, txParamsFrom, txParamsData); + const { decimals } = useAssetDetails( + txParamsTo, + txParamsFrom, + txParamsData, + chainId, + ); const { spendingCap, pending } = useApproveTokenSimulation( currentConfirmation as TransactionMeta, diff --git a/ui/pages/confirmations/confirm-token-transaction-base/confirm-token-transaction-base.js b/ui/pages/confirmations/confirm-token-transaction-base/confirm-token-transaction-base.js index c15c6bdc251f..077d5c757dcb 100644 --- a/ui/pages/confirmations/confirm-token-transaction-base/confirm-token-transaction-base.js +++ b/ui/pages/confirmations/confirm-token-transaction-base/confirm-token-transaction-base.js @@ -19,8 +19,8 @@ import { getSelectedInternalAccount, selectConversionRateByChainId, selectNetworkConfigurationByChainId, + selectNftContractsByChainId, } from '../../../selectors'; -import { getNftContracts } from '../../../ducks/metamask/metamask'; import { TokenStandard } from '../../../../shared/constants/transaction'; import { getWeiHexFromDecimalValue, @@ -61,7 +61,10 @@ export default function ConfirmTokenTransactionBase({ ); const { address: userAddress } = useSelector(getSelectedInternalAccount); - const nftCollections = useSelector(getNftContracts); + + const nftCollections = useSelector((state) => + selectNftContractsByChainId(state, chainId), + ); const ethTransactionTotalMaxAmount = Number( hexWEIToDecETH(hexMaximumTransactionFee), diff --git a/ui/pages/confirmations/confirm-transaction/confirm-token-transaction-switch.js b/ui/pages/confirmations/confirm-transaction/confirm-token-transaction-switch.js index 1bf5c8771b4f..72f570c5b98b 100644 --- a/ui/pages/confirmations/confirm-transaction/confirm-token-transaction-switch.js +++ b/ui/pages/confirmations/confirm-transaction/confirm-token-transaction-switch.js @@ -27,6 +27,7 @@ import { useAssetDetails } from '../hooks/useAssetDetails'; export default function ConfirmTokenTransactionSwitch({ transaction }) { const { + chainId, txParams: { data, to: tokenAddress, from: userAddress } = {}, layer1GasFee, } = transaction; @@ -44,7 +45,7 @@ export default function ConfirmTokenTransactionSwitch({ transaction }) { tokenAmount, tokenId, toAddress, - } = useAssetDetails(tokenAddress, userAddress, data); + } = useAssetDetails(tokenAddress, userAddress, data, chainId); const { ethTransactionTotal, @@ -221,6 +222,7 @@ export default function ConfirmTokenTransactionSwitch({ transaction }) { ConfirmTokenTransactionSwitch.propTypes = { transaction: PropTypes.shape({ + chainId: PropTypes.string, origin: PropTypes.string, txParams: PropTypes.shape({ data: PropTypes.string, diff --git a/ui/pages/confirmations/hooks/useAssetDetails.js b/ui/pages/confirmations/hooks/useAssetDetails.js index 4a9afaf05468..bea2f6da89a8 100644 --- a/ui/pages/confirmations/hooks/useAssetDetails.js +++ b/ui/pages/confirmations/hooks/useAssetDetails.js @@ -1,7 +1,7 @@ import { isEqual } from 'lodash'; import { useState, useEffect } from 'react'; import { useSelector, useDispatch } from 'react-redux'; -import { getNfts, getTokens } from '../../../ducks/metamask/metamask'; +import { getTokens } from '../../../ducks/metamask/metamask'; import { getAssetDetails } from '../../../helpers/utils/token-util'; import { hideLoadingIndication, @@ -10,11 +10,18 @@ import { import { isEqualCaseInsensitive } from '../../../../shared/modules/string-utils'; import { usePrevious } from '../../../hooks/usePrevious'; import { useTokenTracker } from '../../../hooks/useTokenTracker'; +import { selectNftsByChainId } from '../../../selectors'; -export function useAssetDetails(tokenAddress, userAddress, transactionData) { +export function useAssetDetails( + tokenAddress, + userAddress, + transactionData, + chainId, +) { const dispatch = useDispatch(); + // state selectors - const nfts = useSelector(getNfts); + const nfts = useSelector((state) => selectNftsByChainId(state, chainId)); const tokens = useSelector(getTokens, isEqual); const currentToken = tokens.find((token) => isEqualCaseInsensitive(token.address, tokenAddress), diff --git a/ui/pages/confirmations/token-allowance/token-allowance.js b/ui/pages/confirmations/token-allowance/token-allowance.js index 82fcd91756fa..be732e749afa 100644 --- a/ui/pages/confirmations/token-allowance/token-allowance.js +++ b/ui/pages/confirmations/token-allowance/token-allowance.js @@ -29,7 +29,6 @@ import { PageContainerFooter } from '../../../components/ui/page-container'; import ContractDetailsModal from '../components/contract-details-modal/contract-details-modal'; import { getCustomTokenAmount, - getNetworkIdentifier, transactionFeeSelector, getKnownMethodData, getUnapprovedTxCount, @@ -76,8 +75,11 @@ import FeeDetailsComponent from '../components/fee-details-component/fee-details import { BlockaidResultType } from '../../../../shared/constants/security-provider'; import { QueuedRequestsBannerAlert } from '../confirmation/components/queued-requests-banner-alert/queued-requests-banner-alert'; -// eslint-disable-next-line import/no-duplicates -import { selectNetworkConfigurationByChainId } from '../../../selectors/selectors'; +import { + selectNetworkConfigurationByChainId, + selectNetworkIdentifierByChainId, + // eslint-disable-next-line import/no-duplicates +} from '../../../selectors/selectors'; ///: BEGIN:ONLY_INCLUDE_IF(build-mmi) // eslint-disable-next-line import/no-duplicates @@ -145,9 +147,13 @@ export default function TokenAllowance({ const fromAccount = useSelector((state) => getTargetAccountWithSendEtherInfo(state, userAddress), ); - const networkIdentifier = useSelector(getNetworkIdentifier); + const { chainId } = txData; + const networkIdentifier = useSelector((state) => + selectNetworkIdentifierByChainId(state, chainId), + ); + const { blockExplorerUrls } = useSelector((state) => selectNetworkConfigurationByChainId(state, chainId), diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index d4eeb4b65f4b..d09d31b82f18 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -750,6 +750,35 @@ export const selectConversionRateByChainId = createSelector( }, ); +export const selectNftsByChainId = createSelector( + getSelectedInternalAccount, + (state) => state.metamask.allNfts, + (_state, chainId) => chainId, + (selectedAccount, nfts, chainId) => { + return nfts?.[selectedAccount.address]?.[chainId] ?? []; + }, +); + +export const selectNftContractsByChainId = createSelector( + getSelectedInternalAccount, + (state) => state.metamask.allNftContracts, + (_state, chainId) => chainId, + (selectedAccount, nftContracts, chainId) => { + return nftContracts?.[selectedAccount.address]?.[chainId] ?? []; + }, +); + +export const selectNetworkIdentifierByChainId = createSelector( + selectNetworkConfigurationByChainId, + selectDefaultRpcEndpointByChainId, + (networkConfiguration, defaultRpcEndpoint) => { + const { name: nickname } = networkConfiguration ?? {}; + const { url: rpcUrl, networkClientId } = defaultRpcEndpoint ?? {}; + + return nickname || rpcUrl || networkClientId; + }, +); + export function getRequestingNetworkInfo(state, chainIds) { // If chainIds is undefined, set it to an empty array let processedChainIds = chainIds === undefined ? [] : chainIds;