src/format/wire.ts
v0.3.0 · 1.1 KB
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'));
}