const WEI_DECIMALS = 18n export function formatWeiAsEth(value: string, fractionDigits = 4): string { try { const normalizedDigits = Math.max(0, Math.min(18, fractionDigits)) const wei = BigInt(value) const divisor = 10n ** WEI_DECIMALS const whole = wei / divisor const fraction = wei % divisor if (normalizedDigits === 0) { return `${whole.toString()} ETH` } const scale = 10n ** (WEI_DECIMALS - BigInt(normalizedDigits)) const truncatedFraction = fraction / scale const paddedFraction = truncatedFraction .toString() .padStart(normalizedDigits, '0') .replace(/0+$/, '') if (!paddedFraction) { return `${whole.toString()} ETH` } return `${whole.toString()}.${paddedFraction} ETH` } catch { return '0 ETH' } } export function formatUnits(value: string | number | null | undefined, decimals = 18, fractionDigits = 4): string { try { const safeDecimals = Math.max(0, Math.min(36, decimals)) const normalizedDigits = Math.max(0, Math.min(12, fractionDigits)) const amount = BigInt(typeof value === 'number' ? value.toString() : value || '0') const divisor = 10n ** BigInt(safeDecimals) const whole = amount / divisor const fraction = amount % divisor if (normalizedDigits === 0 || safeDecimals === 0) { return whole.toString() } const scale = 10n ** BigInt(Math.max(0, safeDecimals - normalizedDigits)) const truncatedFraction = fraction / scale const paddedFraction = truncatedFraction .toString() .padStart(Math.min(normalizedDigits, safeDecimals), '0') .replace(/0+$/, '') return paddedFraction ? `${whole.toString()}.${paddedFraction}` : whole.toString() } catch { return '0' } } export function formatTokenAmount(value: string | number | null | undefined, decimals = 18, symbol?: string | null, fractionDigits = 4): string { const formatted = formatUnits(value, decimals, fractionDigits) return symbol ? `${formatted} ${symbol}` : formatted } export function formatTimestamp(value?: string | null): string { if (!value) return 'Unknown' const date = new Date(value) if (Number.isNaN(date.getTime())) { return value } return date.toLocaleString() }