From 00416fa21822c5aff8e87d114b7746901e2a79f6 Mon Sep 17 00:00:00 2001 From: Jon Tzeng Date: Thu, 30 Jan 2025 20:16:47 -0800 Subject: [PATCH] Fix `useSelector` calls for accessing non-existent `exchangeRates` --- CHANGELOG.md | 1 + src/actions/ReceiveDropdown.tsx | 3 ++- src/components/scenes/WalletDetailsScene.tsx | 6 ++++-- src/components/themed/TransactionListRow.tsx | 4 ++-- src/components/tiles/NetworkFeeTile.tsx | 3 ++- src/hooks/useTokenDisplayData.ts | 3 ++- 6 files changed, 13 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 568875d7b2b..280b6ff6eaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ - changed: `TransactionListScene` split into two scenes: `TransactionListScene` and `WalletDetailsScene` - changed: All floating `NotificationCard`s are dismissible - fixed: Show correct staked balance for deprecated Velodrome pools +- fixed: Crash when retrieving `exchangeRates` in some situations when no internet is available ## 4.21.1 (2025-01-28) diff --git a/src/actions/ReceiveDropdown.tsx b/src/actions/ReceiveDropdown.tsx index 1ef6c30eb2b..8410cd086ad 100644 --- a/src/actions/ReceiveDropdown.tsx +++ b/src/actions/ReceiveDropdown.tsx @@ -7,6 +7,7 @@ import { FlashNotification } from '../components/navigation/FlashNotification' import { Airship, showError } from '../components/services/AirshipInstance' import { lstrings } from '../locales/strings' import { getExchangeDenom, selectDisplayDenom } from '../selectors/DenominationSelectors' +import { getExchangeRate } from '../selectors/WalletSelectors' import { ThunkAction } from '../types/reduxTypes' import { NavigationBase } from '../types/routerTypes' import { calculateSpamThreshold, convertNativeToDisplay, zeroString } from '../util/utils' @@ -35,7 +36,7 @@ export function showReceiveDropdown(navigation: NavigationBase, transaction: Edg // Check the spam limits: const { spamFilterOn } = state.ui.settings - const exchangeRate = state.exchangeRates[`${currencyCode}_${isoFiatCurrencyCode}`] + const exchangeRate = getExchangeRate(state, currencyCode, isoFiatCurrencyCode) const exchangeDenom = getExchangeDenom(wallet.currencyConfig, tokenId) const spamThreshold = calculateSpamThreshold(exchangeRate, exchangeDenom) if (spamFilterOn && (zeroString(exchangeRate) || lt(nativeAmount, spamThreshold))) { diff --git a/src/components/scenes/WalletDetailsScene.tsx b/src/components/scenes/WalletDetailsScene.tsx index 4511f9b0091..35d8114a852 100644 --- a/src/components/scenes/WalletDetailsScene.tsx +++ b/src/components/scenes/WalletDetailsScene.tsx @@ -16,6 +16,7 @@ import { useWatch } from '../../hooks/useWatch' import { formatNumber } from '../../locales/intl' import { lstrings } from '../../locales/strings' import { getExchangeDenomByCurrencyCode } from '../../selectors/DenominationSelectors' +import { getExchangeRate } from '../../selectors/WalletSelectors' import { FooterRender } from '../../state/SceneFooterState' import { useSceneScrollHandler } from '../../state/SceneScrollState' import { useDispatch, useSelector } from '../../types/reactRedux' @@ -72,8 +73,9 @@ function WalletDetailsComponent(props: Props) { // Selectors: const exchangeDenom = getExchangeDenomByCurrencyCode(wallet.currencyConfig, currencyCode) - const fiatCurrencyCode = useSelector(state => state.ui.settings.defaultIsoFiat).replace('iso:', '') - const exchangeRate = useSelector(state => state.exchangeRates[`${currencyCode}_${state.ui.settings.defaultIsoFiat}`]) + const defaultIsoFiat = useSelector(state => state.ui.settings.defaultIsoFiat) + const fiatCurrencyCode = defaultIsoFiat.replace('iso:', '') + const exchangeRate = useSelector(state => getExchangeRate(state, currencyCode, defaultIsoFiat)) const spamFilterOn = useSelector(state => state.ui.settings.spamFilterOn) const activeUsername = useSelector(state => state.core.account.username) const isLightAccount = activeUsername == null diff --git a/src/components/themed/TransactionListRow.tsx b/src/components/themed/TransactionListRow.tsx index 40a0289fc45..5e15d7bfbe3 100644 --- a/src/components/themed/TransactionListRow.tsx +++ b/src/components/themed/TransactionListRow.tsx @@ -18,6 +18,7 @@ import { useHistoricalRate } from '../../hooks/useHistoricalRate' import { formatNumber } from '../../locales/intl' import { lstrings } from '../../locales/strings' import { getExchangeDenom } from '../../selectors/DenominationSelectors' +import { getExchangeRate } from '../../selectors/WalletSelectors' import { useSelector } from '../../types/reactRedux' import { NavigationBase } from '../../types/routerTypes' import { @@ -62,8 +63,7 @@ export function TransactionListRow(props: Props) { const defaultAmountFiat = metadata.exchangeAmount?.[defaultIsoFiat] ?? 0 // CryptoAmount - const rateKey = `${currencyCode}_${defaultIsoFiat}` - const exchangeRate: string = useSelector(state => state.exchangeRates[rateKey]) + const exchangeRate: string = useSelector(state => getExchangeRate(state, currencyCode, defaultIsoFiat)) let maxConversionDecimals = DEFAULT_TRUNCATE_PRECISION if (exchangeRate != null && gt(exchangeRate, '0')) { const precisionAdjustValue = precisionAdjust({ diff --git a/src/components/tiles/NetworkFeeTile.tsx b/src/components/tiles/NetworkFeeTile.tsx index 108165746dd..0c60240def6 100644 --- a/src/components/tiles/NetworkFeeTile.tsx +++ b/src/components/tiles/NetworkFeeTile.tsx @@ -5,6 +5,7 @@ import { useDisplayDenom } from '../../hooks/useDisplayDenom' import { useFiatText } from '../../hooks/useFiatText' import { lstrings } from '../../locales/strings' import { getExchangeDenom } from '../../selectors/DenominationSelectors' +import { getExchangeRate } from '../../selectors/WalletSelectors' import { useSelector } from '../../types/reactRedux' import { getCryptoText } from '../../util/cryptoTextUtils' import { getDenomFromIsoCode } from '../../util/utils' @@ -26,7 +27,7 @@ export const NetworkFeeTile = (props: Props) => { const defaultIsoFiat = useSelector(state => state.ui.settings.defaultIsoFiat) const fiatDenomination = getDenomFromIsoCode(defaultIsoFiat) - const exchangeRate = useSelector(state => state.exchangeRates[`${currencyCode}_${defaultIsoFiat}`]) + const exchangeRate = useSelector(state => getExchangeRate(state, currencyCode, defaultIsoFiat)) const exchangeDenominationMultiplier = getExchangeDenom(currencyConfig, null).multiplier const exchangeDenominationName = getExchangeDenom(currencyConfig, null).name diff --git a/src/hooks/useTokenDisplayData.ts b/src/hooks/useTokenDisplayData.ts index 14101ce661a..b3eacb2d03e 100644 --- a/src/hooks/useTokenDisplayData.ts +++ b/src/hooks/useTokenDisplayData.ts @@ -1,5 +1,6 @@ import { EdgeCurrencyWallet, EdgeTokenId } from 'edge-core-js' +import { getExchangeRate } from '../selectors/WalletSelectors' import { useSelector } from '../types/reactRedux' import { getDenomFromIsoCode, zeroString } from '../util/utils' @@ -27,7 +28,7 @@ export const useTokenDisplayData = (props: { tokenId: EdgeTokenId; wallet: EdgeC // BASE / QUOTE = PRICE, where: // - 'Fiat' is the QUOTE, defined by the wallet's fiatCurrencyCode // - 'Yest' is an index for a historical price from 24 hours ago. - const usdFiatPrice = useSelector(state => state.exchangeRates[`iso:USD_${isoFiatCurrencyCode}`]) + const usdFiatPrice = useSelector(state => getExchangeRate(state, currencyCode, isoFiatCurrencyCode)) const assetFiatPrice = useCurrencyFiatRate({ currencyCode, isoFiatCurrencyCode