diff --git a/app/vibenet/library/format.test.ts b/app/vibenet/library/format.test.ts new file mode 100644 index 0000000..24119d8 --- /dev/null +++ b/app/vibenet/library/format.test.ts @@ -0,0 +1,18 @@ +import { describe, expect, it } from 'vitest'; + +import { formatAmount } from './format'; + +describe('formatAmount', () => { + it('formats positive fractional amounts', () => { + expect(formatAmount('1500000000000000000', 18)).toBe('1.5'); + }); + + it('keeps the sign separate when formatting negative amounts', () => { + expect(formatAmount('-1500000000000000000', 18)).toBe('-1.5'); + expect(formatAmount('-500000000000000000', 18)).toBe('-0.5'); + }); + + it('returns the original raw value when it cannot parse an amount', () => { + expect(formatAmount('not-a-number', 18)).toBe('not-a-number'); + }); +}); diff --git a/app/vibenet/library/format.ts b/app/vibenet/library/format.ts index 4f2550d..d608385 100644 --- a/app/vibenet/library/format.ts +++ b/app/vibenet/library/format.ts @@ -32,14 +32,16 @@ export function formatAmount(raw: string, decimals: number, maxFractionDigits = try { const value = BigInt(raw); if (value === 0n) return '0'; + const sign = value < 0n ? '-' : ''; + const magnitude = value < 0n ? -value : value; const divisor = 10n ** BigInt(decimals); - const whole = (value / divisor).toLocaleString(); - const frac = (value % divisor) + const whole = (magnitude / divisor).toLocaleString(); + const frac = (magnitude % divisor) .toString() .padStart(decimals, '0') .slice(0, maxFractionDigits) .replace(/0+$/, ''); - return frac ? `${whole}.${frac}` : whole; + return frac ? `${sign}${whole}.${frac}` : `${sign}${whole}`; } catch { return raw; }