Skip to content
markpaper

src/format/wire.ts

v0.3.0 · 1.1 KB

Download file
import { parseDec, toPlain } from './decimal.js';
import type { Numeric } from './types.js';

/**
 * Canonical decimal string for the wire and for comparisons: no exponent, no
 * trailing zeros, no leading zeros, no `-0` (`'83.2050'` -> `'83.205'`,
 * `1e-7` -> `'0.0000001'`, `1.5e21` -> `'1500000000000000000000'`). Does not round.
 *
 * Why:
 * - `String(n)` switches to exponent notation below 1e-6 and from 1e21, and the
 *   SDK's decimal schema (`^[0-9]+(\.[0-9]+)?$`) rejects such strings.
 * - The SDK (0.33) strips trailing zeros before signing, so the canonical form is
 *   byte-identical to what is signed and to how prices read back; stored order
 *   keys must use the same form, since a raw number never equals the exchange's
 *   string and gives endless cancel/re-place loops.
 * - Never derive a tick from the string length: trailing zeros are gone
 *   (`'40'` is not "tick 1"); use `priceTick` instead.
 *
 * Throws `HlFormatError` on non-finite or malformed input.
 */
export function normalizeDecimal(value: Numeric): string {
  return toPlain(parseDec(value, 'decimal'));
}
All files