diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index cd4eff2f0b..26e8d1ab17 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -71,10 +71,10 @@ jobs:
- name: Checkout
uses: actions/checkout@v2
- - name: Set up Node.js 18.15.0
+ - name: Set up Node.js
uses: actions/setup-node@v1
with:
- node-version: 18.15.0
+ node-version: 20.9.0
registry-url: 'https://npm.pkg.github.com'
scope: '@kybernetwork'
@@ -147,10 +147,10 @@ jobs:
- name: Checkout
uses: actions/checkout@v2
- - name: Set up Node.js 18.15.0
+ - name: Set up Node.js
uses: actions/setup-node@v1
with:
- node-version: 18.15.0
+ node-version: 20.9.0
registry-url: 'https://npm.pkg.github.com'
scope: '@kybernetwork'
diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml
index 170fa2a8d9..a1e9cf6fc0 100644
--- a/.github/workflows/cypress.yml
+++ b/.github/workflows/cypress.yml
@@ -70,10 +70,10 @@ jobs:
- name: Check out Git repository
uses: actions/checkout@v3
- - name: Set up Node.js 18.15.0
+ - name: Set up Node.js
uses: actions/setup-node@v3
with:
- node-version: 18.15.0
+ node-version: 20.9.0
registry-url: 'https://npm.pkg.github.com'
scope: '@kybernetwork'
@@ -84,9 +84,9 @@ jobs:
- name: Install linux deps
run: |
- sudo apt-get install --no-install-recommends -y \
- fluxbox \
- xvfb
+ sudo apt-get install --no-install-recommends -y \
+ fluxbox \
+ xvfb
- name: Yarn Build
env:
@@ -118,14 +118,14 @@ jobs:
yarn preview &
yarn test-e2e -c baseUrl='http://127.0.0.1:4173/' -e grepTags=smoke,NETWORK=Ethereum
env:
- DISPLAY: :0.0
+ DISPLAY: :0.0
- name: Archive e2e artifacts
uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8
if: always()
with:
- name: e2e-artifacts
- path: |
- cypress/videos
- cypress/screenshots
+ name: e2e-artifacts
+ path: |
+ cypress/videos
+ cypress/screenshots
continue-on-error: true
diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml
index cabf110ec8..946aefb8ef 100644
--- a/.github/workflows/pr.yaml
+++ b/.github/workflows/pr.yaml
@@ -70,10 +70,10 @@ jobs:
- name: Checkout
uses: actions/checkout@v2
- - name: Set up Node.js 18.15.0
+ - name: Set up Node.js
uses: actions/setup-node@v1
with:
- node-version: 18.15.0
+ node-version: 20.9.0
registry-url: 'https://npm.pkg.github.com'
scope: '@kybernetwork'
@@ -144,10 +144,10 @@ jobs:
- name: Check out Git repository
uses: actions/checkout@v2
- - name: Set up Node.js 18.15.0
+ - name: Set up Node.js
uses: actions/setup-node@v1
with:
- node-version: 18.15.0
+ node-version: 20.9.0
registry-url: 'https://npm.pkg.github.com'
scope: '@kybernetwork'
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 4fc695a362..a96e6244d1 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -38,10 +38,10 @@ jobs:
- name: Checkout
uses: actions/checkout@v2
- - name: Set up Node.js 18.15.0
+ - name: Set up Node.js
uses: actions/setup-node@v1
with:
- node-version: 18.15.0
+ node-version: 20.9.0
registry-url: 'https://npm.pkg.github.com'
scope: '@kybernetwork'
diff --git a/.github/workflows/schedule.yml b/.github/workflows/schedule.yml
index ad37319e3d..fd159f85b8 100644
--- a/.github/workflows/schedule.yml
+++ b/.github/workflows/schedule.yml
@@ -17,10 +17,10 @@ jobs:
- name: Trigger Code Checkout
uses: actions/checkout@v3
- - name: Set up Node.js 18.15.0
+ - name: Set up Node.js
uses: actions/setup-node@v3
with:
- node-version: 18.15.0
+ node-version: 20.9.0
registry-url: 'https://npm.pkg.github.com'
scope: '@kybernetwork'
diff --git a/package.json b/package.json
index 67d7d6bdbe..20d3bc1ac8 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,7 @@
"homepage": "/",
"license": "GPL-3.0-or-later",
"engines": {
- "node": "~18.15.0",
+ "node": "~20.9.0",
"yarn": ">=1.22"
},
"packageManager": "yarn@1.22.19",
@@ -158,7 +158,7 @@
"@types/dompurify": "^3.0.3",
"@types/mixpanel-browser": "^2.38.0",
"@types/multicodec": "^1.0.0",
- "@types/node": "^13.13.52",
+ "@types/node": "^20.8.8",
"@types/numeral": "^2.0.0",
"@types/react": "^18.0.15",
"@types/react-dom": "^18.0.8",
@@ -208,4 +208,4 @@
"@lingui/core": "3.14.0",
"@lingui/conf": "3.16.0"
}
-}
+}
\ No newline at end of file
diff --git a/src/components/Announcement/PrivateAnnoucement/InboxItemKyberAIWatchList.tsx b/src/components/Announcement/PrivateAnnoucement/InboxItemKyberAIWatchList.tsx
index f7696b09be..e675629cf2 100644
--- a/src/components/Announcement/PrivateAnnoucement/InboxItemKyberAIWatchList.tsx
+++ b/src/components/Announcement/PrivateAnnoucement/InboxItemKyberAIWatchList.tsx
@@ -48,7 +48,12 @@ export const TokenInfo = ({
{' '}
0 ? theme.apr : theme.red}>
({+priceChange > 0 && '+'}
- {formatDisplayNumber(+priceChange / 100, { style: 'percent', fractionDigits: 2, allowNegative: true })})
+ {formatDisplayNumber(+priceChange / 100, {
+ style: 'percent',
+ fractionDigits: 2,
+ allowDisplayNegative: true,
+ })}
+ )
)}
diff --git a/src/components/ProAmm/CandleStickChart.tsx b/src/components/ProAmm/CandleStickChart.tsx
index 3bc8726ef2..a5ba9bfc4f 100644
--- a/src/components/ProAmm/CandleStickChart.tsx
+++ b/src/components/ProAmm/CandleStickChart.tsx
@@ -125,7 +125,8 @@ const CandleStickChart = ({
borderColor: 'rgba(197, 203, 206, 0.8)',
},
localization: {
- priceFormatter: (val: number) => formatDisplayNumber(val, { significantDigits: 6, allowNegative: true }),
+ priceFormatter: (val: number) =>
+ formatDisplayNumber(val, { significantDigits: 6, allowDisplayNegative: true }),
},
})
diff --git a/src/components/YieldPools/ListItem.tsx b/src/components/YieldPools/ListItem.tsx
index 19352a890d..056304d8eb 100644
--- a/src/components/YieldPools/ListItem.tsx
+++ b/src/components/YieldPools/ListItem.tsx
@@ -577,7 +577,11 @@ const ListItem = ({ farm }: ListItemProps) => {
- {formatDisplayNumber(userStakedBalanceUSD, { style: 'currency', significantDigits: 6, allowZero: false })}
+ {formatDisplayNumber(userStakedBalanceUSD, {
+ style: 'currency',
+ significantDigits: 6,
+ allowDisplayZero: false,
+ })}
diff --git a/src/components/swapv2/LimitOrder/useValidateInputError.tsx b/src/components/swapv2/LimitOrder/useValidateInputError.tsx
index 3a158ebb26..c02d0e8923 100644
--- a/src/components/swapv2/LimitOrder/useValidateInputError.tsx
+++ b/src/components/swapv2/LimitOrder/useValidateInputError.tsx
@@ -48,7 +48,7 @@ const useValidateInputError = ({
const formatNum = formatDisplayNumber(remainBalance, {
style: 'decimal',
fractionDigits: 6,
- allowNegative: true,
+ allowDisplayNegative: true,
})
return (
diff --git a/src/pages/MyEarnings/TotalEarningsAndChainSelect.tsx b/src/pages/MyEarnings/TotalEarningsAndChainSelect.tsx
index 764c1cee8d..dc5fdc6809 100644
--- a/src/pages/MyEarnings/TotalEarningsAndChainSelect.tsx
+++ b/src/pages/MyEarnings/TotalEarningsAndChainSelect.tsx
@@ -143,7 +143,7 @@ const TotalEarningsAndChainSelect: React.FC = ({ totalEarningToday, total
style: 'percent',
fractionDigits: 2,
significantDigits: 6,
- allowNegative: true,
+ allowDisplayNegative: true,
})
: ''
diff --git a/src/types/intl.d.ts b/src/types/intl.d.ts
new file mode 100644
index 0000000000..2bcdf5ecf5
--- /dev/null
+++ b/src/types/intl.d.ts
@@ -0,0 +1,5 @@
+declare namespace Intl {
+ interface NumberFormatOptions {
+ roundingPriority?: 'auto' | 'morePrecision' | 'lessPrecision'
+ }
+}
diff --git a/src/utils/dmm.ts b/src/utils/dmm.ts
index f9884b5b31..d37f500246 100644
--- a/src/utils/dmm.ts
+++ b/src/utils/dmm.ts
@@ -251,7 +251,7 @@ export const getMyLiquidity = (
(parseFloat(liquidityPosition.liquidityTokenBalance) * parseFloat(liquidityPosition.pool.reserveUSD)) /
parseFloat(liquidityPosition.pool.totalSupply)
- return formatDisplayNumber(myLiquidity, { style: 'currency', significantDigits: 4, allowZero: false })
+ return formatDisplayNumber(myLiquidity, { style: 'currency', significantDigits: 4, allowDisplayZero: false })
}
function useFarmRewardsPerTimeUnit(farm?: Farm): RewardPerTimeUnit[] {
diff --git a/src/utils/numbers.ts b/src/utils/numbers.ts
index e50be0019c..abfc09f831 100644
--- a/src/utils/numbers.ts
+++ b/src/utils/numbers.ts
@@ -67,28 +67,40 @@ const subscriptMap: { [key: string]: string } = {
}
const log10 = (n: Fraction): number => {
- const parsedN = Number(n.toSignificant(30))
+ const parsedN = Number(n.toFixed(100))
return Math.log10(parsedN)
}
-// - $ 123,456,222,333.44444 e+22 eur5
-const regex = /^\s*?\+?(-)?\s*?(\$)?\s*?([\d,]+)(?:\.(\d+))?\s*?(?:e\+?(\-?\d+))?\s*?(%|\w+?)?\s*?$/
-const parseNumPart = (str: string): [string, string, string, string, string, string] => {
+
+const unitMapping: { [key: string]: string } = {
+ k: '3',
+ m: '6',
+ b: '9',
+ t: '12',
+}
+// - $ 123,456,222,333.44444K e+22 eur5
+const regex = /^\s*?\+?(-)?\s*?(\$)?\s*?([\d,]+)(?:\.(\d+))?(\s*?(?:K|M|T))?(?:\s*?e\+?(\-?\d+))?\s*?(%|\w+?)?\s*?$/
+const parseNumPart = (str: string): [string, string, string, string, string, string, string] => {
const parsedResult = regex.exec(str)
if (parsedResult) {
- const [, negative, currency, integer, decimal, exponent, unit] = parsedResult
- return [negative || '', currency || '', integer, decimal || '', exponent, unit || '']
+ const [, negative, currency, integer, decimal, exponentUnit, exponent, unit] = parsedResult
+ return [negative || '', currency || '', integer, decimal || '', exponentUnit || '', exponent || '', unit || '']
}
- return ['', '', '0', '', '', ''] // [negative, currency, integer, decimal, exponent, unit]
+ return ['', '', '0', '', '', '', '']
}
const parseString = (value: string): Fraction => {
try {
- const [negative, _currency, integer, decimal, e, _unit] = parseNumPart(value)
- const exponent = Number(e || '0') - decimal.length
+ const [negative, _currency, integer, decimal, exponentUnit, e, _unit] = parseNumPart(value)
+ const trimedNumerator = (negative + integer.replace(/,/g, '') + decimal).replace(/^0+/, '').replace(/^-0+/, '-')
+ const exponent =
+ Number(e || '0') +
+ Number(exponentUnit ? unitMapping[exponentUnit.toLowerCase().trim()] ?? '0' : '0') -
+ decimal.length
+
if (exponent > 0) {
- return new Fraction(negative + integer.replace(/,/g, '') + decimal + '0'.repeat(exponent), 1)
+ return new Fraction(trimedNumerator + '0'.repeat(exponent), 1)
}
- return new Fraction(negative + integer.replace(/,/g, '') + decimal, 10 ** -exponent)
+ return new Fraction(trimedNumerator, '1' + '0'.repeat(-exponent))
} catch (e) {
return new Fraction(0, 1)
}
@@ -105,12 +117,12 @@ export const parseFraction = (value: FormatValue): Fraction => {
value instanceof Price
) {
const valueStr = (() => {
- if (typeof value === 'string') return parseString(value).toFixed(18)
+ if (typeof value === 'string') return parseString(value).toFixed(100)
if (typeof value === 'number') return toString(value)
if (value instanceof BigNumber) return value.toString()
if (value instanceof CurrencyAmount) return value.toFixed(value.currency.decimals)
if (value instanceof Price) return value.toFixed(18)
- if (value instanceof Percent) return value.divide(100).toFixed(18)
+ if (value instanceof Percent) return value.divide(100).toFixed(100)
return '0'
})()
return new Fraction(valueStr.replace('.', ''), '1' + '0'.repeat(valueStr.split('.')[1]?.length || 0))
@@ -131,8 +143,8 @@ type FormatOptions = {
fractionDigits?: number // usually for percent & currency styles
significantDigits?: number // usually for decimal style
fallback?: string
- allowNegative?: boolean
- allowZero?: boolean
+ allowDisplayNegative?: boolean
+ allowDisplayZero?: boolean
}
interface RequiredFraction extends FormatOptions {
fractionDigits: number // usually for percent & currency styles
@@ -163,8 +175,8 @@ export const formatDisplayNumber = (
significantDigits,
fractionDigits,
fallback = '--',
- allowNegative = false,
- allowZero = true,
+ allowDisplayNegative = false,
+ allowDisplayZero = true,
}: RequiredFraction | RequiredSignificant,
): string => {
const currency = style === 'currency' ? '$' : ''
@@ -173,20 +185,20 @@ export const formatDisplayNumber = (
if (value === undefined || value === null || Number.isNaN(value)) return fallbackResult
const parsedFraction = parseFraction(value)
- if (!allowNegative && parsedFraction.lessThan(BIG_INT_ZERO)) return fallbackResult
- if (!allowZero && parsedFraction.equalTo(BIG_INT_ZERO)) return fallbackResult
+ if (!allowDisplayNegative && parsedFraction.lessThan(BIG_INT_ZERO)) return fallbackResult
+ if (!allowDisplayZero && parsedFraction.equalTo(BIG_INT_ZERO)) return fallbackResult
const shownFraction = style === 'percent' ? parsedFraction.multiply(100) : parsedFraction
const absShownFraction = shownFraction.lessThan(0) ? shownFraction.multiply(-1) : shownFraction
if (absShownFraction.lessThan(BIG_INT_ONE) && !shownFraction.equalTo(BIG_INT_ZERO)) {
- const decimal = shownFraction.toSignificant(Math.max(30, significantDigits || 0, fractionDigits || 0)).split('.')[1]
+ const decimal = shownFraction.toFixed(100).split('.')[1]
const negative = shownFraction.lessThan(BIG_INT_ZERO) ? '-' : ''
const numberOfLeadingZeros = -Math.floor(log10(absShownFraction) + 1)
const slicedDecimal = decimal
.replace(/^0+/, '')
- .slice(0, fractionDigits)
- .slice(0, significantDigits || 6)
+ .slice(0, fractionDigits ? fractionDigits : 30)
+ .slice(0, significantDigits ? significantDigits : 30)
.replace(/0+$/, '')
if (numberOfLeadingZeros > 3) {
@@ -213,20 +225,8 @@ export const formatDisplayNumber = (
maximumFractionDigits: fractionDigits,
minimumSignificantDigits: significantDigits ? 1 : undefined,
maximumSignificantDigits: significantDigits,
+ roundingPriority: fractionDigits && significantDigits ? 'lessPrecision' : undefined,
})
- const result = formatter.format(
- Number(parsedFraction.toSignificant(Math.max(30, significantDigits || 0, fractionDigits || 0))),
- )
-
- // Intl.NumberFormat does not handle maximumFractionDigits well when used along with maximumSignificantDigits
- // It might return number with longer fraction digits than maximumFractionDigits
- // Hence, we have to do an additional step that manually slice those oversize fraction digits
- if (fractionDigits !== undefined) {
- const [negative, currency, integer, decimal, _exponent, unit] = parseNumPart(result)
- const trimedSlicedDecimal = decimal?.slice(0, fractionDigits).replace(/0+$/, '')
- if (trimedSlicedDecimal) return negative + currency + integer + '.' + trimedSlicedDecimal + unit
- return negative + currency + integer + unit
- }
- return result
+ return formatter.format(Number(parsedFraction.toFixed(100)))
}
diff --git a/yarn.lock b/yarn.lock
index 8f867837fd..1dec1b3ade 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4784,11 +4784,6 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240"
integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==
-"@types/node@^13.13.52":
- version "13.13.52"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.52.tgz#03c13be70b9031baaed79481c0c0cfb0045e53f7"
- integrity sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==
-
"@types/node@^14.14.31":
version "14.18.42"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.42.tgz#fa39b2dc8e0eba61bdf51c66502f84e23b66e114"
@@ -4799,6 +4794,13 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.48.tgz#3bc872236cdb31cb51024d8875d655e25db489a4"
integrity sha512-mlaecDKQ7rIZrYD7iiKNdzFb6e/qD5I9U1rAhq+Fd+DWvYVs+G2kv74UFHmSOlg5+i/vF3XxuR522V4u8BqO+Q==
+"@types/node@^20.8.8":
+ version "20.8.8"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.8.tgz#adee050b422061ad5255fc38ff71b2bb96ea2a0e"
+ integrity sha512-YRsdVxq6OaLfmR9Hy816IMp33xOBjfyOgUd77ehqg96CFywxAPbDbXvAsuN2KVg2HOT8Eh6uAfU+l4WffwPVrQ==
+ dependencies:
+ undici-types "~5.25.1"
+
"@types/normalize-package-data@^2.4.0":
version "2.4.1"
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301"
@@ -17088,6 +17090,11 @@ underscore@^1.13.6:
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.6.tgz#04786a1f589dc6c09f761fc5f45b89e935136441"
integrity sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==
+undici-types@~5.25.1:
+ version "5.25.3"
+ resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.25.3.tgz#e044115914c85f0bcbb229f346ab739f064998c3"
+ integrity sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==
+
unique-string@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-3.0.0.tgz#84a1c377aff5fd7a8bc6b55d8244b2bd90d75b9a"