# `@suaveplan/license` — constants _(no submodules)_ ## Purpose Wire-format constants for the license package. Every value here is part of the binary contract: the per-field bit widths (`FIELD_BITS`), the Base32 alphabet, the signature lengths, the version byte, and the day-to-millisecond conversion factor. Changing any constant breaks every existing license key, so they live in their own module and are imported by every code path that touches the format. ## Features - `LICENSE_VERSION` (currently `2`) — pinned by the 3-bit version field; `validateLicense` rejects any payload with a higher version. - `FULL_SIGNATURE_BYTES` (64) / `SIGNATURE_BYTES` (20) / `MIN_SIGNATURE_BYTES` (16) — the three signature-length thresholds honoured by generation and validation. - `BASE32_ALPHABET` — 32-char Crockford-style alphabet (no I/L/O/U) used by both encode and decode. - `LICENSE_SCHEMA` — per-field maximum values, used by Zod schemas and by the bounds checks in `packPayload`. - `FIELD_BITS` — per-field bit widths summing to 72, consumed by the bitpacker. - `PAYLOAD_BYTES` (9), `OBFUSCATION_PAYLOAD_CHARS` (15), and `MS_PER_DAY` (86 400 000) — derived constants pulled out so callers don't have to recompute them. ## Usage: Basic ```ts import { LICENSE_VERSION, BASE32_ALPHABET } from "@suaveplan/license/constants/constants"; console.log(`Targeting wire format v${LICENSE_VERSION}`); console.log(`Alphabet size: ${BASE32_ALPHABET.length}`); // 32 ``` ## Usage: Advanced Bounds-checking a payload field at the application layer before constructing it: ```ts import { LICENSE_SCHEMA } from "@suaveplan/license/constants/constants"; import type { LicensePayload } from "@suaveplan/license/types/license"; function clampPayload(p: LicensePayload): LicensePayload { return { ...p, productId: Math.min(p.productId, LICENSE_SCHEMA.productId), timeValue: Math.min(p.timeValue, LICENSE_SCHEMA.timeValue), }; } ``` ## API Reference | Symbol | Type | Value | |---|---|---| | `LICENSE_VERSION` | `2` | Current format version | | `FULL_SIGNATURE_BYTES` | `64` | secp256k1 compact signature length | | `SIGNATURE_BYTES` | `20` | Default truncated-signature length | | `MIN_SIGNATURE_BYTES` | `16` | Lowest acceptable truncation | | `BASE32_ALPHABET` | `string` | `0-9A-HJKMNP-TV-Z` (32 chars) | | `LICENSE_SCHEMA` | `Readonly>` | Per-field max values | | `FIELD_BITS` | `Readonly>` | Per-field bit widths | | `PAYLOAD_BYTES` | `9` | Packed payload size | | `OBFUSCATION_PAYLOAD_CHARS` | `15` | Chars rotated by obfuscation | | `MS_PER_DAY` | `86_400_000` | UTC day in milliseconds | ## Implementation Notes Every constant is declared `as const`, so its TypeScript type is the literal value (e.g. `LICENSE_VERSION: 2`), giving exhaustiveness benefits when compared in `switch` statements. The two records (`LICENSE_SCHEMA` and `FIELD_BITS`) are also frozen at the type level via `as const`, preventing accidental mutation through their `Readonly` view.