{"version":3,"file":"index.mjs","names":["ComponentsSeed","ComponentsSeed"],"sources":["../src/cli.ts","../src/seed.ts","../src/random.ts","../src/util.ts","../src/formats/hex.ts","../src/formats/bip39.ts","../src/formats/sskr.ts","../src/formats/envelope.ts","../src/formats/seed-format.ts","../src/formats/multipart.ts","../src/formats/random.ts","../src/formats/base6.ts","../src/formats/base10.ts","../src/formats/bits.ts","../src/formats/dice.ts","../src/formats/cards.ts","../src/formats/ints.ts","../src/formats/bytewords-standard.ts","../src/formats/bytewords-minimal.ts","../src/formats/bytewords-uri.ts","../src/formats/format.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * CLI types and interfaces\n * Ported from seedtool-cli-rust/src/cli.rs\n */\n\nimport * as readline from \"node:readline\";\nimport * as fs from \"node:fs\";\nimport { SSKRGroupSpec, SSKRSpec } from \"@bcts/components\";\nimport type { SecureRandomNumberGenerator } from \"@bcts/rand\";\nimport type { Envelope } from \"@bcts/envelope\";\nimport type { Seed } from \"./seed.js\";\nimport type { DeterministicRandomNumberGenerator } from \"./random.js\";\n\n// ============================================================================\n// Enums (matching Rust ValueEnum)\n// ============================================================================\n\n/**\n * Input format keys.\n * Matches Rust InputFormatKey enum in format.rs\n */\nexport enum InputFormatKey {\n  Random = \"random\",\n  Hex = \"hex\",\n  Btw = \"btw\",\n  Btwu = \"btwu\",\n  Btwm = \"btwm\",\n  Bits = \"bits\",\n  Cards = \"cards\",\n  Dice = \"dice\",\n  Base6 = \"base6\",\n  Base10 = \"base10\",\n  Ints = \"ints\",\n  Bip39 = \"bip39\",\n  Sskr = \"sskr\",\n  Envelope = \"envelope\",\n  Multipart = \"multipart\",\n  Seed = \"seed\",\n}\n\n/**\n * Output format keys.\n * Matches Rust OutputFormatKey enum in format.rs\n */\nexport enum OutputFormatKey {\n  Hex = \"hex\",\n  Btw = \"btw\",\n  Btwu = \"btwu\",\n  Btwm = \"btwm\",\n  Bits = \"bits\",\n  Cards = \"cards\",\n  Dice = \"dice\",\n  Base6 = \"base6\",\n  Base10 = \"base10\",\n  Ints = \"ints\",\n  Bip39 = \"bip39\",\n  Sskr = \"sskr\",\n  Envelope = \"envelope\",\n  Multipart = \"multipart\",\n  Seed = \"seed\",\n}\n\n/**\n * SSKR output format keys.\n * Matches Rust SSKRFormatKey enum in sskr.rs\n */\nexport enum SSKRFormatKey {\n  Envelope = \"envelope\",\n  Btw = \"btw\",\n  Btwm = \"btwm\",\n  Btwu = \"btwu\",\n  Ur = \"ur\",\n}\n\n// ============================================================================\n// RNG Source Type\n// ============================================================================\n\n/**\n * RNG source - either secure or deterministic.\n * Matches Rust RngSource enum.\n */\nexport type RngSource =\n  | { type: \"secure\"; rng: SecureRandomNumberGenerator }\n  | { type: \"deterministic\"; rng: DeterministicRandomNumberGenerator };\n\n// ============================================================================\n// Validation Functions\n// ============================================================================\n\n/**\n * Parse and validate low int (0-254).\n * Matches Rust parse_low_int function.\n */\nexport function parseLowInt(s: string): number {\n  const n = parseInt(s, 10);\n  if (isNaN(n) || n < 0 || n > 254) {\n    throw new Error(`Invalid low value: ${s}. Must be 0-254.`);\n  }\n  return n;\n}\n\n/**\n * Parse and validate high int (1-255).\n * Matches Rust parse_high_int function.\n */\nexport function parseHighInt(s: string): number {\n  const n = parseInt(s, 10);\n  if (isNaN(n) || n < 1 || n > 255) {\n    throw new Error(`Invalid high value: ${s}. Must be 1-255.`);\n  }\n  return n;\n}\n\n/**\n * Parse and validate group threshold (1-16).\n * Matches Rust parse_group_threshold function.\n */\nexport function parseGroupThreshold(s: string): number {\n  const n = parseInt(s, 10);\n  if (isNaN(n) || n < 1 || n > 16) {\n    throw new Error(`Invalid group threshold: ${s}. Must be 1-16.`);\n  }\n  return n;\n}\n\n/**\n * Parse date string.\n * Accepts \"now\" or ISO-8601 format.\n * Matches Rust parse_date function.\n */\nexport function parseDate(s: string): Date {\n  if (s === \"now\") {\n    return new Date();\n  }\n  const date = new Date(s);\n  if (isNaN(date.getTime())) {\n    throw new Error(`Invalid date: ${s}. Use ISO-8601 format or 'now'.`);\n  }\n  return date;\n}\n\n/**\n * Parse SSKR group specification \"M-of-N\".\n * Returns SSKRGroupSpec instance.\n */\nexport function parseGroupSpec(s: string): SSKRGroupSpec {\n  const regex = /^(\\d+)-of-(\\d+)$/i;\n  const match = regex.exec(s);\n  if (match === null) {\n    throw new Error(`Invalid group specification: ${s}. Use format 'M-of-N' (e.g., '2-of-3').`);\n  }\n  const threshold = parseInt(match[1], 10);\n  const count = parseInt(match[2], 10);\n  return SSKRGroupSpec.new(threshold, count);\n}\n\n// ============================================================================\n// Cli Class\n// ============================================================================\n\n/**\n * CLI state and configuration.\n * Matches Rust Cli struct.\n */\nexport class Cli {\n  /** The input to be transformed. If required and not present, will be read from stdin. */\n  input?: string;\n\n  /** The number of output units (hex bytes, base-10 digits, etc.) */\n  count = 16;\n\n  /** The input format. Default: Random */\n  in = InputFormatKey.Random;\n\n  /** The output format. Default: Hex */\n  out = OutputFormatKey.Hex;\n\n  /** The lowest int returned (0-254). Default: 0 */\n  low = 0;\n\n  /** The highest int returned (1-255), low < high. Default: 9 */\n  high = 9;\n\n  /** The name of the seed. */\n  name?: string;\n\n  /** The note associated with the seed. */\n  note?: string;\n\n  /** The seed's creation date, in ISO-8601 format. May also be `now`. */\n  date?: Date;\n\n  /** For `multipart` output, max fragment length. Default: 500 */\n  maxFragmentLen = 500;\n\n  /** For `multipart` output, additional parts for fountain encoding. Default: 0 */\n  additionalParts = 0;\n\n  /** Group specifications for SSKR. */\n  groups: SSKRGroupSpec[] = [];\n\n  /** The number of groups that must meet their threshold. Default: 1 */\n  groupThreshold = 1;\n\n  /** SSKR output format. Default: Envelope */\n  sskrFormat = SSKRFormatKey.Envelope;\n\n  /** Deterministic RNG seed string. */\n  deterministic?: string;\n\n  /** The seed being processed (internal state). */\n  seed?: Seed;\n\n  /** The RNG source (internal state). */\n  rng?: RngSource;\n\n  /**\n   * Get input from argument or lazily read it from stdin.\n   *\n   * Mirrors Rust's `Cli::expect_input` (seedtool-cli-rust/src/cli.rs:191-200):\n   * stdin is touched only when an input-consuming code path actually needs it.\n   * Modes like `--in random` or `-d <SEED>` (deterministic) never call this,\n   * so they exit cleanly even when stdin is a non-TTY but no input is piped.\n   *\n   * Reads the stdin file descriptor synchronously via `fs.readFileSync(0, ...)`\n   * and caches the trimmed result on `this.input` so subsequent calls don't\n   * re-read.\n   */\n  expectInput(): string {\n    if (this.input !== undefined) {\n      return this.input;\n    }\n    this.input = fs.readFileSync(0, \"utf-8\").trim();\n    return this.input;\n  }\n\n  /**\n   * Get input from argument or read from stdin asynchronously.\n   * This is the async version for actual CLI use.\n   */\n  async expectInputAsync(): Promise<string> {\n    if (this.input !== undefined) {\n      return this.input;\n    }\n\n    // Read from stdin\n    return new Promise((resolve, reject) => {\n      let data = \"\";\n      const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout,\n        terminal: false,\n      });\n\n      rl.on(\"line\", (line: string) => {\n        data += `${line}\\n`;\n      });\n\n      rl.on(\"close\", () => {\n        resolve(data.trim());\n      });\n\n      rl.on(\"error\", (err: Error) => {\n        reject(err);\n      });\n    });\n  }\n\n  /**\n   * Get the seed, throwing if not initialized.\n   * Matches Rust expect_seed method.\n   */\n  expectSeed(): Seed {\n    if (this.seed === undefined) {\n      throw new Error(\"Seed not initialized\");\n    }\n    return this.seed;\n  }\n\n  /**\n   * Generate random data using the configured RNG.\n   * Matches Rust random_data method.\n   */\n  randomData(size: number): Uint8Array {\n    if (this.rng === undefined) {\n      throw new Error(\"RNG not initialized\");\n    }\n    if (this.rng.type === \"secure\") {\n      return this.rng.rng.randomData(size);\n    } else {\n      return this.rng.rng.deterministicRandomData(size);\n    }\n  }\n\n  /**\n   * Get the seed with CLI overrides applied (name, note, date).\n   * Matches Rust seed_with_overrides method.\n   */\n  seedWithOverrides(): Seed {\n    const seed = this.expectSeed().clone();\n    if (this.name !== undefined) {\n      seed.setName(this.name);\n    }\n    if (this.note !== undefined) {\n      seed.setNote(this.note);\n    }\n    if (this.date !== undefined) {\n      seed.setCreationDate(this.date);\n    }\n    return seed;\n  }\n\n  /**\n   * Convert the seed (with overrides) to an Envelope.\n   * Matches Rust to_envelope method.\n   */\n  toEnvelope(): Envelope {\n    return this.seedWithOverrides().toEnvelope();\n  }\n\n  /**\n   * Build SSKR spec from CLI options.\n   * Matches Rust sskr_spec method.\n   */\n  sskrSpec(): SSKRSpec {\n    return SSKRSpec.new(this.groupThreshold, this.groups);\n  }\n\n  /**\n   * Clone the CLI state.\n   */\n  clone(): Cli {\n    const cli = new Cli();\n    if (this.input !== undefined) cli.input = this.input;\n    cli.count = this.count;\n    cli.in = this.in;\n    cli.out = this.out;\n    cli.low = this.low;\n    cli.high = this.high;\n    if (this.name !== undefined) cli.name = this.name;\n    if (this.note !== undefined) cli.note = this.note;\n    if (this.date !== undefined) cli.date = this.date;\n    cli.maxFragmentLen = this.maxFragmentLen;\n    cli.additionalParts = this.additionalParts;\n    cli.groups = [...this.groups];\n    cli.groupThreshold = this.groupThreshold;\n    cli.sskrFormat = this.sskrFormat;\n    if (this.deterministic !== undefined) cli.deterministic = this.deterministic;\n    if (this.seed !== undefined) cli.seed = this.seed.clone();\n    if (this.rng !== undefined) cli.rng = this.rng;\n    return cli;\n  }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Seed type for seedtool-cli\n * Ported from seedtool-cli-rust/src/seed.rs\n *\n * This is a local Seed type that wraps the seed data with metadata\n * and provides Envelope conversion. It differs from @bcts/components Seed\n * in that it doesn't enforce minimum length (for CLI flexibility) and\n * has direct Envelope conversion methods.\n */\n\nimport { Envelope } from \"@bcts/envelope\";\nimport { Seed as ComponentsSeed } from \"@bcts/components\";\nimport { NAME, NOTE, DATE, SEED_TYPE } from \"@bcts/known-values\";\nimport { CborDate } from \"@bcts/dcbor\";\n\n/**\n * Seed with optional metadata.\n * Matches Rust Seed struct in seed.rs.\n */\nexport class Seed {\n  private readonly _data: Uint8Array;\n  private _name: string;\n  private _note: string;\n  private _creationDate: Date | undefined;\n\n  /**\n   * Create a new Seed with the given data.\n   * Matches Rust Seed::new function.\n   */\n  constructor(data: Uint8Array) {\n    this._data = new Uint8Array(data);\n    this._name = \"\";\n    this._note = \"\";\n    this._creationDate = undefined;\n  }\n\n  /**\n   * Create a new Seed with data and optional metadata.\n   * Matches Rust Seed::new_opt function.\n   */\n  static newOpt(data: Uint8Array, name: string, note: string, creationDate?: Date): Seed {\n    const seed = new Seed(data);\n    seed._name = name;\n    seed._note = note;\n    seed._creationDate = creationDate;\n    return seed;\n  }\n\n  /**\n   * Create a new Seed from raw data.\n   * Convenience factory method.\n   */\n  static new(data: Uint8Array): Seed {\n    return new Seed(data);\n  }\n\n  // ============================================================================\n  // Accessors\n  // ============================================================================\n\n  /**\n   * Get the seed data.\n   * Matches Rust seed.data() method.\n   */\n  data(): Uint8Array {\n    return this._data;\n  }\n\n  /**\n   * Get the seed name.\n   * Matches Rust seed.name() method.\n   * Returns empty string if not set.\n   */\n  name(): string {\n    return this._name;\n  }\n\n  /**\n   * Set the seed name.\n   * Matches Rust seed.set_name() method.\n   */\n  setName(name: string): void {\n    this._name = name;\n  }\n\n  /**\n   * Get the seed note.\n   * Matches Rust seed.note() method.\n   * Returns empty string if not set.\n   */\n  note(): string {\n    return this._note;\n  }\n\n  /**\n   * Set the seed note.\n   * Matches Rust seed.set_note() method.\n   */\n  setNote(note: string): void {\n    this._note = note;\n  }\n\n  /**\n   * Get the creation date.\n   * Matches Rust seed.creation_date() method.\n   */\n  creationDate(): Date | undefined {\n    return this._creationDate;\n  }\n\n  /**\n   * Set the creation date.\n   * Matches Rust seed.set_creation_date() method.\n   */\n  setCreationDate(date: Date | undefined): void {\n    this._creationDate = date;\n  }\n\n  // ============================================================================\n  // Cloning\n  // ============================================================================\n\n  /**\n   * Clone the seed.\n   */\n  clone(): Seed {\n    return Seed.newOpt(new Uint8Array(this._data), this._name, this._note, this._creationDate);\n  }\n\n  // ============================================================================\n  // Envelope Conversion\n  // ============================================================================\n\n  /**\n   * Convert to Envelope.\n   * Matches Rust impl From<Seed> for Envelope.\n   *\n   * Creates an envelope with:\n   * - Subject: byte string of seed data\n   * - Type assertion: 'Seed'\n   * - Optional date assertion\n   * - Optional name assertion (if not empty)\n   * - Optional note assertion (if not empty)\n   */\n  toEnvelope(): Envelope {\n    // Create envelope with seed data as byte string subject\n    let envelope = Envelope.new(this._data);\n\n    // Add type assertion\n    envelope = envelope.addType(SEED_TYPE);\n\n    // Add optional date assertion (using CBOR Date tag 1)\n    if (this._creationDate !== undefined) {\n      const cborDate = CborDate.fromDatetime(this._creationDate);\n      envelope = envelope.addAssertion(DATE, cborDate);\n    }\n\n    // Add optional name assertion (only if not empty)\n    if (this._name.length > 0) {\n      envelope = envelope.addAssertion(NAME, this._name);\n    }\n\n    // Add optional note assertion (only if not empty)\n    if (this._note.length > 0) {\n      envelope = envelope.addAssertion(NOTE, this._note);\n    }\n\n    return envelope;\n  }\n\n  /**\n   * Create a Seed from an Envelope.\n   * Matches Rust impl TryFrom<Envelope> for Seed.\n   */\n  static fromEnvelope(envelope: Envelope): Seed {\n    // Check type\n    envelope.checkTypeValue(SEED_TYPE);\n\n    // Extract data from subject (byte string)\n    const subject = envelope.subject();\n    const leaf = subject.asLeaf();\n    if (leaf === undefined) {\n      throw new Error(\"Seed envelope must have a leaf subject\");\n    }\n    const data = leaf.asByteString();\n    if (data === undefined) {\n      throw new Error(\"Seed envelope subject must be a byte string\");\n    }\n\n    // Extract optional name\n    let name = \"\";\n    try {\n      const nameObj = envelope.objectForPredicate(NAME);\n      if (nameObj !== undefined) {\n        const nameStr = nameObj.asText();\n        if (nameStr !== undefined) {\n          name = nameStr;\n        }\n      }\n    } catch {\n      // Name is optional\n    }\n\n    // Extract optional note\n    let note = \"\";\n    try {\n      const noteObj = envelope.objectForPredicate(NOTE);\n      if (noteObj !== undefined) {\n        const noteStr = noteObj.asText();\n        if (noteStr !== undefined) {\n          note = noteStr;\n        }\n      }\n    } catch {\n      // Note is optional\n    }\n\n    // Extract optional creation date (CBOR Date tag 1)\n    let creationDate: Date | undefined;\n    try {\n      const dateObj = envelope.objectForPredicate(DATE);\n      if (dateObj !== undefined) {\n        // Try to extract as CborDate first (tag 1)\n        const leaf = dateObj.asLeaf();\n        if (leaf !== undefined) {\n          const cborDate = CborDate.fromTaggedCbor(leaf);\n          creationDate = cborDate.datetime();\n        }\n      }\n    } catch {\n      // Date is optional, or might be a different format - try ISO string fallback\n      try {\n        const dateObj = envelope.objectForPredicate(DATE);\n        if (dateObj !== undefined) {\n          const dateStr = dateObj.asText();\n          if (dateStr !== undefined) {\n            creationDate = new Date(dateStr);\n          }\n        }\n      } catch {\n        // Date is optional\n      }\n    }\n\n    return Seed.newOpt(data, name, note, creationDate);\n  }\n\n  // ============================================================================\n  // ComponentsSeed Conversion\n  // ============================================================================\n\n  /**\n   * Convert to @bcts/components Seed.\n   * Matches Rust impl TryFrom<&Seed> for ComponentsSeed.\n   */\n  toComponentsSeed(): ComponentsSeed {\n    return ComponentsSeed.newOpt(\n      this._data,\n      this._name.length > 0 ? this._name : undefined,\n      this._note.length > 0 ? this._note : undefined,\n      this._creationDate,\n    );\n  }\n\n  /**\n   * Create from @bcts/components Seed.\n   * Matches Rust impl From<ComponentsSeed> for Seed.\n   */\n  static fromComponentsSeed(seed: ComponentsSeed): Seed {\n    return Seed.newOpt(seed.asBytes(), seed.name(), seed.note(), seed.creationDate());\n  }\n\n  // ============================================================================\n  // String Representation\n  // ============================================================================\n\n  /**\n   * Get string representation.\n   */\n  toString(): string {\n    const hex = Array.from(this._data.slice(0, 8))\n      .map((b) => b.toString(16).padStart(2, \"0\"))\n      .join(\"\");\n    return `Seed(${hex}..., ${this._data.length} bytes)`;\n  }\n\n  /**\n   * Check equality with another Seed.\n   */\n  equals(other: Seed): boolean {\n    if (this._data.length !== other._data.length) return false;\n    for (let i = 0; i < this._data.length; i++) {\n      if (this._data[i] !== other._data[i]) return false;\n    }\n    if (this._name !== other._name) return false;\n    if (this._note !== other._note) return false;\n    if (this._creationDate?.getTime() !== other._creationDate?.getTime()) return false;\n    return true;\n  }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Random number generation utilities\n * Ported from seedtool-cli-rust/src/random.rs\n */\n\nimport { sha256 } from \"@noble/hashes/sha2.js\";\nimport { hkdf } from \"@noble/hashes/hkdf.js\";\n\n/** SHA256 output size in bytes */\nconst SHA256_SIZE = 32;\n\n/**\n * Deterministic random number generator.\n * Matches Rust DeterministicRandomNumberGenerator struct.\n *\n * Uses HKDF-HMAC-SHA256 to generate deterministic random data\n * from a seed, with an incrementing salt for each call.\n */\nexport class DeterministicRandomNumberGenerator {\n  private readonly seed: Uint8Array;\n  private salt: bigint;\n\n  /**\n   * Create a new deterministic RNG from a 32-byte seed.\n   */\n  constructor(seed: Uint8Array) {\n    if (seed.length !== SHA256_SIZE) {\n      throw new Error(`Seed must be ${SHA256_SIZE} bytes, got ${seed.length}`);\n    }\n    this.seed = new Uint8Array(seed);\n    this.salt = 0n;\n  }\n\n  /**\n   * Create a new deterministic RNG from a seed string.\n   * The string is hashed with SHA256 to produce the seed.\n   * Matches Rust new_with_seed function.\n   */\n  static newWithSeed(seedString: string): DeterministicRandomNumberGenerator {\n    const encoder = new TextEncoder();\n    const seed = sha256(encoder.encode(seedString));\n    return new DeterministicRandomNumberGenerator(seed);\n  }\n\n  /**\n   * Generate deterministic random data.\n   * Matches Rust deterministic_random_data method.\n   *\n   * Each call increments the salt and uses HKDF to derive\n   * the requested number of bytes.\n   */\n  deterministicRandomData(size: number): Uint8Array {\n    this.salt += 1n;\n\n    // Convert salt to little-endian bytes\n    const saltBytes = new Uint8Array(8);\n    const view = new DataView(saltBytes.buffer);\n    // Split into low and high 32-bit parts for BigInt handling\n    const low = Number(this.salt & 0xffffffffn);\n    const high = Number((this.salt >> 32n) & 0xffffffffn);\n    view.setUint32(0, low, true); // little-endian\n    view.setUint32(4, high, true);\n\n    return hkdfHmacSha256(this.seed, saltBytes, size);\n  }\n\n  /**\n   * Clone the RNG state.\n   */\n  clone(): DeterministicRandomNumberGenerator {\n    const rng = new DeterministicRandomNumberGenerator(this.seed);\n    rng.salt = this.salt;\n    return rng;\n  }\n}\n\n/**\n * HKDF-HMAC-SHA256 key derivation.\n * Matches Rust hkdf_hmac_sha256 function from bc-crypto.\n */\nexport function hkdfHmacSha256(ikm: Uint8Array, salt: Uint8Array, length: number): Uint8Array {\n  // @noble/hashes hkdf takes (hash, ikm, salt, info, length)\n  // Use empty info for our use case\n  return hkdf(sha256, ikm, salt, new Uint8Array(0), length);\n}\n\n/**\n * Generate deterministic random data from entropy using SHA256.\n * If n <= 32, returns the first n bytes of SHA256(entropy).\n * Matches Rust sha256_deterministic_random function.\n *\n * @param entropy - The entropy bytes to hash\n * @param n - Number of bytes to return (must be <= 32)\n * @throws Error if n > 32\n */\nexport function sha256DeterministicRandom(entropy: Uint8Array, n: number): Uint8Array {\n  const seed = sha256(entropy);\n  if (n <= seed.length) {\n    return seed.slice(0, n);\n  } else {\n    throw new Error(\"Random number generator limits reached.\");\n  }\n}\n\n/**\n * Generate deterministic random data from a string using SHA256.\n * Matches Rust sha256_deterministic_random_string function.\n *\n * @param str - The string to hash\n * @param n - Number of bytes to return (must be <= 32)\n * @throws Error if n > 32\n */\nexport function sha256DeterministicRandomString(str: string, n: number): Uint8Array {\n  const encoder = new TextEncoder();\n  const entropy = encoder.encode(str);\n  return sha256DeterministicRandom(entropy, n);\n}\n\n/**\n * Generate deterministic random data from entropy using HKDF.\n * This can generate any length output.\n * Matches Rust deterministic_random function.\n *\n * @param entropy - The entropy bytes\n * @param n - Number of bytes to return\n */\nexport function deterministicRandom(entropy: Uint8Array, n: number): Uint8Array {\n  const seed = sha256(entropy);\n  return hkdfHmacSha256(seed, new Uint8Array(0), n);\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Utility functions for data conversion\n * Ported from seedtool-cli-rust/src/util.rs\n */\n\n/**\n * Convert bytes to hex string.\n * Matches Rust data_to_hex function.\n */\nexport function dataToHex(bytes: Uint8Array): string {\n  return Array.from(bytes)\n    .map((b) => b.toString(16).padStart(2, \"0\"))\n    .join(\"\");\n}\n\n/**\n * Convert hex string to bytes.\n *\n * Mirrors the error wording produced by Rust's `hex` crate\n * (`FromHexError::OddLength` and `FromHexError::InvalidHexCharacter`),\n * which seedtool-cli-rust surfaces unchanged through anyhow:\n *\n *   \"Odd number of digits\"\n *   \"Invalid character '{c}' at position {n}\"\n *\n * The outer CLI layer adds the `Error: ` prefix to match Rust's anyhow\n * output.\n */\nexport function hexToData(hex: string): Uint8Array {\n  if (hex.length % 2 !== 0) {\n    throw new Error(\"Odd number of digits\");\n  }\n  const bytes = new Uint8Array(hex.length / 2);\n  for (let i = 0; i < hex.length; i += 2) {\n    const hi = hexCharToNibble(hex, i);\n    const lo = hexCharToNibble(hex, i + 1);\n    bytes[i / 2] = (hi << 4) | lo;\n  }\n  return bytes;\n}\n\nfunction hexCharToNibble(hex: string, index: number): number {\n  const c = hex.charCodeAt(index);\n  // 0..9\n  if (c >= 0x30 && c <= 0x39) return c - 0x30;\n  // a..f\n  if (c >= 0x61 && c <= 0x66) return c - 0x61 + 10;\n  // A..F\n  if (c >= 0x41 && c <= 0x46) return c - 0x41 + 10;\n  throw new Error(`Invalid character '${hex[index]}' at position ${index}`);\n}\n\n/**\n * Convert byte values to a different base range [0, base-1].\n * Each byte (0-255) is scaled proportionally to the target base.\n * Matches Rust data_to_base function.\n *\n * @param buf - Input bytes\n * @param base - Target base (e.g., 6 for base-6)\n * @returns Array of values in range [0, base-1]\n */\nexport function dataToBase(buf: Uint8Array, base: number): Uint8Array {\n  const result = new Uint8Array(buf.length);\n  for (let i = 0; i < buf.length; i++) {\n    // Scale from [0,255] to [0,base-1] with rounding\n    result[i] = Math.round((buf[i] / 255) * (base - 1));\n  }\n  return result;\n}\n\n/**\n * Convert bytes to an alphabet string using a base and alphabet function.\n * Matches Rust data_to_alphabet function.\n *\n * @param buf - Input bytes\n * @param base - Target base\n * @param toAlphabet - Function to convert index to character\n * @returns String of alphabet characters\n */\nexport function dataToAlphabet(\n  buf: Uint8Array,\n  base: number,\n  toAlphabet: (n: number) => string,\n): string {\n  const data = dataToBase(buf, base);\n  return Array.from(data)\n    .map((b) => toAlphabet(b))\n    .join(\"\");\n}\n\n/**\n * Parse whitespace-separated integers.\n * Matches Rust parse_ints function.\n *\n * @param input - Space-separated integer string\n * @returns Array of bytes\n * @throws Error if any integer is out of range [0, 255]\n */\nexport function parseInts(input: string): Uint8Array {\n  const parts = input.trim().split(/\\s+/);\n  const result: number[] = [];\n  for (const s of parts) {\n    if (s === \"\") continue;\n    const i = parseInt(s, 10);\n    if (isNaN(i)) {\n      throw new Error(`Invalid integer: ${s}`);\n    }\n    if (i < 0 || i > 255) {\n      throw new Error(\"Integer out of range. Allowed: [0-255]\");\n    }\n    result.push(i);\n  }\n  return new Uint8Array(result);\n}\n\n/**\n * Convert bytes to a string of integers in a given range.\n * Matches Rust data_to_ints function.\n *\n * @param buf - Input bytes\n * @param low - Lowest output value (0-254)\n * @param high - Highest output value (1-255), low < high\n * @param separator - String to separate values\n * @returns String of integers\n * @throws Error if range is invalid\n */\nexport function dataToInts(buf: Uint8Array, low: number, high: number, separator: string): string {\n  if (!(low < high && high <= 255)) {\n    throw new Error(\"Int conversion range must be in 0 <= low < high <= 255.\");\n  }\n  const base = high - low + 1;\n  const data = dataToBase(buf, base);\n  return Array.from(data)\n    .map((b) => (b + low).toString())\n    .join(separator);\n}\n\n/**\n * Parse a string of digits in a given range to bytes.\n * Matches Rust digits_to_data function.\n *\n * @param inStr - String of digits\n * @param low - Lowest valid digit\n * @param high - Highest valid digit\n * @returns Array of digit values\n * @throws Error if any digit is out of range\n */\nexport function digitsToData(inStr: string, low: number, high: number): Uint8Array {\n  const result: number[] = [];\n  for (const c of inStr) {\n    const n = c.charCodeAt(0) - \"0\".charCodeAt(0);\n    if (n < low || n > high) {\n      // Mirrors Rust util.rs:64 (`bail!(\"Invalid digit.\")`). The terser wording\n      // is intentional — if Rust's diagnostic is broadened upstream, mirror here.\n      throw new Error(\"Invalid digit.\");\n    }\n    result.push(n);\n  }\n  return new Uint8Array(result);\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Hex format\n * Ported from seedtool-cli-rust/src/formats/hex.rs\n */\n\nimport type { Cli } from \"../cli.js\";\nimport type { InputFormat, OutputFormat } from \"./format.js\";\nimport { Seed } from \"../seed.js\";\nimport { hexToData, dataToHex } from \"../util.js\";\n\n/**\n * Hexadecimal format handler.\n * Round-trippable: hex → seed → hex.\n */\nexport class HexFormat implements InputFormat, OutputFormat {\n  name(): string {\n    return \"hex\";\n  }\n\n  roundTrippable(): boolean {\n    return true;\n  }\n\n  processInput(state: Cli): Cli {\n    const input = state.expectInput();\n    const seed = Seed.new(hexToData(input));\n    state.seed = seed;\n    return state;\n  }\n\n  processOutput(state: Cli): string {\n    return dataToHex(state.expectSeed().data());\n  }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * BIP39 mnemonic format\n * Ported from seedtool-cli-rust/src/formats/bip39.rs\n */\n\nimport type { Cli } from \"../cli.js\";\nimport type { InputFormat, OutputFormat } from \"./format.js\";\nimport { Seed } from \"../seed.js\";\nimport { mnemonicToEntropy, entropyToMnemonic, validateMnemonic } from \"@scure/bip39\";\nimport { wordlist } from \"@scure/bip39/wordlists/english.js\";\n\n/**\n * BIP39 mnemonic format handler.\n * Round-trippable: mnemonic → seed → mnemonic.\n */\nexport class Bip39Format implements InputFormat, OutputFormat {\n  name(): string {\n    return \"bip39\";\n  }\n\n  roundTrippable(): boolean {\n    return true;\n  }\n\n  processInput(state: Cli): Cli {\n    const input = state.expectInput();\n    // Normalize the mnemonic (lowercase, single spaces)\n    const normalized = input.toLowerCase().trim().replace(/\\s+/g, \" \");\n\n    if (!validateMnemonic(normalized, wordlist)) {\n      throw new Error(\"Invalid BIP39 mnemonic\");\n    }\n\n    const entropy = mnemonicToEntropy(normalized, wordlist);\n    state.seed = Seed.new(entropy);\n    return state;\n  }\n\n  processOutput(state: Cli): string {\n    const mnemonic = entropyToMnemonic(state.expectSeed().data(), wordlist);\n    return mnemonic;\n  }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * SSKR format\n * Ported from seedtool-cli-rust/src/formats/sskr.rs\n */\n\nimport { SSKRFormatKey, type Cli } from \"../cli.js\";\nimport type { InputFormat, OutputFormat } from \"./format.js\";\nimport { Seed } from \"../seed.js\";\nimport { Envelope, SymmetricKey } from \"@bcts/envelope\";\nimport {\n  SSKRShare,\n  SSKRSecret,\n  sskrGenerate,\n  sskrCombine,\n  type SSKRShareCbor,\n} from \"@bcts/components\";\nimport { encodeBytewords, decodeBytewords, BytewordsStyle, UR } from \"@bcts/uniform-resources\";\nimport { SSKR_SHARE, SSKR_SHARE_V1 } from \"@bcts/tags\";\nimport { toByteString, toTaggedValue, decodeCbor, expectBytes } from \"@bcts/dcbor\";\nimport type { Spec } from \"@bcts/sskr\";\n\n/**\n * SSKR format handler.\n * Round-trippable: sskr shares → seed → sskr shares.\n * Supports multiple sub-formats: envelope, btw, btwm, btwu, ur.\n */\nexport class SSKRFormat implements InputFormat, OutputFormat {\n  name(): string {\n    return \"sskr\";\n  }\n\n  roundTrippable(): boolean {\n    return true;\n  }\n\n  processInput(state: Cli): Cli {\n    const input = state.expectInput();\n    state.seed = parseSskrSeed(input);\n    return state;\n  }\n\n  processOutput(state: Cli): string {\n    const spec = state.sskrSpec();\n    const seed = state.expectSeed();\n    const format = state.sskrFormat;\n    return outputSskrSeed(seed, spec, format);\n  }\n}\n\n//\n// Output Helpers\n//\n\nfunction outputSskrSeed(seed: Seed, spec: Spec, format: SSKRFormatKey): string {\n  switch (format) {\n    case SSKRFormatKey.Envelope: {\n      const seedEnvelope = seed.toEnvelope();\n      const contentKey = SymmetricKey.new();\n      const encryptedEnvelope = seedEnvelope.wrap().encryptSubject(contentKey);\n      // Use type assertion for prototype extension method\n      const shareEnvelopes: Envelope[] = (\n        encryptedEnvelope as unknown as {\n          sskrSplitFlattened: (spec: Spec, key: SymmetricKey) => Envelope[];\n        }\n      ).sskrSplitFlattened(spec, contentKey);\n\n      const shareEnvelopesStrings: string[] = shareEnvelopes.map((env: Envelope) => env.urString());\n      return shareEnvelopesStrings.join(\"\\n\");\n    }\n    case SSKRFormatKey.Btw: {\n      return makeBytewordsShares(spec, seed, BytewordsStyle.Standard);\n    }\n    case SSKRFormatKey.Btwm: {\n      return makeBytewordsShares(spec, seed, BytewordsStyle.Minimal);\n    }\n    case SSKRFormatKey.Btwu: {\n      return makeBytewordsShares(spec, seed, BytewordsStyle.Uri);\n    }\n    case SSKRFormatKey.Ur: {\n      const shares = makeShares(spec, seed);\n      const urStrings: string[] = shares.map((share) => {\n        const ur = UR.new(\"sskr\", toByteString(share.asBytes()));\n        return ur.toString();\n      });\n      return urStrings.join(\"\\n\");\n    }\n  }\n}\n\nfunction makeShares(spec: Spec, seed: Seed): SSKRShareCbor[] {\n  const secret = SSKRSecret.new(seed.data());\n  const shareGroups = sskrGenerate(spec, secret);\n  const flatShares: SSKRShareCbor[] = [];\n  for (const group of shareGroups) {\n    for (const shareData of group) {\n      flatShares.push(SSKRShare.fromData(shareData));\n    }\n  }\n  return flatShares;\n}\n\nfunction makeBytewordsShares(spec: Spec, seed: Seed, style: BytewordsStyle): string {\n  const shares = makeShares(spec, seed);\n  const cborShares = shares.map((share) =>\n    toTaggedValue(SSKR_SHARE.value, toByteString(share.asBytes())),\n  );\n  const sharesStrings = cborShares.map((share) => encodeBytewords(share.toData(), style));\n  return sharesStrings.join(\"\\n\");\n}\n\n//\n// Input Helpers\n//\n\nfunction parseEnvelopes(input: string): Seed | null {\n  try {\n    const shareStrings = input.split(/\\s+/).filter((s) => s.length > 0);\n    const shareEnvelopes: Envelope[] = [];\n    for (const str of shareStrings) {\n      try {\n        const envelope = Envelope.fromURString(str);\n        shareEnvelopes.push(envelope);\n      } catch {\n        // Skip non-envelope strings\n      }\n    }\n\n    if (shareEnvelopes.length === 0) {\n      return null;\n    }\n\n    // Use type assertion for static prototype extension method\n    const sskrJoin = (Envelope as unknown as { sskrJoin: (envelopes: Envelope[]) => Envelope })\n      .sskrJoin;\n    const recoveredEnvelope: Envelope = sskrJoin(shareEnvelopes).unwrap();\n\n    return Seed.fromEnvelope(recoveredEnvelope);\n  } catch {\n    return null;\n  }\n}\n\nfunction fromUntaggedCborShares(untaggedCborShares: Uint8Array[]): Seed | null {\n  try {\n    const recoveredSecret = sskrCombine(untaggedCborShares);\n    return Seed.new(recoveredSecret.getData());\n  } catch {\n    return null;\n  }\n}\n\nfunction fromTaggedCborShares(taggedCborDataShares: Uint8Array[]): Seed | null {\n  try {\n    const untaggedShares: Uint8Array[] = [];\n    for (const data of taggedCborDataShares) {\n      const cbor = decodeCbor(data);\n      // Extract the tagged value and ensure it's the expected tag\n      const tagged = cbor as { tag?: number; value?: unknown };\n      if (tagged.tag !== SSKR_SHARE.value && tagged.tag !== SSKR_SHARE_V1.value) {\n        return null;\n      }\n      const content =\n        tagged.value !== undefined ? (tagged.value as ReturnType<typeof decodeCbor>) : cbor;\n      const bytes = expectBytes(content);\n      untaggedShares.push(bytes);\n    }\n    return fromUntaggedCborShares(untaggedShares);\n  } catch {\n    return null;\n  }\n}\n\nfunction parseBytewords(input: string, style: BytewordsStyle): Seed | null {\n  try {\n    // Standard bytewords include spaces, so we can only split on newlines.\n    let shareStrings: string[];\n    if (style === BytewordsStyle.Standard) {\n      shareStrings = input.split(\"\\n\").filter((s) => s.length > 0);\n    } else {\n      shareStrings = input.split(/\\s+/).filter((s) => s.length > 0);\n    }\n\n    const cborDataShares: Uint8Array[] = [];\n    for (const s of shareStrings) {\n      try {\n        const decoded = decodeBytewords(s, style);\n        cborDataShares.push(decoded);\n      } catch {\n        // Skip invalid bytewords\n      }\n    }\n\n    if (cborDataShares.length === 0) {\n      return null;\n    }\n\n    return fromTaggedCborShares(cborDataShares);\n  } catch {\n    return null;\n  }\n}\n\nfunction parseUr(input: string, expectedTagValue: number, allowTaggedCbor: boolean): Seed | null {\n  try {\n    // Get the expected type name\n    const expectedType = expectedTagValue === SSKR_SHARE.value ? \"sskr\" : \"crypto-sskr\";\n\n    const shareStrings = input.split(/\\s+/).filter((s) => s.length > 0);\n    const urs: UR[] = [];\n\n    for (const str of shareStrings) {\n      try {\n        const ur = UR.fromURString(str);\n        urs.push(ur);\n      } catch {\n        // Skip non-UR strings\n      }\n    }\n\n    if (urs.length === 0) {\n      return null;\n    }\n\n    // Ensure every UR is of the expected type\n    for (const ur of urs) {\n      if (ur.urTypeStr() !== expectedType) {\n        return null;\n      }\n    }\n\n    const untaggedCborShares: Uint8Array[] = [];\n    for (const ur of urs) {\n      let cbor = ur.cbor();\n\n      // Legacy SSKR shares might have tagged CBOR, even though they're\n      // URs so they shouldn't be.\n      if (allowTaggedCbor) {\n        try {\n          const decoded = decodeCbor(cbor.toData());\n          const tagged = decoded as { tag?: number; value?: unknown };\n          if (tagged.tag === SSKR_SHARE.value || tagged.tag === SSKR_SHARE_V1.value) {\n            const content = tagged.value as { buffer?: Uint8Array };\n            cbor = content as unknown as ReturnType<typeof toByteString>;\n          }\n        } catch {\n          // Not tagged CBOR, use as-is\n        }\n      }\n\n      // The CBOR should be a byte string\n      const bytes = expectBytes(cbor);\n      untaggedCborShares.push(bytes);\n    }\n\n    return fromUntaggedCborShares(untaggedCborShares);\n  } catch {\n    return null;\n  }\n}\n\nfunction parseSskrSeed(input: string): Seed {\n  // Try envelope format first\n  const envelopeResult = parseEnvelopes(input);\n  if (envelopeResult !== null) {\n    return envelopeResult;\n  }\n\n  // Try bytewords standard format\n  const btwResult = parseBytewords(input, BytewordsStyle.Standard);\n  if (btwResult !== null) {\n    return btwResult;\n  }\n\n  // Try bytewords minimal format\n  const btwmResult = parseBytewords(input, BytewordsStyle.Minimal);\n  if (btwmResult !== null) {\n    return btwmResult;\n  }\n\n  // Try bytewords uri format\n  const btwuResult = parseBytewords(input, BytewordsStyle.Uri);\n  if (btwuResult !== null) {\n    return btwuResult;\n  }\n\n  // Try UR format (current tag)\n  const urResult = parseUr(input, Number(SSKR_SHARE.value), false);\n  if (urResult !== null) {\n    return urResult;\n  }\n\n  // Try legacy UR format (v1 tag, allow tagged cbor)\n  const urLegacyResult = parseUr(input, Number(SSKR_SHARE_V1.value), true);\n  if (urLegacyResult !== null) {\n    return urLegacyResult;\n  }\n\n  throw new Error(\"Insufficient or invalid SSKR shares.\");\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Envelope format\n * Ported from seedtool-cli-rust/src/formats/envelope.rs\n */\n\nimport type { Cli } from \"../cli.js\";\nimport type { InputFormat, OutputFormat } from \"./format.js\";\nimport { Seed } from \"../seed.js\";\nimport { Envelope } from \"@bcts/envelope\";\n\n/**\n * Gordian Envelope format handler.\n * Round-trippable: envelope UR → seed → envelope UR.\n */\nexport class EnvelopeFormat implements InputFormat, OutputFormat {\n  name(): string {\n    return \"envelope\";\n  }\n\n  roundTrippable(): boolean {\n    return true;\n  }\n\n  processInput(state: Cli): Cli {\n    const input = state.expectInput();\n    const envelope = Envelope.fromURString(input);\n    state.seed = Seed.fromEnvelope(envelope);\n    return state;\n  }\n\n  processOutput(state: Cli): string {\n    return state.toEnvelope().urString();\n  }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Seed UR format\n * Ported from seedtool-cli-rust/src/formats/seed.rs\n */\n\nimport type { Cli } from \"../cli.js\";\nimport type { InputFormat, OutputFormat } from \"./format.js\";\nimport { Seed } from \"../seed.js\";\nimport { Seed as ComponentsSeed } from \"@bcts/components\";\n\n/**\n * Seed UR format handler.\n * Round-trippable: seed UR → seed → seed UR.\n * Uses the ur:seed format from bc-components.\n */\nexport class SeedFormat implements InputFormat, OutputFormat {\n  name(): string {\n    return \"seed\";\n  }\n\n  roundTrippable(): boolean {\n    return true;\n  }\n\n  processInput(state: Cli): Cli {\n    const input = state.expectInput();\n    const componentsSeed = ComponentsSeed.fromURString(input);\n    state.seed = Seed.fromComponentsSeed(componentsSeed);\n    return state;\n  }\n\n  processOutput(state: Cli): string {\n    const seed = state.seedWithOverrides();\n    const componentsSeed = seed.toComponentsSeed();\n    return componentsSeed.urString();\n  }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Multipart UR format\n * Ported from seedtool-cli-rust/src/formats/multipart.rs\n */\n\nimport type { Cli } from \"../cli.js\";\nimport type { InputFormat, OutputFormat } from \"./format.js\";\nimport { Seed } from \"../seed.js\";\nimport { Envelope } from \"@bcts/envelope\";\nimport { MultipartEncoder, MultipartDecoder } from \"@bcts/uniform-resources\";\n\n/**\n * Multipart UR format handler.\n * Round-trippable: multipart URs → seed → multipart URs.\n * Uses fountain encoding for reliable transmission.\n */\nexport class MultipartFormat implements InputFormat, OutputFormat {\n  name(): string {\n    return \"multipart\";\n  }\n\n  roundTrippable(): boolean {\n    return true;\n  }\n\n  processInput(state: Cli): Cli {\n    const input = state.expectInput();\n    const shares = input.split(/\\s+/).filter((s) => s.length > 0);\n\n    const decoder = new MultipartDecoder();\n    for (const share of shares) {\n      decoder.receive(share);\n      if (decoder.isComplete()) {\n        break;\n      }\n    }\n\n    if (!decoder.isComplete()) {\n      // Mirrors Rust multipart.rs:30 verbatim, including the upstream copy-paste\n      // bug that says \"SSKR shares\" instead of \"multipart shares\". Replicated\n      // for byte-identical stderr; mirror the corrected wording once Rust is\n      // fixed upstream.\n      throw new Error(\"Insufficient SSKR shares\");\n    }\n\n    const ur = decoder.message();\n    if (ur === undefined || ur === null) {\n      throw new Error(\"Failed to decode multipart message\");\n    }\n\n    const envelope = Envelope.fromUR(ur);\n    state.seed = Seed.fromEnvelope(envelope);\n    return state;\n  }\n\n  processOutput(state: Cli): string {\n    const ur = state.toEnvelope().ur();\n    const encoder = new MultipartEncoder(ur, state.maxFragmentLen);\n    const partsCount = encoder.partsCount() + state.additionalParts;\n\n    const parts: string[] = [];\n    for (let i = 0; i < partsCount; i++) {\n      parts.push(encoder.nextPart());\n    }\n\n    return parts.join(\"\\n\");\n  }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Random format\n * Ported from seedtool-cli-rust/src/formats/random.rs\n */\n\nimport type { Cli } from \"../cli.js\";\nimport type { InputFormat } from \"./format.js\";\nimport { Seed } from \"../seed.js\";\n\n/**\n * Random seed generation format.\n * Input-only: generates a new random seed.\n */\nexport class RandomFormat implements InputFormat {\n  name(): string {\n    return \"random\";\n  }\n\n  roundTrippable(): boolean {\n    return true;\n  }\n\n  processInput(state: Cli): Cli {\n    const data = state.randomData(state.count);\n    state.seed = Seed.new(data);\n    return state;\n  }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Base6 format\n * Ported from seedtool-cli-rust/src/formats/base6.rs\n */\n\nimport type { Cli } from \"../cli.js\";\nimport type { InputFormat, OutputFormat } from \"./format.js\";\nimport { Seed } from \"../seed.js\";\nimport { sha256DeterministicRandomString } from \"../random.js\";\nimport { dataToInts, digitsToData } from \"../util.js\";\n\n/**\n * Base-6 format handler.\n * NOT round-trippable: input is entropy source.\n * Digits 0-5 (compatible with https://iancoleman.io/bip39/).\n */\nexport class Base6Format implements InputFormat, OutputFormat {\n  name(): string {\n    return \"base6\";\n  }\n\n  roundTrippable(): boolean {\n    return false;\n  }\n\n  processInput(state: Cli): Cli {\n    const input = state.expectInput();\n    // Syntax check only - validates that all characters are 0-5\n    digitsToData(input, 0, 5);\n    // Use SHA256 deterministic random to generate seed from input\n    const data = sha256DeterministicRandomString(input, state.count);\n    state.seed = Seed.new(data);\n    return state;\n  }\n\n  processOutput(state: Cli): string {\n    return dataToInts(state.expectSeed().data(), 0, 5, \"\");\n  }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Base10 format\n * Ported from seedtool-cli-rust/src/formats/base10.rs\n */\n\nimport type { Cli } from \"../cli.js\";\nimport type { InputFormat, OutputFormat } from \"./format.js\";\nimport { Seed } from \"../seed.js\";\nimport { sha256DeterministicRandomString } from \"../random.js\";\nimport { dataToInts, digitsToData } from \"../util.js\";\n\n/**\n * Base-10 format handler.\n * NOT round-trippable: input is entropy source.\n * Digits 0-9 (compatible with https://iancoleman.io/bip39/).\n */\nexport class Base10Format implements InputFormat, OutputFormat {\n  name(): string {\n    return \"base10\";\n  }\n\n  roundTrippable(): boolean {\n    return false;\n  }\n\n  processInput(state: Cli): Cli {\n    const input = state.expectInput();\n    // Syntax check only - validates that all characters are 0-9\n    digitsToData(input, 0, 9);\n    // Use SHA256 deterministic random to generate seed from input\n    const data = sha256DeterministicRandomString(input, state.count);\n    state.seed = Seed.new(data);\n    return state;\n  }\n\n  processOutput(state: Cli): string {\n    return dataToInts(state.expectSeed().data(), 0, 9, \"\");\n  }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Bits format\n * Ported from seedtool-cli-rust/src/formats/bits.rs\n */\n\nimport type { Cli } from \"../cli.js\";\nimport type { InputFormat, OutputFormat } from \"./format.js\";\nimport { Seed } from \"../seed.js\";\nimport { sha256DeterministicRandomString } from \"../random.js\";\nimport { dataToInts, digitsToData } from \"../util.js\";\n\n/**\n * Binary format handler.\n * NOT round-trippable: input is entropy source.\n * Bits 0-1 (compatible with https://iancoleman.io/bip39/).\n */\nexport class BitsFormat implements InputFormat, OutputFormat {\n  name(): string {\n    return \"bits\";\n  }\n\n  roundTrippable(): boolean {\n    return false;\n  }\n\n  processInput(state: Cli): Cli {\n    const input = state.expectInput();\n    // Syntax check only - validates that all characters are 0-1\n    digitsToData(input, 0, 1);\n    // Use SHA256 deterministic random to generate seed from input\n    const data = sha256DeterministicRandomString(input, state.count);\n    state.seed = Seed.new(data);\n    return state;\n  }\n\n  processOutput(state: Cli): string {\n    return dataToInts(state.expectSeed().data(), 0, 1, \"\");\n  }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Dice format\n * Ported from seedtool-cli-rust/src/formats/dice.rs\n */\n\nimport type { Cli } from \"../cli.js\";\nimport type { InputFormat, OutputFormat } from \"./format.js\";\nimport { Seed } from \"../seed.js\";\nimport { sha256DeterministicRandomString } from \"../random.js\";\nimport { dataToInts, digitsToData } from \"../util.js\";\n\n/**\n * Dice roll format handler.\n * NOT round-trippable: input is entropy source.\n * Digits 1-6 (compatible with https://iancoleman.io/bip39/).\n */\nexport class DiceFormat implements InputFormat, OutputFormat {\n  name(): string {\n    return \"dice\";\n  }\n\n  roundTrippable(): boolean {\n    return false;\n  }\n\n  processInput(state: Cli): Cli {\n    const input = state.expectInput();\n    // Syntax check only - validates that all characters are 1-6\n    digitsToData(input, 1, 6);\n    // Use SHA256 deterministic random to generate seed from input\n    const data = sha256DeterministicRandomString(input, state.count);\n    state.seed = Seed.new(data);\n    return state;\n  }\n\n  processOutput(state: Cli): string {\n    return dataToInts(state.expectSeed().data(), 1, 6, \"\");\n  }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Cards format\n * Ported from seedtool-cli-rust/src/formats/cards.rs\n */\n\nimport type { Cli } from \"../cli.js\";\nimport type { InputFormat, OutputFormat } from \"./format.js\";\nimport { Seed } from \"../seed.js\";\nimport { deterministicRandom } from \"../random.js\";\nimport { dataToAlphabet } from \"../util.js\";\n\n// Arrangement of cards per:\n// https://github.com/iancoleman/bip39/blob/master/src/js/entropy.js\nconst CARD_SUITS = \"cdhs\";\nconst CARD_RANKS = \"a23456789tjqk\";\n\n/**\n * Parse a card rank character.\n * Returns index 0-12.\n */\nfunction parseRank(c: string): number {\n  const lower = c.toLowerCase();\n  const index = CARD_RANKS.indexOf(lower);\n  if (index === -1) {\n    // Mirrors Rust cards.rs:43 — terse, no offending-char suffix.\n    throw new Error(\"Invalid card rank. Allowed: [A,2-9,T,J,Q,K]\");\n  }\n  return index;\n}\n\n/**\n * Parse a card suit character.\n * Returns index 0-3.\n */\nfunction parseSuit(c: string): number {\n  const lower = c.toLowerCase();\n  const index = CARD_SUITS.indexOf(lower);\n  if (index === -1) {\n    // Mirrors Rust cards.rs:53 verbatim, including the upstream copy-paste bug\n    // that says \"rank\" instead of \"suit\" and orders [D,C,H,S]. We replicate\n    // the bug for byte-identical stderr; once Rust is fixed upstream, mirror\n    // the corrected wording here.\n    throw new Error(\"Invalid card rank. Allowed: [D,C,H,S]\");\n  }\n  return index;\n}\n\n/**\n * Convert card string to byte array.\n * Each pair of characters represents one card.\n */\nfunction cardsToData(cards: string): Uint8Array {\n  const len = cards.length;\n  if (len % 2 !== 0) {\n    throw new Error(\"Cards string must have even number of characters.\");\n  }\n  const count = len / 2;\n  const result = new Uint8Array(count);\n  for (let i = 0; i < count; i++) {\n    const rank = parseRank(cards[i * 2]);\n    const suit = parseSuit(cards[i * 2 + 1]);\n    const n = suit * 13 + rank;\n    result[i] = n;\n  }\n  return result;\n}\n\n/**\n * Convert a card index (0-51) to card string.\n */\nfunction toCard(n: number): string {\n  if (n > 51) {\n    throw new Error(`Card index out of range: ${n}`);\n  }\n  const rank = n % 13;\n  const suit = Math.floor(n / 13);\n  return CARD_RANKS[rank] + CARD_SUITS[suit];\n}\n\n/**\n * Playing cards format handler.\n * NOT round-trippable: input is entropy source.\n * Card notation: rank (A,2-9,T,J,Q,K) + suit (C,D,H,S).\n */\nexport class CardsFormat implements InputFormat, OutputFormat {\n  name(): string {\n    return \"cards\";\n  }\n\n  roundTrippable(): boolean {\n    return false;\n  }\n\n  processInput(state: Cli): Cli {\n    const input = state.expectInput();\n    const entropy = cardsToData(input);\n    const data = deterministicRandom(entropy, state.count);\n    state.seed = Seed.new(data);\n    return state;\n  }\n\n  processOutput(state: Cli): string {\n    return dataToAlphabet(state.expectSeed().data(), 52, toCard);\n  }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Ints format\n * Ported from seedtool-cli-rust/src/formats/ints.rs\n */\n\nimport type { Cli } from \"../cli.js\";\nimport type { InputFormat, OutputFormat } from \"./format.js\";\nimport { Seed } from \"../seed.js\";\nimport { deterministicRandom } from \"../random.js\";\nimport { dataToInts, parseInts } from \"../util.js\";\n\n/**\n * Integer list format handler.\n * NOT round-trippable: input is entropy source.\n * Configurable range via --low and --high CLI options.\n */\nexport class IntsFormat implements InputFormat, OutputFormat {\n  name(): string {\n    return \"ints\";\n  }\n\n  roundTrippable(): boolean {\n    return false;\n  }\n\n  processInput(state: Cli): Cli {\n    const input = state.expectInput();\n    const entropy = parseInts(input);\n    const data = deterministicRandom(entropy, state.count);\n    state.seed = Seed.new(data);\n    return state;\n  }\n\n  processOutput(state: Cli): string {\n    return dataToInts(state.expectSeed().data(), state.low, state.high, \" \");\n  }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Bytewords Standard format\n * Ported from seedtool-cli-rust/src/formats/bytewords_standard.rs\n */\n\nimport type { Cli } from \"../cli.js\";\nimport type { InputFormat, OutputFormat } from \"./format.js\";\nimport { Seed } from \"../seed.js\";\nimport { encodeBytewords, decodeBytewords, BytewordsStyle } from \"@bcts/uniform-resources\";\n\n/**\n * Bytewords Standard format handler.\n * Round-trippable: bytewords → seed → bytewords.\n * Uses full words separated by spaces.\n */\nexport class BytewordsStandardFormat implements InputFormat, OutputFormat {\n  name(): string {\n    return \"btw\";\n  }\n\n  roundTrippable(): boolean {\n    return true;\n  }\n\n  processInput(state: Cli): Cli {\n    const input = state.expectInput();\n    const data = decodeBytewords(input, BytewordsStyle.Standard);\n    state.seed = Seed.new(data);\n    return state;\n  }\n\n  processOutput(state: Cli): string {\n    return encodeBytewords(state.expectSeed().data(), BytewordsStyle.Standard);\n  }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Bytewords Minimal format\n * Ported from seedtool-cli-rust/src/formats/bytewords_minimal.rs\n */\n\nimport type { Cli } from \"../cli.js\";\nimport type { InputFormat, OutputFormat } from \"./format.js\";\nimport { Seed } from \"../seed.js\";\nimport { encodeBytewords, decodeBytewords, BytewordsStyle } from \"@bcts/uniform-resources\";\n\n/**\n * Bytewords Minimal format handler.\n * Round-trippable: bytewords → seed → bytewords.\n * Uses 2-letter abbreviations without separators.\n */\nexport class BytewordsMinimalFormat implements InputFormat, OutputFormat {\n  name(): string {\n    return \"btwm\";\n  }\n\n  roundTrippable(): boolean {\n    return true;\n  }\n\n  processInput(state: Cli): Cli {\n    const input = state.expectInput();\n    const data = decodeBytewords(input, BytewordsStyle.Minimal);\n    state.seed = Seed.new(data);\n    return state;\n  }\n\n  processOutput(state: Cli): string {\n    return encodeBytewords(state.expectSeed().data(), BytewordsStyle.Minimal);\n  }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Bytewords URI format\n * Ported from seedtool-cli-rust/src/formats/bytewords_uri.rs\n */\n\nimport type { Cli } from \"../cli.js\";\nimport type { InputFormat, OutputFormat } from \"./format.js\";\nimport { Seed } from \"../seed.js\";\nimport { encodeBytewords, decodeBytewords, BytewordsStyle } from \"@bcts/uniform-resources\";\n\n/**\n * Bytewords URI format handler.\n * Round-trippable: bytewords → seed → bytewords.\n * Uses full words separated by hyphens (URI-safe).\n */\nexport class BytewordsUriFormat implements InputFormat, OutputFormat {\n  name(): string {\n    return \"btwu\";\n  }\n\n  roundTrippable(): boolean {\n    return true;\n  }\n\n  processInput(state: Cli): Cli {\n    const input = state.expectInput();\n    const data = decodeBytewords(input, BytewordsStyle.Uri);\n    state.seed = Seed.new(data);\n    return state;\n  }\n\n  processOutput(state: Cli): string {\n    return encodeBytewords(state.expectSeed().data(), BytewordsStyle.Uri);\n  }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Format traits and factory functions\n * Ported from seedtool-cli-rust/src/formats/format.rs\n */\n\nimport { InputFormatKey, OutputFormatKey, type Cli } from \"../cli.js\";\n\n// ============================================================================\n// Format Interfaces (Traits)\n// ============================================================================\n\n/**\n * Base format interface.\n * Matches Rust Format trait.\n */\nexport interface Format {\n  /** Get the format name */\n  name(): string;\n  /** Whether this format supports round-trip conversion */\n  roundTrippable(): boolean;\n}\n\n/**\n * Input format interface.\n * Matches Rust InputFormat trait.\n */\nexport interface InputFormat extends Format {\n  /** Process input and update CLI state with seed */\n  processInput(state: Cli): Cli;\n}\n\n/**\n * Output format interface.\n * Matches Rust OutputFormat trait.\n */\nexport interface OutputFormat extends Format {\n  /** Process seed from CLI state and return output string */\n  processOutput(state: Cli): string;\n}\n\n// ============================================================================\n// Format Factory Functions\n// ============================================================================\n\n// Import formats (will be implemented in subsequent files)\nimport { HexFormat } from \"./hex.js\";\nimport { Bip39Format } from \"./bip39.js\";\nimport { SSKRFormat } from \"./sskr.js\";\nimport { EnvelopeFormat } from \"./envelope.js\";\nimport { SeedFormat } from \"./seed-format.js\";\nimport { MultipartFormat } from \"./multipart.js\";\nimport { RandomFormat } from \"./random.js\";\nimport { Base6Format } from \"./base6.js\";\nimport { Base10Format } from \"./base10.js\";\nimport { BitsFormat } from \"./bits.js\";\nimport { DiceFormat } from \"./dice.js\";\nimport { CardsFormat } from \"./cards.js\";\nimport { IntsFormat } from \"./ints.js\";\nimport { BytewordsStandardFormat } from \"./bytewords-standard.js\";\nimport { BytewordsMinimalFormat } from \"./bytewords-minimal.js\";\nimport { BytewordsUriFormat } from \"./bytewords-uri.js\";\n\n/**\n * Select input format by key.\n * Matches Rust select_input_format function.\n */\nexport function selectInputFormat(key: InputFormatKey): InputFormat {\n  switch (key) {\n    case InputFormatKey.Random:\n      return new RandomFormat();\n    case InputFormatKey.Hex:\n      return new HexFormat();\n    case InputFormatKey.Btw:\n      return new BytewordsStandardFormat();\n    case InputFormatKey.Btwu:\n      return new BytewordsUriFormat();\n    case InputFormatKey.Btwm:\n      return new BytewordsMinimalFormat();\n    case InputFormatKey.Bits:\n      return new BitsFormat();\n    case InputFormatKey.Cards:\n      return new CardsFormat();\n    case InputFormatKey.Dice:\n      return new DiceFormat();\n    case InputFormatKey.Base6:\n      return new Base6Format();\n    case InputFormatKey.Base10:\n      return new Base10Format();\n    case InputFormatKey.Ints:\n      return new IntsFormat();\n    case InputFormatKey.Bip39:\n      return new Bip39Format();\n    case InputFormatKey.Sskr:\n      return new SSKRFormat();\n    case InputFormatKey.Envelope:\n      return new EnvelopeFormat();\n    case InputFormatKey.Multipart:\n      return new MultipartFormat();\n    case InputFormatKey.Seed:\n      return new SeedFormat();\n  }\n}\n\n/**\n * Select output format by key.\n * Matches Rust select_output_format function.\n */\nexport function selectOutputFormat(key: OutputFormatKey): OutputFormat {\n  switch (key) {\n    case OutputFormatKey.Hex:\n      return new HexFormat();\n    case OutputFormatKey.Btw:\n      return new BytewordsStandardFormat();\n    case OutputFormatKey.Btwu:\n      return new BytewordsUriFormat();\n    case OutputFormatKey.Btwm:\n      return new BytewordsMinimalFormat();\n    case OutputFormatKey.Bits:\n      return new BitsFormat();\n    case OutputFormatKey.Cards:\n      return new CardsFormat();\n    case OutputFormatKey.Dice:\n      return new DiceFormat();\n    case OutputFormatKey.Base6:\n      return new Base6Format();\n    case OutputFormatKey.Base10:\n      return new Base10Format();\n    case OutputFormatKey.Ints:\n      return new IntsFormat();\n    case OutputFormatKey.Bip39:\n      return new Bip39Format();\n    case OutputFormatKey.Sskr:\n      return new SSKRFormat();\n    case OutputFormatKey.Envelope:\n      return new EnvelopeFormat();\n    case OutputFormatKey.Multipart:\n      return new MultipartFormat();\n    case OutputFormatKey.Seed:\n      return new SeedFormat();\n  }\n}\n"],"mappings":"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"}