Skip to content

Commit 4d4fccb

Browse files
authored
Merge pull request #830 from relayprotocol/joseph/fe-7664-token-amount-overflow-on-success-screen
Improved token amount formatting on success screen
2 parents cd98b61 + 05c072e commit 4d4fccb

File tree

3 files changed

+68
-7
lines changed

3 files changed

+68
-7
lines changed

.changeset/strong-women-stand.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@relayprotocol/relay-kit-ui': patch
3+
---
4+
5+
Improved token amount formatting on success screen

packages/ui/src/components/common/TransactionModal/steps/SwapSuccessStep.tsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
type ExecuteStepItem
2323
} from '@relayprotocol/relay-sdk'
2424
import { bitcoin } from '../../../../utils/bitcoin.js'
25-
import { formatBN } from '../../../../utils/numbers.js'
25+
import { formatSignificantDigits } from '../../../../utils/numbers.js'
2626
import { TransactionsByChain } from './TransactionsByChain.js'
2727
import { faArrowRight, faCheck } from '@fortawesome/free-solid-svg-icons'
2828
import { RelayIcon, XIcon } from '../../../../icons/index.js'
@@ -76,9 +76,8 @@ export const SwapSuccessStep: FC<SwapSuccessStepProps> = ({
7676
const chains = relayClient?.chains
7777

7878
const _fromAmountFormatted = transaction?.data?.metadata?.currencyIn?.amount
79-
? formatBN(
79+
? formatSignificantDigits(
8080
transaction?.data?.metadata?.currencyIn?.amount,
81-
5,
8281
transaction?.data?.metadata?.currencyIn?.currency?.decimals ?? 18
8382
)
8483
: fromAmountFormatted
@@ -88,9 +87,8 @@ export const SwapSuccessStep: FC<SwapSuccessStepProps> = ({
8887
transaction?.data?.metadata?.currencyIn?.currency?.metadata?.logoURI ??
8988
fromToken?.logoURI
9089
const _toAmountFormatted = transaction?.data?.metadata?.currencyOut?.amount
91-
? formatBN(
90+
? formatSignificantDigits(
9291
transaction?.data?.metadata?.currencyOut?.amount,
93-
5,
9492
transaction?.data?.metadata?.currencyOut?.currency?.decimals ?? 18
9593
)
9694
: toAmountFormatted
@@ -145,9 +143,8 @@ export const SwapSuccessStep: FC<SwapSuccessStepProps> = ({
145143
transaction?.data?.metadata?.currencyGasTopup?.currency
146144
const formattedGasTopUpAmount = transaction?.data?.metadata?.currencyGasTopup
147145
?.amount
148-
? formatBN(
146+
? formatSignificantDigits(
149147
BigInt(transaction?.data?.metadata?.currencyGasTopup?.amount),
150-
5,
151148
gasTopUpAmountCurrency?.decimals ?? 18
152149
)
153150
: undefined

packages/ui/src/utils/numbers.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,10 +240,69 @@ function formatFixedLength(amount: string, maxLength: number) {
240240
return result
241241
}
242242

243+
/**
244+
* Formats a number to 6 total digits with special handling for decimals.
245+
* For numbers >= 1: rounds to 6 significant digits (e.g., 289.97568 → 289.976, 1234.5678 → 1234.57)
246+
* For numbers < 1: truncates to "0." + 5 digits (e.g., 0.00056 → 0.00056, 0.0001234567 → 0.00012)
247+
* @param value The number to format (as number, string, or bigint)
248+
* @param decimals Optional decimals for bigint conversion (default 18)
249+
* @returns Formatted string with 6 total digits
250+
*/
251+
function formatSignificantDigits(
252+
value: number | string | bigint | null | undefined,
253+
decimals: number = 18
254+
): string {
255+
if (value === null || value === undefined) return '-'
256+
257+
let num: number
258+
if (typeof value === 'bigint') {
259+
num = +formatUnits(value, decimals)
260+
} else if (typeof value === 'string') {
261+
try {
262+
num = +formatUnits(BigInt(value), decimals)
263+
} catch {
264+
num = parseFloat(value)
265+
}
266+
} else {
267+
num = value
268+
}
269+
270+
if (isNaN(num) || num === 0) return '0'
271+
272+
const absNum = Math.abs(num)
273+
const isNegative = num < 0
274+
275+
let result: string
276+
277+
if (absNum >= 1) {
278+
result = absNum.toPrecision(6)
279+
280+
if (!result.includes('e')) {
281+
result = result.replace(/(\.\d*?[1-9])0+$/, '$1').replace(/\.0+$/, '')
282+
}
283+
} else {
284+
if (absNum < 0.00001) {
285+
result = '< 0.00001'
286+
} else {
287+
const strNum = absNum.toString()
288+
const [, decimalPart] = strNum.split('.')
289+
const truncated = decimalPart.substring(0, 5)
290+
result = '0.' + truncated
291+
result = result.replace(/0+$/, '')
292+
if (result === '0.' || result === '0') {
293+
result = '< 0.00001'
294+
}
295+
}
296+
}
297+
298+
return isNegative ? '-' + result : result
299+
}
300+
243301
export {
244302
formatDollar,
245303
formatBN,
246304
formatFixedLength,
247305
formatNumber,
306+
formatSignificantDigits,
248307
truncateBalance
249308
}

0 commit comments

Comments
 (0)