forked from Uniswap/interface
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathformatNumbers.ts
More file actions
134 lines (128 loc) · 4.79 KB
/
Copy pathformatNumbers.ts
File metadata and controls
134 lines (128 loc) · 4.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* Copied from Uniswap/v-3: https://github.com/Uniswap/v3-info/blob/master/src/utils/numbers.ts */
import { Currency, CurrencyAmount, Price } from '@uniswap/sdk-core'
import { DEFAULT_LOCALE } from 'constants/locales'
import numbro from 'numbro'
// 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))
}
return floatForLargerNumbers
}
// 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 FormatDollarArgs {
num: number | undefined | null
isPrice?: boolean
lessPreciseStablecoinValues?: boolean
digits?: number
round?: boolean
}
/**
* Returns a USD dollar or equivalent denominated numerical value formatted
* in human readable string for use in template.
*
* Adheres to guidelines for prices and other numbers defined here:
* https://www.notion.so/uniswaplabs/Number-standards-fbb9f533f10e4e22820722c2f66d23c0
* @param num numerical value denominated in USD or USD equivalent
* @param isPrice whether the amount represents a price or not
* @param lessPreciseStablecoinValues whether or not we should show less precise values for
* stablecoins (around 1$ in value always) for the sake of readability
* @param digits number of digits after the decimal for non-price amounts
* @param round whether or not to round up non-price amounts
*/
export const formatDollar = ({
num,
isPrice = false,
lessPreciseStablecoinValues = false,
digits = 2,
round = true,
}: FormatDollarArgs): string => {
// For USD dollar denominated prices.
if (isPrice) {
if (num === 0) return '$0.00'
if (!num) return '-'
if (num < 0.000001) {
return `$${num.toExponential(2)}`
}
if ((num >= 0.000001 && num < 0.1) || num > 1000000) {
return `$${Number(num).toPrecision(3)}`
}
// We only show 2 decimal places in explore table for stablecoin value ranges
// for the sake of readability (as opposed to the usual 3 elsewhere).
if (num >= 0.1 && num < (lessPreciseStablecoinValues ? 0.9995 : 1.05)) {
return `$${num.toFixed(3)}`
}
return `$${Number(num.toFixed(2)).toLocaleString(DEFAULT_LOCALE, { minimumFractionDigits: 2 })}`
}
// For volume dollar amounts, like market cap, total value locked, etc.
else {
if (num === 0) return '$0.00'
if (!num) return '-'
if (num < 0.000001) {
return '$<0.000001'
}
if (num >= 0.000001 && num < 0.1) {
return `$${Number(num).toPrecision(3)}`
}
if (num >= 0.1 && num < 1.05) {
return `$${num.toFixed(3)}`
}
return numbro(num)
.formatCurrency({
average: round,
mantissa: num > 1000 ? 2 : digits,
abbreviations: {
million: 'M',
billion: 'B',
},
})
.toUpperCase()
}
}
/**
* Returns a numerical amount of any token formatted in human readable string for use in template.
*
* For transaction review numbers, such as token quantities, NFT price (token-denominated),
* network fees, transaction history items. Adheres to guidelines defined here:
* https://www.notion.so/uniswaplabs/Number-standards-fbb9f533f10e4e22820722c2f66d23c0
* @param num numerical value denominated in any token
* @param maxDigits the maximum number of digits that should be shown for the quantity
*/
export const formatTransactionAmount = (num: number | undefined | null, maxDigits = 9) => {
if (num === 0) return '0.00'
if (!num) return ''
if (num < 0.00001) {
return '<0.00001'
}
if (num >= 0.00001 && num < 1) {
return `${Number(num.toFixed(5)).toLocaleString(DEFAULT_LOCALE, {
minimumFractionDigits: 2,
maximumFractionDigits: 5,
})}`
}
if (num >= 1 && num < 10000) {
return `${Number(num.toPrecision(6)).toLocaleString(DEFAULT_LOCALE, {
minimumFractionDigits: 2,
maximumFractionDigits: 6,
})}`
}
if (num >= 10000 && num < 1000000) {
return `${Number(num.toFixed(2)).toLocaleString(DEFAULT_LOCALE, { minimumFractionDigits: 2 })}`
}
// For very large numbers, switch to scientific notation and show as much precision
// as permissible by maxDigits param.
if (num >= Math.pow(10, maxDigits - 1)) {
return `${num.toExponential(maxDigits - 3)}`
}
return `${Number(num.toFixed(2)).toLocaleString(DEFAULT_LOCALE, { minimumFractionDigits: 2 })}`
}