chore: only exposing useFormatter (#7308)
This commit is contained in:
parent
cf09e80934
commit
91c2013522
@ -2,6 +2,7 @@ import { TransactionStatus, useActivityQuery } from 'graphql/data/__generated__/
|
||||
import { useEffect, useMemo } from 'react'
|
||||
import { usePendingOrders } from 'state/signatures/hooks'
|
||||
import { usePendingTransactions, useTransactionCanceller } from 'state/transactions/hooks'
|
||||
import { useFormatter } from 'utils/formatNumbers'
|
||||
|
||||
import { useLocalActivities } from './parseLocal'
|
||||
import { parseRemoteActivities } from './parseRemote'
|
||||
@ -55,6 +56,7 @@ function combineActivities(localMap: ActivityMap = {}, remoteMap: ActivityMap =
|
||||
}
|
||||
|
||||
export function useAllActivities(account: string) {
|
||||
const { formatNumberOrString } = useFormatter()
|
||||
const { data, loading, refetch } = useActivityQuery({
|
||||
variables: { account },
|
||||
errorPolicy: 'all',
|
||||
@ -62,7 +64,10 @@ export function useAllActivities(account: string) {
|
||||
})
|
||||
|
||||
const localMap = useLocalActivities(account)
|
||||
const remoteMap = useMemo(() => parseRemoteActivities(data?.portfolios?.[0].assetActivities), [data?.portfolios])
|
||||
const remoteMap = useMemo(
|
||||
() => parseRemoteActivities(formatNumberOrString, data?.portfolios?.[0].assetActivities),
|
||||
[data?.portfolios, formatNumberOrString]
|
||||
)
|
||||
const updateCancelledTx = useTransactionCanceller()
|
||||
|
||||
/* Updates locally stored pendings tx's when remote data contains a conflicting cancellation tx */
|
||||
|
@ -11,6 +11,7 @@ import {
|
||||
TransactionType as MockTxType,
|
||||
} from 'state/transactions/types'
|
||||
import { renderHook } from 'test-utils/render'
|
||||
import { useFormatter } from 'utils/formatNumbers'
|
||||
|
||||
import { UniswapXOrderStatus } from '../../../../lib/hooks/orders/types'
|
||||
import { SignatureDetails, SignatureType } from '../../../../state/signatures/types'
|
||||
@ -237,6 +238,8 @@ jest.mock('../../../../state/transactions/hooks', () => {
|
||||
|
||||
describe('parseLocalActivity', () => {
|
||||
it('returns swap activity fields with known tokens, exact input', () => {
|
||||
const { formatNumber } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
const details = {
|
||||
info: mockSwapInfo(
|
||||
MockTradeType.EXACT_INPUT,
|
||||
@ -251,7 +254,7 @@ describe('parseLocalActivity', () => {
|
||||
},
|
||||
} as TransactionDetails
|
||||
const chainId = ChainId.MAINNET
|
||||
expect(transactionToActivity(details, chainId, mockTokenAddressMap)).toEqual({
|
||||
expect(transactionToActivity(details, chainId, mockTokenAddressMap, formatNumber)).toEqual({
|
||||
chainId: 1,
|
||||
currencies: [MockUSDC_MAINNET, MockDAI],
|
||||
descriptor: '1.00 USDC for 1.00 DAI',
|
||||
@ -264,6 +267,8 @@ describe('parseLocalActivity', () => {
|
||||
})
|
||||
|
||||
it('returns swap activity fields with known tokens, exact output', () => {
|
||||
const { formatNumber } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
const details = {
|
||||
info: mockSwapInfo(
|
||||
MockTradeType.EXACT_OUTPUT,
|
||||
@ -278,7 +283,7 @@ describe('parseLocalActivity', () => {
|
||||
},
|
||||
} as TransactionDetails
|
||||
const chainId = ChainId.MAINNET
|
||||
expect(transactionToActivity(details, chainId, mockTokenAddressMap)).toMatchObject({
|
||||
expect(transactionToActivity(details, chainId, mockTokenAddressMap, formatNumber)).toMatchObject({
|
||||
chainId: 1,
|
||||
currencies: [MockUSDC_MAINNET, MockDAI],
|
||||
descriptor: '1.00 USDC for 1.00 DAI',
|
||||
@ -288,6 +293,8 @@ describe('parseLocalActivity', () => {
|
||||
})
|
||||
|
||||
it('returns swap activity fields with unknown tokens', () => {
|
||||
const { formatNumber } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
const details = {
|
||||
info: mockSwapInfo(
|
||||
MockTradeType.EXACT_INPUT,
|
||||
@ -303,7 +310,7 @@ describe('parseLocalActivity', () => {
|
||||
} as TransactionDetails
|
||||
const chainId = ChainId.MAINNET
|
||||
const tokens = {} as ChainTokenMap
|
||||
expect(transactionToActivity(details, chainId, tokens)).toMatchObject({
|
||||
expect(transactionToActivity(details, chainId, tokens, formatNumber)).toMatchObject({
|
||||
chainId: 1,
|
||||
currencies: [undefined, undefined],
|
||||
descriptor: 'Unknown for Unknown',
|
||||
@ -496,13 +503,16 @@ describe('parseLocalActivity', () => {
|
||||
})
|
||||
|
||||
it('Signature to activity - returns undefined if is on chain order', () => {
|
||||
const { formatNumber } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(
|
||||
signatureToActivity(
|
||||
{
|
||||
type: SignatureType.SIGN_UNISWAPX_ORDER,
|
||||
status: UniswapXOrderStatus.FILLED,
|
||||
} as SignatureDetails,
|
||||
{}
|
||||
{},
|
||||
formatNumber
|
||||
)
|
||||
).toBeUndefined()
|
||||
|
||||
@ -512,7 +522,8 @@ describe('parseLocalActivity', () => {
|
||||
type: SignatureType.SIGN_UNISWAPX_ORDER,
|
||||
status: UniswapXOrderStatus.CANCELLED,
|
||||
} as SignatureDetails,
|
||||
{}
|
||||
{},
|
||||
formatNumber
|
||||
)
|
||||
).toBeUndefined()
|
||||
})
|
||||
|
@ -2,7 +2,6 @@ import { BigNumber } from '@ethersproject/bignumber'
|
||||
import { t } from '@lingui/macro'
|
||||
import { ChainId, Currency, CurrencyAmount, TradeType } from '@uniswap/sdk-core'
|
||||
import UniswapXBolt from 'assets/svg/bolt.svg'
|
||||
import { SupportedLocale } from 'constants/locales'
|
||||
import { nativeOnChain } from 'constants/tokens'
|
||||
import { TransactionStatus } from 'graphql/data/__generated__/types-and-hooks'
|
||||
import { ChainTokenMap, useAllTokensMultichain } from 'hooks/Tokens'
|
||||
@ -24,11 +23,13 @@ import {
|
||||
TransactionType,
|
||||
WrapTransactionInfo,
|
||||
} from 'state/transactions/types'
|
||||
import { formatCurrencyAmount, useFormatterLocales } from 'utils/formatNumbers'
|
||||
import { NumberType, useFormatter } from 'utils/formatNumbers'
|
||||
|
||||
import { CancelledTransactionTitleTable, getActivityTitle, OrderTextTable } from '../constants'
|
||||
import { Activity, ActivityMap } from './types'
|
||||
|
||||
type FormatNumberFunctionType = ReturnType<typeof useFormatter>['formatNumber']
|
||||
|
||||
function getCurrency(currencyId: string, chainId: ChainId, tokens: ChainTokenMap): Currency | undefined {
|
||||
return currencyId === 'ETH' ? nativeOnChain(chainId) : tokens[chainId]?.[currencyId]
|
||||
}
|
||||
@ -38,15 +39,21 @@ function buildCurrencyDescriptor(
|
||||
amtA: string,
|
||||
currencyB: Currency | undefined,
|
||||
amtB: string,
|
||||
delimiter = t`for`,
|
||||
locale?: SupportedLocale
|
||||
formatNumber: FormatNumberFunctionType,
|
||||
delimiter = t`for`
|
||||
) {
|
||||
const formattedA = currencyA
|
||||
? formatCurrencyAmount({ amount: CurrencyAmount.fromRawAmount(currencyA, amtA), locale })
|
||||
? formatNumber({
|
||||
input: parseFloat(CurrencyAmount.fromRawAmount(currencyA, amtA).toSignificant()),
|
||||
type: NumberType.TokenNonTx,
|
||||
})
|
||||
: t`Unknown`
|
||||
const symbolA = currencyA?.symbol ?? ''
|
||||
const formattedB = currencyB
|
||||
? formatCurrencyAmount({ amount: CurrencyAmount.fromRawAmount(currencyB, amtB), locale })
|
||||
? formatNumber({
|
||||
input: parseFloat(CurrencyAmount.fromRawAmount(currencyB, amtB).toSignificant()),
|
||||
type: NumberType.TokenNonTx,
|
||||
})
|
||||
: t`Unknown`
|
||||
const symbolB = currencyB?.symbol ?? ''
|
||||
return [formattedA, symbolA, delimiter, formattedB, symbolB].filter(Boolean).join(' ')
|
||||
@ -56,7 +63,7 @@ function parseSwap(
|
||||
swap: ExactInputSwapTransactionInfo | ExactOutputSwapTransactionInfo,
|
||||
chainId: ChainId,
|
||||
tokens: ChainTokenMap,
|
||||
locale?: SupportedLocale
|
||||
formatNumber: FormatNumberFunctionType
|
||||
): Partial<Activity> {
|
||||
const tokenIn = getCurrency(swap.inputCurrencyId, chainId, tokens)
|
||||
const tokenOut = getCurrency(swap.outputCurrencyId, chainId, tokens)
|
||||
@ -66,18 +73,29 @@ function parseSwap(
|
||||
: [swap.expectedInputCurrencyAmountRaw, swap.outputCurrencyAmountRaw]
|
||||
|
||||
return {
|
||||
descriptor: buildCurrencyDescriptor(tokenIn, inputRaw, tokenOut, outputRaw, undefined, locale),
|
||||
descriptor: buildCurrencyDescriptor(tokenIn, inputRaw, tokenOut, outputRaw, formatNumber, undefined),
|
||||
currencies: [tokenIn, tokenOut],
|
||||
prefixIconSrc: swap.isUniswapXOrder ? UniswapXBolt : undefined,
|
||||
}
|
||||
}
|
||||
|
||||
function parseWrap(wrap: WrapTransactionInfo, chainId: ChainId, status: TransactionStatus): Partial<Activity> {
|
||||
function parseWrap(
|
||||
wrap: WrapTransactionInfo,
|
||||
chainId: ChainId,
|
||||
status: TransactionStatus,
|
||||
formatNumber: FormatNumberFunctionType
|
||||
): Partial<Activity> {
|
||||
const native = nativeOnChain(chainId)
|
||||
const wrapped = native.wrapped
|
||||
const [input, output] = wrap.unwrapped ? [wrapped, native] : [native, wrapped]
|
||||
|
||||
const descriptor = buildCurrencyDescriptor(input, wrap.currencyAmountRaw, output, wrap.currencyAmountRaw)
|
||||
const descriptor = buildCurrencyDescriptor(
|
||||
input,
|
||||
wrap.currencyAmountRaw,
|
||||
output,
|
||||
wrap.currencyAmountRaw,
|
||||
formatNumber
|
||||
)
|
||||
const title = getActivityTitle(TransactionType.WRAP, status, wrap.unwrapped)
|
||||
const currencies = wrap.unwrapped ? [wrapped, native] : [native, wrapped]
|
||||
|
||||
@ -107,11 +125,16 @@ type GenericLPInfo = Omit<
|
||||
AddLiquidityV3PoolTransactionInfo | RemoveLiquidityV3TransactionInfo | AddLiquidityV2PoolTransactionInfo,
|
||||
'type'
|
||||
>
|
||||
function parseLP(lp: GenericLPInfo, chainId: ChainId, tokens: ChainTokenMap): Partial<Activity> {
|
||||
function parseLP(
|
||||
lp: GenericLPInfo,
|
||||
chainId: ChainId,
|
||||
tokens: ChainTokenMap,
|
||||
formatNumber: FormatNumberFunctionType
|
||||
): Partial<Activity> {
|
||||
const baseCurrency = getCurrency(lp.baseCurrencyId, chainId, tokens)
|
||||
const quoteCurrency = getCurrency(lp.quoteCurrencyId, chainId, tokens)
|
||||
const [baseRaw, quoteRaw] = [lp.expectedAmountBaseRaw, lp.expectedAmountQuoteRaw]
|
||||
const descriptor = buildCurrencyDescriptor(baseCurrency, baseRaw, quoteCurrency, quoteRaw, t`and`)
|
||||
const descriptor = buildCurrencyDescriptor(baseCurrency, baseRaw, quoteCurrency, quoteRaw, formatNumber, t`and`)
|
||||
|
||||
return { descriptor, currencies: [baseCurrency, quoteCurrency] }
|
||||
}
|
||||
@ -119,7 +142,8 @@ function parseLP(lp: GenericLPInfo, chainId: ChainId, tokens: ChainTokenMap): Pa
|
||||
function parseCollectFees(
|
||||
collect: CollectFeesTransactionInfo,
|
||||
chainId: ChainId,
|
||||
tokens: ChainTokenMap
|
||||
tokens: ChainTokenMap,
|
||||
formatNumber: FormatNumberFunctionType
|
||||
): Partial<Activity> {
|
||||
// Adapts CollectFeesTransactionInfo to generic LP type
|
||||
const {
|
||||
@ -128,7 +152,12 @@ function parseCollectFees(
|
||||
expectedCurrencyOwed0: expectedAmountBaseRaw,
|
||||
expectedCurrencyOwed1: expectedAmountQuoteRaw,
|
||||
} = collect
|
||||
return parseLP({ baseCurrencyId, quoteCurrencyId, expectedAmountBaseRaw, expectedAmountQuoteRaw }, chainId, tokens)
|
||||
return parseLP(
|
||||
{ baseCurrencyId, quoteCurrencyId, expectedAmountBaseRaw, expectedAmountQuoteRaw },
|
||||
chainId,
|
||||
tokens,
|
||||
formatNumber
|
||||
)
|
||||
}
|
||||
|
||||
function parseMigrateCreateV3(
|
||||
@ -157,7 +186,7 @@ export function transactionToActivity(
|
||||
details: TransactionDetails,
|
||||
chainId: ChainId,
|
||||
tokens: ChainTokenMap,
|
||||
locale?: SupportedLocale
|
||||
formatNumber: FormatNumberFunctionType
|
||||
): Activity | undefined {
|
||||
try {
|
||||
const status = getTransactionStatus(details)
|
||||
@ -176,19 +205,19 @@ export function transactionToActivity(
|
||||
let additionalFields: Partial<Activity> = {}
|
||||
const info = details.info
|
||||
if (info.type === TransactionType.SWAP) {
|
||||
additionalFields = parseSwap(info, chainId, tokens, locale)
|
||||
additionalFields = parseSwap(info, chainId, tokens, formatNumber)
|
||||
} else if (info.type === TransactionType.APPROVAL) {
|
||||
additionalFields = parseApproval(info, chainId, tokens, status)
|
||||
} else if (info.type === TransactionType.WRAP) {
|
||||
additionalFields = parseWrap(info, chainId, status)
|
||||
additionalFields = parseWrap(info, chainId, status, formatNumber)
|
||||
} else if (
|
||||
info.type === TransactionType.ADD_LIQUIDITY_V3_POOL ||
|
||||
info.type === TransactionType.REMOVE_LIQUIDITY_V3 ||
|
||||
info.type === TransactionType.ADD_LIQUIDITY_V2_POOL
|
||||
) {
|
||||
additionalFields = parseLP(info, chainId, tokens)
|
||||
additionalFields = parseLP(info, chainId, tokens, formatNumber)
|
||||
} else if (info.type === TransactionType.COLLECT_FEES) {
|
||||
additionalFields = parseCollectFees(info, chainId, tokens)
|
||||
additionalFields = parseCollectFees(info, chainId, tokens, formatNumber)
|
||||
} else if (info.type === TransactionType.MIGRATE_LIQUIDITY_V3 || info.type === TransactionType.CREATE_V3_POOL) {
|
||||
additionalFields = parseMigrateCreateV3(info, chainId, tokens)
|
||||
}
|
||||
@ -210,7 +239,7 @@ export function transactionToActivity(
|
||||
export function signatureToActivity(
|
||||
signature: SignatureDetails,
|
||||
tokens: ChainTokenMap,
|
||||
locale?: SupportedLocale
|
||||
formatNumber: FormatNumberFunctionType
|
||||
): Activity | undefined {
|
||||
switch (signature.type) {
|
||||
case SignatureType.SIGN_UNISWAPX_ORDER: {
|
||||
@ -229,7 +258,7 @@ export function signatureToActivity(
|
||||
from: signature.offerer,
|
||||
statusMessage,
|
||||
prefixIconSrc: UniswapXBolt,
|
||||
...parseSwap(signature.swapInfo, signature.chainId, tokens, locale),
|
||||
...parseSwap(signature.swapInfo, signature.chainId, tokens, formatNumber),
|
||||
}
|
||||
}
|
||||
default:
|
||||
@ -241,24 +270,24 @@ export function useLocalActivities(account: string): ActivityMap {
|
||||
const allTransactions = useMultichainTransactions()
|
||||
const allSignatures = useAllSignatures()
|
||||
const tokens = useAllTokensMultichain()
|
||||
const { formatterLocale } = useFormatterLocales()
|
||||
const { formatNumber } = useFormatter()
|
||||
|
||||
return useMemo(() => {
|
||||
const activityMap: ActivityMap = {}
|
||||
for (const [transaction, chainId] of allTransactions) {
|
||||
if (transaction.from !== account) continue
|
||||
|
||||
const activity = transactionToActivity(transaction, chainId, tokens, formatterLocale)
|
||||
const activity = transactionToActivity(transaction, chainId, tokens, formatNumber)
|
||||
if (activity) activityMap[transaction.hash] = activity
|
||||
}
|
||||
|
||||
for (const signature of Object.values(allSignatures)) {
|
||||
if (signature.offerer !== account) continue
|
||||
|
||||
const activity = signatureToActivity(signature, tokens, formatterLocale)
|
||||
const activity = signatureToActivity(signature, tokens, formatNumber)
|
||||
if (activity) activityMap[signature.id] = activity
|
||||
}
|
||||
|
||||
return activityMap
|
||||
}, [account, allSignatures, allTransactions, formatterLocale, tokens])
|
||||
}, [account, allSignatures, allTransactions, formatNumber, tokens])
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ import { gqlToCurrency, logSentryErrorForUnsupportedChain, supportedChainIdFromG
|
||||
import ms from 'ms'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { isAddress } from 'utils'
|
||||
import { formatFiatPrice, formatNumberOrString, NumberType } from 'utils/formatNumbers'
|
||||
import { NumberType, useFormatter } from 'utils/formatNumbers'
|
||||
|
||||
import { MOONPAY_SENDER_ADDRESSES, OrderStatusTable, OrderTextTable } from '../constants'
|
||||
import { Activity } from './types'
|
||||
@ -34,6 +34,8 @@ type TransactionChanges = {
|
||||
NftApproveForAll: NftApproveForAllPartsFragment[]
|
||||
}
|
||||
|
||||
type FormatNumberOrStringFunctionType = ReturnType<typeof useFormatter>['formatNumberOrString']
|
||||
|
||||
// TODO: Move common contract metadata to a backend service
|
||||
const UNI_IMG =
|
||||
'https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984/logo.png'
|
||||
@ -140,13 +142,13 @@ function getSwapDescriptor({
|
||||
* @param transactedValue Transacted value amount from TokenTransfer API response
|
||||
* @returns parsed & formatted USD value as a string if currency is of type USD
|
||||
*/
|
||||
function formatTransactedValue(transactedValue: TokenTransferPartsFragment['transactedValue']): string {
|
||||
if (!transactedValue) return '-'
|
||||
function getTransactedValue(transactedValue: TokenTransferPartsFragment['transactedValue']): number | undefined {
|
||||
if (!transactedValue) return undefined
|
||||
const price = transactedValue?.currency === GQLCurrency.Usd ? transactedValue.value ?? undefined : undefined
|
||||
return formatFiatPrice(price)
|
||||
return price
|
||||
}
|
||||
|
||||
function parseSwap(changes: TransactionChanges) {
|
||||
function parseSwap(changes: TransactionChanges, formatNumberOrString: FormatNumberOrStringFunctionType) {
|
||||
if (changes.NftTransfer.length > 0 && changes.TokenTransfer.length === 1) {
|
||||
const collectionCounts = getCollectionCounts(changes.NftTransfer)
|
||||
|
||||
@ -168,8 +170,8 @@ function parseSwap(changes: TransactionChanges) {
|
||||
|
||||
if (sent && received) {
|
||||
const adjustedInput = parseFloat(sent.quantity) - parseFloat(refund?.quantity ?? '0')
|
||||
const inputAmount = formatNumberOrString(adjustedInput, NumberType.TokenNonTx)
|
||||
const outputAmount = formatNumberOrString(received.quantity, NumberType.TokenNonTx)
|
||||
const inputAmount = formatNumberOrString({ input: adjustedInput, type: NumberType.TokenNonTx })
|
||||
const outputAmount = formatNumberOrString({ input: received.quantity, type: NumberType.TokenNonTx })
|
||||
return {
|
||||
title: getSwapTitle(sent, received),
|
||||
descriptor: getSwapDescriptor({ tokenIn: sent.asset, inputAmount, tokenOut: received.asset, outputAmount }),
|
||||
@ -180,8 +182,8 @@ function parseSwap(changes: TransactionChanges) {
|
||||
return { title: t`Unknown Swap` }
|
||||
}
|
||||
|
||||
function parseSwapOrder(changes: TransactionChanges) {
|
||||
return { ...parseSwap(changes), prefixIconSrc: UniswapXBolt }
|
||||
function parseSwapOrder(changes: TransactionChanges, formatNumberOrString: FormatNumberOrStringFunctionType) {
|
||||
return { ...parseSwap(changes, formatNumberOrString), prefixIconSrc: UniswapXBolt }
|
||||
}
|
||||
|
||||
function parseApprove(changes: TransactionChanges) {
|
||||
@ -194,12 +196,12 @@ function parseApprove(changes: TransactionChanges) {
|
||||
return { title: t`Unknown Approval` }
|
||||
}
|
||||
|
||||
function parseLPTransfers(changes: TransactionChanges) {
|
||||
function parseLPTransfers(changes: TransactionChanges, formatNumberOrString: FormatNumberOrStringFunctionType) {
|
||||
const poolTokenA = changes.TokenTransfer[0]
|
||||
const poolTokenB = changes.TokenTransfer[1]
|
||||
|
||||
const tokenAQuanitity = formatNumberOrString(poolTokenA.quantity, NumberType.TokenNonTx)
|
||||
const tokenBQuantity = formatNumberOrString(poolTokenB.quantity, NumberType.TokenNonTx)
|
||||
const tokenAQuanitity = formatNumberOrString({ input: poolTokenA.quantity, type: NumberType.TokenNonTx })
|
||||
const tokenBQuantity = formatNumberOrString({ input: poolTokenB.quantity, type: NumberType.TokenNonTx })
|
||||
|
||||
return {
|
||||
descriptor: `${tokenAQuanitity} ${poolTokenA.asset.symbol} and ${tokenBQuantity} ${poolTokenB.asset.symbol}`,
|
||||
@ -211,11 +213,15 @@ function parseLPTransfers(changes: TransactionChanges) {
|
||||
type TransactionActivity = AssetActivityPartsFragment & { details: TransactionDetailsPartsFragment }
|
||||
type OrderActivity = AssetActivityPartsFragment & { details: SwapOrderDetailsPartsFragment }
|
||||
|
||||
function parseSendReceive(changes: TransactionChanges, assetActivity: TransactionActivity) {
|
||||
function parseSendReceive(
|
||||
changes: TransactionChanges,
|
||||
formatNumberOrString: FormatNumberOrStringFunctionType,
|
||||
assetActivity: TransactionActivity
|
||||
) {
|
||||
// TODO(cartcrom): remove edge cases after backend implements
|
||||
// Edge case: Receiving two token transfers in interaction w/ V3 manager === removing liquidity. These edge cases should potentially be moved to backend
|
||||
if (changes.TokenTransfer.length === 2 && callsPositionManagerContract(assetActivity)) {
|
||||
return { title: t`Removed Liquidity`, ...parseLPTransfers(changes) }
|
||||
return { title: t`Removed Liquidity`, ...parseLPTransfers(changes, formatNumberOrString) }
|
||||
}
|
||||
|
||||
let transfer: NftTransferPartsFragment | TokenTransferPartsFragment | undefined
|
||||
@ -230,7 +236,7 @@ function parseSendReceive(changes: TransactionChanges, assetActivity: Transactio
|
||||
} else if (changes.TokenTransfer.length === 1) {
|
||||
transfer = changes.TokenTransfer[0]
|
||||
assetName = transfer.asset.symbol
|
||||
amount = formatNumberOrString(transfer.quantity, NumberType.TokenNonTx)
|
||||
amount = formatNumberOrString({ input: transfer.quantity, type: NumberType.TokenNonTx })
|
||||
currencies = [gqlToCurrency(transfer.asset)]
|
||||
}
|
||||
|
||||
@ -241,7 +247,10 @@ function parseSendReceive(changes: TransactionChanges, assetActivity: Transactio
|
||||
return isMoonpayPurchase && transfer.__typename === 'TokenTransfer'
|
||||
? {
|
||||
title: t`Purchased`,
|
||||
descriptor: `${amount} ${assetName} ${t`for`} ${formatTransactedValue(transfer.transactedValue)}`,
|
||||
descriptor: `${amount} ${assetName} ${t`for`} ${formatNumberOrString({
|
||||
input: getTransactedValue(transfer.transactedValue),
|
||||
type: NumberType.FiatTokenPrice,
|
||||
})}`,
|
||||
logos: [moonpayLogoSrc],
|
||||
currencies,
|
||||
}
|
||||
@ -263,25 +272,37 @@ function parseSendReceive(changes: TransactionChanges, assetActivity: Transactio
|
||||
return { title: t`Unknown Send` }
|
||||
}
|
||||
|
||||
function parseMint(changes: TransactionChanges, assetActivity: TransactionActivity) {
|
||||
function parseMint(
|
||||
changes: TransactionChanges,
|
||||
formatNumberOrString: FormatNumberOrStringFunctionType,
|
||||
assetActivity: TransactionActivity
|
||||
) {
|
||||
const collectionMap = getCollectionCounts(changes.NftTransfer)
|
||||
if (Object.keys(collectionMap).length === 1) {
|
||||
const collectionName = Object.keys(collectionMap)[0]
|
||||
|
||||
// Edge case: Minting a v3 positon represents adding liquidity
|
||||
if (changes.TokenTransfer.length === 2 && callsPositionManagerContract(assetActivity)) {
|
||||
return { title: t`Added Liquidity`, ...parseLPTransfers(changes) }
|
||||
return { title: t`Added Liquidity`, ...parseLPTransfers(changes, formatNumberOrString) }
|
||||
}
|
||||
return { title: t`Minted`, descriptor: `${collectionMap[collectionName]} ${collectionName}` }
|
||||
}
|
||||
return { title: t`Unknown Mint` }
|
||||
}
|
||||
|
||||
function parseUnknown(_changes: TransactionChanges, assetActivity: TransactionActivity) {
|
||||
function parseUnknown(
|
||||
_changes: TransactionChanges,
|
||||
_formatNumberOrString: FormatNumberOrStringFunctionType,
|
||||
assetActivity: TransactionActivity
|
||||
) {
|
||||
return { title: t`Contract Interaction`, ...COMMON_CONTRACTS[assetActivity.details.to.toLowerCase()] }
|
||||
}
|
||||
|
||||
type ActivityTypeParser = (changes: TransactionChanges, assetActivity: TransactionActivity) => Partial<Activity>
|
||||
type ActivityTypeParser = (
|
||||
changes: TransactionChanges,
|
||||
formatNumberOrString: FormatNumberOrStringFunctionType,
|
||||
assetActivity: TransactionActivity
|
||||
) => Partial<Activity>
|
||||
const ActivityParserByType: { [key: string]: ActivityTypeParser | undefined } = {
|
||||
[ActivityType.Swap]: parseSwap,
|
||||
[ActivityType.SwapOrder]: parseSwapOrder,
|
||||
@ -345,7 +366,10 @@ function parseUniswapXOrder({ details, chain, timestamp }: OrderActivity): Activ
|
||||
}
|
||||
}
|
||||
|
||||
function parseRemoteActivity(assetActivity: AssetActivityPartsFragment): Activity | undefined {
|
||||
function parseRemoteActivity(
|
||||
assetActivity: AssetActivityPartsFragment,
|
||||
formatNumberOrString: FormatNumberOrStringFunctionType
|
||||
): Activity | undefined {
|
||||
try {
|
||||
if (assetActivity.details.__typename === 'SwapOrderDetails') {
|
||||
return parseUniswapXOrder(assetActivity as OrderActivity)
|
||||
@ -385,6 +409,7 @@ function parseRemoteActivity(assetActivity: AssetActivityPartsFragment): Activit
|
||||
|
||||
const parsedFields = ActivityParserByType[assetActivity.details.type]?.(
|
||||
changes,
|
||||
formatNumberOrString,
|
||||
assetActivity as TransactionActivity
|
||||
)
|
||||
return { ...defaultFields, ...parsedFields }
|
||||
@ -394,9 +419,12 @@ function parseRemoteActivity(assetActivity: AssetActivityPartsFragment): Activit
|
||||
}
|
||||
}
|
||||
|
||||
export function parseRemoteActivities(assetActivities?: readonly AssetActivityPartsFragment[]) {
|
||||
export function parseRemoteActivities(
|
||||
formatNumberOrString: FormatNumberOrStringFunctionType,
|
||||
assetActivities?: readonly AssetActivityPartsFragment[]
|
||||
) {
|
||||
return assetActivities?.reduce((acc: { [hash: string]: Activity }, assetActivity) => {
|
||||
const activity = parseRemoteActivity(assetActivity)
|
||||
const activity = parseRemoteActivity(assetActivity, formatNumberOrString)
|
||||
if (activity) acc[activity.hash] = activity
|
||||
return acc
|
||||
}, {})
|
||||
|
@ -18,7 +18,7 @@ import { useCallback, useEffect, useState } from 'react'
|
||||
import { Link, useNavigate } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
import { ThemedText } from 'theme'
|
||||
import { formatUSDPrice } from 'utils/formatNumbers'
|
||||
import { useFormatter } from 'utils/formatNumbers'
|
||||
|
||||
import { DeltaArrow, DeltaText } from '../Tokens/TokenDetails/Delta'
|
||||
import { useAddRecentlySearchedAsset } from './RecentlySearchedAssets'
|
||||
@ -128,6 +128,7 @@ interface TokenRowProps {
|
||||
export const TokenRow = ({ token, isHovered, setHoveredIndex, toggleOpen, index, eventProperties }: TokenRowProps) => {
|
||||
const addRecentlySearchedAsset = useAddRecentlySearchedAsset()
|
||||
const navigate = useNavigate()
|
||||
const { formatFiatPrice } = useFormatter()
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
const address = !token.address && token.standard === TokenStandard.Native ? 'NATIVE' : token.address
|
||||
@ -184,7 +185,7 @@ export const TokenRow = ({ token, isHovered, setHoveredIndex, toggleOpen, index,
|
||||
{!!token.market?.price?.value && (
|
||||
<>
|
||||
<Row gap="4">
|
||||
<Box className={styles.primaryText}>{formatUSDPrice(token.market.price.value)}</Box>
|
||||
<Box className={styles.primaryText}>{formatFiatPrice({ price: token.market.price.value })}</Box>
|
||||
</Row>
|
||||
<PriceChangeContainer>
|
||||
<DeltaArrow delta={token.market?.pricePercentChange?.value} />
|
||||
|
@ -17,6 +17,7 @@ import { useOrder } from 'state/signatures/hooks'
|
||||
import { useTransaction } from 'state/transactions/hooks'
|
||||
import styled from 'styled-components'
|
||||
import { EllipsisStyle, ThemedText } from 'theme'
|
||||
import { useFormatter } from 'utils/formatNumbers'
|
||||
import { ExplorerDataType, getExplorerLink } from 'utils/getExplorerLink'
|
||||
|
||||
const StyledClose = styled(X)<{ $padding: number }>`
|
||||
@ -137,9 +138,10 @@ export function TransactionPopupContent({
|
||||
}) {
|
||||
const transaction = useTransaction(hash)
|
||||
const tokens = useAllTokensMultichain()
|
||||
const { formatNumber } = useFormatter()
|
||||
if (!transaction) return null
|
||||
|
||||
const activity = transactionToActivity(transaction, chainId, tokens)
|
||||
const activity = transactionToActivity(transaction, chainId, tokens, formatNumber)
|
||||
|
||||
if (!activity) return null
|
||||
|
||||
@ -153,9 +155,10 @@ export function UniswapXOrderPopupContent({ orderHash, onClose }: { orderHash: s
|
||||
const order = useOrder(orderHash)
|
||||
const tokens = useAllTokensMultichain()
|
||||
const openOffchainActivityModal = useOpenOffchainActivityModal()
|
||||
const { formatNumber } = useFormatter()
|
||||
if (!order) return null
|
||||
|
||||
const activity = signatureToActivity(order, tokens)
|
||||
const activity = signatureToActivity(order, tokens, formatNumber)
|
||||
|
||||
if (!activity) return null
|
||||
|
||||
|
@ -15,7 +15,7 @@ import { Link } from 'react-router-dom'
|
||||
import { Bound } from 'state/mint/v3/actions'
|
||||
import styled from 'styled-components'
|
||||
import { HideSmall, MEDIA_WIDTHS, SmallOnly, ThemedText } from 'theme'
|
||||
import { formatTickPrice } from 'utils/formatTickPrice'
|
||||
import { useFormatter } from 'utils/formatNumbers'
|
||||
import { unwrappedToken } from 'utils/unwrappedToken'
|
||||
|
||||
import { DAI, USDC_MAINNET, USDT, WBTC, WRAPPED_NATIVE_CURRENCY } from '../../constants/tokens'
|
||||
@ -172,6 +172,8 @@ export default function PositionListItem({
|
||||
tickLower,
|
||||
tickUpper,
|
||||
}: PositionListItemProps) {
|
||||
const { formatTickPrice } = useFormatter()
|
||||
|
||||
const token0 = useToken(token0Address)
|
||||
const token1 = useToken(token1Address)
|
||||
|
||||
|
@ -14,7 +14,7 @@ import { ReactNode, useCallback, useState } from 'react'
|
||||
import { Bound } from 'state/mint/v3/actions'
|
||||
import { useTheme } from 'styled-components'
|
||||
import { ThemedText } from 'theme'
|
||||
import { formatTickPrice } from 'utils/formatTickPrice'
|
||||
import { useFormatter } from 'utils/formatNumbers'
|
||||
import { unwrappedToken } from 'utils/unwrappedToken'
|
||||
|
||||
export const PositionPreview = ({
|
||||
@ -31,6 +31,7 @@ export const PositionPreview = ({
|
||||
ticksAtLimit: { [bound: string]: boolean | undefined }
|
||||
}) => {
|
||||
const theme = useTheme()
|
||||
const { formatTickPrice } = useFormatter()
|
||||
|
||||
const currency0 = unwrappedToken(position.pool.token0)
|
||||
const currency1 = unwrappedToken(position.pool.token1)
|
||||
|
@ -17,7 +17,7 @@ import { Info, TrendingUp } from 'react-feather'
|
||||
import styled, { useTheme } from 'styled-components'
|
||||
import { ThemedText } from 'theme'
|
||||
import { textFadeIn } from 'theme/styles'
|
||||
import { formatUSDPrice } from 'utils/formatNumbers'
|
||||
import { useFormatter } from 'utils/formatNumbers'
|
||||
|
||||
import { calculateDelta, DeltaArrow, formatDelta } from './Delta'
|
||||
|
||||
@ -87,6 +87,7 @@ interface PriceChartProps {
|
||||
export function PriceChart({ width, height, prices: originalPrices, timePeriod }: PriceChartProps) {
|
||||
const locale = useActiveLocale()
|
||||
const theme = useTheme()
|
||||
const { formatFiatPrice } = useFormatter()
|
||||
|
||||
const { prices, blanks } = useMemo(
|
||||
() =>
|
||||
@ -208,13 +209,13 @@ export function PriceChart({ width, height, prices: originalPrices, timePeriod }
|
||||
<ChartHeader data-cy="chart-header">
|
||||
{displayPrice.value ? (
|
||||
<>
|
||||
<TokenPrice>{formatUSDPrice(displayPrice.value)}</TokenPrice>
|
||||
<TokenPrice>{formatFiatPrice({ price: displayPrice.value })}</TokenPrice>
|
||||
<ChartDelta startingPrice={startingPrice} endingPrice={displayPrice} />
|
||||
</>
|
||||
) : lastPrice.value ? (
|
||||
<OutdatedContainer>
|
||||
<OutdatedPriceContainer>
|
||||
<TokenPrice>{formatUSDPrice(lastPrice.value)}</TokenPrice>
|
||||
<TokenPrice>{formatFiatPrice({ price: lastPrice.value })}</TokenPrice>
|
||||
<MouseoverTooltip text={tooltipMessage}>
|
||||
<Info size={16} />
|
||||
</MouseoverTooltip>
|
||||
|
@ -16,7 +16,7 @@ import { CSSProperties, ReactNode } from 'react'
|
||||
import { Link, useParams } from 'react-router-dom'
|
||||
import styled, { css, useTheme } from 'styled-components'
|
||||
import { BREAKPOINTS, ClickableStyle } from 'theme'
|
||||
import { formatUSDPrice, NumberType, useFormatter } from 'utils/formatNumbers'
|
||||
import { NumberType, useFormatter } from 'utils/formatNumbers'
|
||||
|
||||
import {
|
||||
LARGE_MEDIA_BREAKPOINT,
|
||||
@ -440,7 +440,7 @@ interface LoadedRowProps {
|
||||
|
||||
/* Loaded State: row component with token information */
|
||||
export const LoadedRow = forwardRef((props: LoadedRowProps, ref: ForwardedRef<HTMLDivElement>) => {
|
||||
const { formatNumber } = useFormatter()
|
||||
const { formatFiatPrice, formatNumber } = useFormatter()
|
||||
|
||||
const { tokenListIndex, tokenListLength, token, sortRank } = props
|
||||
const filterString = useAtomValue(filterStringAtom)
|
||||
@ -463,7 +463,7 @@ export const LoadedRow = forwardRef((props: LoadedRowProps, ref: ForwardedRef<HT
|
||||
}
|
||||
|
||||
// A simple 0 price indicates the price is not currently available from the api
|
||||
const price = token.market?.price?.value === 0 ? '-' : formatUSDPrice(token.market?.price?.value)
|
||||
const price = token.market?.price?.value === 0 ? '-' : formatFiatPrice({ price: token.market?.price?.value })
|
||||
|
||||
// TODO: currency logo sizing mobile (32px) vs. desktop (24px)
|
||||
return (
|
||||
|
@ -17,7 +17,6 @@ import { useRouterPreference, useUserSlippageTolerance } from 'state/user/hooks'
|
||||
import styled, { DefaultTheme, useTheme } from 'styled-components'
|
||||
import { ExternalLink, ThemedText } from 'theme'
|
||||
import { FormatterRule, NumberType, SIX_SIG_FIGS_NO_COMMAS, useFormatter } from 'utils/formatNumbers'
|
||||
import { priceToPreciseFloat } from 'utils/formatNumbers'
|
||||
import getRoutingDiagramEntries from 'utils/getRoutingDiagramEntries'
|
||||
import { formatSwapButtonClickEventProperties } from 'utils/loggingFormatters'
|
||||
import { getPriceImpactColor } from 'utils/prices'
|
||||
@ -85,7 +84,7 @@ export default function SwapModalFooter({
|
||||
const label = `${trade.executionPrice.baseCurrency?.symbol} `
|
||||
const labelInverted = `${trade.executionPrice.quoteCurrency?.symbol}`
|
||||
const formattedPrice = formatNumber({
|
||||
input: priceToPreciseFloat(trade.executionPrice),
|
||||
input: trade.executionPrice ? parseFloat(trade.executionPrice.toFixed(9)) : undefined,
|
||||
type: NumberType.TokenTx,
|
||||
})
|
||||
const txCount = getTransactionCount(trade)
|
||||
|
@ -6,7 +6,6 @@ import {
|
||||
TEST_TRADE_EXACT_OUTPUT,
|
||||
} from 'test-utils/constants'
|
||||
import { render, screen } from 'test-utils/render'
|
||||
import { formatCurrencyAmount, NumberType } from 'utils/formatNumbers'
|
||||
|
||||
import SwapModalHeader from './SwapModalHeader'
|
||||
|
||||
@ -17,16 +16,8 @@ describe('SwapModalHeader.tsx', () => {
|
||||
)
|
||||
expect(asFragment()).toMatchSnapshot()
|
||||
expect(screen.getByText(/Output is estimated. You will receive at least /i)).toBeInTheDocument()
|
||||
expect(screen.getByTestId('INPUT-amount')).toHaveTextContent(
|
||||
`${formatCurrencyAmount({ amount: TEST_TRADE_EXACT_INPUT.inputAmount, type: NumberType.TokenTx })} ${
|
||||
TEST_TRADE_EXACT_INPUT.inputAmount.currency.symbol ?? ''
|
||||
}`
|
||||
)
|
||||
expect(screen.getByTestId('OUTPUT-amount')).toHaveTextContent(
|
||||
`${formatCurrencyAmount({ amount: TEST_TRADE_EXACT_INPUT.outputAmount, type: NumberType.TokenTx })} ${
|
||||
TEST_TRADE_EXACT_INPUT.outputAmount.currency.symbol ?? ''
|
||||
}`
|
||||
)
|
||||
expect(screen.getByTestId('INPUT-amount')).toHaveTextContent(`<0.00001 ABC`)
|
||||
expect(screen.getByTestId('OUTPUT-amount')).toHaveTextContent(`<0.00001 DEF`)
|
||||
})
|
||||
|
||||
it('renders ETH input token for an ETH input UniswapX swap', () => {
|
||||
@ -39,16 +30,8 @@ describe('SwapModalHeader.tsx', () => {
|
||||
)
|
||||
expect(asFragment()).toMatchSnapshot()
|
||||
expect(screen.getByText(/Output is estimated. You will receive at least /i)).toBeInTheDocument()
|
||||
expect(screen.getByTestId('INPUT-amount')).toHaveTextContent(
|
||||
`${formatCurrencyAmount({ amount: TEST_DUTCH_TRADE_ETH_INPUT.inputAmount, type: NumberType.TokenTx })} ${
|
||||
ETH_MAINNET.symbol
|
||||
}`
|
||||
)
|
||||
expect(screen.getByTestId('OUTPUT-amount')).toHaveTextContent(
|
||||
`${formatCurrencyAmount({ amount: TEST_DUTCH_TRADE_ETH_INPUT.outputAmount, type: NumberType.TokenTx })} ${
|
||||
TEST_DUTCH_TRADE_ETH_INPUT.outputAmount.currency.symbol ?? ''
|
||||
}`
|
||||
)
|
||||
expect(screen.getByTestId('INPUT-amount')).toHaveTextContent(`<0.00001 ETH`)
|
||||
expect(screen.getByTestId('OUTPUT-amount')).toHaveTextContent(`<0.00001 DEF`)
|
||||
})
|
||||
|
||||
it('test trade exact output, no recipient', () => {
|
||||
@ -58,15 +41,7 @@ describe('SwapModalHeader.tsx', () => {
|
||||
expect(asFragment()).toMatchSnapshot()
|
||||
expect(screen.getByText(/Input is estimated. You will sell at most/i)).toBeInTheDocument()
|
||||
|
||||
expect(screen.getByTestId('INPUT-amount')).toHaveTextContent(
|
||||
`${formatCurrencyAmount({ amount: TEST_TRADE_EXACT_OUTPUT.inputAmount, type: NumberType.TokenTx })} ${
|
||||
TEST_TRADE_EXACT_OUTPUT.inputAmount.currency.symbol ?? ''
|
||||
}`
|
||||
)
|
||||
expect(screen.getByTestId('OUTPUT-amount')).toHaveTextContent(
|
||||
`${formatCurrencyAmount({ amount: TEST_TRADE_EXACT_OUTPUT.outputAmount, type: NumberType.TokenTx })} ${
|
||||
TEST_TRADE_EXACT_OUTPUT.outputAmount.currency.symbol ?? ''
|
||||
}`
|
||||
)
|
||||
expect(screen.getByTestId('INPUT-amount')).toHaveTextContent(`<0.00001 ABC`)
|
||||
expect(screen.getByTestId('OUTPUT-amount')).toHaveTextContent(`<0.00001 GHI`)
|
||||
})
|
||||
})
|
||||
|
@ -6,7 +6,7 @@ import { Markets, TrendingCollection } from 'nft/types'
|
||||
import { ethNumberStandardFormatter } from 'nft/utils'
|
||||
import styled from 'styled-components'
|
||||
import { ThemedText } from 'theme/components/text'
|
||||
import { formatNumberOrString, NumberType } from 'utils/formatNumbers'
|
||||
import { NumberType, useFormatter } from 'utils/formatNumbers'
|
||||
|
||||
const CarouselCardBorder = styled.div`
|
||||
width: 100%;
|
||||
@ -198,6 +198,8 @@ interface MarketplaceRowProps {
|
||||
}
|
||||
|
||||
const MarketplaceRow = ({ marketplace, floorInEth, listings }: MarketplaceRowProps) => {
|
||||
const { formatNumberOrString } = useFormatter()
|
||||
|
||||
return (
|
||||
<>
|
||||
<TableElement>
|
||||
@ -212,7 +214,7 @@ const MarketplaceRow = ({ marketplace, floorInEth, listings }: MarketplaceRowPro
|
||||
<TableElement>
|
||||
<ThemedText.BodySmall color="neutral2">
|
||||
{Number(floorInEth) > 0
|
||||
? `${formatNumberOrString(floorInEth, NumberType.NFTTokenFloorPriceTrailingZeros)} ETH`
|
||||
? `${formatNumberOrString({ input: floorInEth, type: NumberType.NFTTokenFloorPriceTrailingZeros })} ETH`
|
||||
: '-'}
|
||||
</ThemedText.BodySmall>
|
||||
</TableElement>
|
||||
|
@ -38,7 +38,6 @@ import { currencyId } from 'utils/currencyId'
|
||||
import { WrongChainError } from 'utils/errors'
|
||||
import { formatCurrencyAmount } from 'utils/formatCurrencyAmount'
|
||||
import { NumberType, useFormatter } from 'utils/formatNumbers'
|
||||
import { formatTickPrice } from 'utils/formatTickPrice'
|
||||
import { unwrappedToken } from 'utils/unwrappedToken'
|
||||
|
||||
import RangeBadge from '../../components/Badge/RangeBadge'
|
||||
@ -389,6 +388,7 @@ function PositionPageContent() {
|
||||
const { tokenId: tokenIdFromUrl } = useParams<{ tokenId?: string }>()
|
||||
const { chainId, account, provider } = useWeb3React()
|
||||
const theme = useTheme()
|
||||
const { formatTickPrice } = useFormatter()
|
||||
|
||||
const parsedTokenId = tokenIdFromUrl ? BigNumber.from(tokenIdFromUrl) : undefined
|
||||
const { loading, position: positionDetails } = useV3PositionFromTokenId(parsedTokenId)
|
||||
|
@ -1,523 +1,461 @@
|
||||
import { CurrencyAmount, Percent, Price } from '@uniswap/sdk-core'
|
||||
import { USDC_MAINNET, WBTC } from 'constants/tokens'
|
||||
import { renderHook } from '@testing-library/react'
|
||||
import { CurrencyAmount, Percent } from '@uniswap/sdk-core'
|
||||
import { USDC_MAINNET } from 'constants/tokens'
|
||||
import { useCurrencyConversionFlagEnabled } from 'featureFlags/flags/currencyConversion'
|
||||
import { Currency } from 'graphql/data/__generated__/types-and-hooks'
|
||||
import { useLocalCurrencyConversionRate } from 'graphql/data/ConversionRate'
|
||||
import { useActiveLocalCurrency } from 'hooks/useActiveLocalCurrency'
|
||||
import { useActiveLocale } from 'hooks/useActiveLocale'
|
||||
import { mocked } from 'test-utils/mocked'
|
||||
|
||||
import {
|
||||
currencyAmountToPreciseFloat,
|
||||
formatNumber,
|
||||
formatPriceImpact,
|
||||
formatReviewSwapCurrencyAmount,
|
||||
formatSlippage,
|
||||
formatUSDPrice,
|
||||
NumberType,
|
||||
priceToPreciseFloat,
|
||||
} from './formatNumbers'
|
||||
import { NumberType, useFormatter } from './formatNumbers'
|
||||
|
||||
it('formats token reference numbers correctly', () => {
|
||||
expect(formatNumber({ input: 1234567000000000, type: NumberType.TokenNonTx })).toBe('>999T')
|
||||
expect(formatNumber({ input: 1234567000000000, type: NumberType.TokenNonTx, locale: 'de-DE' })).toBe('>999\xa0Bio.')
|
||||
expect(formatNumber({ input: 1002345, type: NumberType.TokenNonTx })).toBe('1.00M')
|
||||
expect(formatNumber({ input: 1002345, type: NumberType.TokenNonTx, locale: 'de-DE' })).toBe('1,00\xa0Mio.')
|
||||
expect(formatNumber({ input: 1234, type: NumberType.TokenNonTx })).toBe('1,234.00')
|
||||
expect(formatNumber({ input: 1234, type: NumberType.TokenNonTx, locale: 'de-DE' })).toBe('1.234,00')
|
||||
expect(formatNumber({ input: 0.00909, type: NumberType.TokenNonTx })).toBe('0.009')
|
||||
expect(formatNumber({ input: 0.00909, type: NumberType.TokenNonTx, locale: 'de-DE' })).toBe('0,009')
|
||||
expect(formatNumber({ input: 0.09001, type: NumberType.TokenNonTx })).toBe('0.090')
|
||||
expect(formatNumber({ input: 0.09001, type: NumberType.TokenNonTx, locale: 'de-DE' })).toBe('0,090')
|
||||
expect(formatNumber({ input: 0.00099, type: NumberType.TokenNonTx })).toBe('<0.001')
|
||||
expect(formatNumber({ input: 0.00099, type: NumberType.TokenNonTx, locale: 'de-DE' })).toBe('<0,001')
|
||||
expect(formatNumber({ input: 0, type: NumberType.TokenNonTx })).toBe('0')
|
||||
expect(formatNumber({ input: 0, type: NumberType.TokenNonTx, locale: 'de-DE' })).toBe('0')
|
||||
})
|
||||
it('formats token transaction numbers correctly', () => {
|
||||
expect(formatNumber({ input: 1234567.8901, type: NumberType.TokenTx })).toBe('1,234,567.89')
|
||||
expect(formatNumber({ input: 1234567.8901, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('1\xa0234\xa0567,89')
|
||||
expect(formatNumber({ input: 765432.1, type: NumberType.TokenTx })).toBe('765,432.10')
|
||||
expect(formatNumber({ input: 765432.1, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('765\xa0432,10')
|
||||
jest.mock('hooks/useActiveLocale')
|
||||
jest.mock('hooks/useActiveLocalCurrency')
|
||||
jest.mock('graphql/data/ConversionRate')
|
||||
jest.mock('featureFlags/flags/currencyConversion')
|
||||
|
||||
expect(formatNumber({ input: 7654.321, type: NumberType.TokenTx })).toBe('7,654.32')
|
||||
expect(formatNumber({ input: 7654.321, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('7\xa0654,32')
|
||||
expect(formatNumber({ input: 765.4321, type: NumberType.TokenTx })).toBe('765.432')
|
||||
expect(formatNumber({ input: 765.4321, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('765,432')
|
||||
expect(formatNumber({ input: 76.54321, type: NumberType.TokenTx })).toBe('76.5432')
|
||||
expect(formatNumber({ input: 76.54321, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('76,5432')
|
||||
expect(formatNumber({ input: 7.654321, type: NumberType.TokenTx })).toBe('7.65432')
|
||||
expect(formatNumber({ input: 7.654321, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('7,65432')
|
||||
expect(formatNumber({ input: 7.60000054321, type: NumberType.TokenTx })).toBe('7.60')
|
||||
expect(formatNumber({ input: 7.60000054321, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('7,60')
|
||||
expect(formatNumber({ input: 7.6, type: NumberType.TokenTx })).toBe('7.60')
|
||||
expect(formatNumber({ input: 7.6, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('7,60')
|
||||
expect(formatNumber({ input: 7, type: NumberType.TokenTx })).toBe('7.00')
|
||||
expect(formatNumber({ input: 7, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('7,00')
|
||||
describe('formatNumber', () => {
|
||||
beforeEach(() => {
|
||||
mocked(useLocalCurrencyConversionRate).mockReturnValue({ data: 1.0, isLoading: false })
|
||||
mocked(useCurrencyConversionFlagEnabled).mockReturnValue(true)
|
||||
})
|
||||
|
||||
expect(formatNumber({ input: 0.987654321, type: NumberType.TokenTx })).toBe('0.98765')
|
||||
expect(formatNumber({ input: 0.987654321, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('0,98765')
|
||||
expect(formatNumber({ input: 0.9, type: NumberType.TokenTx })).toBe('0.90')
|
||||
expect(formatNumber({ input: 0.9, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('0,90')
|
||||
expect(formatNumber({ input: 0.901000123, type: NumberType.TokenTx })).toBe('0.901')
|
||||
expect(formatNumber({ input: 0.901000123, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('0,901')
|
||||
expect(formatNumber({ input: 0.000000001, type: NumberType.TokenTx })).toBe('<0.00001')
|
||||
expect(formatNumber({ input: 0.000000001, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('<0,00001')
|
||||
expect(formatNumber({ input: 0, type: NumberType.TokenTx })).toBe('0')
|
||||
expect(formatNumber({ input: 0, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('0')
|
||||
})
|
||||
it('formats token reference numbers correctly', () => {
|
||||
const { formatNumber } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
it('formats fiat estimates on token details pages correctly', () => {
|
||||
expect(formatNumber({ input: 1234567.891, type: NumberType.FiatTokenDetails })).toBe('$1.23M')
|
||||
expect(
|
||||
formatNumber({
|
||||
input: 1234567.891,
|
||||
type: NumberType.FiatTokenDetails,
|
||||
locale: 'fr-FR',
|
||||
localCurrency: Currency.Eur,
|
||||
})
|
||||
).toBe('1,23\xa0M\xa0€')
|
||||
expect(formatNumber({ input: 1234.5678, type: NumberType.FiatTokenDetails })).toBe('$1,234.57')
|
||||
expect(
|
||||
formatNumber({ input: 1234.5678, type: NumberType.FiatTokenDetails, locale: 'fr-FR', localCurrency: Currency.Eur })
|
||||
).toBe('1\u202f234,57\xa0€')
|
||||
expect(formatNumber({ input: 1.048942, type: NumberType.FiatTokenDetails })).toBe('$1.049')
|
||||
expect(
|
||||
formatNumber({ input: 1.048942, type: NumberType.FiatTokenDetails, locale: 'fr-FR', localCurrency: Currency.Eur })
|
||||
).toBe('1,049\xa0€')
|
||||
expect(formatNumber({ input: 1234567000000000, type: NumberType.TokenNonTx })).toBe('>999T')
|
||||
expect(formatNumber({ input: 1002345, type: NumberType.TokenNonTx })).toBe('1.00M')
|
||||
expect(formatNumber({ input: 1234, type: NumberType.TokenNonTx })).toBe('1,234.00')
|
||||
expect(formatNumber({ input: 0.00909, type: NumberType.TokenNonTx })).toBe('0.009')
|
||||
expect(formatNumber({ input: 0.09001, type: NumberType.TokenNonTx })).toBe('0.090')
|
||||
expect(formatNumber({ input: 0.00099, type: NumberType.TokenNonTx })).toBe('<0.001')
|
||||
expect(formatNumber({ input: 0, type: NumberType.TokenNonTx })).toBe('0')
|
||||
})
|
||||
|
||||
expect(formatNumber({ input: 0.001231, type: NumberType.FiatTokenDetails })).toBe('$0.00123')
|
||||
expect(
|
||||
formatNumber({ input: 0.001231, type: NumberType.FiatTokenDetails, locale: 'fr-FR', localCurrency: Currency.Eur })
|
||||
).toBe('0,00123\xa0€')
|
||||
expect(formatNumber({ input: 0.00001231, type: NumberType.FiatTokenDetails })).toBe('$0.0000123')
|
||||
expect(
|
||||
formatNumber({ input: 0.00001231, type: NumberType.FiatTokenDetails, locale: 'fr-FR', localCurrency: Currency.Eur })
|
||||
).toBe('0,0000123\xa0€')
|
||||
it('formats token reference numbers correctly with deutsch locale', () => {
|
||||
mocked(useActiveLocale).mockReturnValue('de-DE')
|
||||
const { formatNumber } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(formatNumber({ input: 0.0000001234, type: NumberType.FiatTokenDetails })).toBe('$0.000000123')
|
||||
expect(
|
||||
formatNumber({
|
||||
input: 0.0000001234,
|
||||
type: NumberType.FiatTokenDetails,
|
||||
locale: 'fr-FR',
|
||||
localCurrency: Currency.Eur,
|
||||
})
|
||||
).toBe('0,000000123\xa0€')
|
||||
expect(formatNumber({ input: 0.000000009876, type: NumberType.FiatTokenDetails })).toBe('<$0.00000001')
|
||||
expect(
|
||||
formatNumber({
|
||||
input: 0.000000009876,
|
||||
type: NumberType.FiatTokenDetails,
|
||||
locale: 'fr-FR',
|
||||
localCurrency: Currency.Eur,
|
||||
})
|
||||
).toBe('<0,00000001\xa0€')
|
||||
})
|
||||
expect(formatNumber({ input: 1234567000000000, type: NumberType.TokenNonTx })).toBe('>999\xa0Bio.')
|
||||
expect(formatNumber({ input: 1002345, type: NumberType.TokenNonTx })).toBe('1,00\xa0Mio.')
|
||||
expect(formatNumber({ input: 1234, type: NumberType.TokenNonTx })).toBe('1.234,00')
|
||||
expect(formatNumber({ input: 0.00909, type: NumberType.TokenNonTx })).toBe('0,009')
|
||||
expect(formatNumber({ input: 0.09001, type: NumberType.TokenNonTx })).toBe('0,090')
|
||||
expect(formatNumber({ input: 0.00099, type: NumberType.TokenNonTx })).toBe('<0,001')
|
||||
expect(formatNumber({ input: 0, type: NumberType.TokenNonTx })).toBe('0')
|
||||
})
|
||||
|
||||
it('formats fiat estimates for tokens correctly', () => {
|
||||
expect(formatNumber({ input: 1234567.891, type: NumberType.FiatTokenPrice })).toBe('$1.23M')
|
||||
expect(
|
||||
formatNumber({ input: 1234567.891, type: NumberType.FiatTokenPrice, locale: 'es-ES', localCurrency: Currency.Jpy })
|
||||
).toBe('1,23\xa0M¥')
|
||||
expect(formatNumber({ input: 1234.5678, type: NumberType.FiatTokenPrice })).toBe('$1,234.57')
|
||||
expect(
|
||||
formatNumber({ input: 1234.5678, type: NumberType.FiatTokenPrice, locale: 'es-ES', localCurrency: Currency.Jpy })
|
||||
).toBe('1234,57\xa0¥')
|
||||
expect(
|
||||
formatNumber({ input: 12345.678, type: NumberType.FiatTokenPrice, locale: 'es-ES', localCurrency: Currency.Jpy })
|
||||
).toBe('12.345,68\xa0¥')
|
||||
it('formats token transaction numbers correctly', () => {
|
||||
const { formatNumber } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(formatNumber({ input: 0.010235, type: NumberType.FiatTokenPrice })).toBe('$0.0102')
|
||||
expect(
|
||||
formatNumber({ input: 0.010235, type: NumberType.FiatTokenPrice, locale: 'es-ES', localCurrency: Currency.Jpy })
|
||||
).toBe('0,0102\xa0¥')
|
||||
expect(formatNumber({ input: 0.001231, type: NumberType.FiatTokenPrice })).toBe('$0.00123')
|
||||
expect(
|
||||
formatNumber({ input: 0.001231, type: NumberType.FiatTokenPrice, locale: 'es-ES', localCurrency: Currency.Jpy })
|
||||
).toBe('0,00123\xa0¥')
|
||||
expect(formatNumber({ input: 0.00001231, type: NumberType.FiatTokenPrice })).toBe('$0.0000123')
|
||||
expect(
|
||||
formatNumber({ input: 0.00001231, type: NumberType.FiatTokenPrice, locale: 'es-ES', localCurrency: Currency.Jpy })
|
||||
).toBe('0,0000123\xa0¥')
|
||||
expect(formatNumber({ input: 1234567.8901, type: NumberType.TokenTx })).toBe('1,234,567.89')
|
||||
expect(formatNumber({ input: 765432.1, type: NumberType.TokenTx })).toBe('765,432.10')
|
||||
|
||||
expect(formatNumber({ input: 0.0000001234, type: NumberType.FiatTokenPrice })).toBe('$0.000000123')
|
||||
expect(
|
||||
formatNumber({ input: 0.0000001234, type: NumberType.FiatTokenPrice, locale: 'es-ES', localCurrency: Currency.Jpy })
|
||||
).toBe('0,000000123\xa0¥')
|
||||
expect(formatNumber({ input: 0.000000009876, type: NumberType.FiatTokenPrice })).toBe('<$0.00000001')
|
||||
expect(
|
||||
formatNumber({
|
||||
input: 0.000000009876,
|
||||
type: NumberType.FiatTokenPrice,
|
||||
locale: 'es-ES',
|
||||
localCurrency: Currency.Jpy,
|
||||
})
|
||||
).toBe('<0,00000001\xa0¥')
|
||||
expect(formatNumber({ input: 10000000000000000000000000000000, type: NumberType.FiatTokenPrice })).toBe(
|
||||
'$1.000000E31'
|
||||
)
|
||||
expect(
|
||||
formatNumber({
|
||||
input: 10000000000000000000000000000000,
|
||||
type: NumberType.FiatTokenPrice,
|
||||
locale: 'es-ES',
|
||||
localCurrency: Currency.Jpy,
|
||||
})
|
||||
).toBe('1,000000E31\xa0¥')
|
||||
})
|
||||
expect(formatNumber({ input: 7654.321, type: NumberType.TokenTx })).toBe('7,654.32')
|
||||
expect(formatNumber({ input: 765.4321, type: NumberType.TokenTx })).toBe('765.432')
|
||||
expect(formatNumber({ input: 76.54321, type: NumberType.TokenTx })).toBe('76.5432')
|
||||
expect(formatNumber({ input: 7.654321, type: NumberType.TokenTx })).toBe('7.65432')
|
||||
expect(formatNumber({ input: 7.60000054321, type: NumberType.TokenTx })).toBe('7.60')
|
||||
expect(formatNumber({ input: 7.6, type: NumberType.TokenTx })).toBe('7.60')
|
||||
expect(formatNumber({ input: 7, type: NumberType.TokenTx })).toBe('7.00')
|
||||
|
||||
it('formats fiat estimates for token stats correctly', () => {
|
||||
expect(formatNumber({ input: 1234576, type: NumberType.FiatTokenStats })).toBe('$1.2M')
|
||||
expect(
|
||||
formatNumber({ input: 1234576, type: NumberType.FiatTokenStats, locale: 'ja-JP', localCurrency: Currency.Cad })
|
||||
).toBe('CA$123.5万')
|
||||
expect(formatNumber({ input: 234567, type: NumberType.FiatTokenStats })).toBe('$234.6K')
|
||||
expect(
|
||||
formatNumber({ input: 234567, type: NumberType.FiatTokenStats, locale: 'ja-JP', localCurrency: Currency.Cad })
|
||||
).toBe('CA$23.5万')
|
||||
expect(formatNumber({ input: 123.456, type: NumberType.FiatTokenStats })).toBe('$123.46')
|
||||
expect(
|
||||
formatNumber({ input: 123.456, type: NumberType.FiatTokenStats, locale: 'ja-JP', localCurrency: Currency.Cad })
|
||||
).toBe('CA$123.46')
|
||||
expect(formatNumber({ input: 1.23, type: NumberType.FiatTokenStats })).toBe('$1.23')
|
||||
expect(
|
||||
formatNumber({ input: 1.23, type: NumberType.FiatTokenStats, locale: 'ja-JP', localCurrency: Currency.Cad })
|
||||
).toBe('CA$1.23')
|
||||
expect(formatNumber({ input: 0.123, type: NumberType.FiatTokenStats })).toBe('$0.12')
|
||||
expect(
|
||||
formatNumber({ input: 0.123, type: NumberType.FiatTokenStats, locale: 'ja-JP', localCurrency: Currency.Cad })
|
||||
).toBe('CA$0.12')
|
||||
expect(formatNumber({ input: 0.00123, type: NumberType.FiatTokenStats })).toBe('<$0.01')
|
||||
expect(
|
||||
formatNumber({ input: 0.00123, type: NumberType.FiatTokenStats, locale: 'ja-JP', localCurrency: Currency.Cad })
|
||||
).toBe('<CA$0.01')
|
||||
expect(formatNumber({ input: 0, type: NumberType.FiatTokenStats })).toBe('-')
|
||||
expect(
|
||||
formatNumber({ input: 0, type: NumberType.FiatTokenStats, locale: 'ja-JP', localCurrency: Currency.Cad })
|
||||
).toBe('-')
|
||||
})
|
||||
expect(formatNumber({ input: 0.987654321, type: NumberType.TokenTx })).toBe('0.98765')
|
||||
expect(formatNumber({ input: 0.9, type: NumberType.TokenTx })).toBe('0.90')
|
||||
expect(formatNumber({ input: 0.901000123, type: NumberType.TokenTx })).toBe('0.901')
|
||||
expect(formatNumber({ input: 0.000000001, type: NumberType.TokenTx })).toBe('<0.00001')
|
||||
expect(formatNumber({ input: 0, type: NumberType.TokenTx })).toBe('0')
|
||||
})
|
||||
|
||||
it('formats gas USD prices correctly', () => {
|
||||
expect(formatNumber({ input: 1234567.891, type: NumberType.FiatGasPrice })).toBe('$1.23M')
|
||||
expect(
|
||||
formatNumber({ input: 1234567.891, type: NumberType.FiatGasPrice, locale: 'pt-PR', localCurrency: Currency.Thb })
|
||||
).toBe('฿\xa01,23\xa0mi')
|
||||
expect(formatNumber({ input: 18.448, type: NumberType.FiatGasPrice })).toBe('$18.45')
|
||||
expect(
|
||||
formatNumber({ input: 18.448, type: NumberType.FiatGasPrice, locale: 'pt-PR', localCurrency: Currency.Thb })
|
||||
).toBe('฿\xa018,45')
|
||||
expect(formatNumber({ input: 0.0099, type: NumberType.FiatGasPrice })).toBe('<$0.01')
|
||||
expect(
|
||||
formatNumber({ input: 0.0099, type: NumberType.FiatGasPrice, locale: 'pt-PR', localCurrency: Currency.Thb })
|
||||
).toBe('<฿\xa00,01')
|
||||
expect(formatNumber({ input: 0, type: NumberType.FiatGasPrice })).toBe('$0.00')
|
||||
expect(formatNumber({ input: 0, type: NumberType.FiatGasPrice, locale: 'pt-PR', localCurrency: Currency.Thb })).toBe(
|
||||
'฿\xa00,00'
|
||||
)
|
||||
})
|
||||
it('formats token transaction numbers correctly with russian locale', () => {
|
||||
mocked(useActiveLocale).mockReturnValue('ru-RU')
|
||||
const { formatNumber } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
it('formats USD token quantities prices correctly', () => {
|
||||
expect(formatNumber({ input: 1234567.891, type: NumberType.FiatTokenQuantity })).toBe('$1.23M')
|
||||
expect(formatNumber({ input: 1234567.891, type: NumberType.FiatTokenQuantity, localCurrency: Currency.Ngn })).toBe(
|
||||
'₦1.23M'
|
||||
)
|
||||
expect(formatNumber({ input: 18.448, type: NumberType.FiatTokenQuantity })).toBe('$18.45')
|
||||
expect(formatNumber({ input: 18.448, type: NumberType.FiatTokenQuantity, localCurrency: Currency.Ngn })).toBe(
|
||||
'₦18.45'
|
||||
)
|
||||
expect(formatNumber({ input: 0.0099, type: NumberType.FiatTokenQuantity })).toBe('<$0.01')
|
||||
expect(formatNumber({ input: 0.0099, type: NumberType.FiatTokenQuantity, localCurrency: Currency.Ngn })).toBe(
|
||||
'<₦0.01'
|
||||
)
|
||||
expect(formatNumber({ input: 0, type: NumberType.FiatTokenQuantity })).toBe('$0.00')
|
||||
expect(formatNumber({ input: 0, type: NumberType.FiatTokenQuantity, localCurrency: Currency.Ngn })).toBe('₦0.00')
|
||||
})
|
||||
expect(formatNumber({ input: 1234567.8901, type: NumberType.TokenTx })).toBe('1\xa0234\xa0567,89')
|
||||
expect(formatNumber({ input: 765432.1, type: NumberType.TokenTx })).toBe('765\xa0432,10')
|
||||
|
||||
it('formats Swap text input/output numbers correctly', () => {
|
||||
expect(formatNumber({ input: 1234567.8901, type: NumberType.SwapTradeAmount })).toBe('1234570')
|
||||
expect(formatNumber({ input: 1234567.8901, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('1234570')
|
||||
expect(formatNumber({ input: 765432.1, type: NumberType.SwapTradeAmount })).toBe('765432')
|
||||
expect(formatNumber({ input: 765432.1, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('765432')
|
||||
expect(formatNumber({ input: 7654.321, type: NumberType.TokenTx })).toBe('7\xa0654,32')
|
||||
expect(formatNumber({ input: 765.4321, type: NumberType.TokenTx })).toBe('765,432')
|
||||
expect(formatNumber({ input: 76.54321, type: NumberType.TokenTx })).toBe('76,5432')
|
||||
expect(formatNumber({ input: 7.654321, type: NumberType.TokenTx })).toBe('7,65432')
|
||||
expect(formatNumber({ input: 7.60000054321, type: NumberType.TokenTx })).toBe('7,60')
|
||||
expect(formatNumber({ input: 7.6, type: NumberType.TokenTx })).toBe('7,60')
|
||||
expect(formatNumber({ input: 7, type: NumberType.TokenTx })).toBe('7,00')
|
||||
|
||||
expect(formatNumber({ input: 7654.321, type: NumberType.SwapTradeAmount })).toBe('7654.32')
|
||||
expect(formatNumber({ input: 7654.321, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('7654.32')
|
||||
expect(formatNumber({ input: 765.4321, type: NumberType.SwapTradeAmount })).toBe('765.432')
|
||||
expect(formatNumber({ input: 765.4321, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('765.432')
|
||||
expect(formatNumber({ input: 76.54321, type: NumberType.SwapTradeAmount })).toBe('76.5432')
|
||||
expect(formatNumber({ input: 76.54321, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('76.5432')
|
||||
expect(formatNumber({ input: 7.654321, type: NumberType.SwapTradeAmount })).toBe('7.65432')
|
||||
expect(formatNumber({ input: 7.654321, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('7.65432')
|
||||
expect(formatNumber({ input: 7.60000054321, type: NumberType.SwapTradeAmount })).toBe('7.60')
|
||||
expect(formatNumber({ input: 7.60000054321, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('7.60')
|
||||
expect(formatNumber({ input: 7.6, type: NumberType.SwapTradeAmount })).toBe('7.60')
|
||||
expect(formatNumber({ input: 7.6, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('7.60')
|
||||
expect(formatNumber({ input: 7, type: NumberType.SwapTradeAmount })).toBe('7.00')
|
||||
expect(formatNumber({ input: 7, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('7.00')
|
||||
expect(formatNumber({ input: 0.987654321, type: NumberType.TokenTx })).toBe('0,98765')
|
||||
expect(formatNumber({ input: 0.9, type: NumberType.TokenTx })).toBe('0,90')
|
||||
expect(formatNumber({ input: 0.901000123, type: NumberType.TokenTx })).toBe('0,901')
|
||||
expect(formatNumber({ input: 0.000000001, type: NumberType.TokenTx })).toBe('<0,00001')
|
||||
expect(formatNumber({ input: 0, type: NumberType.TokenTx })).toBe('0')
|
||||
})
|
||||
|
||||
expect(formatNumber({ input: 0.987654321, type: NumberType.SwapTradeAmount })).toBe('0.98765')
|
||||
expect(formatNumber({ input: 0.987654321, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('0.98765')
|
||||
expect(formatNumber({ input: 0.9, type: NumberType.SwapTradeAmount })).toBe('0.90')
|
||||
expect(formatNumber({ input: 0.9, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('0.90')
|
||||
expect(formatNumber({ input: 0.901000123, type: NumberType.SwapTradeAmount })).toBe('0.901')
|
||||
expect(formatNumber({ input: 0.901000123, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('0.901')
|
||||
expect(formatNumber({ input: 0.000000001, type: NumberType.SwapTradeAmount })).toBe('0.000000001')
|
||||
expect(formatNumber({ input: 0.000000001, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('0.000000001')
|
||||
expect(formatNumber({ input: 0, type: NumberType.SwapTradeAmount })).toBe('0')
|
||||
expect(formatNumber({ input: 0, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('0')
|
||||
})
|
||||
it('formats fiat estimates on token details pages correctly', () => {
|
||||
const { formatNumber } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
it('formats NFT numbers correctly', () => {
|
||||
expect(formatNumber({ input: 1234567000000000, type: NumberType.NFTTokenFloorPrice })).toBe('>999T')
|
||||
expect(
|
||||
formatNumber({
|
||||
input: 1234567000000000,
|
||||
type: NumberType.NFTTokenFloorPrice,
|
||||
locale: 'pt-BR',
|
||||
localCurrency: Currency.Brl,
|
||||
})
|
||||
).toBe('>999\xa0tri')
|
||||
expect(formatNumber({ input: 1002345, type: NumberType.NFTTokenFloorPrice })).toBe('1M')
|
||||
expect(
|
||||
formatNumber({
|
||||
input: 1002345,
|
||||
type: NumberType.NFTTokenFloorPrice,
|
||||
locale: 'pt-BR',
|
||||
localCurrency: Currency.Brl,
|
||||
})
|
||||
).toBe('1\xa0mi')
|
||||
expect(formatNumber({ input: 1234, type: NumberType.NFTTokenFloorPrice })).toBe('1.23K')
|
||||
expect(
|
||||
formatNumber({
|
||||
input: 1234,
|
||||
type: NumberType.NFTTokenFloorPrice,
|
||||
locale: 'pt-BR',
|
||||
localCurrency: Currency.Brl,
|
||||
})
|
||||
).toBe('1,23\xa0mil')
|
||||
expect(formatNumber({ input: 12.34467, type: NumberType.NFTTokenFloorPrice })).toBe('12.34')
|
||||
expect(
|
||||
formatNumber({
|
||||
input: 12.34467,
|
||||
type: NumberType.NFTTokenFloorPrice,
|
||||
locale: 'pt-BR',
|
||||
localCurrency: Currency.Brl,
|
||||
})
|
||||
).toBe('12,34')
|
||||
expect(formatNumber({ input: 12.1, type: NumberType.NFTTokenFloorPrice })).toBe('12.1')
|
||||
expect(
|
||||
formatNumber({
|
||||
input: 12.1,
|
||||
type: NumberType.NFTTokenFloorPrice,
|
||||
locale: 'pt-BR',
|
||||
localCurrency: Currency.Brl,
|
||||
})
|
||||
).toBe('12,1')
|
||||
expect(formatNumber({ input: 0.00909, type: NumberType.NFTTokenFloorPrice })).toBe('0.009')
|
||||
expect(
|
||||
formatNumber({
|
||||
input: 0.00909,
|
||||
type: NumberType.NFTTokenFloorPrice,
|
||||
locale: 'pt-BR',
|
||||
localCurrency: Currency.Brl,
|
||||
})
|
||||
).toBe('0,009')
|
||||
expect(formatNumber({ input: 0.09001, type: NumberType.NFTTokenFloorPrice })).toBe('0.09')
|
||||
expect(
|
||||
formatNumber({
|
||||
input: 0.09001,
|
||||
type: NumberType.NFTTokenFloorPrice,
|
||||
locale: 'pt-BR',
|
||||
localCurrency: Currency.Brl,
|
||||
})
|
||||
).toBe('0,09')
|
||||
expect(formatNumber({ input: 0.00099, type: NumberType.NFTTokenFloorPrice })).toBe('<0.001')
|
||||
expect(
|
||||
formatNumber({
|
||||
input: 0.00099,
|
||||
type: NumberType.NFTTokenFloorPrice,
|
||||
locale: 'pt-BR',
|
||||
localCurrency: Currency.Brl,
|
||||
})
|
||||
).toBe('<0,001')
|
||||
expect(formatNumber({ input: 0, type: NumberType.NFTTokenFloorPrice })).toBe('0')
|
||||
expect(
|
||||
formatNumber({
|
||||
input: 0,
|
||||
type: NumberType.NFTTokenFloorPrice,
|
||||
locale: 'pt-BR',
|
||||
localCurrency: Currency.Brl,
|
||||
})
|
||||
).toBe('0')
|
||||
expect(formatNumber({ input: 1234567.891, type: NumberType.FiatTokenDetails })).toBe('$1.23M')
|
||||
expect(formatNumber({ input: 1234.5678, type: NumberType.FiatTokenDetails })).toBe('$1,234.57')
|
||||
expect(formatNumber({ input: 1.048942, type: NumberType.FiatTokenDetails })).toBe('$1.049')
|
||||
|
||||
expect(formatNumber({ input: 12.1, type: NumberType.NFTTokenFloorPriceTrailingZeros })).toBe('12.10')
|
||||
expect(
|
||||
formatNumber({
|
||||
input: 12.1,
|
||||
type: NumberType.NFTTokenFloorPriceTrailingZeros,
|
||||
locale: 'pt-BR',
|
||||
localCurrency: Currency.Brl,
|
||||
})
|
||||
).toBe('12,10')
|
||||
expect(formatNumber({ input: 0.09001, type: NumberType.NFTTokenFloorPriceTrailingZeros })).toBe('0.090')
|
||||
expect(
|
||||
formatNumber({
|
||||
input: 0.09001,
|
||||
type: NumberType.NFTTokenFloorPriceTrailingZeros,
|
||||
locale: 'pt-BR',
|
||||
localCurrency: Currency.Brl,
|
||||
})
|
||||
).toBe('0,090')
|
||||
expect(formatNumber({ input: 0.001231, type: NumberType.FiatTokenDetails })).toBe('$0.00123')
|
||||
expect(formatNumber({ input: 0.00001231, type: NumberType.FiatTokenDetails })).toBe('$0.0000123')
|
||||
|
||||
expect(formatNumber({ input: 0.987654321, type: NumberType.NFTCollectionStats })).toBe('1')
|
||||
expect(
|
||||
formatNumber({
|
||||
input: 0.987654321,
|
||||
type: NumberType.NFTCollectionStats,
|
||||
locale: 'pt-BR',
|
||||
localCurrency: Currency.Brl,
|
||||
})
|
||||
).toBe('1')
|
||||
expect(formatNumber({ input: 0.9, type: NumberType.NFTCollectionStats })).toBe('1')
|
||||
expect(
|
||||
formatNumber({ input: 0.9, type: NumberType.NFTCollectionStats, locale: 'pt-BR', localCurrency: Currency.Brl })
|
||||
).toBe('1')
|
||||
expect(formatNumber({ input: 76543.21, type: NumberType.NFTCollectionStats })).toBe('76.5K')
|
||||
expect(
|
||||
formatNumber({ input: 76543.21, type: NumberType.NFTCollectionStats, locale: 'pt-BR', localCurrency: Currency.Brl })
|
||||
).toBe('76,5\xa0mil')
|
||||
expect(formatNumber({ input: 7.60000054321, type: NumberType.NFTCollectionStats })).toBe('8')
|
||||
expect(
|
||||
formatNumber({
|
||||
input: 7.60000054321,
|
||||
type: NumberType.NFTCollectionStats,
|
||||
locale: 'pt-BR',
|
||||
localCurrency: Currency.Brl,
|
||||
})
|
||||
).toBe('8')
|
||||
expect(formatNumber({ input: 1234567890, type: NumberType.NFTCollectionStats })).toBe('1.2B')
|
||||
expect(
|
||||
formatNumber({
|
||||
input: 1234567890,
|
||||
type: NumberType.NFTCollectionStats,
|
||||
locale: 'pt-BR',
|
||||
localCurrency: Currency.Brl,
|
||||
})
|
||||
).toBe('1,2\xa0bi')
|
||||
expect(formatNumber({ input: 1234567000000000, type: NumberType.NFTCollectionStats })).toBe('1234.6T')
|
||||
expect(
|
||||
formatNumber({
|
||||
input: 1234567000000000,
|
||||
type: NumberType.NFTCollectionStats,
|
||||
locale: 'pt-BR',
|
||||
localCurrency: Currency.Brl,
|
||||
})
|
||||
).toBe('1234,6\xa0tri')
|
||||
expect(formatNumber({ input: 0.0000001234, type: NumberType.FiatTokenDetails })).toBe('$0.000000123')
|
||||
expect(formatNumber({ input: 0.000000009876, type: NumberType.FiatTokenDetails })).toBe('<$0.00000001')
|
||||
})
|
||||
|
||||
it('formats fiat estimates on token details pages correctly with french locale and euro currency', () => {
|
||||
mocked(useActiveLocale).mockReturnValue('fr-FR')
|
||||
mocked(useActiveLocalCurrency).mockReturnValue(Currency.Eur)
|
||||
const { formatNumber } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(formatNumber({ input: 1234567.891, type: NumberType.FiatTokenDetails })).toBe('1,23\xa0M\xa0€')
|
||||
expect(formatNumber({ input: 1234.5678, type: NumberType.FiatTokenDetails })).toBe('1\u202f234,57\xa0€')
|
||||
expect(formatNumber({ input: 1.048942, type: NumberType.FiatTokenDetails })).toBe('1,049\xa0€')
|
||||
|
||||
expect(formatNumber({ input: 0.001231, type: NumberType.FiatTokenDetails })).toBe('0,00123\xa0€')
|
||||
expect(formatNumber({ input: 0.00001231, type: NumberType.FiatTokenDetails })).toBe('0,0000123\xa0€')
|
||||
|
||||
expect(formatNumber({ input: 0.0000001234, type: NumberType.FiatTokenDetails })).toBe('0,000000123\xa0€')
|
||||
expect(formatNumber({ input: 0.000000009876, type: NumberType.FiatTokenDetails })).toBe('<0,00000001\xa0€')
|
||||
})
|
||||
|
||||
it('formats fiat estimates for tokens correctly', () => {
|
||||
const { formatNumber } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(formatNumber({ input: 1234567.891, type: NumberType.FiatTokenPrice })).toBe('$1.23M')
|
||||
expect(formatNumber({ input: 1234.5678, type: NumberType.FiatTokenPrice })).toBe('$1,234.57')
|
||||
|
||||
expect(formatNumber({ input: 0.010235, type: NumberType.FiatTokenPrice })).toBe('$0.0102')
|
||||
expect(formatNumber({ input: 0.001231, type: NumberType.FiatTokenPrice })).toBe('$0.00123')
|
||||
expect(formatNumber({ input: 0.00001231, type: NumberType.FiatTokenPrice })).toBe('$0.0000123')
|
||||
|
||||
expect(formatNumber({ input: 0.0000001234, type: NumberType.FiatTokenPrice })).toBe('$0.000000123')
|
||||
expect(formatNumber({ input: 0.000000009876, type: NumberType.FiatTokenPrice })).toBe('<$0.00000001')
|
||||
expect(formatNumber({ input: 10000000000000000000000000000000, type: NumberType.FiatTokenPrice })).toBe(
|
||||
'$1.000000E31'
|
||||
)
|
||||
})
|
||||
|
||||
it('formats fiat estimates for tokens correctly with spanish locale and yen currency', () => {
|
||||
mocked(useActiveLocale).mockReturnValue('es-ES')
|
||||
mocked(useActiveLocalCurrency).mockReturnValue(Currency.Jpy)
|
||||
const { formatNumber } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(formatNumber({ input: 1234567.891, type: NumberType.FiatTokenPrice })).toBe('1,23\xa0M¥')
|
||||
expect(formatNumber({ input: 1234.5678, type: NumberType.FiatTokenPrice })).toBe('1234,57\xa0¥')
|
||||
expect(formatNumber({ input: 12345.678, type: NumberType.FiatTokenPrice })).toBe('12.345,68\xa0¥')
|
||||
|
||||
expect(formatNumber({ input: 0.010235, type: NumberType.FiatTokenPrice })).toBe('0,0102\xa0¥')
|
||||
expect(formatNumber({ input: 0.001231, type: NumberType.FiatTokenPrice })).toBe('0,00123\xa0¥')
|
||||
expect(formatNumber({ input: 0.00001231, type: NumberType.FiatTokenPrice })).toBe('0,0000123\xa0¥')
|
||||
|
||||
expect(formatNumber({ input: 0.0000001234, type: NumberType.FiatTokenPrice })).toBe('0,000000123\xa0¥')
|
||||
expect(formatNumber({ input: 0.000000009876, type: NumberType.FiatTokenPrice })).toBe('<0,00000001\xa0¥')
|
||||
expect(formatNumber({ input: 10000000000000000000000000000000, type: NumberType.FiatTokenPrice })).toBe(
|
||||
'1,000000E31\xa0¥'
|
||||
)
|
||||
})
|
||||
|
||||
it('formats fiat estimates for token stats correctly', () => {
|
||||
const { formatNumber } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(formatNumber({ input: 1234576, type: NumberType.FiatTokenStats })).toBe('$1.2M')
|
||||
expect(formatNumber({ input: 234567, type: NumberType.FiatTokenStats })).toBe('$234.6K')
|
||||
expect(formatNumber({ input: 123.456, type: NumberType.FiatTokenStats })).toBe('$123.46')
|
||||
expect(formatNumber({ input: 1.23, type: NumberType.FiatTokenStats })).toBe('$1.23')
|
||||
expect(formatNumber({ input: 0.123, type: NumberType.FiatTokenStats })).toBe('$0.12')
|
||||
expect(formatNumber({ input: 0.00123, type: NumberType.FiatTokenStats })).toBe('<$0.01')
|
||||
expect(formatNumber({ input: 0, type: NumberType.FiatTokenStats })).toBe('-')
|
||||
})
|
||||
|
||||
it('formats fiat estimates for token stats correctly with japenese locale and cad currency', () => {
|
||||
mocked(useActiveLocale).mockReturnValue('ja-JP')
|
||||
mocked(useActiveLocalCurrency).mockReturnValue(Currency.Cad)
|
||||
const { formatNumber } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(formatNumber({ input: 1234576, type: NumberType.FiatTokenStats })).toBe('CA$123.5万')
|
||||
expect(formatNumber({ input: 234567, type: NumberType.FiatTokenStats })).toBe('CA$23.5万')
|
||||
expect(formatNumber({ input: 123.456, type: NumberType.FiatTokenStats })).toBe('CA$123.46')
|
||||
expect(formatNumber({ input: 1.23, type: NumberType.FiatTokenStats })).toBe('CA$1.23')
|
||||
expect(formatNumber({ input: 0.123, type: NumberType.FiatTokenStats })).toBe('CA$0.12')
|
||||
expect(formatNumber({ input: 0.00123, type: NumberType.FiatTokenStats })).toBe('<CA$0.01')
|
||||
expect(formatNumber({ input: 0, type: NumberType.FiatTokenStats })).toBe('-')
|
||||
})
|
||||
|
||||
it('formats gas USD prices correctly', () => {
|
||||
const { formatNumber } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(formatNumber({ input: 1234567.891, type: NumberType.FiatGasPrice })).toBe('$1.23M')
|
||||
expect(formatNumber({ input: 18.448, type: NumberType.FiatGasPrice })).toBe('$18.45')
|
||||
expect(formatNumber({ input: 0.0099, type: NumberType.FiatGasPrice })).toBe('<$0.01')
|
||||
expect(formatNumber({ input: 0, type: NumberType.FiatGasPrice })).toBe('$0.00')
|
||||
})
|
||||
|
||||
it('formats gas prices correctly with portugese locale and thai baht currency', () => {
|
||||
mocked(useActiveLocale).mockReturnValue('pt-PR')
|
||||
mocked(useActiveLocalCurrency).mockReturnValue(Currency.Thb)
|
||||
const { formatNumber } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(formatNumber({ input: 1234567.891, type: NumberType.FiatGasPrice })).toBe('฿\xa01,23\xa0mi')
|
||||
expect(formatNumber({ input: 18.448, type: NumberType.FiatGasPrice })).toBe('฿\xa018,45')
|
||||
expect(formatNumber({ input: 0.0099, type: NumberType.FiatGasPrice })).toBe('<฿\xa00,01')
|
||||
expect(formatNumber({ input: 0, type: NumberType.FiatGasPrice })).toBe('฿\xa00,00')
|
||||
})
|
||||
|
||||
it('formats USD token quantities prices correctly', () => {
|
||||
const { formatNumber } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(formatNumber({ input: 1234567.891, type: NumberType.FiatTokenQuantity })).toBe('$1.23M')
|
||||
expect(formatNumber({ input: 18.448, type: NumberType.FiatTokenQuantity })).toBe('$18.45')
|
||||
expect(formatNumber({ input: 0.0099, type: NumberType.FiatTokenQuantity })).toBe('<$0.01')
|
||||
expect(formatNumber({ input: 0, type: NumberType.FiatTokenQuantity })).toBe('$0.00')
|
||||
})
|
||||
|
||||
it('formats token quantities prices correctly with nigerian naira currency', () => {
|
||||
mocked(useActiveLocalCurrency).mockReturnValue(Currency.Ngn)
|
||||
const { formatNumber } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(formatNumber({ input: 1234567.891, type: NumberType.FiatTokenQuantity })).toBe('₦1.23M')
|
||||
expect(formatNumber({ input: 18.448, type: NumberType.FiatTokenQuantity })).toBe('₦18.45')
|
||||
expect(formatNumber({ input: 0.0099, type: NumberType.FiatTokenQuantity })).toBe('<₦0.01')
|
||||
expect(formatNumber({ input: 0, type: NumberType.FiatTokenQuantity })).toBe('₦0.00')
|
||||
})
|
||||
|
||||
it('formats Swap text input/output numbers correctly', () => {
|
||||
const { formatNumber } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(formatNumber({ input: 1234567.8901, type: NumberType.SwapTradeAmount })).toBe('1234570')
|
||||
expect(formatNumber({ input: 765432.1, type: NumberType.SwapTradeAmount })).toBe('765432')
|
||||
|
||||
expect(formatNumber({ input: 7654.321, type: NumberType.SwapTradeAmount })).toBe('7654.32')
|
||||
expect(formatNumber({ input: 765.4321, type: NumberType.SwapTradeAmount })).toBe('765.432')
|
||||
expect(formatNumber({ input: 76.54321, type: NumberType.SwapTradeAmount })).toBe('76.5432')
|
||||
expect(formatNumber({ input: 7.654321, type: NumberType.SwapTradeAmount })).toBe('7.65432')
|
||||
expect(formatNumber({ input: 7.60000054321, type: NumberType.SwapTradeAmount })).toBe('7.60')
|
||||
expect(formatNumber({ input: 7.6, type: NumberType.SwapTradeAmount })).toBe('7.60')
|
||||
expect(formatNumber({ input: 7, type: NumberType.SwapTradeAmount })).toBe('7.00')
|
||||
|
||||
expect(formatNumber({ input: 0.987654321, type: NumberType.SwapTradeAmount })).toBe('0.98765')
|
||||
expect(formatNumber({ input: 0.9, type: NumberType.SwapTradeAmount })).toBe('0.90')
|
||||
expect(formatNumber({ input: 0.901000123, type: NumberType.SwapTradeAmount })).toBe('0.901')
|
||||
expect(formatNumber({ input: 0.000000001, type: NumberType.SwapTradeAmount })).toBe('0.000000001')
|
||||
expect(formatNumber({ input: 0, type: NumberType.SwapTradeAmount })).toBe('0')
|
||||
})
|
||||
|
||||
it('formats Swap text input/output numbers correctly with Korean locale', () => {
|
||||
mocked(useActiveLocale).mockReturnValue('ko-KR')
|
||||
const { formatNumber } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(formatNumber({ input: 1234567.8901, type: NumberType.SwapTradeAmount })).toBe('1234570')
|
||||
expect(formatNumber({ input: 765432.1, type: NumberType.SwapTradeAmount })).toBe('765432')
|
||||
|
||||
expect(formatNumber({ input: 7654.321, type: NumberType.SwapTradeAmount })).toBe('7654.32')
|
||||
expect(formatNumber({ input: 765.4321, type: NumberType.SwapTradeAmount })).toBe('765.432')
|
||||
expect(formatNumber({ input: 76.54321, type: NumberType.SwapTradeAmount })).toBe('76.5432')
|
||||
expect(formatNumber({ input: 7.654321, type: NumberType.SwapTradeAmount })).toBe('7.65432')
|
||||
expect(formatNumber({ input: 7.60000054321, type: NumberType.SwapTradeAmount })).toBe('7.60')
|
||||
expect(formatNumber({ input: 7.6, type: NumberType.SwapTradeAmount })).toBe('7.60')
|
||||
expect(formatNumber({ input: 7, type: NumberType.SwapTradeAmount })).toBe('7.00')
|
||||
|
||||
expect(formatNumber({ input: 0.987654321, type: NumberType.SwapTradeAmount })).toBe('0.98765')
|
||||
expect(formatNumber({ input: 0.9, type: NumberType.SwapTradeAmount })).toBe('0.90')
|
||||
expect(formatNumber({ input: 0.901000123, type: NumberType.SwapTradeAmount })).toBe('0.901')
|
||||
expect(formatNumber({ input: 0.000000001, type: NumberType.SwapTradeAmount })).toBe('0.000000001')
|
||||
expect(formatNumber({ input: 0, type: NumberType.SwapTradeAmount })).toBe('0')
|
||||
})
|
||||
|
||||
it('formats NFT numbers correctly', () => {
|
||||
const { formatNumber } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(formatNumber({ input: 1234567000000000, type: NumberType.NFTTokenFloorPrice })).toBe('>999T')
|
||||
expect(formatNumber({ input: 1002345, type: NumberType.NFTTokenFloorPrice })).toBe('1M')
|
||||
expect(formatNumber({ input: 1234, type: NumberType.NFTTokenFloorPrice })).toBe('1.23K')
|
||||
expect(formatNumber({ input: 12.34467, type: NumberType.NFTTokenFloorPrice })).toBe('12.34')
|
||||
expect(formatNumber({ input: 12.1, type: NumberType.NFTTokenFloorPrice })).toBe('12.1')
|
||||
expect(formatNumber({ input: 0.00909, type: NumberType.NFTTokenFloorPrice })).toBe('0.009')
|
||||
expect(formatNumber({ input: 0.09001, type: NumberType.NFTTokenFloorPrice })).toBe('0.09')
|
||||
expect(formatNumber({ input: 0.00099, type: NumberType.NFTTokenFloorPrice })).toBe('<0.001')
|
||||
expect(formatNumber({ input: 0, type: NumberType.NFTTokenFloorPrice })).toBe('0')
|
||||
|
||||
expect(formatNumber({ input: 12.1, type: NumberType.NFTTokenFloorPriceTrailingZeros })).toBe('12.10')
|
||||
expect(formatNumber({ input: 0.09001, type: NumberType.NFTTokenFloorPriceTrailingZeros })).toBe('0.090')
|
||||
|
||||
expect(formatNumber({ input: 0.987654321, type: NumberType.NFTCollectionStats })).toBe('1')
|
||||
expect(formatNumber({ input: 0.9, type: NumberType.NFTCollectionStats })).toBe('1')
|
||||
expect(formatNumber({ input: 76543.21, type: NumberType.NFTCollectionStats })).toBe('76.5K')
|
||||
expect(formatNumber({ input: 7.60000054321, type: NumberType.NFTCollectionStats })).toBe('8')
|
||||
expect(formatNumber({ input: 1234567890, type: NumberType.NFTCollectionStats })).toBe('1.2B')
|
||||
expect(formatNumber({ input: 1234567000000000, type: NumberType.NFTCollectionStats })).toBe('1234.6T')
|
||||
})
|
||||
|
||||
it('formats NFT numbers correctly with brazilian portugese locale and braziliean real currency', () => {
|
||||
mocked(useActiveLocale).mockReturnValue('pt-Br')
|
||||
mocked(useActiveLocalCurrency).mockReturnValue(Currency.Brl)
|
||||
const { formatNumber } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(formatNumber({ input: 1234567000000000, type: NumberType.NFTTokenFloorPrice })).toBe('>999\xa0tri')
|
||||
expect(formatNumber({ input: 1002345, type: NumberType.NFTTokenFloorPrice })).toBe('1\xa0mi')
|
||||
expect(formatNumber({ input: 1234, type: NumberType.NFTTokenFloorPrice })).toBe('1,23\xa0mil')
|
||||
expect(formatNumber({ input: 12.34467, type: NumberType.NFTTokenFloorPrice })).toBe('12,34')
|
||||
expect(formatNumber({ input: 12.1, type: NumberType.NFTTokenFloorPrice })).toBe('12,1')
|
||||
expect(formatNumber({ input: 0.00909, type: NumberType.NFTTokenFloorPrice })).toBe('0,009')
|
||||
expect(formatNumber({ input: 0.09001, type: NumberType.NFTTokenFloorPrice })).toBe('0,09')
|
||||
expect(formatNumber({ input: 0.00099, type: NumberType.NFTTokenFloorPrice })).toBe('<0,001')
|
||||
expect(formatNumber({ input: 0, type: NumberType.NFTTokenFloorPrice })).toBe('0')
|
||||
|
||||
expect(formatNumber({ input: 12.1, type: NumberType.NFTTokenFloorPriceTrailingZeros })).toBe('12,10')
|
||||
expect(formatNumber({ input: 0.09001, type: NumberType.NFTTokenFloorPriceTrailingZeros })).toBe('0,090')
|
||||
|
||||
expect(formatNumber({ input: 0.987654321, type: NumberType.NFTCollectionStats })).toBe('1')
|
||||
expect(formatNumber({ input: 0.9, type: NumberType.NFTCollectionStats })).toBe('1')
|
||||
expect(formatNumber({ input: 76543.21, type: NumberType.NFTCollectionStats })).toBe('76,5\xa0mil')
|
||||
expect(formatNumber({ input: 7.60000054321, type: NumberType.NFTCollectionStats })).toBe('8')
|
||||
expect(formatNumber({ input: 1234567890, type: NumberType.NFTCollectionStats })).toBe('1,2\xa0bi')
|
||||
expect(formatNumber({ input: 1234567000000000, type: NumberType.NFTCollectionStats })).toBe('1234,6\xa0tri')
|
||||
})
|
||||
})
|
||||
|
||||
describe('formatUSDPrice', () => {
|
||||
it('should correctly format 0.000000009876', () => {
|
||||
expect(formatUSDPrice(0.000000009876)).toBe('<$0.00000001')
|
||||
beforeEach(() => {
|
||||
mocked(useLocalCurrencyConversionRate).mockReturnValue({ data: 1.0, isLoading: false })
|
||||
mocked(useCurrencyConversionFlagEnabled).mockReturnValue(true)
|
||||
})
|
||||
it('should correctly format 0.00001231', () => {
|
||||
expect(formatUSDPrice(0.00001231)).toBe('$0.0000123')
|
||||
|
||||
it('format fiat price correctly', () => {
|
||||
const { formatFiatPrice } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(formatFiatPrice({ price: 0.000000009876 })).toBe('<$0.00000001')
|
||||
expect(formatFiatPrice({ price: 0.00001231 })).toBe('$0.0000123')
|
||||
expect(formatFiatPrice({ price: 0.001231 })).toBe('$0.00123')
|
||||
expect(formatFiatPrice({ price: 0.0 })).toBe('$0.00')
|
||||
expect(formatFiatPrice({ price: 0 })).toBe('$0.00')
|
||||
expect(formatFiatPrice({ price: 1.048942 })).toBe('$1.05')
|
||||
expect(formatFiatPrice({ price: 0.10235 })).toBe('$0.102')
|
||||
expect(formatFiatPrice({ price: 1_234.5678 })).toBe('$1,234.57')
|
||||
expect(formatFiatPrice({ price: 1_234_567.891 })).toBe('$1.23M')
|
||||
expect(formatFiatPrice({ price: 1_000_000_000_000 })).toBe('$1.00T')
|
||||
expect(formatFiatPrice({ price: 1_000_000_000_000_000 })).toBe('$1000.00T')
|
||||
})
|
||||
it('should correctly format 0.001231', () => {
|
||||
expect(formatUSDPrice(0.001231)).toBe('$0.00123')
|
||||
})
|
||||
it('should correctly format 0.0', () => {
|
||||
expect(formatUSDPrice(0.0)).toBe('$0.00')
|
||||
})
|
||||
it('should correctly format 0', () => {
|
||||
expect(formatUSDPrice(0)).toBe('$0.00')
|
||||
})
|
||||
it('should correctly format 1.048942', () => {
|
||||
expect(formatUSDPrice(1.048942)).toBe('$1.05')
|
||||
})
|
||||
it('should correctly format 0.10235', () => {
|
||||
expect(formatUSDPrice(0.10235)).toBe('$0.102')
|
||||
})
|
||||
it('should correctly format 1234.5678', () => {
|
||||
expect(formatUSDPrice(1_234.5678)).toBe('$1,234.57')
|
||||
})
|
||||
it('should correctly format 1234567.8910', () => {
|
||||
expect(formatUSDPrice(1_234_567.891)).toBe('$1.23M')
|
||||
})
|
||||
it('should correctly format 1000000000000', () => {
|
||||
expect(formatUSDPrice(1_000_000_000_000)).toBe('$1.00T')
|
||||
})
|
||||
it('should correctly format 1000000000000000', () => {
|
||||
expect(formatUSDPrice(1_000_000_000_000_000)).toBe('$1000.00T')
|
||||
|
||||
it('format fiat price correctly in euros with french locale', () => {
|
||||
mocked(useActiveLocalCurrency).mockReturnValue(Currency.Eur)
|
||||
mocked(useActiveLocale).mockReturnValue('fr-FR')
|
||||
const { formatFiatPrice } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(formatFiatPrice({ price: 0.000000009876 })).toBe('<0,00000001\xa0€')
|
||||
expect(formatFiatPrice({ price: 0.00001231 })).toBe('0,0000123\xa0€')
|
||||
expect(formatFiatPrice({ price: 0.001231 })).toBe('0,00123\xa0€')
|
||||
expect(formatFiatPrice({ price: 0.0 })).toBe('0,00\xa0€')
|
||||
expect(formatFiatPrice({ price: 0 })).toBe('0,00\xa0€')
|
||||
expect(formatFiatPrice({ price: 1.048942 })).toBe('1,05\xa0€')
|
||||
expect(formatFiatPrice({ price: 0.10235 })).toBe('0,102\xa0€')
|
||||
expect(formatFiatPrice({ price: 1_234.5678 })).toBe('1\u202f234,57\xa0€')
|
||||
expect(formatFiatPrice({ price: 1_234_567.891 })).toBe('1,23\xa0M\xa0€')
|
||||
expect(formatFiatPrice({ price: 1_000_000_000_000 })).toBe('1,00\xa0Bn\xa0€')
|
||||
expect(formatFiatPrice({ price: 1_000_000_000_000_000 })).toBe('1000,00\xa0Bn\xa0€')
|
||||
})
|
||||
})
|
||||
|
||||
describe('formatPriceImpact', () => {
|
||||
beforeEach(() => {
|
||||
mocked(useLocalCurrencyConversionRate).mockReturnValue({ data: 1.0, isLoading: false })
|
||||
mocked(useCurrencyConversionFlagEnabled).mockReturnValue(true)
|
||||
})
|
||||
|
||||
it('should correctly format undefined', () => {
|
||||
const { formatPriceImpact } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(formatPriceImpact(undefined)).toBe('-')
|
||||
})
|
||||
|
||||
it('correctly formats a percent with 3 significant digits', () => {
|
||||
const { formatPriceImpact } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(formatPriceImpact(new Percent(-1, 100000))).toBe('0.001%')
|
||||
expect(formatPriceImpact(new Percent(-1, 1000))).toBe('0.100%')
|
||||
expect(formatPriceImpact(new Percent(-1, 100))).toBe('1.000%')
|
||||
expect(formatPriceImpact(new Percent(-1, 10))).toBe('10.000%')
|
||||
expect(formatPriceImpact(new Percent(-1, 1))).toBe('100.000%')
|
||||
})
|
||||
|
||||
it('correctly formats a percent with 3 significant digits with french locale', () => {
|
||||
mocked(useActiveLocale).mockReturnValue('fr-FR')
|
||||
const { formatPriceImpact } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(formatPriceImpact(new Percent(-1, 100000))).toBe('0,001%')
|
||||
expect(formatPriceImpact(new Percent(-1, 1000))).toBe('0,100%')
|
||||
expect(formatPriceImpact(new Percent(-1, 100))).toBe('1,000%')
|
||||
expect(formatPriceImpact(new Percent(-1, 10))).toBe('10,000%')
|
||||
expect(formatPriceImpact(new Percent(-1, 1))).toBe('100,000%')
|
||||
})
|
||||
})
|
||||
|
||||
describe('formatSlippage', () => {
|
||||
beforeEach(() => {
|
||||
mocked(useLocalCurrencyConversionRate).mockReturnValue({ data: 1.0, isLoading: false })
|
||||
mocked(useCurrencyConversionFlagEnabled).mockReturnValue(true)
|
||||
})
|
||||
|
||||
it('should correctly format undefined', () => {
|
||||
const { formatSlippage } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(formatSlippage(undefined)).toBe('-')
|
||||
})
|
||||
|
||||
it('correctly formats a percent with 3 significant digits', () => {
|
||||
const { formatSlippage } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
expect(formatSlippage(new Percent(1, 100000))).toBe('0.001%')
|
||||
expect(formatSlippage(new Percent(1, 1000))).toBe('0.100%')
|
||||
expect(formatSlippage(new Percent(1, 100))).toBe('1.000%')
|
||||
expect(formatSlippage(new Percent(1, 10))).toBe('10.000%')
|
||||
expect(formatSlippage(new Percent(1, 1))).toBe('100.000%')
|
||||
})
|
||||
})
|
||||
|
||||
describe('currencyAmountToPreciseFloat', () => {
|
||||
it('small number', () => {
|
||||
const currencyAmount = CurrencyAmount.fromFractionalAmount(USDC_MAINNET, '20000', '7')
|
||||
expect(currencyAmountToPreciseFloat(currencyAmount)).toEqual(0.00285714)
|
||||
})
|
||||
it('tiny number', () => {
|
||||
const currencyAmount = CurrencyAmount.fromFractionalAmount(USDC_MAINNET, '2', '7')
|
||||
expect(currencyAmountToPreciseFloat(currencyAmount)).toEqual(0.000000285714)
|
||||
})
|
||||
it('lots of decimals', () => {
|
||||
const currencyAmount = CurrencyAmount.fromFractionalAmount(USDC_MAINNET, '200000000', '7')
|
||||
expect(currencyAmountToPreciseFloat(currencyAmount)).toEqual(28.571428)
|
||||
})
|
||||
it('integer', () => {
|
||||
const currencyAmount = CurrencyAmount.fromRawAmount(USDC_MAINNET, '20000000')
|
||||
expect(currencyAmountToPreciseFloat(currencyAmount)).toEqual(20.0)
|
||||
})
|
||||
})
|
||||
it('correctly formats a percent with 3 significant digits with french locale', () => {
|
||||
mocked(useActiveLocale).mockReturnValue('fr-FR')
|
||||
const { formatSlippage } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
describe('priceToPreciseFloat', () => {
|
||||
it('small number', () => {
|
||||
const price = new Price(WBTC, USDC_MAINNET, 1234, 1)
|
||||
expect(priceToPreciseFloat(price)).toEqual(0.0810373)
|
||||
})
|
||||
it('tiny number', () => {
|
||||
const price = new Price(WBTC, USDC_MAINNET, 12345600, 1)
|
||||
expect(priceToPreciseFloat(price)).toEqual(0.00000810005)
|
||||
})
|
||||
it('lots of decimals', () => {
|
||||
const price = new Price(WBTC, USDC_MAINNET, 123, 7)
|
||||
expect(priceToPreciseFloat(price)).toEqual(5.691056911)
|
||||
})
|
||||
it('integer', () => {
|
||||
const price = new Price(WBTC, USDC_MAINNET, 1, 7)
|
||||
expect(priceToPreciseFloat(price)).toEqual(700)
|
||||
expect(formatSlippage(new Percent(1, 100000))).toBe('0,001%')
|
||||
expect(formatSlippage(new Percent(1, 1000))).toBe('0,100%')
|
||||
expect(formatSlippage(new Percent(1, 100))).toBe('1,000%')
|
||||
expect(formatSlippage(new Percent(1, 10))).toBe('10,000%')
|
||||
expect(formatSlippage(new Percent(1, 1))).toBe('100,000%')
|
||||
})
|
||||
})
|
||||
|
||||
describe('formatReviewSwapCurrencyAmount', () => {
|
||||
beforeEach(() => {
|
||||
mocked(useLocalCurrencyConversionRate).mockReturnValue({ data: 1.0, isLoading: false })
|
||||
mocked(useCurrencyConversionFlagEnabled).mockReturnValue(true)
|
||||
})
|
||||
|
||||
it('should use TokenTx formatting under a default length', () => {
|
||||
const { formatReviewSwapCurrencyAmount } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
const currencyAmount = CurrencyAmount.fromRawAmount(USDC_MAINNET, '2000000000') // 2,000 USDC
|
||||
expect(formatReviewSwapCurrencyAmount(currencyAmount)).toBe('2,000')
|
||||
})
|
||||
|
||||
it('should use TokenTx formatting under a default length with french locales', () => {
|
||||
mocked(useActiveLocale).mockReturnValue('fr-FR')
|
||||
const { formatReviewSwapCurrencyAmount } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
const currencyAmount = CurrencyAmount.fromRawAmount(USDC_MAINNET, '2000000000') // 2,000 USDC
|
||||
expect(formatReviewSwapCurrencyAmount(currencyAmount)).toBe('2\u202f000')
|
||||
})
|
||||
|
||||
it('should use SwapTradeAmount formatting over the default length', () => {
|
||||
const { formatReviewSwapCurrencyAmount } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
const currencyAmount = CurrencyAmount.fromRawAmount(USDC_MAINNET, '2000000000000') // 2,000,000 USDC
|
||||
expect(formatReviewSwapCurrencyAmount(currencyAmount)).toBe('2000000')
|
||||
})
|
||||
|
||||
it('should use SwapTradeAmount formatting over the default length with french locales', () => {
|
||||
mocked(useActiveLocale).mockReturnValue('fr-FR')
|
||||
const { formatReviewSwapCurrencyAmount } = renderHook(() => useFormatter()).result.current
|
||||
|
||||
const currencyAmount = CurrencyAmount.fromRawAmount(USDC_MAINNET, '2000000000000') // 2,000,000 USDC
|
||||
expect(formatReviewSwapCurrencyAmount(currencyAmount)).toBe('2000000')
|
||||
})
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Currency, CurrencyAmount, Percent, Price } from '@uniswap/sdk-core'
|
||||
import { Currency, CurrencyAmount, Percent, Price, Token } from '@uniswap/sdk-core'
|
||||
import {
|
||||
DEFAULT_LOCAL_CURRENCY,
|
||||
LOCAL_CURRENCY_SYMBOL_DISPLAY_TYPE,
|
||||
@ -12,6 +12,7 @@ import { useActiveLocalCurrency } from 'hooks/useActiveLocalCurrency'
|
||||
import { useActiveLocale } from 'hooks/useActiveLocale'
|
||||
import usePrevious from 'hooks/usePrevious'
|
||||
import { useCallback, useMemo } from 'react'
|
||||
import { Bound } from 'state/mint/v3/actions'
|
||||
|
||||
type Nullish<T> = T | null | undefined
|
||||
type NumberFormatOptions = Intl.NumberFormatOptions
|
||||
@ -392,7 +393,7 @@ interface FormatNumberOptions {
|
||||
conversionRate?: number
|
||||
}
|
||||
|
||||
export function formatNumber({
|
||||
function formatNumber({
|
||||
input,
|
||||
type = NumberType.TokenNonTx,
|
||||
placeholder = '-',
|
||||
@ -434,7 +435,7 @@ interface FormatCurrencyAmountOptions {
|
||||
conversionRate?: number
|
||||
}
|
||||
|
||||
export function formatCurrencyAmount({
|
||||
function formatCurrencyAmount({
|
||||
amount,
|
||||
type = NumberType.TokenNonTx,
|
||||
placeholder,
|
||||
@ -452,7 +453,7 @@ export function formatCurrencyAmount({
|
||||
})
|
||||
}
|
||||
|
||||
export function formatPriceImpact(priceImpact: Percent | undefined, locale: SupportedLocale = DEFAULT_LOCALE): string {
|
||||
function formatPriceImpact(priceImpact: Percent | undefined, locale: SupportedLocale = DEFAULT_LOCALE): string {
|
||||
if (!priceImpact) return '-'
|
||||
|
||||
return `${Number(priceImpact.multiply(-1).toFixed(3)).toLocaleString(locale, {
|
||||
@ -462,13 +463,17 @@ export function formatPriceImpact(priceImpact: Percent | undefined, locale: Supp
|
||||
})}%`
|
||||
}
|
||||
|
||||
export function formatSlippage(slippage: Percent | undefined) {
|
||||
function formatSlippage(slippage: Percent | undefined, locale: SupportedLocale = DEFAULT_LOCALE) {
|
||||
if (!slippage) return '-'
|
||||
|
||||
return `${slippage.toFixed(3)}%`
|
||||
return `${Number(slippage.toFixed(3)).toLocaleString(locale, {
|
||||
minimumFractionDigits: 3,
|
||||
maximumFractionDigits: 3,
|
||||
useGrouping: false,
|
||||
})}%`
|
||||
}
|
||||
|
||||
interface FormatPriceProps {
|
||||
interface FormatPriceOptions {
|
||||
price: Nullish<Price<Currency, Currency>>
|
||||
type: FormatterType
|
||||
locale?: SupportedLocale
|
||||
@ -476,13 +481,13 @@ interface FormatPriceProps {
|
||||
conversionRate?: number
|
||||
}
|
||||
|
||||
export function formatPrice({
|
||||
function formatPrice({
|
||||
price,
|
||||
type = NumberType.FiatTokenPrice,
|
||||
locale = DEFAULT_LOCALE,
|
||||
localCurrency = DEFAULT_LOCAL_CURRENCY,
|
||||
conversionRate,
|
||||
}: FormatPriceProps): string {
|
||||
}: FormatPriceOptions): string {
|
||||
if (price === null || price === undefined) {
|
||||
return '-'
|
||||
}
|
||||
@ -490,45 +495,80 @@ export function formatPrice({
|
||||
return formatNumber({ input: parseFloat(price.toSignificant()), type, locale, localCurrency, conversionRate })
|
||||
}
|
||||
|
||||
export function formatNumberOrString(price: Nullish<number | string>, type: FormatterType): string {
|
||||
if (price === null || price === undefined) return '-'
|
||||
if (typeof price === 'string') return formatNumber({ input: parseFloat(price), type })
|
||||
return formatNumber({ input: price, type })
|
||||
interface FormatTickPriceOptions {
|
||||
price?: Price<Token, Token>
|
||||
atLimit: { [bound in Bound]?: boolean | undefined }
|
||||
direction: Bound
|
||||
placeholder?: string
|
||||
numberType?: NumberType
|
||||
locale?: SupportedLocale
|
||||
localCurrency?: SupportedLocalCurrency
|
||||
conversionRate?: number
|
||||
}
|
||||
|
||||
export function formatUSDPrice(price: Nullish<number | string>, type: NumberType = NumberType.FiatTokenPrice): string {
|
||||
return formatNumberOrString(price, type)
|
||||
}
|
||||
|
||||
/** Formats USD and non-USD prices */
|
||||
export function formatFiatPrice(price: Nullish<number>, currency = 'USD'): string {
|
||||
if (price === null || price === undefined) return '-'
|
||||
return new Intl.NumberFormat('en-US', { style: 'currency', currency }).format(price)
|
||||
}
|
||||
|
||||
// Convert [CurrencyAmount] to number with necessary precision for price formatting.
|
||||
export const currencyAmountToPreciseFloat = (currencyAmount: CurrencyAmount<Currency> | undefined) => {
|
||||
if (!currencyAmount) return undefined
|
||||
const floatForLargerNumbers = parseFloat(currencyAmount.toExact())
|
||||
if (floatForLargerNumbers < 0.1) {
|
||||
return parseFloat(currencyAmount.toSignificant(6))
|
||||
function formatTickPrice({
|
||||
price,
|
||||
atLimit,
|
||||
direction,
|
||||
placeholder,
|
||||
numberType,
|
||||
locale,
|
||||
localCurrency,
|
||||
conversionRate,
|
||||
}: FormatTickPriceOptions) {
|
||||
if (atLimit[direction]) {
|
||||
return direction === Bound.LOWER ? '0' : '∞'
|
||||
}
|
||||
return floatForLargerNumbers
|
||||
|
||||
if (!price && placeholder !== undefined) {
|
||||
return placeholder
|
||||
}
|
||||
|
||||
return formatPrice({ price, type: numberType ?? NumberType.TokenNonTx, locale, localCurrency, conversionRate })
|
||||
}
|
||||
|
||||
// Convert [Price] to number with necessary precision for price formatting.
|
||||
export const priceToPreciseFloat = (price: Price<Currency, Currency> | undefined) => {
|
||||
if (!price) return undefined
|
||||
const floatForLargerNumbers = parseFloat(price.toFixed(9))
|
||||
if (floatForLargerNumbers < 0.1) {
|
||||
return parseFloat(price.toSignificant(6))
|
||||
}
|
||||
return floatForLargerNumbers
|
||||
interface FormatNumberOrStringOptions {
|
||||
input: Nullish<number | string>
|
||||
type: FormatterType
|
||||
locale?: SupportedLocale
|
||||
localCurrency?: SupportedLocalCurrency
|
||||
conversionRate?: number
|
||||
}
|
||||
|
||||
function formatNumberOrString({
|
||||
input,
|
||||
type,
|
||||
locale,
|
||||
localCurrency,
|
||||
conversionRate,
|
||||
}: FormatNumberOrStringOptions): string {
|
||||
if (input === null || input === undefined) return '-'
|
||||
if (typeof input === 'string')
|
||||
return formatNumber({ input: parseFloat(input), type, locale, localCurrency, conversionRate })
|
||||
return formatNumber({ input, type, locale, localCurrency, conversionRate })
|
||||
}
|
||||
|
||||
interface FormatFiatPriceOptions {
|
||||
price: Nullish<number | string>
|
||||
type?: FormatterType
|
||||
locale?: SupportedLocale
|
||||
localCurrency?: SupportedLocalCurrency
|
||||
conversionRate?: number
|
||||
}
|
||||
|
||||
function formatFiatPrice({
|
||||
price,
|
||||
type = NumberType.FiatTokenPrice,
|
||||
locale,
|
||||
localCurrency,
|
||||
conversionRate,
|
||||
}: FormatFiatPriceOptions): string {
|
||||
return formatNumberOrString({ input: price, type, locale, localCurrency, conversionRate })
|
||||
}
|
||||
|
||||
const MAX_AMOUNT_STR_LENGTH = 9
|
||||
|
||||
export function formatReviewSwapCurrencyAmount(
|
||||
function formatReviewSwapCurrencyAmount(
|
||||
amount: CurrencyAmount<Currency>,
|
||||
locale: SupportedLocale = DEFAULT_LOCALE
|
||||
): string {
|
||||
@ -539,7 +579,7 @@ export function formatReviewSwapCurrencyAmount(
|
||||
return formattedAmount
|
||||
}
|
||||
|
||||
export function useFormatterLocales(): {
|
||||
function useFormatterLocales(): {
|
||||
formatterLocale: SupportedLocale
|
||||
formatterLocalCurrency: SupportedLocalCurrency
|
||||
} {
|
||||
@ -620,7 +660,7 @@ export function useFormatter() {
|
||||
)
|
||||
|
||||
const formatPriceWithLocales = useCallback(
|
||||
(options: Omit<FormatPriceProps, LocalesType>) =>
|
||||
(options: Omit<FormatPriceOptions, LocalesType>) =>
|
||||
formatPrice({
|
||||
...options,
|
||||
locale: formatterLocale,
|
||||
@ -640,20 +680,66 @@ export function useFormatter() {
|
||||
[formatterLocale]
|
||||
)
|
||||
|
||||
const formatSlippageWithLocales = useCallback(
|
||||
(slippage: Percent | undefined) => formatSlippage(slippage, formatterLocale),
|
||||
[formatterLocale]
|
||||
)
|
||||
|
||||
const formatTickPriceWithLocales = useCallback(
|
||||
(options: Omit<FormatTickPriceOptions, LocalesType>) =>
|
||||
formatTickPrice({
|
||||
...options,
|
||||
locale: formatterLocale,
|
||||
localCurrency: currencyToFormatWith,
|
||||
conversionRate: localCurrencyConversionRateToFormatWith,
|
||||
}),
|
||||
[currencyToFormatWith, formatterLocale, localCurrencyConversionRateToFormatWith]
|
||||
)
|
||||
|
||||
const formatNumberOrStringWithLocales = useCallback(
|
||||
(options: Omit<FormatNumberOrStringOptions, LocalesType>) =>
|
||||
formatNumberOrString({
|
||||
...options,
|
||||
locale: formatterLocale,
|
||||
localCurrency: currencyToFormatWith,
|
||||
conversionRate: localCurrencyConversionRateToFormatWith,
|
||||
}),
|
||||
[currencyToFormatWith, formatterLocale, localCurrencyConversionRateToFormatWith]
|
||||
)
|
||||
|
||||
const formatFiatPriceWithLocales = useCallback(
|
||||
(options: Omit<FormatFiatPriceOptions, LocalesType>) =>
|
||||
formatFiatPrice({
|
||||
...options,
|
||||
locale: formatterLocale,
|
||||
localCurrency: currencyToFormatWith,
|
||||
conversionRate: localCurrencyConversionRateToFormatWith,
|
||||
}),
|
||||
[currencyToFormatWith, formatterLocale, localCurrencyConversionRateToFormatWith]
|
||||
)
|
||||
|
||||
return useMemo(
|
||||
() => ({
|
||||
formatCurrencyAmount: formatCurrencyAmountWithLocales,
|
||||
formatFiatPrice: formatFiatPriceWithLocales,
|
||||
formatNumber: formatNumberWithLocales,
|
||||
formatNumberOrString: formatNumberOrStringWithLocales,
|
||||
formatPrice: formatPriceWithLocales,
|
||||
formatPriceImpact: formatPriceImpactWithLocales,
|
||||
formatReviewSwapCurrencyAmount: formatReviewSwapCurrencyAmountWithLocales,
|
||||
formatSlippage: formatSlippageWithLocales,
|
||||
formatTickPrice: formatTickPriceWithLocales,
|
||||
}),
|
||||
[
|
||||
formatCurrencyAmountWithLocales,
|
||||
formatFiatPriceWithLocales,
|
||||
formatNumberOrStringWithLocales,
|
||||
formatNumberWithLocales,
|
||||
formatPriceImpactWithLocales,
|
||||
formatPriceWithLocales,
|
||||
formatReviewSwapCurrencyAmountWithLocales,
|
||||
formatSlippageWithLocales,
|
||||
formatTickPriceWithLocales,
|
||||
]
|
||||
)
|
||||
}
|
||||
|
@ -1,24 +0,0 @@
|
||||
import { Price, Token } from '@uniswap/sdk-core'
|
||||
import { formatPrice, NumberType } from 'utils/formatNumbers'
|
||||
|
||||
import { Bound } from '../state/mint/v3/actions'
|
||||
|
||||
interface FormatTickPriceArgs {
|
||||
price?: Price<Token, Token>
|
||||
atLimit: { [bound in Bound]?: boolean | undefined }
|
||||
direction: Bound
|
||||
placeholder?: string
|
||||
numberType?: NumberType
|
||||
}
|
||||
|
||||
export function formatTickPrice({ price, atLimit, direction, placeholder, numberType }: FormatTickPriceArgs) {
|
||||
if (atLimit[direction]) {
|
||||
return direction === Bound.LOWER ? '0' : '∞'
|
||||
}
|
||||
|
||||
if (!price && placeholder !== undefined) {
|
||||
return placeholder
|
||||
}
|
||||
|
||||
return formatPrice({ price, type: numberType ?? NumberType.TokenNonTx })
|
||||
}
|
Loading…
Reference in New Issue
Block a user