diff --git a/suite-common/formatters/src/formatters/prepareCryptoAmountFormatter.ts b/suite-common/formatters/src/formatters/prepareCryptoAmountFormatter.ts index 3fa0cb4471e..0d1a06988e4 100644 --- a/suite-common/formatters/src/formatters/prepareCryptoAmountFormatter.ts +++ b/suite-common/formatters/src/formatters/prepareCryptoAmountFormatter.ts @@ -1,6 +1,6 @@ import { A } from '@mobily/ts-belt'; -import { networks, NetworkSymbol } from '@suite-common/wallet-config'; +import { getNetworkOptional, isNetworkSymbol, NetworkSymbol } from '@suite-common/wallet-config'; import { amountToSatoshi, formatAmount, @@ -39,6 +39,37 @@ const truncateDecimals = (value: string, maxDecimals: number, isEllipsisAppended // These coins will looks very bad in app because for example ETH have 18 numbers... So we hardcode enabled coins here. const COINS_WITH_SATS = ['btc', 'test'] satisfies NetworkSymbol[]; +const convertToUnit = ( + value: string, + isBalance: boolean, + config: FormatterConfig, + symbol?: string, +) => { + const { bitcoinAmountUnit } = config; + const decimals = getNetworkOptional(symbol)?.decimals ?? 0; + const areAmountUnitsSupported = A.includes(COINS_WITH_SATS, symbol); + + if (isBalance && areAmountUnitsSupported && bitcoinAmountUnit === PROTO.AmountUnit.SATOSHI) { + return amountToSatoshi(value, decimals); + } + + // if it's not balance and sats units are disabled, values other than balances are in sats so we need to convert it to BTC + if ( + !isBalance && + (bitcoinAmountUnit !== PROTO.AmountUnit.SATOSHI || !areAmountUnitsSupported) + ) { + return formatAmount(value, decimals ?? 8); + } + + return value; +}; + +const appendSymbol = (value: string, config: FormatterConfig, symbol: NetworkSymbol) => { + const NetworkSymbolFormatter = prepareNetworkSymbolFormatter(config); + + return `${value} ${NetworkSymbolFormatter.format(symbol)}`; +}; + export const prepareCryptoAmountFormatter = (config: FormatterConfig) => makeFormatter( ( @@ -52,45 +83,16 @@ export const prepareCryptoAmountFormatter = (config: FormatterConfig) => }, shouldRedactNumbers, ) => { - const { bitcoinAmountUnit } = config; - - const decimals = networks[symbol!]?.decimals || 0; - - // const areAmountUnitsSupported = A.includes(features, 'amount-unit'); - const areAmountUnitsSupported = A.includes(COINS_WITH_SATS, symbol); - - let formattedValue: string = value; - - // balances are not in sats, but already formatted to BTC so we need to convert it back to sats if needed - if ( - isBalance && - areAmountUnitsSupported && - bitcoinAmountUnit === PROTO.AmountUnit.SATOSHI - ) { - formattedValue = amountToSatoshi(value, decimals); - } - - // if it's not balance and sats units are disabled, values other than balances are in sats so we need to convert it to BTC - if ( - !isBalance && - (bitcoinAmountUnit !== PROTO.AmountUnit.SATOSHI || !areAmountUnitsSupported) - ) { - formattedValue = formatAmount(value, decimals ?? 8); - } - - if (maxDisplayedDecimals) { - formattedValue = truncateDecimals( - formattedValue, - maxDisplayedDecimals, - isEllipsisAppended, - ); - } - - if (withSymbol) { - const NetworkSymbolFormatter = prepareNetworkSymbolFormatter(config); - - formattedValue = `${formattedValue} ${NetworkSymbolFormatter.format(symbol!)}`; - } + const convertedValue = convertToUnit(value, isBalance, config, symbol); + + const truncatedValue = maxDisplayedDecimals + ? truncateDecimals(convertedValue, maxDisplayedDecimals, isEllipsisAppended) + : convertedValue; + + const formattedValue = + withSymbol && symbol && isNetworkSymbol(symbol) + ? appendSymbol(truncatedValue, config, symbol) + : truncatedValue; return shouldRedactNumbers ? redactNumericalSubstring(formattedValue) : formattedValue; }, diff --git a/suite-common/formatters/src/formatters/prepareFiatAmountFormatter.ts b/suite-common/formatters/src/formatters/prepareFiatAmountFormatter.ts index e1386d812b1..24e25fcbd31 100644 --- a/suite-common/formatters/src/formatters/prepareFiatAmountFormatter.ts +++ b/suite-common/formatters/src/formatters/prepareFiatAmountFormatter.ts @@ -10,34 +10,41 @@ export type FiatAmountFormatterDataContext = { [K in keyof T]: T[K]; }; +const handleBigNumberFormatting = ( + value: string | number, + dataContext: FiatAmountFormatterDataContext, + config: FormatterConfig, +) => { + const { intl, fiatCurrency } = config; + const { style, currency, minimumFractionDigits, maximumFractionDigits } = dataContext; + const fiatValue = new BigNumber(value); + const currencyForDisplay = currency ?? fiatCurrency; + + if (fiatValue.gt(Number.MAX_SAFE_INTEGER)) { + return `${value} ${currencyForDisplay}`; + } + + return intl.formatNumber(fiatValue.toNumber(), { + ...dataContext, + style: style || 'currency', + currency: currencyForDisplay, + minimumFractionDigits: minimumFractionDigits ?? 2, + maximumFractionDigits: maximumFractionDigits ?? 2, + }); +}; + export const prepareFiatAmountFormatter = (config: FormatterConfig) => makeFormatter< string | number, string | null, FiatAmountFormatterDataContext >((value, dataContext, shouldRedactNumbers) => { - const { intl, fiatCurrency } = config; - const { style, currency, minimumFractionDigits, maximumFractionDigits } = dataContext; const fiatValue = new BigNumber(value); - const currencyForDisplay = currency ?? fiatCurrency; - if (fiatValue.isNaN()) { return null; } - let formattedValue: string = ''; - - if (fiatValue.gt(Number.MAX_SAFE_INTEGER)) { - formattedValue = `${value} ${currencyForDisplay}`; - } else { - formattedValue = intl.formatNumber(fiatValue.toNumber(), { - ...dataContext, - style: style || 'currency', - currency: currencyForDisplay, - minimumFractionDigits: minimumFractionDigits ?? 2, - maximumFractionDigits: maximumFractionDigits ?? 2, - }); - } + const formattedValue = handleBigNumberFormatting(value, dataContext, config); return shouldRedactNumbers ? redactNumericalSubstring(formattedValue) : formattedValue; }, 'FiatAmountFormatter');