From b69f1b11ee674433364e307215d2105f57a3b0c1 Mon Sep 17 00:00:00 2001 From: li0nd3v Date: Tue, 24 Mar 2026 11:22:09 +0100 Subject: [PATCH 1/7] feat: currencies --- mobile/app/Currency.tsx | 89 +++++++++++++++++++ mobile/app/PocketSwitch.tsx | 12 ++- mobile/app/Settings.tsx | 4 + mobile/app/Tools.tsx | 2 +- mobile/app/TransactionDetails.tsx | 11 ++- mobile/app/send/send-amount-btc.tsx | 7 +- mobile/app/send/send-amount-lightning.tsx | 4 +- mobile/app/send/send-confirm-lightning.tsx | 11 ++- mobile/app/send/send-confirm.tsx | 11 ++- mobile/app/transfer/confirm.tsx | 11 ++- mobile/components/AmountInput.tsx | 13 +-- mobile/components/Balance.tsx | 21 +++-- mobile/components/DashboardTiles.tsx | 13 +-- mobile/components/TokenRow.tsx | 9 +- mobile/components/Transaction.tsx | 11 ++- mobile/components/YieldRow.tsx | 9 +- mobile/components/navigation/ScreenHeader.tsx | 3 +- .../transfer/TransferAmountSection.tsx | 11 ++- mobile/hooks/withAsset.tsx | 7 +- 19 files changed, 203 insertions(+), 56 deletions(-) create mode 100644 mobile/app/Currency.tsx diff --git a/mobile/app/Currency.tsx b/mobile/app/Currency.tsx new file mode 100644 index 000000000..255bb20a2 --- /dev/null +++ b/mobile/app/Currency.tsx @@ -0,0 +1,89 @@ +import React from 'react'; +import { SafeAreaView } from 'react-native-safe-area-context'; +import { ScrollView, StyleSheet, View } from 'react-native'; +import { Ionicons } from '@expo/vector-icons'; +import { Stack } from 'expo-router'; + +import ScreenHeader from '@/components/navigation/ScreenHeader'; +import SettingsRow from '@/components/SettingsRow'; +import { globalDarkBackground } from '@shared/constants/Colors'; +import { useSettings } from '@shared/hooks/useSettings'; +import { SUPPORTED_FIAT_CURRENCIES, TFiat } from '@shared/types/fiat'; + +const CURRENCY_OPTIONS = SUPPORTED_FIAT_CURRENCIES; + +export default function CurrencyScreen() { + const { settings, updateSetting } = useSettings(); + const selectedCurrency = (settings as any).currency as TFiat; + + return ( + + + + + + + + {CURRENCY_OPTIONS.map((item: TFiat, index: number) => { + const isSelected = selectedCurrency === item; + const isLastItem = index === CURRENCY_OPTIONS.length - 1; + + return ( + + + + updateSetting('currency' as any, item as any)} hideChevron testID={`CurrencyOption-${item}`} /> + + {isSelected && ( + + + + )} + + {!isLastItem && } + + ); + })} + + + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + }, + safeArea: { + flex: 1, + }, + scrollContainer: { + flex: 1, + }, + scrollContent: { + paddingHorizontal: 16, + paddingTop: 24, + paddingBottom: 0, + }, + settingsGroup: { + backgroundColor: 'rgba(255, 255, 255, 0.1)', + borderRadius: 12, + overflow: 'hidden', + }, + rowContainer: { + flexDirection: 'row', + alignItems: 'center', + }, + rowContent: { + flex: 1, + }, + selectedIconContainer: { + marginRight: 16, + }, + divider: { + height: 1, + backgroundColor: 'rgba(255, 255, 255, 0.1)', + marginLeft: 16, + }, +}); diff --git a/mobile/app/PocketSwitch.tsx b/mobile/app/PocketSwitch.tsx index 863368592..3ed4f9628 100644 --- a/mobile/app/PocketSwitch.tsx +++ b/mobile/app/PocketSwitch.tsx @@ -15,11 +15,14 @@ import { getDecimalsByNetwork, getTickerByNetwork } from '@shared/models/network import { formatBalance, formatFiatBalance } from '@shared/modules/string-utils'; import { NETWORK_BITCOIN } from '@shared/types/networks'; import { useExchangeRate } from '@shared/hooks/useExchangeRate'; +import { useSelectedFiat } from '@shared/hooks/useSelectedFiat'; +import { formatFiatDisplay } from '@shared/modules/fiat-utils'; import { overlayBackgroundSections } from '@shared/constants/Colors'; const TotalBalanceSection = () => { const availableNetworks = useAvailableNetworks(); - const { exchangeRate } = useExchangeRate(NETWORK_BITCOIN, 'USD'); + const fiat = useSelectedFiat(); + const { exchangeRate } = useExchangeRate(NETWORK_BITCOIN, fiat); // Get balances for all accounts (hooks must be called unconditionally) const { accountBalance: balance0 } = useAccountBalance(0, availableNetworks); @@ -39,7 +42,7 @@ const TotalBalanceSection = () => { Total balance - ${totalUsd} + {formatFiatDisplay(totalUsd, fiat)} ); @@ -48,7 +51,8 @@ const ListItem = ({ item, onPress, accountNumber, currentAccountNumber }: { item const availableNetworks = useAvailableNetworks(); const IconComponent = item.iconCollection === 'ion' ? Ionicons : Foundation; const { accountBalance } = useAccountBalance(accountNumber, availableNetworks); - const { exchangeRate } = useExchangeRate(NETWORK_BITCOIN, 'USD'); + const fiat = useSelectedFiat(); + const { exchangeRate } = useExchangeRate(NETWORK_BITCOIN, fiat); const active = accountNumber === currentAccountNumber; @@ -66,7 +70,7 @@ const ListItem = ({ item, onPress, accountNumber, currentAccountNumber }: { item - ${usdBalance} + {formatFiatDisplay(usdBalance, fiat)} ); diff --git a/mobile/app/Settings.tsx b/mobile/app/Settings.tsx index c9171be27..a263a27b8 100644 --- a/mobile/app/Settings.tsx +++ b/mobile/app/Settings.tsx @@ -92,6 +92,9 @@ export default function SettingsScreen() { const handleToolsPress = () => { router.push('/Tools'); }; + const handleCurrencyPress = () => { + router.push('/Currency'); + }; const handleSupportPress = async () => { try { @@ -173,6 +176,7 @@ export default function SettingsScreen() { key: 'options', hasBackground: false, data: [ + { id: 'currency', title: 'Currency', onPress: handleCurrencyPress, testID: 'CurrencyButton' }, { id: 'tools', title: 'Tools', onPress: handleToolsPress, testID: 'ToolsButton' }, { id: 'support', title: 'Support', onPress: handleSupportPress }, { id: 'about', title: 'About', onPress: handleAboutPress }, diff --git a/mobile/app/Tools.tsx b/mobile/app/Tools.tsx index eda25a366..43f55e877 100644 --- a/mobile/app/Tools.tsx +++ b/mobile/app/Tools.tsx @@ -414,7 +414,7 @@ export default function TabThreeScreen() { return ( {(Object.keys(SETTINGS_CONFIG) as TSettingsKey[]) - .filter((key) => key !== 'biometricAuth' && key !== 'seedBackedUp') + .filter((key) => key !== 'biometricAuth' && key !== 'seedBackedUp' && key !== 'currency') .map((key, index, array) => { const config = SETTINGS_CONFIG[key as keyof typeof SETTINGS_CONFIG]; const currentValue = settings[key as keyof typeof SETTINGS_CONFIG]; diff --git a/mobile/app/TransactionDetails.tsx b/mobile/app/TransactionDetails.tsx index 877ef07e6..a5b107bd5 100644 --- a/mobile/app/TransactionDetails.tsx +++ b/mobile/app/TransactionDetails.tsx @@ -12,7 +12,9 @@ import DetachedSheet from '@/components/DetachedSheet'; import { ThemedText } from '@/components/ThemedText'; import { getNetworkImageAsset } from '@/utils/networkAssets'; import { useExchangeRate } from '@shared/hooks/useExchangeRate'; +import { useSelectedFiat } from '@shared/hooks/useSelectedFiat'; import { getDecimalsByNetwork, getIsEVM, getTickerByNetwork } from '@shared/models/network-getters'; +import { formatFiatDisplay } from '@shared/modules/fiat-utils'; import { getTokenInfo, getTokenIconColor } from '@shared/models/token-list'; import { capitalizeFirstLetter, formatBalance, formatFiatBalance } from '@shared/modules/string-utils'; import { CommonTransaction } from '@shared/types/common-transaction'; @@ -26,7 +28,8 @@ export default function TransactionDetails() { const currentLayerNetwork = layerNetwork as string | undefined; const ticker = getTickerByNetwork(network); const decimals = getDecimalsByNetwork(network); - const { exchangeRate } = useExchangeRate(network, 'USD'); + const fiat = useSelectedFiat(); + const { exchangeRate } = useExchangeRate(network, fiat); const networkImage = getNetworkImageAsset(network); const networkIconContent = networkImage ? : null; const [imageLoadErrors, setImageLoadErrors] = useState<{ [key: string]: boolean }>({}); @@ -317,9 +320,9 @@ export default function TransactionDetails() { return ''; } - if (transaction.amount === undefined || !exchangeRate) return '— USD'; - return `${formatFiatBalance(Math.abs(transaction.amount).toString(), decimals, exchangeRate)} USD`; - }, [isZeroAmountWithTokens, transaction.amount, decimals, exchangeRate]); + if (transaction.amount === undefined || !exchangeRate) return `${fiat} —`; + return formatFiatDisplay(formatFiatBalance(Math.abs(transaction.amount).toString(), decimals, exchangeRate), fiat); + }, [isZeroAmountWithTokens, transaction.amount, decimals, exchangeRate, fiat]); const directionText = useMemo(() => { if (isZeroAmountWithTokens && singleTokenInfo) { diff --git a/mobile/app/send/send-amount-btc.tsx b/mobile/app/send/send-amount-btc.tsx index b3b5dde7f..4312eb970 100644 --- a/mobile/app/send/send-amount-btc.tsx +++ b/mobile/app/send/send-amount-btc.tsx @@ -16,7 +16,9 @@ import { CreateTransactionTarget } from '@shared/class/wallets/types'; import { AccountNumberContext } from '@shared/hooks/AccountNumberContext'; import { useBalance } from '@shared/hooks/useBalance'; import { useCachedExchangeRate } from '@shared/hooks/useCachedExchangeRate'; +import { useSelectedFiat } from '@shared/hooks/useSelectedFiat'; import { getDecimalsByNetwork, getTickerByNetwork } from '@shared/models/network-getters'; +import { formatFiatDisplay } from '@shared/modules/fiat-utils'; import { sleep } from '@shared/modules/sleep'; import { formatBalance } from '@shared/modules/string-utils'; import { validateAddress } from '@shared/modules/wallet-utils'; @@ -40,7 +42,8 @@ const SendAmountBtc: React.FC = () => { const { network, address, amount: contextAmount, setAmount: setContextAmount, setCreatedTransaction, bitcoin, denomination, setDenomination } = useSendFlow(); const { accountNumber } = useContext(AccountNumberContext); const { balance } = useBalance(network, accountNumber, BackgroundExecutor); - const { exchangeRate } = useCachedExchangeRate(network, 'USD'); + const fiat = useSelectedFiat(); + const { exchangeRate } = useCachedExchangeRate(network, fiat); const [localAmount, setLocalAmount] = useState(contextAmount); const [selectedFeeRate, setSelectedFeeRate] = useState(); @@ -67,7 +70,7 @@ const SendAmountBtc: React.FC = () => { if (denomination === 'Fiat' && exchangeRate) { const feeInNative = new BigNumber(feeInSats).dividedBy(new BigNumber(10).pow(getDecimalsByNetwork(network))); const feeInFiat = feeInNative.multipliedBy(Number(exchangeRate)); - return `$${feeInFiat.toFixed(2)}`; + return formatFiatDisplay(feeInFiat.toFixed(2), fiat); } else { return `${formatBalance(feeInSats.toString(), getDecimalsByNetwork(network))} ${getTickerByNetwork(network)}`; } diff --git a/mobile/app/send/send-amount-lightning.tsx b/mobile/app/send/send-amount-lightning.tsx index 9182f46b3..72a5f961e 100644 --- a/mobile/app/send/send-amount-lightning.tsx +++ b/mobile/app/send/send-amount-lightning.tsx @@ -17,6 +17,7 @@ import { AccountNumberContext } from '@shared/hooks/AccountNumberContext'; import { NetworkContext } from '@shared/hooks/NetworkContext'; import { useBalance } from '@shared/hooks/useBalance'; import { useCachedExchangeRate } from '@shared/hooks/useCachedExchangeRate'; +import { useSelectedFiat } from '@shared/hooks/useSelectedFiat'; import { getDecimalsByNetwork, getTickerByNetwork } from '@shared/models/network-getters'; import { formatBalance } from '@shared/modules/string-utils'; import { NETWORK_BITCOIN } from '@shared/types/networks'; @@ -30,7 +31,8 @@ const SendAmountLightning: React.FC = () => { assert(lightning && lightning.layer, 'Lightning context not found'); const { layer } = lightning; const { balance } = useBalance(layer, accountNumber, BackgroundExecutor); - const { exchangeRate } = useCachedExchangeRate(NETWORK_BITCOIN, 'USD'); + const fiat = useSelectedFiat(); + const { exchangeRate } = useCachedExchangeRate(NETWORK_BITCOIN, fiat); const [localAmount, setLocalAmount] = useState(amount); const [localMemo, setLocalMemo] = useState(''); diff --git a/mobile/app/send/send-confirm-lightning.tsx b/mobile/app/send/send-confirm-lightning.tsx index 4baebf090..174d87ecb 100644 --- a/mobile/app/send/send-confirm-lightning.tsx +++ b/mobile/app/send/send-confirm-lightning.tsx @@ -18,7 +18,9 @@ import { SparkWallet } from '@shared/class/wallets/spark-wallet'; import { TLightningWallet } from '@shared/types/TWallet'; import { AccountNumberContext } from '@shared/hooks/AccountNumberContext'; import { useCachedExchangeRate } from '@shared/hooks/useCachedExchangeRate'; +import { useSelectedFiat } from '@shared/hooks/useSelectedFiat'; import { getDecimalsByNetwork, getTickerByNetwork } from '@shared/models/network-getters'; +import { formatFiatDisplay } from '@shared/modules/fiat-utils'; import { formatBalance } from '@shared/modules/string-utils'; import { NETWORK_BITCOIN } from '@shared/types/networks'; import { useSendFlow } from './_layout'; @@ -30,7 +32,8 @@ const SendConfirmLightning: React.FC = () => { const router = useRouter(); const { lightning, network } = useSendFlow(); const { accountNumber } = useContext(AccountNumberContext); - const { exchangeRate } = useCachedExchangeRate(NETWORK_BITCOIN, 'USD'); + const fiat = useSelectedFiat(); + const { exchangeRate } = useCachedExchangeRate(NETWORK_BITCOIN, fiat); assert(lightning && lightning.layer && lightning.invoice, 'No lightning data available'); const decoded = lightning.decodedInvoice; @@ -156,9 +159,9 @@ const SendConfirmLightning: React.FC = () => { const totalDisplay = formatBalance(String(totalSats), networkDecimals); // USD conversions - const amountUsdValue = exchangeRate ? `$${new BigNumber(invoiceAmountSats).dividedBy(new BigNumber(10).pow(networkDecimals)).multipliedBy(Number(exchangeRate)).toFixed(2)}` : ''; - const feeUsd = exchangeRate ? `$${new BigNumber(feeSats).dividedBy(new BigNumber(10).pow(networkDecimals)).multipliedBy(Number(exchangeRate)).toFixed(2)}` : ''; - const totalUsd = exchangeRate ? `$${new BigNumber(totalSats).dividedBy(new BigNumber(10).pow(networkDecimals)).multipliedBy(Number(exchangeRate)).toFixed(2)}` : ''; + const amountUsdValue = exchangeRate ? formatFiatDisplay(new BigNumber(invoiceAmountSats).dividedBy(new BigNumber(10).pow(networkDecimals)).multipliedBy(Number(exchangeRate)).toFixed(2), fiat) : ''; + const feeUsd = exchangeRate ? formatFiatDisplay(new BigNumber(feeSats).dividedBy(new BigNumber(10).pow(networkDecimals)).multipliedBy(Number(exchangeRate)).toFixed(2), fiat) : ''; + const totalUsd = exchangeRate ? formatFiatDisplay(new BigNumber(totalSats).dividedBy(new BigNumber(10).pow(networkDecimals)).multipliedBy(Number(exchangeRate)).toFixed(2), fiat) : ''; // Format invoice display let invoiceDisplay = lightning.invoice; diff --git a/mobile/app/send/send-confirm.tsx b/mobile/app/send/send-confirm.tsx index 585851215..5228e355d 100644 --- a/mobile/app/send/send-confirm.tsx +++ b/mobile/app/send/send-confirm.tsx @@ -23,7 +23,9 @@ import { StacksWallet } from '@shared/class/wallets/stacks-wallet'; import { AccountNumberContext } from '@shared/hooks/AccountNumberContext'; import { NetworkContext } from '@shared/hooks/NetworkContext'; import { useCachedExchangeRate } from '@shared/hooks/useCachedExchangeRate'; +import { useSelectedFiat } from '@shared/hooks/useSelectedFiat'; import { getDecimalsByNetwork, getIsAccountBased, getIsEVM, getTickerByNetwork } from '@shared/models/network-getters'; +import { formatFiatDisplay } from '@shared/modules/fiat-utils'; import { formatBalance } from '@shared/modules/string-utils'; import { NETWORK_ARK, NETWORK_ARK_MUTINYNET, NETWORK_BITCOIN, NETWORK_LIQUID, NETWORK_LIQUID_TESTNET, NETWORK_SPARK, NETWORK_STACKS, NETWORK_USDT } from '@shared/types/networks'; import { useSendFlow } from './_layout'; @@ -33,7 +35,8 @@ const SendConfirm: React.FC = ({ ticker, token }) => { const { network: contextNetwork } = useContext(NetworkContext); const { network, address, amount, createdTransaction, memo, liquidPrepareResult } = useSendFlow(); const { accountNumber } = useContext(AccountNumberContext); - const { exchangeRate } = useCachedExchangeRate(network, 'USD'); + const fiat = useSelectedFiat(); + const { exchangeRate } = useCachedExchangeRate(network, fiat); const displayNetwork = contextNetwork === NETWORK_USDT ? contextNetwork : network; @@ -117,8 +120,8 @@ const SendConfirm: React.FC = ({ ticker, token }) => { const isTokenSend = !!token; // USD conversions - const amountUsdValue = exchangeRate && !isTokenSend ? `$${BigNumber(amount).multipliedBy(Number(exchangeRate)).toFixed(2)}` : ''; - const usdFee = exchangeRate ? `$${feeInNativeUnits.multipliedBy(Number(exchangeRate)).toFixed(2)}` : ''; + const amountUsdValue = exchangeRate && !isTokenSend ? formatFiatDisplay(BigNumber(amount).multipliedBy(Number(exchangeRate)).toFixed(2), fiat) : ''; + const usdFee = exchangeRate ? formatFiatDisplay(feeInNativeUnits.multipliedBy(Number(exchangeRate)).toFixed(2), fiat) : ''; // Total calculation let totalUsd: string; @@ -130,7 +133,7 @@ const SendConfirm: React.FC = ({ ticker, token }) => { totalDisplay = `${amount} ${ticker}`; } else { const totalAmount = BigNumber(amount).plus(feeInNativeUnits); - totalUsd = exchangeRate ? `$${totalAmount.multipliedBy(Number(exchangeRate)).toFixed(2)}` : ''; + totalUsd = exchangeRate ? formatFiatDisplay(totalAmount.multipliedBy(Number(exchangeRate)).toFixed(2), fiat) : ''; totalDisplay = `${totalAmount.toFixed()} ${ticker}`; } diff --git a/mobile/app/transfer/confirm.tsx b/mobile/app/transfer/confirm.tsx index cda45a20f..ec80112bb 100644 --- a/mobile/app/transfer/confirm.tsx +++ b/mobile/app/transfer/confirm.tsx @@ -14,8 +14,10 @@ import { EvmWallet } from '@shared/class/evm-wallet'; import { InterfaceSendQuotable, walletCanSendQuote } from '@shared/class/wallets/interface-send-quotable'; import { AccountNumberContext } from '@shared/hooks/AccountNumberContext'; import { useAssetExchangeRate } from '@shared/hooks/useAssetExchangeRate'; +import { useSelectedFiat } from '@shared/hooks/useSelectedFiat'; import { AllNetworkInfos } from '@shared/models/all-network-infos'; import { getAssetInfo } from '@shared/models/asset-info'; +import { formatFiatDisplay } from '@shared/modules/fiat-utils'; import { sleep } from '@shared/modules/sleep'; import { TSupportedLazyInitWalletNetworks } from '@shared/modules/wallet-utils'; import type { AssetId } from '@shared/types/asset'; @@ -31,6 +33,7 @@ export default function TransferConfirm() { const { height: screenHeight } = useWindowDimensions(); const { sendAsset, receiveAsset, quote, setQuote, setCommitted, transferService } = useTransferFlow(); const { accountNumber } = useContext(AccountNumberContext); + const fiat = useSelectedFiat(); const { exchangeRate: sendRate } = useAssetExchangeRate(sendAsset); const { exchangeRate: receiveRate } = useAssetExchangeRate(receiveAsset); @@ -258,8 +261,8 @@ export default function TransferConfirm() { const sendAmount = quote?.sendAmount ?? ''; const receiveAmount = quote?.receiveAmount ?? ''; - const sendFiat = sendRate && sendAmount ? `$${new BigNumber(sendAmount).multipliedBy(sendRate).toFixed(2)}` : ''; - const receiveFiat = receiveRate && receiveAmount ? `$${new BigNumber(receiveAmount).multipliedBy(receiveRate).toFixed(2)}` : ''; + const sendFiat = sendRate && sendAmount ? formatFiatDisplay(new BigNumber(sendAmount).multipliedBy(sendRate).toFixed(2), fiat) : ''; + const receiveFiat = receiveRate && receiveAmount ? formatFiatDisplay(new BigNumber(receiveAmount).multipliedBy(receiveRate).toFixed(2), fiat) : ''; const isExpired = !isNativeDeposit && expirySeconds <= 0; const isReady = !isPreparing && !error && !isExpired; @@ -303,7 +306,7 @@ export default function TransferConfirm() { {sendAmount} {sendAssetInfo.ticker} - {sendFiat || '$0.00'} + {sendFiat || formatFiatDisplay('0.00', fiat)} @@ -321,7 +324,7 @@ export default function TransferConfirm() { {receiveAmount} {receiveAssetInfo.ticker} - {receiveFiat || '$0.00'} + {receiveFiat || formatFiatDisplay('0.00', fiat)} diff --git a/mobile/components/AmountInput.tsx b/mobile/components/AmountInput.tsx index cde9d62a6..87b54c33b 100644 --- a/mobile/components/AmountInput.tsx +++ b/mobile/components/AmountInput.tsx @@ -7,6 +7,8 @@ import Pressable from './Pressable'; import { ThemedText } from './ThemedText'; import { overlayBackgroundDeeper } from '@shared/constants/Colors'; +import { useSelectedFiat } from '@shared/hooks/useSelectedFiat'; +import { formatFiatDisplay } from '@shared/modules/fiat-utils'; export interface AmountInputProps { value: string; @@ -37,6 +39,7 @@ export default function AmountInput({ disabled = false, testID, }: AmountInputProps) { + const fiat = useSelectedFiat(); const inputRef = useRef(null); const [localDisplayValue, setLocalDisplayValue] = useState(''); const isFocused = useRef(false); @@ -133,12 +136,12 @@ export default function AmountInput({ const secondaryValue = useMemo(() => { if (denomination === 'Native') { - const fiat = nativeToFiat(value); - return `${fiat} USD`; + const fiatValue = nativeToFiat(value); + return formatFiatDisplay(fiatValue, fiat); } else { return `${value} ${ticker}`; } - }, [value, denomination, ticker, nativeToFiat]); + }, [value, denomination, ticker, nativeToFiat, fiat]); const canSwitchDenomination = !!exchangeRateNumber && !!onDenominationSwitch; @@ -146,11 +149,11 @@ export default function AmountInput({ if (denomination === 'Fiat' && exchangeRateNumber) { const balanceBN = new BigNumber(balance); const fiatBalance = balanceBN.multipliedBy(exchangeRateNumber); - return `$${fiatBalance.toFixed(2)}`; + return formatFiatDisplay(fiatBalance.toFixed(2), fiat); } else { return `${balance} ${ticker}`; } - }, [balance, denomination, exchangeRateNumber, ticker]); + }, [balance, denomination, exchangeRateNumber, ticker, fiat]); return ( diff --git a/mobile/components/Balance.tsx b/mobile/components/Balance.tsx index a998956d1..dfa59477b 100644 --- a/mobile/components/Balance.tsx +++ b/mobile/components/Balance.tsx @@ -16,10 +16,12 @@ import { AccountNumberContext } from '@shared/hooks/AccountNumberContext'; import { NetworkContext } from '@shared/hooks/NetworkContext'; import { useBalance } from '@shared/hooks/useBalance'; import { useExchangeRate } from '@shared/hooks/useExchangeRate'; +import { useSelectedFiat } from '@shared/hooks/useSelectedFiat'; import { useTokenBalance } from '@shared/hooks/useTokenBalance'; import { useTokenDiscovery } from '@shared/hooks/useTokenDiscovery'; import { fiatOnRamp } from '@shared/models/fiat-on-ramp'; import { getDecimalsByNetwork, getTickerByNetwork } from '@shared/models/network-getters'; +import { formatFiatDisplay } from '@shared/modules/fiat-utils'; import { capitalizeFirstLetter, formatBalance, formatFiatBalance } from '@shared/modules/string-utils'; import { NETWORK_LIGHTNING, NETWORK_LIGHTNING_TESTNET, NETWORK_LIQUID, NETWORK_LIQUID_TESTNET, NETWORK_ROOTSTOCK, NETWORK_SPARK, NETWORK_USDT, NETWORK_ARK, Networks } from '@shared/types/networks'; import { CachedTokenInfo } from '@shared/types/token-info'; @@ -29,8 +31,9 @@ const Balance = forwardRef<{ refresh: () => void }>((props, ref) => { const router = useRouter(); const { network } = useContext(NetworkContext); const { accountNumber } = useContext(AccountNumberContext); + const fiat = useSelectedFiat(); const { balance, mutate } = useBalance(network, accountNumber, BackgroundExecutor); - const { exchangeRate } = useExchangeRate(network, 'USD'); + const { exchangeRate } = useExchangeRate(network, fiat); const ticker = getTickerByNetwork(network); const canBuyWithFiat = fiatOnRamp?.[network]?.canBuyWithFiat; @@ -62,7 +65,7 @@ const Balance = forwardRef<{ refresh: () => void }>((props, ref) => { {displayBalance} {ticker} - ${displaySubBalance} + {formatFiatDisplay(displaySubBalance, fiat)} {canBuyWithFiat && ( @@ -86,6 +89,7 @@ export const BalanceLightning = forwardRef<{ refresh: () => void }, BalanceLight const { onSelectNetwork = () => {}, selectedNetwork = undefined, showTotalBalance = true } = props; const { network } = useContext(NetworkContext); const { accountNumber } = useContext(AccountNumberContext); + const fiat = useSelectedFiat(); // Lightning network aggregates balances from Spark, Ark, and Liquid networks // Each underlying network has its own balance and exchange rate @@ -94,9 +98,9 @@ export const BalanceLightning = forwardRef<{ refresh: () => void }, BalanceLight const { balance: sparkBalance, mutate: mutateSpark } = useBalance(NETWORK_SPARK, accountNumber, BackgroundExecutor); const { balance: arkBalance, mutate: mutateArk } = useBalance(NETWORK_ARK, accountNumber, BackgroundExecutor); const { balance: liquidBalance, mutate: mutateLiquid } = useBalance(liquidNetwork, accountNumber, BackgroundExecutor); - const { exchangeRate: sparkExchangeRate } = useExchangeRate(NETWORK_SPARK, 'USD'); - const { exchangeRate: arkExchangeRate } = useExchangeRate(NETWORK_ARK, 'USD'); - const { exchangeRate: liquidExchangeRate } = useExchangeRate(liquidNetwork, 'USD'); + const { exchangeRate: sparkExchangeRate } = useExchangeRate(NETWORK_SPARK, fiat); + const { exchangeRate: arkExchangeRate } = useExchangeRate(NETWORK_ARK, fiat); + const { exchangeRate: liquidExchangeRate } = useExchangeRate(liquidNetwork, fiat); // delay rendering of adjustsFontSizeToFit to avoid layout issues on Android const [adjustsFontSizeToFit, setAdjustsFontSizeToFit] = useState(false); @@ -189,7 +193,10 @@ export const BalanceLightning = forwardRef<{ refresh: () => void }, BalanceLight const networkImage = getNetworkImageAsset(network); const networkIconContent = networkImage ? : null; const formattedBalance = balance !== undefined ? formatBalance(balance, Number(getDecimalsByNetwork(network)), 8) : '—'; - const formattedFiatBalance = exchangeRate !== undefined && balance !== undefined ? '$' + formatFiatBalance(balance, Number(getDecimalsByNetwork(network)), Number(exchangeRate)) : '$—'; + const formattedFiatBalance = + exchangeRate !== undefined && balance !== undefined + ? formatFiatDisplay(formatFiatBalance(balance, Number(getDecimalsByNetwork(network)), Number(exchangeRate)), fiat) + : formatFiatDisplay('—', fiat); const ticker = getTickerByNetwork(network); return ( @@ -218,7 +225,7 @@ export const BalanceLightning = forwardRef<{ refresh: () => void }, BalanceLight {displayBalance} {ticker} - ${displaySubBalance} + {formatFiatDisplay(displaySubBalance, fiat)} {icons} diff --git a/mobile/components/DashboardTiles.tsx b/mobile/components/DashboardTiles.tsx index 7d30786bf..2f64f8371 100644 --- a/mobile/components/DashboardTiles.tsx +++ b/mobile/components/DashboardTiles.tsx @@ -12,6 +12,8 @@ import { getIsTestnet, getTickerByNetwork, getDecimalsByNetwork } from '@shared/ import { AccountNumberContext } from '@shared/hooks/AccountNumberContext'; import { useCachedBalance } from '@shared/hooks/useCachedBalance'; import { useCachedExchangeRate } from '@shared/hooks/useCachedExchangeRate'; +import { useSelectedFiat } from '@shared/hooks/useSelectedFiat'; +import { formatFiatDisplay } from '@shared/modules/fiat-utils'; import { capitalizeFirstLetter, formatBalance, formatFiatBalance } from '@shared/modules/string-utils'; import { ThemedText } from '@/components/ThemedText'; @@ -49,9 +51,10 @@ interface LayerCardTileProps extends DashboardTileProps { const LayerCardTile = ({ card, index, onCardPress, transitionId: _transitionId, disableNavigation = false, accountNumber }: LayerCardTileProps & { accountNumber?: number }) => { const router = useRouter(); + const fiat = useSelectedFiat(); const { balance } = useCachedBalance(card.networkId, accountNumber || 0); - const { exchangeRate } = useCachedExchangeRate(card.networkId, 'USD'); + const { exchangeRate } = useCachedExchangeRate(card.networkId, fiat); const [hasTimedOut, setHasTimedOut] = useState(false); // Animation for squeeze effect @@ -65,7 +68,7 @@ const LayerCardTile = ({ card, index, onCardPress, transitionId: _transitionId, const displayCard = useMemo(() => { const isTestnet = getIsTestnet(card.networkId as any); let formattedBalance = '0.00000'; - let formattedUsdValue = '$0.00'; + let formattedUsdValue = formatFiatDisplay('0.00', fiat); if (balance !== undefined && balance !== null) { formattedBalance = formatBalance(balance, getDecimalsByNetwork(card.networkId as any), 8); @@ -76,7 +79,7 @@ const LayerCardTile = ({ card, index, onCardPress, transitionId: _transitionId, if (isTestnet) { formattedUsdValue = 'Testnet'; } else if (balance !== undefined && balance !== null && exchangeRate) { - formattedUsdValue = `$${formatFiatBalance(balance, getDecimalsByNetwork(card.networkId as any), +exchangeRate)}`; + formattedUsdValue = formatFiatDisplay(formatFiatBalance(balance, getDecimalsByNetwork(card.networkId as any), +exchangeRate), fiat); } else { formattedUsdValue = '...'; } @@ -89,7 +92,7 @@ const LayerCardTile = ({ card, index, onCardPress, transitionId: _transitionId, } return { ...card, balance: formattedBalance, usdValue: formattedUsdValue }; - }, [card, balance, exchangeRate, hasTimedOut]); + }, [card, balance, exchangeRate, hasTimedOut, fiat]); const gradientColors = useMemo(() => { let gradKey: keyof typeof sharedGradients = 'base'; for (const key of Object.keys(sharedGradients)) { @@ -209,7 +212,7 @@ const useNetworkCards = (accountNumber: number): LayerCard[] => { name: capitalizeFirstLetter(network), ticker: ticker, balance: '0.00000', - usdValue: isTestnet ? 'Testnet' : '$0.00', + usdValue: isTestnet ? 'Testnet' : formatFiatDisplay('0.00', 'USD'), color: gradientColors[0], icon: null, tags: isTestnet ? ['Testnet'] : [], diff --git a/mobile/components/TokenRow.tsx b/mobile/components/TokenRow.tsx index b225455de..9cbc194c2 100644 --- a/mobile/components/TokenRow.tsx +++ b/mobile/components/TokenRow.tsx @@ -8,8 +8,10 @@ import { BackgroundExecutor } from '@/src/modules/background-executor'; import { AccountNumberContext } from '@shared/hooks/AccountNumberContext'; import { NetworkContext } from '@shared/hooks/NetworkContext'; import { useTokenBalance } from '@shared/hooks/useTokenBalance'; +import { useSelectedFiat } from '@shared/hooks/useSelectedFiat'; import { useTokenExchangeRate } from '@shared/hooks/useTokenExchangeRate'; import { getTokenIconColor } from '@shared/models/token-list'; +import { formatFiatDisplay } from '@shared/modules/fiat-utils'; import { formatBalance, formatFiatBalance } from '@shared/modules/string-utils'; import { CachedTokenInfo } from '@shared/types/token-info'; @@ -28,8 +30,9 @@ const TokenRow: React.FC<{ token: CachedTokenInfo; onPress: (token: CachedTokenI }) => { const { network } = useContext(NetworkContext); const { accountNumber } = useContext(AccountNumberContext); + const fiat = useSelectedFiat(); const { balance } = useTokenBalance(network, accountNumber, token.id, BackgroundExecutor); - const { tokenExchangeRate } = useTokenExchangeRate(network, token.id, 'USD'); + const { tokenExchangeRate } = useTokenExchangeRate(network, token.id, fiat); // Calculate formatted balance to determine visibility const effectiveBalance = balance ?? token.balance ?? '0'; @@ -78,7 +81,9 @@ const TokenRow: React.FC<{ token: CachedTokenInfo; onPress: (token: CachedTokenI {formattedBalance} {token?.symbol} - {balance && tokenExchangeRate && tokenExchangeRate > 0 ? '$' + formatFiatBalance(balance, token.decimals, tokenExchangeRate) : null} + + {balance && tokenExchangeRate && tokenExchangeRate > 0 ? formatFiatDisplay(formatFiatBalance(balance, token.decimals, tokenExchangeRate), fiat) : null} + ); diff --git a/mobile/components/Transaction.tsx b/mobile/components/Transaction.tsx index 8aa0aeb44..aeb29c94d 100644 --- a/mobile/components/Transaction.tsx +++ b/mobile/components/Transaction.tsx @@ -6,6 +6,8 @@ import Pressable from './Pressable'; import { ThemedText } from '@/components/ThemedText'; import { getDecimalsByNetwork, getTickerByNetwork } from '@shared/models/network-getters'; +import { useSelectedFiat } from '@shared/hooks/useSelectedFiat'; +import { formatFiatDisplay } from '@shared/modules/fiat-utils'; import { useExchangeRate } from '@shared/hooks/useExchangeRate'; import { formatBalance, formatFiatBalance } from '@shared/modules/string-utils'; import { CommonTransaction } from '@shared/types/common-transaction'; @@ -17,7 +19,8 @@ interface TransactionProps { } export default function Transaction({ transaction, onPress }: TransactionProps) { - const { exchangeRate } = useExchangeRate(transaction.network, 'USD'); + const fiat = useSelectedFiat(); + const { exchangeRate } = useExchangeRate(transaction.network, fiat); const decimals = getDecimalsByNetwork(transaction.network); const ticker = getTickerByNetwork(transaction.network); const [imageLoadError, setImageLoadError] = useState(false); @@ -66,10 +69,10 @@ export default function Transaction({ transaction, onPress }: TransactionProps) if (transaction.amount !== undefined && exchangeRate) { const usdAmount = formatFiatBalance(Math.abs(transaction.amount).toString(), decimals, exchangeRate); - return `$${usdAmount}`; + return formatFiatDisplay(usdAmount, fiat); } - return '$0.00'; - }, [isZeroAmountWithSingleToken, transaction.amount, exchangeRate, decimals]); + return formatFiatDisplay('0.00', fiat); + }, [isZeroAmountWithSingleToken, transaction.amount, exchangeRate, decimals, fiat]); const formattedTransactionDate = useMemo(() => { if (transaction.status === 'pending') { diff --git a/mobile/components/YieldRow.tsx b/mobile/components/YieldRow.tsx index 27466f94c..5d3ffe84e 100644 --- a/mobile/components/YieldRow.tsx +++ b/mobile/components/YieldRow.tsx @@ -8,8 +8,10 @@ import { BackgroundExecutor } from '@/src/modules/background-executor'; import { AccountNumberContext } from '@shared/hooks/AccountNumberContext'; import { NetworkContext } from '@shared/hooks/NetworkContext'; import { useTokenBalance } from '@shared/hooks/useTokenBalance'; +import { useSelectedFiat } from '@shared/hooks/useSelectedFiat'; import { useYieldDiscovery, YieldBearingCachedTokenInfo } from '@shared/hooks/useYieldDiscovery'; import { getTokenIconColor } from '@shared/models/token-list'; +import { formatFiatDisplay } from '@shared/modules/fiat-utils'; import { formatBalance, formatFiatBalance } from '@shared/modules/string-utils'; import { useTokenExchangeRate } from '@shared/hooks/useTokenExchangeRate'; import { Networks } from '@shared/types/networks'; @@ -25,8 +27,9 @@ const YieldRow: React.FC<{ token: YieldBearingCachedTokenInfo; onPress: (token: network, }) => { const { accountNumber } = useContext(AccountNumberContext); + const fiat = useSelectedFiat(); const { balance } = useTokenBalance(network, accountNumber, token.id, BackgroundExecutor); - const { tokenExchangeRate } = useTokenExchangeRate(network, token.id, 'USD'); + const { tokenExchangeRate } = useTokenExchangeRate(network, token.id, fiat); // Calculate formatted balance to determine visibility const effectiveBalance = balance ?? token.balance ?? '0'; @@ -83,7 +86,9 @@ const YieldRow: React.FC<{ token: YieldBearingCachedTokenInfo; onPress: (token: {formattedBalance} {token?.symbol} - {balance && tokenExchangeRate && tokenExchangeRate > 0 ? '$' + formatFiatBalance(balance, token.decimals, tokenExchangeRate) : null} + + {balance && tokenExchangeRate && tokenExchangeRate > 0 ? formatFiatDisplay(formatFiatBalance(balance, token.decimals, tokenExchangeRate), fiat) : null} + ); diff --git a/mobile/components/navigation/ScreenHeader.tsx b/mobile/components/navigation/ScreenHeader.tsx index f2a8fe14c..e42ec2c77 100644 --- a/mobile/components/navigation/ScreenHeader.tsx +++ b/mobile/components/navigation/ScreenHeader.tsx @@ -57,7 +57,8 @@ const styles = StyleSheet.create({ title: { textAlign: 'center', color: 'white', - opacity: 0.8, + fontSize: 18, + fontWeight: '600', }, }); diff --git a/mobile/components/transfer/TransferAmountSection.tsx b/mobile/components/transfer/TransferAmountSection.tsx index b46961a0a..219dc6b11 100644 --- a/mobile/components/transfer/TransferAmountSection.tsx +++ b/mobile/components/transfer/TransferAmountSection.tsx @@ -5,6 +5,8 @@ import { StyleSheet, TextInput, View } from 'react-native'; import { overlayBackgroundDeeper } from '@shared/constants/Colors'; import { getAssetInfo } from '@shared/models/asset-info'; +import { useSelectedFiat } from '@shared/hooks/useSelectedFiat'; +import { formatFiatDisplay } from '@shared/modules/fiat-utils'; import { AssetId } from '@shared/types/asset'; import { Denomination } from '@shared/types/transfer'; import Pressable from '../Pressable'; @@ -38,6 +40,7 @@ export default function TransferAmountSection({ exchangeRate, onDenominationSwitch, }: TransferAmountSectionProps) { + const fiat = useSelectedFiat(); const inputRef = useRef(null); const [localDisplayValue, setLocalDisplayValue] = useState(''); const isFocused = useRef(false); @@ -98,13 +101,13 @@ export default function TransferAmountSection({ const secondaryValue = useMemo(() => { if (!hasRate) return ''; if (denomination === 'Native') { - const fiat = nativeToFiat(amount); - return fiat ? `$${fiat}` : ''; + const fiatValue = nativeToFiat(amount); + return fiatValue ? formatFiatDisplay(fiatValue, fiat) : ''; } else { const ticker = asset ? getAssetInfo(asset).ticker : ''; return amount && amount !== '' ? `${amount} ${ticker}` : ''; } - }, [amount, denomination, asset, nativeToFiat, hasRate]); + }, [amount, denomination, asset, nativeToFiat, hasRate, fiat]); const canSwitch = hasRate && !!onDenominationSwitch; const containerStyle = type === 'send' ? styles.sendContainer : styles.receiveContainer; @@ -130,7 +133,7 @@ export default function TransferAmountSection({ - {secondaryValue || '$0.00'} + {secondaryValue || formatFiatDisplay('0.00', fiat)} {canSwitch && } diff --git a/mobile/hooks/withAsset.tsx b/mobile/hooks/withAsset.tsx index 6d49ba032..d95ca7fd6 100644 --- a/mobile/hooks/withAsset.tsx +++ b/mobile/hooks/withAsset.tsx @@ -6,6 +6,7 @@ import { BackgroundExecutor } from '@/src/modules/background-executor'; import { AccountNumberContext } from '@shared/hooks/AccountNumberContext'; import { useBalance } from '@shared/hooks/useBalance'; import { useExchangeRate } from '@shared/hooks/useExchangeRate'; +import { useSelectedFiat } from '@shared/hooks/useSelectedFiat'; import { useTokenBalance } from '@shared/hooks/useTokenBalance'; import { useTokenDiscovery } from '@shared/hooks/useTokenDiscovery'; import { getDecimalsByNetwork, getTickerByNetwork } from '@shared/models/network-getters'; @@ -28,9 +29,10 @@ export const withAsset =

(Component: React.ComponentType

{ const { network, token } = useSendFlow(); const { accountNumber } = useContext(AccountNumberContext); + const fiat = useSelectedFiat(); const { balance: tokenBalance } = useTokenBalance(network, accountNumber, token!, BackgroundExecutor); const { tokenList } = useTokenDiscovery(network, accountNumber, BackgroundExecutor, LayerzStorage); - const { tokenExchangeRate } = useTokenExchangeRate(network, token ?? '', 'USD'); + const { tokenExchangeRate } = useTokenExchangeRate(network, token ?? '', fiat); const tokenInfo = tokenList.find((t) => t.id === token); if (!tokenInfo) { @@ -43,9 +45,10 @@ export const withAsset =

(Component: React.ComponentType

{ const { network } = useSendFlow(); const { accountNumber } = useContext(AccountNumberContext); + const fiat = useSelectedFiat(); const { balance: networkBalance } = useBalance(network, accountNumber, BackgroundExecutor); - const { exchangeRate: networkExchangeRate } = useExchangeRate(network, 'USD'); + const { exchangeRate: networkExchangeRate } = useExchangeRate(network, fiat); return ; }; From 66fc044539f624f6ee65c3929670fb01200019bb Mon Sep 17 00:00:00 2001 From: li0nd3v Date: Tue, 24 Mar 2026 11:24:16 +0100 Subject: [PATCH 2/7] feat: currencies --- ext/src/pages/Popup/SettingsPage.tsx | 2 +- ext/src/pages/Popup/SwapDetails.tsx | 9 ++++++--- ext/src/pages/Popup/components/Balance.tsx | 23 ++++++++++++++-------- shared/hooks/SettingsContext.tsx | 5 +++++ shared/hooks/useAssetExchangeRate.ts | 6 ++++-- shared/hooks/useCachedExchangeRate.ts | 4 ++-- shared/hooks/useExchangeRate.ts | 4 ++-- shared/hooks/useSelectedFiat.ts | 6 ++++++ shared/hooks/useTokenExchangeRate.ts | 3 +-- shared/models/fiatUnit.ts | 2 +- shared/models/fiatUnits.json | 8 ++++---- shared/modules/fiat-utils.ts | 11 +++++++++++ shared/types/fiat.ts | 3 +++ 13 files changed, 61 insertions(+), 25 deletions(-) create mode 100644 shared/hooks/useSelectedFiat.ts create mode 100644 shared/modules/fiat-utils.ts create mode 100644 shared/types/fiat.ts diff --git a/ext/src/pages/Popup/SettingsPage.tsx b/ext/src/pages/Popup/SettingsPage.tsx index bacd5c6c3..c7d28b6d7 100644 --- a/ext/src/pages/Popup/SettingsPage.tsx +++ b/ext/src/pages/Popup/SettingsPage.tsx @@ -77,7 +77,7 @@ const SettingsPage: React.FC = () => { diff --git a/ext/src/pages/Popup/SwapDetails.tsx b/ext/src/pages/Popup/SwapDetails.tsx index 5f74e69f1..b3d6a0aee 100644 --- a/ext/src/pages/Popup/SwapDetails.tsx +++ b/ext/src/pages/Popup/SwapDetails.tsx @@ -4,7 +4,9 @@ import { ArrowLeftIcon, Copy, ExternalLink } from 'lucide-react'; import { NetworkContext } from '@shared/hooks/NetworkContext'; import { useExchangeRate } from '@shared/hooks/useExchangeRate'; +import { useSelectedFiat } from '@shared/hooks/useSelectedFiat'; import { getDecimalsByNetwork, getTickerByNetwork } from '@shared/models/network-getters'; +import { formatFiatDisplay } from '@shared/modules/fiat-utils'; import { capitalizeFirstLetter, formatBalance, formatFiatBalance } from '@shared/modules/string-utils'; import { CommonSwap } from '@shared/types/common-swap'; import { NETWORK_ARK, NETWORK_ARK_MUTINYNET, NETWORK_SPARK } from '@shared/types/networks'; @@ -21,10 +23,11 @@ const SwapDetails: React.FC = () => { const location = useLocation(); const { network } = useContext(NetworkContext); const { swap } = location.state as SwapDetailsParams; + const fiat = useSelectedFiat(); const ticker = getTickerByNetwork(network); const decimals = getDecimalsByNetwork(network); - const { exchangeRate } = useExchangeRate(network, 'USD'); + const { exchangeRate } = useExchangeRate(network, fiat); const [formattedDate, formattedDateWithTime] = useMemo(() => { if (!swap.timestamp) return ['—', '—']; @@ -48,8 +51,8 @@ const SwapDetails: React.FC = () => { const amountUsd = useMemo(() => { if (!exchangeRate) return ''; - return `${formatFiatBalance(Math.abs(swap.amount).toString(), decimals, exchangeRate)} USD`; - }, [swap.amount, decimals, exchangeRate]); + return formatFiatDisplay(formatFiatBalance(Math.abs(swap.amount).toString(), decimals, exchangeRate), fiat); + }, [swap.amount, decimals, exchangeRate, fiat]); const statusText = useMemo(() => { switch (swap.status) { diff --git a/ext/src/pages/Popup/components/Balance.tsx b/ext/src/pages/Popup/components/Balance.tsx index 9ab274f16..aa6e85977 100644 --- a/ext/src/pages/Popup/components/Balance.tsx +++ b/ext/src/pages/Popup/components/Balance.tsx @@ -7,6 +7,8 @@ import { useAccountBalance } from '@shared/hooks/useAccountBalance'; import { useAvailableNetworks } from '@shared/hooks/useAvailableNetworks'; import { useBalance } from '@shared/hooks/useBalance'; import { useExchangeRate } from '@shared/hooks/useExchangeRate'; +import { useSelectedFiat } from '@shared/hooks/useSelectedFiat'; +import { formatFiatDisplay } from '@shared/modules/fiat-utils'; import { useTokenBalance } from '@shared/hooks/useTokenBalance'; import { useTokenDiscovery } from '@shared/hooks/useTokenDiscovery'; import { fiatOnRamp } from '@shared/models/fiat-on-ramp'; @@ -48,7 +50,8 @@ const BalanceDefault = forwardRef<{ refresh: () => void }, BalanceProps>(({ netw mutate(); }, })); - const { exchangeRate } = useExchangeRate(network, 'USD'); + const fiat = useSelectedFiat(); + const { exchangeRate } = useExchangeRate(network, fiat); const availableNetworks = useAvailableNetworks(); const { accountBalance } = useAccountBalance(accountNumber, availableNetworks); const ticker = getTickerByNetwork(network); @@ -81,7 +84,7 @@ const BalanceDefault = forwardRef<{ refresh: () => void }, BalanceProps>(({ netw

{displayBalance} {ticker} -  {displaySubBalance !== '—' ? `$${displaySubBalance}` : ''} +  {displaySubBalance !== '—' ? formatFiatDisplay(displaySubBalance, fiat) : ''} {canBuyWithFiat ? (