From 64e464e13195941833616e0a06a5e9a016350b0d Mon Sep 17 00:00:00 2001 From: Matthew Walsh Date: Tue, 5 Nov 2024 13:20:44 +0000 Subject: [PATCH] Remove getConversionRate usages --- .eslintrc.js | 7 ++++++- .../confirm/info/hooks/useFeeCalculations.ts | 12 +++++++++--- .../native-send-heading/native-send-heading.tsx | 9 +++++++-- .../useBalanceChanges.test.ts | 17 ++++++++--------- .../simulation-details/useBalanceChanges.ts | 11 ++++++++--- .../confirm-send-token/confirm-send-token.js | 8 ++++++-- .../confirm-token-transaction-base.js | 12 +++++++----- .../confirm-transaction-base.container.js | 4 ++-- ui/pages/confirmations/hooks/test-utils.js | 4 ++-- ui/selectors/selectors.js | 16 ++++++++++++++++ 10 files changed, 71 insertions(+), 29 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index fc66d281c327..bf001c58bc49 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -479,7 +479,12 @@ module.exports = { 'error', { selector: - 'ImportSpecifier[imported.name=/(getCurrentChainId)|(getNativeCurrency)|(getProviderConfig)|(getRpcPrefsForCurrentProvider)/]', + 'ImportSpecifier[imported.name=/' + + '(getCurrentChainId)|' + + '(getNativeCurrency)|' + + '(getProviderConfig)|' + + '(getRpcPrefsForCurrentProvider)|' + + '(getConversionRate)/]', message: 'Avoid using global network selectors in confirmations', }, ], diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useFeeCalculations.ts b/ui/pages/confirmations/components/confirm/info/hooks/useFeeCalculations.ts index 70bd2c0e3af2..5b54dcc710b8 100644 --- a/ui/pages/confirmations/components/confirm/info/hooks/useFeeCalculations.ts +++ b/ui/pages/confirmations/components/confirm/info/hooks/useFeeCalculations.ts @@ -12,10 +12,12 @@ import { multiplyHexes, } from '../../../../../../../shared/modules/conversion.utils'; import { Numeric } from '../../../../../../../shared/modules/Numeric'; -import { getConversionRate } from '../../../../../../ducks/metamask/metamask'; import { useFiatFormatter } from '../../../../../../hooks/useFiatFormatter'; import { useGasFeeEstimates } from '../../../../../../hooks/useGasFeeEstimates'; -import { getCurrentCurrency } from '../../../../../../selectors'; +import { + getCurrentCurrency, + selectConversionRateByChainId, +} from '../../../../../../selectors'; import { getMultichainNetwork } from '../../../../../../selectors/multichain'; import { HEX_ZERO } from '../shared/constants'; import { useEIP1559TxFees } from './useEIP1559TxFees'; @@ -30,9 +32,13 @@ const EMPTY_FEES = { export function useFeeCalculations(transactionMeta: TransactionMeta) { const currentCurrency = useSelector(getCurrentCurrency); - const conversionRate = useSelector(getConversionRate); + const { chainId } = transactionMeta; const fiatFormatter = useFiatFormatter(); + const conversionRate = useSelector((state) => + selectConversionRateByChainId(state, chainId), + ); + const multichainNetwork = useSelector(getMultichainNetwork); const ticker = multichainNetwork?.network?.ticker; diff --git a/ui/pages/confirmations/components/confirm/info/shared/native-send-heading/native-send-heading.tsx b/ui/pages/confirmations/components/confirm/info/shared/native-send-heading/native-send-heading.tsx index a3c2b91c9f8e..bb1897484b2d 100644 --- a/ui/pages/confirmations/components/confirm/info/shared/native-send-heading/native-send-heading.tsx +++ b/ui/pages/confirmations/components/confirm/info/shared/native-send-heading/native-send-heading.tsx @@ -11,7 +11,6 @@ import { } from '../../../../../../../components/component-library'; import Tooltip from '../../../../../../../components/ui/tooltip'; import { getIntlLocale } from '../../../../../../../ducks/locale/locale'; -import { getConversionRate } from '../../../../../../../ducks/metamask/metamask'; import { AlignItems, Display, @@ -29,16 +28,22 @@ import { formatAmountMaxPrecision, } from '../../../../simulation-details/formatAmount'; import { toNonScientificString } from '../../hooks/use-token-values'; +import { selectConversionRateByChainId } from '../../../../../../../selectors'; const NativeSendHeading = () => { const { currentConfirmation: transactionMeta } = useConfirmContext(); + const { chainId } = transactionMeta; + const nativeAssetTransferValue = new BigNumber( transactionMeta.txParams.value as string, ).dividedBy(new BigNumber(10).pow(18)); - const conversionRate = useSelector(getConversionRate); + const conversionRate = useSelector((state) => + selectConversionRateByChainId(state, chainId), + ); + const fiatValue = conversionRate && nativeAssetTransferValue && diff --git a/ui/pages/confirmations/components/simulation-details/useBalanceChanges.test.ts b/ui/pages/confirmations/components/simulation-details/useBalanceChanges.test.ts index f77774c6ec4a..5f2e1dcbfd16 100644 --- a/ui/pages/confirmations/components/simulation-details/useBalanceChanges.test.ts +++ b/ui/pages/confirmations/components/simulation-details/useBalanceChanges.test.ts @@ -6,10 +6,10 @@ import { } from '@metamask/transaction-controller'; import { BigNumber } from 'bignumber.js'; import { TokenStandard } from '../../../../../shared/constants/transaction'; -import { getConversionRate } from '../../../../ducks/metamask/metamask'; import { getTokenStandardAndDetails } from '../../../../store/actions'; import { fetchTokenExchangeRates } from '../../../../helpers/utils/util'; import { memoizedGetTokenStandardAndDetails } from '../../utils/token'; +import { selectConversionRateByChainId } from '../../../../selectors'; import { useBalanceChanges } from './useBalanceChanges'; import { FIAT_UNAVAILABLE } from './types'; @@ -17,13 +17,10 @@ jest.mock('react-redux', () => ({ useSelector: jest.fn((selector) => selector()), })); -jest.mock('../../../../ducks/metamask/metamask', () => ({ - getConversionRate: jest.fn(), -})); - jest.mock('../../../../selectors', () => ({ getCurrentChainId: jest.fn(), getCurrentCurrency: jest.fn(), + selectConversionRateByChainId: jest.fn(), })); jest.mock('../../../../helpers/utils/util', () => ({ @@ -34,7 +31,9 @@ jest.mock('../../../../store/actions', () => ({ getTokenStandardAndDetails: jest.fn(), })); -const mockGetConversionRate = getConversionRate as jest.Mock; +const mockSelectConversionRateByChainId = jest.mocked( + selectConversionRateByChainId, +); const mockGetTokenStandardAndDetails = getTokenStandardAndDetails as jest.Mock; const mockFetchTokenExchangeRates = fetchTokenExchangeRates as jest.Mock; @@ -85,7 +84,7 @@ describe('useBalanceChanges', () => { } return Promise.reject(new Error('Unable to determine token standard')); }); - mockGetConversionRate.mockReturnValue(ETH_TO_FIAT_RATE); + mockSelectConversionRateByChainId.mockReturnValue(ETH_TO_FIAT_RATE); mockFetchTokenExchangeRates.mockResolvedValue({ [ERC20_TOKEN_ADDRESS_1_MOCK]: ERC20_TO_FIAT_RATE_1_MOCK, [ERC20_TOKEN_ADDRESS_2_MOCK]: ERC20_TO_FIAT_RATE_2_MOCK, @@ -344,7 +343,7 @@ describe('useBalanceChanges', () => { }); it('handles native fiat rate with more than 15 significant digits', async () => { - mockGetConversionRate.mockReturnValue(0.1234567890123456); + mockSelectConversionRateByChainId.mockReturnValue(0.1234567890123456); const { result, waitForNextUpdate } = setupHook({ ...dummyBalanceChange, difference: DIFFERENCE_ETH_MOCK, @@ -357,7 +356,7 @@ describe('useBalanceChanges', () => { }); it('handles unavailable native fiat rate', async () => { - mockGetConversionRate.mockReturnValue(null); + mockSelectConversionRateByChainId.mockReturnValue(null); const { result, waitForNextUpdate } = setupHook({ ...dummyBalanceChange, difference: DIFFERENCE_ETH_MOCK, diff --git a/ui/pages/confirmations/components/simulation-details/useBalanceChanges.ts b/ui/pages/confirmations/components/simulation-details/useBalanceChanges.ts index 1bbc9cb5eec8..666682c95c76 100644 --- a/ui/pages/confirmations/components/simulation-details/useBalanceChanges.ts +++ b/ui/pages/confirmations/components/simulation-details/useBalanceChanges.ts @@ -10,8 +10,10 @@ import { BigNumber } from 'bignumber.js'; import { ContractExchangeRates } from '@metamask/assets-controllers'; import { useAsyncResultOrThrow } from '../../../../hooks/useAsyncResult'; import { TokenStandard } from '../../../../../shared/constants/transaction'; -import { getConversionRate } from '../../../../ducks/metamask/metamask'; -import { getCurrentCurrency } from '../../../../selectors'; +import { + getCurrentCurrency, + selectConversionRateByChainId, +} from '../../../../selectors'; import { fetchTokenExchangeRates } from '../../../../helpers/utils/util'; import { ERC20_DEFAULT_DECIMALS, fetchErc20Decimals } from '../../utils/token'; @@ -158,7 +160,10 @@ export const useBalanceChanges = ({ simulationData?: SimulationData; }): { pending: boolean; value: BalanceChange[] } => { const fiatCurrency = useSelector(getCurrentCurrency); - const nativeFiatRate = useSelector(getConversionRate); + + const nativeFiatRate = useSelector((state) => + selectConversionRateByChainId(state, chainId), + ); const { nativeBalanceChange, tokenBalanceChanges = [] } = simulationData ?? {}; diff --git a/ui/pages/confirmations/confirm-send-token/confirm-send-token.js b/ui/pages/confirmations/confirm-send-token/confirm-send-token.js index 0fe088063959..4e68783e9be7 100644 --- a/ui/pages/confirmations/confirm-send-token/confirm-send-token.js +++ b/ui/pages/confirmations/confirm-send-token/confirm-send-token.js @@ -8,9 +8,9 @@ import { editExistingTransaction } from '../../../ducks/send'; import { contractExchangeRateSelector, getCurrentCurrency, + selectConversionRateByChainId, selectNetworkConfigurationByChainId, } from '../../../selectors'; -import { getConversionRate } from '../../../ducks/metamask/metamask'; import { clearConfirmTransaction } from '../../../ducks/confirm-transaction/confirm-transaction.duck'; import { showSendTokenPage } from '../../../store/actions'; import { @@ -47,9 +47,13 @@ export default function ConfirmSendToken({ history.push(SEND_ROUTE); }); }; - const conversionRate = useSelector(getConversionRate); + const { chainId } = transaction; + const conversionRate = useSelector((state) => + selectConversionRateByChainId(state, chainId), + ); + const { nativeCurrency } = useSelector((state) => selectNetworkConfigurationByChainId(state, chainId), ); 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 e361a5d0311f..c15c6bdc251f 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 @@ -17,12 +17,10 @@ import { contractExchangeRateSelector, getCurrentCurrency, getSelectedInternalAccount, + selectConversionRateByChainId, selectNetworkConfigurationByChainId, } from '../../../selectors'; -import { - getConversionRate, - getNftContracts, -} from '../../../ducks/metamask/metamask'; +import { getNftContracts } from '../../../ducks/metamask/metamask'; import { TokenStandard } from '../../../../shared/constants/transaction'; import { getWeiHexFromDecimalValue, @@ -57,7 +55,11 @@ export default function ConfirmTokenTransactionBase({ const blockExplorerUrl = blockExplorerUrls?.[0]; const currentCurrency = useSelector(getCurrentCurrency); - const conversionRate = useSelector(getConversionRate); + + const conversionRate = useSelector((state) => + selectConversionRateByChainId(state, chainId), + ); + const { address: userAddress } = useSelector(getSelectedInternalAccount); const nftCollections = useSelector(getNftContracts); diff --git a/ui/pages/confirmations/confirm-transaction-base/confirm-transaction-base.container.js b/ui/pages/confirmations/confirm-transaction-base/confirm-transaction-base.container.js index 4ab28dc5a136..37f150caa658 100644 --- a/ui/pages/confirmations/confirm-transaction-base/confirm-transaction-base.container.js +++ b/ui/pages/confirmations/confirm-transaction-base/confirm-transaction-base.container.js @@ -71,7 +71,6 @@ import { getIsGasEstimatesLoading, getSendToAccounts, findKeyringForAddress, - getConversionRate, } from '../../../ducks/metamask/metamask'; import { addHexPrefix, @@ -96,6 +95,7 @@ import { CUSTOM_GAS_ESTIMATE } from '../../../../shared/constants/gas'; import { getIsUsingPaymaster } from '../../../selectors/account-abstraction'; import { + selectConversionRateByChainId, selectNetworkConfigurationByChainId, // eslint-disable-next-line import/no-duplicates } from '../../../selectors/selectors'; @@ -174,7 +174,6 @@ const mapStateToProps = (state, ownProps) => { const gasLoadingAnimationIsShowing = getGasLoadingAnimationIsShowing(state); const isBuyableChain = getIsNativeTokenBuyable(state); const { confirmTransaction, metamask } = state; - const conversionRate = getConversionRate(state); const { addressBook, nextNonce } = metamask; const unapprovedTxs = getUnapprovedTransactions(state); @@ -183,6 +182,7 @@ const mapStateToProps = (state, ownProps) => { const txId = transactionId || paramsTransactionId; const transaction = getUnapprovedTransaction(state, txId) ?? {}; const { chainId } = transaction; + const conversionRate = selectConversionRateByChainId(state, chainId); const { from: fromAddress, diff --git a/ui/pages/confirmations/hooks/test-utils.js b/ui/pages/confirmations/hooks/test-utils.js index d8d94926e703..5e327b0467c5 100644 --- a/ui/pages/confirmations/hooks/test-utils.js +++ b/ui/pages/confirmations/hooks/test-utils.js @@ -3,7 +3,6 @@ import { useSelector } from 'react-redux'; import { useMultichainSelector } from '../../../hooks/useMultichainSelector'; import { GasEstimateTypes } from '../../../../shared/constants/gas'; -import { getConversionRate } from '../../../ducks/metamask/metamask'; import { getCurrentCurrency, getShouldShowFiat, @@ -11,6 +10,7 @@ import { getCurrentKeyring, getTokenExchangeRates, getPreferences, + selectConversionRateByChainId, } from '../../../selectors'; import { @@ -104,7 +104,7 @@ export const generateUseSelectorRouter = if (selector === getMultichainIsEvm) { return true; } - if (selector === getConversionRate) { + if (selector === selectConversionRateByChainId) { return MOCK_ETH_USD_CONVERSION_RATE; } if (selector === getMultichainNativeCurrency) { diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index 8b44dd715aba..d4eeb4b65f4b 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -734,6 +734,22 @@ export const selectDefaultRpcEndpointByChainId = createSelector( }, ); +/** + * @type (state: any, chainId: string) => number | undefined + */ +export const selectConversionRateByChainId = createSelector( + selectNetworkConfigurationByChainId, + (state) => state, + (networkConfiguration, state) => { + if (!networkConfiguration) { + return undefined; + } + + const { nativeCurrency } = networkConfiguration; + return state.metamask.currencyRates[nativeCurrency]?.conversionRate; + }, +); + export function getRequestingNetworkInfo(state, chainIds) { // If chainIds is undefined, set it to an empty array let processedChainIds = chainIds === undefined ? [] : chainIds;