SPB Git

Repository Public

amounts.ts 1.3 KB 28 lines typescript

1// Exact integer money arithmetic. No floating point anywhere.2const MAX = (1n << 256n) - 1n;34export function parseUnits(input: string, decimals: number): bigint {5  if (!Number.isInteger(decimals) || decimals < 0 || decimals > 36) throw new Error('bad decimals');6  const s = input.trim().replace(',', '.');7  if (!/^\d{1,60}(\.\d{0,60})?$/.test(s)) throw new Error('invalid amount');8  const [int = '0', frac = ''] = s.split('.');9  if (frac.length > decimals && /[1-9]/.test(frac.slice(decimals))) throw new Error('too many decimals');10  const v = BigInt(int) * 10n ** BigInt(decimals) + BigInt((frac.slice(0, decimals) || '').padEnd(decimals, '0') || '0');11  if (v > MAX) throw new Error('amount overflow');12  return v;13}1415export function formatUnits(value: bigint, decimals: number): string {16  if (value < 0n) throw new Error('negative amount');17  const base = 10n ** BigInt(decimals);18  const int = value / base;19  const frac = (value % base).toString().padStart(decimals, '0').replace(/0+$/, '');20  return frac ? `${int}.${frac}` : int.toString();21}2223/** Parse a canonical base-unit string ("0" or no leading zero, digits only). */24export function baseUnits(s: string): bigint {25  if (!/^(0|[1-9]\d{0,77})$/.test(s)) throw new Error('invalid base-unit integer');26  return BigInt(s);27}28
Files main
Menu

Theme