@bcts/uniform-resources 1.0.0-beta.0 → 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["MajorType"],"sources":["../src/error.ts","../src/utils.ts","../src/ur-type.ts","../src/ur.ts","../src/ur-encodable.ts","../src/ur-decodable.ts","../src/ur-codable.ts","../src/xoshiro.ts","../src/fountain.ts","../src/multipart-encoder.ts","../src/multipart-decoder.ts","../src/bytewords-namespace.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Error type for UR encoding/decoding operations.\n */\nexport class URError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"URError\";\n }\n}\n\n/**\n * Error type for invalid UR schemes.\n *\n * Message matches Rust bc-ur-rust/src/error.rs: `invalid UR scheme`.\n */\nexport class InvalidSchemeError extends URError {\n constructor() {\n super(\"invalid UR scheme\");\n this.name = \"InvalidSchemeError\";\n }\n}\n\n/**\n * Error type for unspecified UR types.\n *\n * Message matches Rust bc-ur-rust/src/error.rs: `no UR type specified`.\n */\nexport class TypeUnspecifiedError extends URError {\n constructor() {\n super(\"no UR type specified\");\n this.name = \"TypeUnspecifiedError\";\n }\n}\n\n/**\n * Error type for invalid UR types.\n *\n * Message matches Rust bc-ur-rust/src/error.rs: `invalid UR type`.\n */\nexport class InvalidTypeError extends URError {\n constructor() {\n super(\"invalid UR type\");\n this.name = \"InvalidTypeError\";\n }\n}\n\n/**\n * Error type for non-single-part URs.\n */\nexport class NotSinglePartError extends URError {\n constructor() {\n super(\"UR is not a single-part\");\n this.name = \"NotSinglePartError\";\n }\n}\n\n/**\n * Error type for unexpected UR types.\n *\n * Message matches Rust bc-ur-rust/src/error.rs:\n * `expected UR type {expected}, but found {found}`.\n */\nexport class UnexpectedTypeError extends URError {\n constructor(expected: string, found: string) {\n super(`expected UR type ${expected}, but found ${found}`);\n this.name = \"UnexpectedTypeError\";\n }\n}\n\n/**\n * Error type for Bytewords encoding/decoding errors.\n *\n * Message matches Rust bc-ur-rust/src/error.rs: `Bytewords error ({0})`.\n */\nexport class BytewordsError extends URError {\n constructor(message: string) {\n super(`Bytewords error (${message})`);\n this.name = \"BytewordsError\";\n }\n}\n\n/**\n * Error type for CBOR encoding/decoding errors.\n *\n * Message matches Rust bc-ur-rust/src/error.rs: `CBOR error ({0})`.\n */\nexport class CBORError extends URError {\n constructor(message: string) {\n super(`CBOR error (${message})`);\n this.name = \"CBORError\";\n }\n}\n\n/**\n * Error type for UR decoder errors.\n * Matches Rust's Error::UR(String) variant.\n */\nexport class URDecodeError extends URError {\n constructor(message: string) {\n super(`UR decoder error (${message})`);\n this.name = \"URDecodeError\";\n }\n}\n\nexport type Result<T> = T | Error;\n\n/**\n * Helper function to check if a result is an error.\n */\nexport function isError(result: unknown): result is Error {\n return result instanceof Error;\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\nimport { BytewordsError, InvalidTypeError } from \"./error.js\";\n\n/**\n * Checks if a character is a valid UR type character.\n *\n * Mirrors Rust's `URTypeChar::is_ur_type` (`bc-ur-rust/src/utils.rs:6-19`):\n * lowercase a-z, digits 0-9, and the hyphen `-`.\n */\nexport function isURTypeChar(char: string): boolean {\n const code = char.charCodeAt(0);\n // Check for lowercase letters (a-z)\n if (code >= 97 && code <= 122) return true;\n // Check for digits (0-9)\n if (code >= 48 && code <= 57) return true;\n // Check for hyphen (-)\n if (code === 45) return true;\n return false;\n}\n\n/**\n * Checks if a string is a valid UR type.\n *\n * Mirrors Rust's `URTypeString::is_ur_type` (`bc-ur-rust/src/utils.rs:26-32`)\n * which is `self.chars().all(...)` — meaning **the empty string is accepted**\n * (a vacuously-true `all` over no chars). We mirror that here so that\n * `URType::new(\"\")` succeeds in both ports; the round-trip then fails at\n * decode-time with `TypeUnspecified`.\n */\nexport function isValidURType(urType: string): boolean {\n return Array.from(urType).every((char) => isURTypeChar(char));\n}\n\n/**\n * Validates and returns a UR type, or throws an error if invalid.\n */\nexport function validateURType(urType: string): string {\n if (!isValidURType(urType)) {\n throw new InvalidTypeError();\n }\n return urType;\n}\n\n/**\n * Bytewords for encoding/decoding bytes as words.\n * See: https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-004-bytewords.md\n */\nexport const BYTEWORDS: string[] = [\n \"able\",\n \"acid\",\n \"also\",\n \"apex\",\n \"aqua\",\n \"arch\",\n \"atom\",\n \"aunt\",\n \"away\",\n \"axis\",\n \"back\",\n \"bald\",\n \"barn\",\n \"belt\",\n \"beta\",\n \"bias\",\n \"blue\",\n \"body\",\n \"brag\",\n \"brew\",\n \"bulb\",\n \"buzz\",\n \"calm\",\n \"cash\",\n \"cats\",\n \"chef\",\n \"city\",\n \"claw\",\n \"code\",\n \"cola\",\n \"cook\",\n \"cost\",\n \"crux\",\n \"curl\",\n \"cusp\",\n \"cyan\",\n \"dark\",\n \"data\",\n \"days\",\n \"deli\",\n \"dice\",\n \"diet\",\n \"door\",\n \"down\",\n \"draw\",\n \"drop\",\n \"drum\",\n \"dull\",\n \"duty\",\n \"each\",\n \"easy\",\n \"echo\",\n \"edge\",\n \"epic\",\n \"even\",\n \"exam\",\n \"exit\",\n \"eyes\",\n \"fact\",\n \"fair\",\n \"fern\",\n \"figs\",\n \"film\",\n \"fish\",\n \"fizz\",\n \"flap\",\n \"flew\",\n \"flux\",\n \"foxy\",\n \"free\",\n \"frog\",\n \"fuel\",\n \"fund\",\n \"gala\",\n \"game\",\n \"gear\",\n \"gems\",\n \"gift\",\n \"girl\",\n \"glow\",\n \"good\",\n \"gray\",\n \"grim\",\n \"guru\",\n \"gush\",\n \"gyro\",\n \"half\",\n \"hang\",\n \"hard\",\n \"hawk\",\n \"heat\",\n \"help\",\n \"high\",\n \"hill\",\n \"holy\",\n \"hope\",\n \"horn\",\n \"huts\",\n \"iced\",\n \"idea\",\n \"idle\",\n \"inch\",\n \"inky\",\n \"into\",\n \"iris\",\n \"iron\",\n \"item\",\n \"jade\",\n \"jazz\",\n \"join\",\n \"jolt\",\n \"jowl\",\n \"judo\",\n \"jugs\",\n \"jump\",\n \"junk\",\n \"jury\",\n \"keep\",\n \"keno\",\n \"kept\",\n \"keys\",\n \"kick\",\n \"kiln\",\n \"king\",\n \"kite\",\n \"kiwi\",\n \"knob\",\n \"lamb\",\n \"lava\",\n \"lazy\",\n \"leaf\",\n \"legs\",\n \"liar\",\n \"limp\",\n \"lion\",\n \"list\",\n \"logo\",\n \"loud\",\n \"love\",\n \"luau\",\n \"luck\",\n \"lung\",\n \"main\",\n \"many\",\n \"math\",\n \"maze\",\n \"memo\",\n \"menu\",\n \"meow\",\n \"mild\",\n \"mint\",\n \"miss\",\n \"monk\",\n \"nail\",\n \"navy\",\n \"need\",\n \"news\",\n \"next\",\n \"noon\",\n \"note\",\n \"numb\",\n \"obey\",\n \"oboe\",\n \"omit\",\n \"onyx\",\n \"open\",\n \"oval\",\n \"owls\",\n \"paid\",\n \"part\",\n \"peck\",\n \"play\",\n \"plus\",\n \"poem\",\n \"pool\",\n \"pose\",\n \"puff\",\n \"puma\",\n \"purr\",\n \"quad\",\n \"quiz\",\n \"race\",\n \"ramp\",\n \"real\",\n \"redo\",\n \"rich\",\n \"road\",\n \"rock\",\n \"roof\",\n \"ruby\",\n \"ruin\",\n \"runs\",\n \"rust\",\n \"safe\",\n \"saga\",\n \"scar\",\n \"sets\",\n \"silk\",\n \"skew\",\n \"slot\",\n \"soap\",\n \"solo\",\n \"song\",\n \"stub\",\n \"surf\",\n \"swan\",\n \"taco\",\n \"task\",\n \"taxi\",\n \"tent\",\n \"tied\",\n \"time\",\n \"tiny\",\n \"toil\",\n \"tomb\",\n \"toys\",\n \"trip\",\n \"tuna\",\n \"twin\",\n \"ugly\",\n \"undo\",\n \"unit\",\n \"urge\",\n \"user\",\n \"vast\",\n \"very\",\n \"veto\",\n \"vial\",\n \"vibe\",\n \"view\",\n \"visa\",\n \"void\",\n \"vows\",\n \"wall\",\n \"wand\",\n \"warm\",\n \"wasp\",\n \"wave\",\n \"waxy\",\n \"webs\",\n \"what\",\n \"when\",\n \"whiz\",\n \"wolf\",\n \"work\",\n \"yank\",\n \"yawn\",\n \"yell\",\n \"yoga\",\n \"yurt\",\n \"zaps\",\n \"zero\",\n \"zest\",\n \"zinc\",\n \"zone\",\n \"zoom\",\n];\n\n/**\n * Create a reverse mapping for fast byteword lookup.\n */\nfunction createBytewordsMap(): Map<string, number> {\n const map = new Map<string, number>();\n BYTEWORDS.forEach((word, index) => {\n map.set(word, index);\n });\n return map;\n}\n\nexport const BYTEWORDS_MAP = createBytewordsMap();\n\n/**\n * Bytemojis for encoding/decoding bytes as emojis.\n * See: https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2024-008-bytemoji.md\n */\nexport const BYTEMOJIS: string[] = [\n \"😀\",\n \"😂\",\n \"😆\",\n \"😉\",\n \"🙄\",\n \"😋\",\n \"😎\",\n \"😍\",\n \"😘\",\n \"😭\",\n \"🫠\",\n \"🥱\",\n \"🤩\",\n \"😶\",\n \"🤨\",\n \"🫥\",\n \"🥵\",\n \"🥶\",\n \"😳\",\n \"🤪\",\n \"😵\",\n \"😡\",\n \"🤢\",\n \"😇\",\n \"🤠\",\n \"🤡\",\n \"🥳\",\n \"🥺\",\n \"😬\",\n \"🤑\",\n \"🙃\",\n \"🤯\",\n \"😈\",\n \"👹\",\n \"👺\",\n \"💀\",\n \"👻\",\n \"👽\",\n \"😺\",\n \"😹\",\n \"😻\",\n \"😽\",\n \"🙀\",\n \"😿\",\n \"🫶\",\n \"🤲\",\n \"🙌\",\n \"🤝\",\n \"👍\",\n \"👎\",\n \"👈\",\n \"👆\",\n \"💪\",\n \"👄\",\n \"🦷\",\n \"👂\",\n \"👃\",\n \"🧠\",\n \"👀\",\n \"🤚\",\n \"🦶\",\n \"🍎\",\n \"🍊\",\n \"🍋\",\n \"🍌\",\n \"🍉\",\n \"🍇\",\n \"🍓\",\n \"🫐\",\n \"🍒\",\n \"🍑\",\n \"🍍\",\n \"🥝\",\n \"🍆\",\n \"🥑\",\n \"🥦\",\n \"🍅\",\n \"🌽\",\n \"🥕\",\n \"🫒\",\n \"🧄\",\n \"🥐\",\n \"🥯\",\n \"🍞\",\n \"🧀\",\n \"🥚\",\n \"🍗\",\n \"🌭\",\n \"🍔\",\n \"🍟\",\n \"🍕\",\n \"🌮\",\n \"🥙\",\n \"🍱\",\n \"🍜\",\n \"🍤\",\n \"🍚\",\n \"🥠\",\n \"🍨\",\n \"🍦\",\n \"🎂\",\n \"🪴\",\n \"🌵\",\n \"🌱\",\n \"💐\",\n \"🍁\",\n \"🍄\",\n \"🌹\",\n \"🌺\",\n \"🌼\",\n \"🌻\",\n \"🌸\",\n \"💨\",\n \"🌊\",\n \"💧\",\n \"💦\",\n \"🌀\",\n \"🌈\",\n \"🌞\",\n \"🌝\",\n \"🌛\",\n \"🌜\",\n \"🌙\",\n \"🌎\",\n \"💫\",\n \"⭐\",\n \"🪐\",\n \"🌐\",\n \"💛\",\n \"💔\",\n \"💘\",\n \"💖\",\n \"💕\",\n \"🏁\",\n \"🚩\",\n \"💬\",\n \"💯\",\n \"🚫\",\n \"🔴\",\n \"🔷\",\n \"🟩\",\n \"🛑\",\n \"🔺\",\n \"🚗\",\n \"🚑\",\n \"🚒\",\n \"🚜\",\n \"🛵\",\n \"🚨\",\n \"🚀\",\n \"🚁\",\n \"🛟\",\n \"🚦\",\n \"🏰\",\n \"🎡\",\n \"🎢\",\n \"🎠\",\n \"🏠\",\n \"🔔\",\n \"🔑\",\n \"🚪\",\n \"🪑\",\n \"🎈\",\n \"💌\",\n \"📦\",\n \"📫\",\n \"📖\",\n \"📚\",\n \"📌\",\n \"🧮\",\n \"🔒\",\n \"💎\",\n \"📷\",\n \"⏰\",\n \"⏳\",\n \"📡\",\n \"💡\",\n \"💰\",\n \"🧲\",\n \"🧸\",\n \"🎁\",\n \"🎀\",\n \"🎉\",\n \"🪭\",\n \"👑\",\n \"🫖\",\n \"🔭\",\n \"🛁\",\n \"🏆\",\n \"🥁\",\n \"🎷\",\n \"🎺\",\n \"🏀\",\n \"🏈\",\n \"🎾\",\n \"🏓\",\n \"✨\",\n \"🔥\",\n \"💥\",\n \"👕\",\n \"👚\",\n \"👖\",\n \"🩳\",\n \"👗\",\n \"👔\",\n \"🧢\",\n \"👓\",\n \"🧶\",\n \"🧵\",\n \"💍\",\n \"👠\",\n \"👟\",\n \"🧦\",\n \"🧤\",\n \"👒\",\n \"👜\",\n \"🐱\",\n \"🐶\",\n \"🐭\",\n \"🐹\",\n \"🐰\",\n \"🦊\",\n \"🐻\",\n \"🐼\",\n \"🐨\",\n \"🐯\",\n \"🦁\",\n \"🐮\",\n \"🐷\",\n \"🐸\",\n \"🐵\",\n \"🐔\",\n \"🐥\",\n \"🦆\",\n \"🦉\",\n \"🐴\",\n \"🦄\",\n \"🐝\",\n \"🐛\",\n \"🦋\",\n \"🐌\",\n \"🐞\",\n \"🐢\",\n \"🐺\",\n \"🐍\",\n \"🪽\",\n \"🐙\",\n \"🦑\",\n \"🪼\",\n \"🦞\",\n \"🦀\",\n \"🐚\",\n \"🦭\",\n \"🐟\",\n \"🐬\",\n \"🐳\",\n];\n\n/**\n * Encodes an arbitrary byte slice as a string of space-separated bytewords.\n *\n * Mirrors `bytewords::encode_to_words` in `bc-ur-rust` (≥ v0.19.1). Does not\n * add a CRC32 checksum — use {@link encodeBytewords} for UR-style encoding.\n */\nexport function encodeToWords(data: Uint8Array): string {\n const words: string[] = [];\n for (const byte of data) {\n const word = BYTEWORDS[byte];\n if (word === undefined) throw new Error(`Invalid byte value: ${byte}`);\n words.push(word);\n }\n return words.join(\" \");\n}\n\n/**\n * Encodes an arbitrary byte slice as a string of space-separated bytemojis.\n *\n * Mirrors `bytewords::encode_to_bytemojis` in `bc-ur-rust` (≥ v0.19.1).\n */\nexport function encodeToBytemojis(data: Uint8Array): string {\n const emojis: string[] = [];\n for (const byte of data) {\n const emoji = BYTEMOJIS[byte];\n if (emoji === undefined) throw new Error(`Invalid byte value: ${byte}`);\n emojis.push(emoji);\n }\n return emojis.join(\" \");\n}\n\n/**\n * Encodes an arbitrary byte slice as minimal bytewords (first + last letter of\n * each word, concatenated with no separator).\n *\n * Mirrors `bytewords::encode_to_minimal_bytewords` in `bc-ur-rust`\n * (≥ v0.19.1). Does not add a CRC32 checksum.\n */\nexport function encodeToMinimalBytewords(data: Uint8Array): string {\n let out = \"\";\n for (const byte of data) {\n const word = BYTEWORDS[byte];\n if (word === undefined) throw new Error(`Invalid byte value: ${byte}`);\n out += word[0] + word[word.length - 1];\n }\n return out;\n}\n\n/**\n * Encodes a 4-byte slice as a string of bytewords for identification.\n *\n * Thin wrapper over {@link encodeToWords} that enforces the 4-byte length\n * contract historically used by `bc-ur-rust`'s `bytewords::identifier`.\n */\nexport function encodeBytewordsIdentifier(data: Uint8Array): string {\n if (data.length !== 4) {\n throw new Error(\"Identifier data must be exactly 4 bytes\");\n }\n return encodeToWords(data);\n}\n\n/**\n * Encodes a 4-byte slice as a string of bytemojis for identification.\n *\n * Thin wrapper over {@link encodeToBytemojis} that enforces the 4-byte length\n * contract historically used by `bc-ur-rust`'s `bytewords::bytemoji_identifier`.\n */\nexport function encodeBytemojisIdentifier(data: Uint8Array): string {\n if (data.length !== 4) {\n throw new Error(\"Identifier data must be exactly 4 bytes\");\n }\n return encodeToBytemojis(data);\n}\n\n/**\n * Returns `true` if `emoji` is one of the 256 bytemojis.\n *\n * Mirrors `bytewords::is_valid_bytemoji` in `bc-ur-rust` (≥ v0.19.1).\n */\nexport function isValidBytemoji(emoji: string): boolean {\n return BYTEMOJI_SET.has(emoji);\n}\n\n/**\n * Canonicalises a byteword token (2–4 ASCII letters, case-insensitive) to its\n * full 4-letter lowercase form. Returns `undefined` if the token is not a\n * valid byteword or any of its short forms.\n *\n * Mirrors `bytewords::canonicalize_byteword` in `bc-ur-rust` (≥ v0.19.1).\n *\n * - 2-letter tokens are matched against the first + last letter of each\n * byteword (identical to the minimal bytewords encoding).\n * - 3-letter tokens are matched against the first 3 and the last 3 letters of\n * each byteword; if both match different entries, the first-3 match wins\n * (matching rust's `or_else` priority).\n * - 4-letter tokens must exactly match a full byteword (after lower-casing).\n */\nexport function canonicalizeByteword(token: string): string | undefined {\n const lower = token.toLowerCase();\n switch (lower.length) {\n case 4:\n return BYTEWORDS_MAP.has(lower) ? lower : undefined;\n case 2:\n return BYTEWORD_FIRST_LAST_MAP.get(lower);\n case 3: {\n return BYTEWORD_FIRST_THREE_MAP.get(lower) ?? BYTEWORD_LAST_THREE_MAP.get(lower);\n }\n default:\n return undefined;\n }\n}\n\n/**\n * Bytewords encoding style.\n */\nexport enum BytewordsStyle {\n /** Full 4-letter words separated by spaces */\n Standard = \"standard\",\n /** Full 4-letter words separated by hyphens (URI-safe) */\n Uri = \"uri\",\n /** First and last character only (minimal) - used by UR encoding */\n Minimal = \"minimal\",\n}\n\n/**\n * Create a reverse mapping for minimal bytewords (first+last char) lookup.\n */\nfunction createMinimalBytewordsMap(): Map<string, number> {\n const map = new Map<string, number>();\n BYTEWORDS.forEach((word, index) => {\n // Minimal encoding uses first and last character\n const minimal = word[0] + word[3];\n map.set(minimal, index);\n });\n return map;\n}\n\nexport const MINIMAL_BYTEWORDS_MAP = createMinimalBytewordsMap();\n\n/**\n * Set of all 256 bytemojis for fast membership testing. Backs\n * {@link isValidBytemoji}.\n */\nconst BYTEMOJI_SET: ReadonlySet<string> = new Set(BYTEMOJIS);\n\n/**\n * Lookup from a 2-letter (first+last) byteword short-form to its full\n * lowercase 4-letter form. Backs {@link canonicalizeByteword}.\n */\nconst BYTEWORD_FIRST_LAST_MAP: ReadonlyMap<string, string> = (() => {\n const map = new Map<string, string>();\n for (const word of BYTEWORDS) {\n map.set(word[0] + word[word.length - 1], word);\n }\n return map;\n})();\n\n/**\n * Lookup from the first 3 letters of a byteword to its full lowercase 4-letter\n * form. Backs {@link canonicalizeByteword}.\n */\nconst BYTEWORD_FIRST_THREE_MAP: ReadonlyMap<string, string> = (() => {\n const map = new Map<string, string>();\n for (const word of BYTEWORDS) {\n map.set(word.slice(0, 3), word);\n }\n return map;\n})();\n\n/**\n * Lookup from the last 3 letters of a byteword to its full lowercase 4-letter\n * form. Backs {@link canonicalizeByteword}.\n */\nconst BYTEWORD_LAST_THREE_MAP: ReadonlyMap<string, string> = (() => {\n const map = new Map<string, string>();\n for (const word of BYTEWORDS) {\n map.set(word.slice(1), word);\n }\n return map;\n})();\n\n/**\n * CRC32 lookup table (IEEE polynomial).\n */\nconst CRC32_TABLE: number[] = (() => {\n const table: number[] = [];\n for (let i = 0; i < 256; i++) {\n let c = i;\n for (let j = 0; j < 8; j++) {\n c = (c & 1) !== 0 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table.push(c >>> 0);\n }\n return table;\n})();\n\n/**\n * Calculate CRC32 checksum of data.\n */\nexport function crc32(data: Uint8Array): number {\n let crc = 0xffffffff;\n for (const byte of data) {\n crc = (CRC32_TABLE[(crc ^ byte) & 0xff] ^ (crc >>> 8)) >>> 0;\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\n/**\n * Convert a 32-bit number to 4 bytes (big-endian).\n */\nfunction uint32ToBytes(value: number): Uint8Array {\n return new Uint8Array([\n (value >>> 24) & 0xff,\n (value >>> 16) & 0xff,\n (value >>> 8) & 0xff,\n value & 0xff,\n ]);\n}\n\n/**\n * Encode data as bytewords with the specified style.\n * Includes CRC32 checksum.\n */\nexport function encodeBytewords(\n data: Uint8Array,\n style: BytewordsStyle = BytewordsStyle.Minimal,\n): string {\n // Append CRC32 checksum\n const checksum = crc32(data);\n const checksumBytes = uint32ToBytes(checksum);\n const dataWithChecksum = new Uint8Array(data.length + 4);\n dataWithChecksum.set(data);\n dataWithChecksum.set(checksumBytes, data.length);\n\n const words: string[] = [];\n for (const byte of dataWithChecksum) {\n const word = BYTEWORDS[byte];\n if (word === undefined) throw new Error(`Invalid byte value: ${byte}`);\n\n switch (style) {\n case BytewordsStyle.Standard:\n words.push(word);\n break;\n case BytewordsStyle.Uri:\n words.push(word);\n break;\n case BytewordsStyle.Minimal:\n // First and last character\n words.push(word[0] + word[3]);\n break;\n }\n }\n\n switch (style) {\n case BytewordsStyle.Standard:\n return words.join(\" \");\n case BytewordsStyle.Uri:\n return words.join(\"-\");\n case BytewordsStyle.Minimal:\n return words.join(\"\");\n }\n}\n\n/**\n * Returns true if every code unit of `s` is in the ASCII range (0..=127).\n *\n * Mirrors Rust's `str::is_ascii` used at `ur::bytewords::decode` line 105.\n * We test the raw code units (rather than Array.from + codepoint) because\n * any non-BMP character has surrogate pairs both ≥ 0xD800, which already\n * exceed 0x7F.\n */\nfunction isAsciiString(s: string): boolean {\n for (let i = 0; i < s.length; i++) {\n if (s.charCodeAt(i) > 0x7f) return false;\n }\n return true;\n}\n\n/**\n * Decode bytewords string back to data.\n * Validates and removes CRC32 checksum.\n *\n * Errors mirror the upstream Rust `ur::bytewords::Error` enum\n * (`ur-0.4.1/src/bytewords.rs`):\n * - `NonAscii` — input contains non-ASCII characters (checked first).\n * - `InvalidLength` — minimal-style input has odd length.\n * - `InvalidWord` — a token does not map to a byteword index.\n * - `InvalidChecksum` — the trailing 4-byte CRC32 does not match.\n *\n * All variants are surfaced as {@link BytewordsError} with the same default\n * `Display` strings as Rust (e.g. \"invalid checksum\", \"non-ASCII\"), so\n * callers can branch on the error class rather than the bare `Error`\n * thrown by earlier revisions of this port.\n */\nexport function decodeBytewords(\n encoded: string,\n style: BytewordsStyle = BytewordsStyle.Minimal,\n): Uint8Array {\n // Rust rejects non-ASCII input up-front (`bytewords.rs:105-107`).\n if (!isAsciiString(encoded)) {\n throw new BytewordsError(\"bytewords string contains non-ASCII characters\");\n }\n const lowercased = encoded.toLowerCase();\n let bytes: number[];\n\n switch (style) {\n case BytewordsStyle.Standard: {\n const words = lowercased.split(\" \");\n bytes = words.map((word) => {\n const index = BYTEWORDS_MAP.get(word);\n if (index === undefined) {\n throw new BytewordsError(\"invalid word\");\n }\n return index;\n });\n break;\n }\n case BytewordsStyle.Uri: {\n // 4-character words separated by hyphens\n const words = lowercased.split(\"-\");\n bytes = words.map((word) => {\n const index = BYTEWORDS_MAP.get(word);\n if (index === undefined) {\n throw new BytewordsError(\"invalid word\");\n }\n return index;\n });\n break;\n }\n case BytewordsStyle.Minimal: {\n // 2-character minimal words with no separator\n if (lowercased.length % 2 !== 0) {\n throw new BytewordsError(\"invalid length\");\n }\n bytes = [];\n for (let i = 0; i < lowercased.length; i += 2) {\n const minimal = lowercased.slice(i, i + 2);\n const index = MINIMAL_BYTEWORDS_MAP.get(minimal);\n if (index === undefined) {\n throw new BytewordsError(\"invalid word\");\n }\n bytes.push(index);\n }\n break;\n }\n }\n\n if (bytes.length < 4) {\n throw new BytewordsError(\"invalid checksum\");\n }\n\n // Extract data and checksum\n const dataWithChecksum = new Uint8Array(bytes);\n const data = dataWithChecksum.slice(0, -4);\n const checksumBytes = dataWithChecksum.slice(-4);\n\n // Verify checksum\n const expectedChecksum = crc32(data);\n const actualChecksum =\n ((checksumBytes[0] << 24) |\n (checksumBytes[1] << 16) |\n (checksumBytes[2] << 8) |\n checksumBytes[3]) >>>\n 0;\n\n if (expectedChecksum !== actualChecksum) {\n throw new BytewordsError(\"invalid checksum\");\n }\n\n return data;\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\nimport { InvalidTypeError } from \"./error\";\nimport { isValidURType } from \"./utils\";\n\n/**\n * Represents a UR (Uniform Resource) type identifier.\n *\n * Valid UR types contain only lowercase letters, digits, and hyphens.\n *\n * @example\n * ```typescript\n * const urType = new URType('test');\n * console.log(urType.string()); // \"test\"\n * ```\n */\nexport class URType {\n private readonly _type: string;\n\n /**\n * Creates a new URType from the provided type string.\n *\n * @param urType - The UR type as a string\n * @throws {InvalidTypeError} If the type contains invalid characters\n *\n * @example\n * ```typescript\n * const urType = new URType('test');\n * ```\n */\n constructor(urType: string) {\n if (!isValidURType(urType)) {\n throw new InvalidTypeError();\n }\n this._type = urType;\n }\n\n /**\n * Returns the string representation of the URType.\n *\n * @example\n * ```typescript\n * const urType = new URType('test');\n * console.log(urType.string()); // \"test\"\n * ```\n */\n string(): string {\n return this._type;\n }\n\n /**\n * Checks equality with another URType based on the type string.\n */\n equals(other: URType): boolean {\n return this._type === other._type;\n }\n\n /**\n * Returns the string representation.\n */\n toString(): string {\n return this._type;\n }\n\n /**\n * Creates a URType from a string, throwing an error if invalid.\n *\n * @param value - The UR type string\n * @returns A new URType instance\n * @throws {InvalidTypeError} If the type is invalid\n */\n static from(value: string): URType {\n return new URType(value);\n }\n\n /**\n * Safely creates a URType, returning a typed `Result`-shaped\n * discriminated union instead of throwing.\n *\n * Mirrors Rust `impl TryFrom<&str> for URType` /\n * `impl TryFrom<String> for URType` (`bc-ur-rust/src/ur_type.rs`),\n * which return `Result<URType, Error>`. The TS shape is the\n * idiomatic discriminated form so callers can branch on `ok`\n * without `instanceof`:\n *\n * @example\n * ```typescript\n * const r = URType.tryFrom(\"test\");\n * if (r.ok) {\n * console.log(r.value.string()); // \"test\"\n * } else {\n * console.error(r.error.message);\n * }\n * ```\n *\n * @param value - The UR type string\n * @returns A typed Result: `{ ok: true; value: URType }` on success,\n * `{ ok: false; error: InvalidTypeError }` on failure.\n */\n static tryFrom(\n value: string,\n ): { ok: true; value: URType } | { ok: false; error: InvalidTypeError } {\n try {\n return { ok: true, value: new URType(value) };\n } catch (error) {\n return { ok: false, error: error as InvalidTypeError };\n }\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\nimport type { Cbor } from \"@bcts/dcbor\";\nimport { decodeCbor } from \"@bcts/dcbor\";\nimport {\n BytewordsError,\n CBORError,\n InvalidSchemeError,\n NotSinglePartError,\n TypeUnspecifiedError,\n UnexpectedTypeError,\n URDecodeError,\n} from \"./error.js\";\nimport { URType } from \"./ur-type.js\";\nimport { encodeBytewords, decodeBytewords, BytewordsStyle } from \"./utils.js\";\n\n/**\n * A Uniform Resource (UR) is a URI-encoded CBOR object.\n *\n * URs are defined in [BCR-2020-005: Uniform Resources](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md).\n *\n * @example\n * ```typescript\n * import { UR } from '@bcts/uniform-resources';\n * import { CBOR } from '@bcts/dcbor';\n *\n * // Create a UR from a CBOR object\n * const cbor = CBOR.fromArray([1, 2, 3]);\n * const ur = UR.new('test', cbor);\n *\n * // Encode to string\n * const urString = ur.string();\n * console.log(urString); // \"ur:test/...\"\n *\n * // Decode from string\n * const decodedUR = UR.fromURString(urString);\n * console.log(decodedUR.urTypeStr()); // \"test\"\n * ```\n */\nexport class UR {\n private readonly _urType: URType;\n private readonly _cbor: Cbor;\n\n /**\n * Creates a new UR from the provided type and CBOR data.\n *\n * @param urType - The UR type (will be validated)\n * @param cbor - The CBOR data to encode\n * @throws {InvalidTypeError} If the type is invalid\n *\n * @example\n * ```typescript\n * const ur = UR.new('bytes', CBOR.fromString('hello'));\n * ```\n */\n static new(urType: string | URType, cbor: Cbor): UR {\n const type = typeof urType === \"string\" ? new URType(urType) : urType;\n return new UR(type, cbor);\n }\n\n /**\n * Creates a new UR from a UR string.\n *\n * Mirrors Rust's `UR::from_ur_string` (`bc-ur-rust/src/ur.rs:25-38`):\n * 1. lowercase the entire string.\n * 2. strip the `\"ur:\"` prefix → {@link InvalidSchemeError} if absent.\n * 3. split on the first `/` → {@link TypeUnspecifiedError} if absent.\n * 4. validate the type via {@link URType} → {@link InvalidTypeError}.\n * 5. delegate the data section to the upstream-style decoder, which\n * classifies the UR as single- or multi-part. Multi-part input is\n * rejected with {@link NotSinglePartError}.\n * 6. decode the bytewords payload (CRC32 + minimal mapping) →\n * {@link BytewordsError} on failure.\n * 7. parse the resulting bytes as CBOR → {@link CBORError} on failure.\n *\n * @param urString - A UR string like \"ur:test/...\"\n * @throws {InvalidSchemeError} If the string doesn't start with \"ur:\"\n * @throws {TypeUnspecifiedError} If no `/` separator is present\n * @throws {InvalidTypeError} If the type contains invalid characters\n * @throws {NotSinglePartError} If the UR is multi-part\n * @throws {URDecodeError} For upstream-decoder errors (invalid indices, etc.)\n * @throws {BytewordsError} If bytewords decoding fails\n * @throws {CBORError} If CBOR parsing fails\n *\n * @example\n * ```typescript\n * const ur = UR.fromURString('ur:test/lsadaoaxjygonesw');\n * ```\n */\n static fromURString(urString: string): UR {\n const { urType, cbor } = URStringDecoder.decode(urString);\n return new UR(urType, cbor);\n }\n\n private constructor(urType: URType, cbor: Cbor) {\n this._urType = urType;\n this._cbor = cbor;\n }\n\n /**\n * Returns the UR type.\n */\n urType(): URType {\n return this._urType;\n }\n\n /**\n * Returns the UR type as a string.\n */\n urTypeStr(): string {\n return this._urType.string();\n }\n\n /**\n * Returns the CBOR data.\n */\n cbor(): Cbor {\n return this._cbor;\n }\n\n /**\n * Returns the string representation of the UR (lowercase, suitable for display).\n *\n * @example\n * ```typescript\n * const ur = UR.new('test', CBOR.fromArray([1, 2, 3]));\n * console.log(ur.string()); // \"ur:test/lsadaoaxjygonesw\"\n * ```\n */\n string(): string {\n const cborData = this._cbor.toData();\n return URStringEncoder.encode(this._urType.string(), cborData);\n }\n\n /**\n * Returns the QR string representation (uppercase, most efficient for QR codes).\n */\n qrString(): string {\n return this.string().toUpperCase();\n }\n\n /**\n * Returns the QR data as bytes (uppercase UR string as UTF-8).\n *\n * Mirrors Rust's `UR::qr_data` (`ur.rs:52`) which does\n * `self.qr_string().as_bytes().to_vec()` — the string's UTF-8 byte\n * representation. We use `TextEncoder` rather than per-codepoint\n * truncation so the behaviour stays correct if the QR string ever\n * contains non-ASCII characters.\n */\n qrData(): Uint8Array {\n return new TextEncoder().encode(this.qrString());\n }\n\n /**\n * Checks if the UR type matches the expected type.\n *\n * @param expectedType - The expected type\n * @throws {UnexpectedTypeError} If the types don't match\n */\n checkType(expectedType: string | URType): void {\n const expected = typeof expectedType === \"string\" ? new URType(expectedType) : expectedType;\n if (!this._urType.equals(expected)) {\n throw new UnexpectedTypeError(expected.string(), this._urType.string());\n }\n }\n\n /**\n * Returns the string representation.\n */\n toString(): string {\n return this.string();\n }\n\n /**\n * Checks equality with another UR.\n *\n * Mirrors Rust's derived `PartialEq for UR` which compares the inner\n * `ur_type` and the inner `cbor` field directly. We compare CBOR\n * bytewise — `Uint8Array` equality, not `Array#toString` (which would\n * coerce to a comma-joined string and could collide on pathological\n * inputs).\n */\n equals(other: UR): boolean {\n if (!this._urType.equals(other._urType)) return false;\n const a = this._cbor.toData();\n const b = other._cbor.toData();\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n }\n}\n\n/**\n * Encodes a UR string using Bytewords minimal encoding.\n * This handles single-part URs according to BCR-2020-005.\n */\nclass URStringEncoder {\n static encode(urType: string, cborData: Uint8Array): string {\n // Encode CBOR data using bytewords minimal style (with CRC32 checksum)\n const encoded = encodeBytewords(cborData, BytewordsStyle.Minimal);\n return `ur:${urType}/${encoded}`;\n }\n}\n\n/**\n * Decodes a UR string back to its components.\n *\n * Mirrors the validation pipeline of Rust's `UR::from_ur_string`\n * (`bc-ur-rust/src/ur.rs:25-38`) plus the upstream `ur::decode`\n * (`ur-0.4.1/src/ur.rs:238-266`):\n *\n * 1. lowercase\n * 2. strip `\"ur:\"` → {@link InvalidSchemeError}\n * 3. find `/` → {@link TypeUnspecifiedError}\n * 4. validate the type → {@link InvalidTypeError}\n * 5. classify single- vs multi-part by looking at the data section\n * 6. multi-part → {@link NotSinglePartError}\n * 7. invalid multi-part indices → {@link URDecodeError(\"Invalid indices\")}\n * 8. minimal bytewords decode → {@link BytewordsError}\n * 9. CBOR parse → {@link CBORError}\n */\nclass URStringDecoder {\n static decode(urString: string): { urType: URType; cbor: Cbor } {\n const lowercased = urString.toLowerCase();\n\n // Step 2: strip the scheme.\n if (!lowercased.startsWith(\"ur:\")) {\n throw new InvalidSchemeError();\n }\n const afterScheme = lowercased.substring(3);\n\n // Step 3: locate the first `/`. Matches Rust's `split_once('/')`.\n const slashIdx = afterScheme.indexOf(\"/\");\n if (slashIdx === -1) {\n throw new TypeUnspecifiedError();\n }\n const typeStr = afterScheme.substring(0, slashIdx);\n const dataSection = afterScheme.substring(slashIdx + 1);\n\n // Step 4: validate the type *before* any bytewords/CBOR work, so that a\n // malformed payload with an invalid type surfaces InvalidTypeError\n // rather than a downstream BytewordsError. Mirrors `ur.rs:31`.\n const urType = new URType(typeStr);\n\n // Step 5/6/7: classify the data section, the way `ur::decode` does\n // (`ur-0.4.1/src/ur.rs:249-265`). If the data section contains a `/`,\n // the prefix is the multi-part `<seqNum>-<seqLen>` indices.\n const lastSlash = dataSection.lastIndexOf(\"/\");\n if (lastSlash !== -1) {\n const indices = dataSection.substring(0, lastSlash);\n const dashIdx = indices.indexOf(\"-\");\n if (dashIdx === -1) {\n throw new URDecodeError(\"Invalid indices\");\n }\n const seqNumStr = indices.substring(0, dashIdx);\n const seqLenStr = indices.substring(dashIdx + 1);\n // Rust uses `parse::<u16>()`; accept non-empty strings of digits only.\n // (parseInt on `\"1a\"` returns 1, so we have to be strict about chars.)\n if (!/^\\d+$/.test(seqNumStr) || !/^\\d+$/.test(seqLenStr)) {\n throw new URDecodeError(\"Invalid indices\");\n }\n const seqNum = Number(seqNumStr);\n const seqLen = Number(seqLenStr);\n if (seqNum > 0xffff || seqLen > 0xffff) {\n throw new URDecodeError(\"Invalid indices\");\n }\n // Successfully parsed as multi-part — but `from_ur_string` only\n // accepts single-part input. Mirrors `ur.rs:33-35`.\n throw new NotSinglePartError();\n }\n\n // Step 8: minimal bytewords decode (CRC32 + minimal mapping).\n let cborData: Uint8Array;\n try {\n cborData = decodeBytewords(dataSection, BytewordsStyle.Minimal);\n } catch (error) {\n if (error instanceof BytewordsError) {\n throw error;\n }\n const message = error instanceof Error ? error.message : String(error);\n throw new BytewordsError(message);\n }\n\n // Step 9: CBOR parse.\n let cbor: Cbor;\n try {\n cbor = decodeCbor(cborData);\n } catch (error) {\n if (error instanceof CBORError) {\n throw error;\n }\n const message = error instanceof Error ? error.message : String(error);\n throw new CBORError(message);\n }\n\n return { urType, cbor };\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\nimport type { CborTaggedEncodable } from \"@bcts/dcbor\";\n\nimport { UR } from \"./ur.js\";\n\n/**\n * A type that can be encoded to a UR (Uniform Resource).\n *\n * Types implementing this interface should be able to convert themselves\n * to CBOR data and associate that with a UR type identifier.\n *\n * Mirrors Rust's `UREncodable` trait (`bc-ur-rust/src/ur_encodable.rs`),\n * which has a blanket impl `impl<T> UREncodable for T where T:\n * CBORTaggedEncodable`. TypeScript has no equivalent of blanket impls, so\n * implementers either write `ur()` / `urString()` directly *or* — for a\n * type that already implements `CborTaggedEncodable` — call the helper\n * functions {@link urFromEncodable} / {@link urStringFromEncodable} below\n * to get the same auto-derivation that Rust provides for free.\n *\n * @example\n * ```typescript\n * class MyType implements UREncodable, CborTaggedEncodable {\n * cborTags(): Tag[] {\n * return [createTag(40000, \"mytype\")];\n * }\n *\n * untaggedCbor(): Cbor { ... }\n * taggedCbor(): Cbor { return createTaggedCbor(this); }\n *\n * // Auto-derived from the first cbor tag's name, just like Rust.\n * ur(): UR { return urFromEncodable(this); }\n * urString(): string { return urStringFromEncodable(this); }\n * }\n * ```\n */\nexport interface UREncodable {\n /**\n * Returns the UR representation of the object.\n */\n ur(): UR;\n\n /**\n * Returns the UR string representation of the object.\n */\n urString(): string;\n}\n\n/**\n * Concrete equivalent of Rust's default `UREncodable::ur` impl\n * (`bc-ur-rust/src/ur_encodable.rs:8-18`):\n *\n * - Reads the first tag returned by `encodable.cborTags()`.\n * - Uses that tag's `name` as the UR type, throwing if no name is set —\n * matching Rust's `panic!(\"CBOR tag {} must have a name. Did you call\n * `register_tags()`?\", tag.value())`.\n * - Wraps the encodable's `untaggedCbor()` in a fresh {@link UR} bound to\n * that type.\n *\n * Use from a class implementing both `UREncodable` and\n * `CborTaggedEncodable` to skip writing the boilerplate yourself.\n */\nexport function urFromEncodable(encodable: CborTaggedEncodable): UR {\n const tags = encodable.cborTags();\n const tag = tags[0];\n if (tag === undefined) {\n throw new Error(\"UREncodable: cborTags() returned no tags\");\n }\n if (tag.name === undefined) {\n throw new Error(`CBOR tag ${tag.value} must have a name. Did you call register_tags()?`);\n }\n return UR.new(tag.name, encodable.untaggedCbor());\n}\n\n/**\n * Concrete equivalent of Rust's default `UREncodable::ur_string` impl\n * (`bc-ur-rust/src/ur_encodable.rs:21`): `self.ur().string()`.\n */\nexport function urStringFromEncodable(encodable: CborTaggedEncodable): string {\n return urFromEncodable(encodable).string();\n}\n\n/**\n * Helper function to check if an object implements UREncodable.\n */\nexport function isUREncodable(obj: unknown): obj is UREncodable {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"ur\" in obj &&\n \"urString\" in obj &&\n typeof (obj as Record<string, unknown>)[\"ur\"] === \"function\" &&\n typeof (obj as Record<string, unknown>)[\"urString\"] === \"function\"\n );\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\nimport type { CborTaggedDecodable } from \"@bcts/dcbor\";\n\nimport { UR } from \"./ur.js\";\n\n/**\n * A type that can be decoded from a UR (Uniform Resource).\n *\n * Types implementing this interface should be able to create themselves\n * from a UR containing their data.\n *\n * Mirrors Rust's `URDecodable` trait (`bc-ur-rust/src/ur_decodable.rs`),\n * which has a blanket impl `impl<T> URDecodable for T where T:\n * CBORTaggedDecodable`. TypeScript has no equivalent of blanket impls, so\n * implementers either write `fromUR()` directly *or* — for a type that\n * already implements `CborTaggedDecodable` — call the helper functions\n * {@link decodableFromUR} / {@link decodableFromURString} below to get the\n * same auto-derivation that Rust provides for free.\n *\n * @example\n * ```typescript\n * class MyType implements URDecodable, CborTaggedDecodable<MyType> {\n * cborTags(): Tag[] {\n * return [createTag(40000, \"mytype\")];\n * }\n * fromUntaggedCbor(cbor: Cbor): MyType { ... }\n * fromTaggedCbor(cbor: Cbor): MyType { ... }\n *\n * // Auto-derived from the first cbor tag's name, matching Rust.\n * fromUR(ur: UR): MyType { return decodableFromUR(this, ur); }\n * fromURString(s: string): MyType { return decodableFromURString(this, s); }\n * }\n * ```\n */\nexport interface URDecodable {\n /**\n * Creates an instance of this type from a UR.\n *\n * @param ur - The UR to decode from\n * @returns An instance of this type\n * @throws If the UR type is wrong or data is malformed\n */\n fromUR(ur: UR): unknown;\n\n /**\n * Creates an instance of this type from a UR string.\n *\n * This is a convenience method that parses the UR string and then\n * calls fromUR().\n *\n * @param urString - The UR string to decode from (e.g., \"ur:type/...\")\n * @returns An instance of this type\n * @throws If the UR string is invalid or data is malformed\n */\n fromURString?(urString: string): unknown;\n}\n\n/**\n * Concrete equivalent of Rust's default `URDecodable::from_ur` impl\n * (`bc-ur-rust/src/ur_decodable.rs:7-15`):\n *\n * 1. Read the first tag returned by `decodable.cborTags()`.\n * 2. Verify the UR's type matches that tag's name via `UR#checkType`\n * (this is what Rust's `ur.check_type(...)` does — surface\n * `UnexpectedTypeError` on mismatch).\n * 3. Delegate to `decodable.fromUntaggedCbor(ur.cbor())`.\n *\n * Use from a class implementing both `URDecodable` and\n * `CborTaggedDecodable<T>` to skip the type-check / delegate boilerplate.\n */\nexport function decodableFromUR<T>(decodable: CborTaggedDecodable<T>, ur: UR): T {\n const tags = decodable.cborTags();\n const tag = tags[0];\n if (tag === undefined) {\n throw new Error(\"URDecodable: cborTags() returned no tags\");\n }\n if (tag.name === undefined) {\n throw new Error(`CBOR tag ${tag.value} must have a name. Did you call register_tags()?`);\n }\n ur.checkType(tag.name);\n return decodable.fromUntaggedCbor(ur.cbor());\n}\n\n/**\n * Concrete equivalent of Rust's default `URDecodable::from_ur_string` impl\n * (`bc-ur-rust/src/ur_decodable.rs:17-22`):\n * `Self::from_ur(UR::from_ur_string(s)?)`.\n */\nexport function decodableFromURString<T>(decodable: CborTaggedDecodable<T>, urString: string): T {\n return decodableFromUR(decodable, UR.fromURString(urString));\n}\n\n/**\n * Helper function to check if an object implements URDecodable.\n */\nexport function isURDecodable(obj: unknown): obj is URDecodable {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"fromUR\" in obj &&\n typeof (obj as Record<string, unknown>)[\"fromUR\"] === \"function\"\n );\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\nimport type { UREncodable } from \"./ur-encodable.js\";\nimport type { URDecodable } from \"./ur-decodable.js\";\n\n/**\n * A type that can be both encoded to and decoded from a UR.\n *\n * This combines the UREncodable and URDecodable interfaces for types\n * that support bidirectional UR conversion.\n *\n * @example\n * ```typescript\n * class MyType implements URCodable {\n * ur(): UR {\n * // Encode to UR\n * }\n *\n * urString(): string {\n * // Return UR string\n * }\n *\n * fromUR(ur: UR): MyType {\n * // Decode from UR\n * }\n *\n * fromURString(urString: string): MyType {\n * // Decode from UR string (convenience method)\n * return this.fromUR(UR.fromURString(urString));\n * }\n * }\n * ```\n */\nexport interface URCodable extends UREncodable, URDecodable {}\n\n/**\n * Helper function to check if an object implements URCodable.\n */\nexport function isURCodable(obj: unknown): obj is URCodable {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"ur\" in obj &&\n \"urString\" in obj &&\n \"fromUR\" in obj &&\n typeof (obj as Record<string, unknown>)[\"ur\"] === \"function\" &&\n typeof (obj as Record<string, unknown>)[\"urString\"] === \"function\" &&\n typeof (obj as Record<string, unknown>)[\"fromUR\"] === \"function\"\n );\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Xoshiro256** PRNG implementation.\n *\n * This is a high-quality, fast pseudo-random number generator used\n * for deterministic fragment selection in fountain codes.\n *\n * Reference: https://prng.di.unimi.it/\n * BC-UR Reference: https://github.com/nicklockwood/fountain-codes\n */\n\nimport { sha256 } from \"@bcts/crypto\";\n\nconst MAX_UINT64 = BigInt(\"0xffffffffffffffff\");\n\n/**\n * Performs a left rotation on a 64-bit BigInt.\n */\nfunction rotl(x: bigint, k: number): bigint {\n const kBigInt = BigInt(k);\n return ((x << kBigInt) | (x >> (64n - kBigInt))) & MAX_UINT64;\n}\n\n/**\n * Xoshiro256** pseudo-random number generator.\n *\n * This PRNG is used for deterministic mixing in fountain codes,\n * allowing both encoder and decoder to agree on which fragments\n * are combined without transmitting that information.\n */\nexport class Xoshiro256 {\n private s: [bigint, bigint, bigint, bigint];\n\n /**\n * Creates a new Xoshiro256** instance from a 32-byte seed.\n *\n * The seed must be exactly 32 bytes (256 bits). The bytes are interpreted\n * using the BC-UR reference algorithm: each 8-byte chunk is read as\n * big-endian then stored as little-endian for the state.\n *\n * @param seed - The seed bytes (must be exactly 32 bytes)\n */\n constructor(seed: Uint8Array) {\n if (seed.length !== 32) {\n throw new Error(`Seed must be 32 bytes, got ${seed.length}`);\n }\n\n // BC-UR reference implementation:\n // For each 8-byte chunk, read as big-endian u64, then convert to little-endian bytes\n // This effectively swaps the byte order within each 8-byte segment\n const s: [bigint, bigint, bigint, bigint] = [0n, 0n, 0n, 0n];\n for (let i = 0; i < 4; i++) {\n // Read 8 bytes as big-endian u64\n let v = 0n;\n for (let n = 0; n < 8; n++) {\n v = (v << 8n) | BigInt(seed[8 * i + n] ?? 0);\n }\n s[i] = v;\n }\n\n this.s = s;\n }\n\n /**\n * Creates a Xoshiro256** instance from raw state values.\n * Useful for seeding with specific values.\n */\n static fromState(s0: bigint, s1: bigint, s2: bigint, s3: bigint): Xoshiro256 {\n const instance = Object.create(Xoshiro256.prototype) as Xoshiro256;\n instance.s = [s0, s1, s2, s3];\n return instance;\n }\n\n /**\n * Generates the next 64-bit random value.\n */\n next(): bigint {\n const result = (rotl((this.s[1] * 5n) & MAX_UINT64, 7) * 9n) & MAX_UINT64;\n\n const t = (this.s[1] << 17n) & MAX_UINT64;\n\n this.s[2] ^= this.s[0];\n this.s[3] ^= this.s[1];\n this.s[1] ^= this.s[2];\n this.s[0] ^= this.s[3];\n\n this.s[2] ^= t;\n this.s[3] = rotl(this.s[3], 45);\n\n return result;\n }\n\n /**\n * Generates a random double in [0, 1).\n * Matches BC-UR reference: self.next() as f64 / (u64::MAX as f64 + 1.0)\n */\n nextDouble(): number {\n const value = this.next();\n // u64::MAX as f64 + 1.0 = 18446744073709551616.0\n return Number(value) / 18446744073709551616.0;\n }\n\n /**\n * Generates a random integer in [low, high] (inclusive).\n * Matches BC-UR reference: (self.next_double() * ((high - low + 1) as f64)) as u64 + low\n */\n nextInt(low: number, high: number): number {\n const range = high - low + 1;\n return Math.floor(this.nextDouble() * range) + low;\n }\n\n /**\n * Generates a random byte [0, 255].\n *\n * Mirrors Rust `Xoshiro256::next_byte` (`ur-0.4.1/src/xoshiro.rs:91`):\n * `self.next_int(0, 255) as u8`\n * This goes through `next_double() * 256.0`, which effectively uses\n * the top 8 bits of the f64-converted u64 — NOT the low 8 bits\n * of the raw `next()` output. Earlier the TS port used `next() & 0xff`,\n * which produced a completely different byte sequence than Rust for\n * the same seeded RNG.\n */\n nextByte(): number {\n return this.nextInt(0, 255);\n }\n\n /**\n * Generates an array of random bytes.\n *\n * Mirrors Rust `Xoshiro256::next_bytes` (`ur-0.4.1/src/xoshiro.rs:95-97`):\n * `(0..n).map(|_| self.next_byte()).collect()`\n */\n nextData(count: number): Uint8Array {\n const result = new Uint8Array(count);\n for (let i = 0; i < count; i++) {\n result[i] = this.nextByte();\n }\n return result;\n }\n\n /**\n * Shuffles items by repeatedly picking random indices.\n * Matches BC-UR reference implementation.\n */\n shuffled<T>(items: T[]): T[] {\n const source = [...items];\n const shuffled: T[] = [];\n while (source.length > 0) {\n const index = this.nextInt(0, source.length - 1);\n const item = source.splice(index, 1)[0];\n if (item !== undefined) {\n shuffled.push(item);\n }\n }\n return shuffled;\n }\n\n /**\n * Chooses the degree (number of fragments to mix) using a weighted sampler.\n * Uses the robust soliton distribution with weights [1/1, 1/2, 1/3, ..., 1/n].\n * Matches BC-UR reference implementation.\n */\n chooseDegree(seqLen: number): number {\n // Create weights: [1/1, 1/2, 1/3, ..., 1/seqLen]\n const weights: number[] = [];\n for (let i = 1; i <= seqLen; i++) {\n weights.push(1.0 / i);\n }\n\n // Use Vose's alias method for weighted sampling\n const sampler = new WeightedSampler(weights);\n return sampler.next(this) + 1; // 1-indexed degree\n }\n}\n\n/**\n * Weighted sampler using Vose's alias method.\n * Allows O(1) sampling from a discrete probability distribution.\n */\nclass WeightedSampler {\n private readonly aliases: number[];\n private readonly probs: number[];\n\n constructor(weights: number[]) {\n const n = weights.length;\n\n // Mirrors Rust `Weighted::new` (`ur-0.4.1/src/sampler.rs:13-19`):\n // assert!(!weights.iter().any(|&p| p < 0.0), \"negative probability encountered\");\n // let summed = weights.iter().sum::<f64>();\n // assert!(summed > 0.0, \"probabilities don't sum to a positive value\");\n if (weights.some((w) => w < 0.0)) {\n throw new Error(\"negative probability encountered\");\n }\n const sum = weights.reduce((a, b) => a + b, 0);\n if (!(sum > 0.0)) {\n throw new Error(\"probabilities don't sum to a positive value\");\n }\n\n const normalized = weights.map((w) => (w * n) / sum);\n\n // Initialize alias table\n this.aliases = Array.from<number>({ length: n }).fill(0);\n this.probs = Array.from<number>({ length: n }).fill(0);\n\n // Partition into small and large\n const small: number[] = [];\n const large: number[] = [];\n\n for (let i = n - 1; i >= 0; i--) {\n if (normalized[i] < 1.0) {\n small.push(i);\n } else {\n large.push(i);\n }\n }\n\n // Build the alias table\n while (small.length > 0 && large.length > 0) {\n const a = small.pop();\n const g = large.pop();\n if (a === undefined || g === undefined) break;\n this.probs[a] = normalized[a] ?? 0;\n this.aliases[a] = g;\n const normalizedG = normalized[g] ?? 0;\n const normalizedA = normalized[a] ?? 0;\n normalized[g] = normalizedG + normalizedA - 1.0;\n if (normalized[g] !== undefined && normalized[g] < 1.0) {\n small.push(g);\n } else {\n large.push(g);\n }\n }\n\n while (large.length > 0) {\n const g = large.pop();\n if (g === undefined) break;\n this.probs[g] = 1.0;\n }\n\n while (small.length > 0) {\n const a = small.pop();\n if (a === undefined) break;\n this.probs[a] = 1.0;\n }\n }\n\n /**\n * Sample from the distribution.\n */\n next(rng: Xoshiro256): number {\n const r1 = rng.nextDouble();\n const r2 = rng.nextDouble();\n const n = this.probs.length;\n const i = Math.floor(n * r1);\n if (r2 < this.probs[i]) {\n return i;\n } else {\n return this.aliases[i];\n }\n }\n}\n\n/**\n * Creates a Xoshiro256 PRNG instance from message checksum and sequence number.\n *\n * This creates an 8-byte seed by concatenating seqNum and checksum (both in\n * big-endian), then hashes it with SHA-256 to get the 32-byte seed for Xoshiro.\n *\n * This matches the BC-UR reference implementation.\n */\nexport function createSeed(checksum: number, seqNum: number): Uint8Array {\n // Create 8-byte seed: seqNum (big-endian) || checksum (big-endian)\n const seed8 = new Uint8Array(8);\n\n // seqNum in big-endian (bytes 0-3)\n seed8[0] = (seqNum >>> 24) & 0xff;\n seed8[1] = (seqNum >>> 16) & 0xff;\n seed8[2] = (seqNum >>> 8) & 0xff;\n seed8[3] = seqNum & 0xff;\n\n // checksum in big-endian (bytes 4-7)\n seed8[4] = (checksum >>> 24) & 0xff;\n seed8[5] = (checksum >>> 16) & 0xff;\n seed8[6] = (checksum >>> 8) & 0xff;\n seed8[7] = checksum & 0xff;\n\n // Hash with SHA-256 to get 32 bytes\n return sha256(seed8);\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Fountain code implementation for multipart URs.\n *\n * This implements a hybrid fixed-rate and rateless fountain code system\n * as specified in BCR-2020-005 and BCR-2024-001.\n *\n * Key concepts:\n * - Parts 1-seqLen are \"pure\" fragments (fixed-rate)\n * - Parts > seqLen are \"mixed\" fragments using XOR (rateless)\n * - Xoshiro256** PRNG ensures encoder/decoder agree on mixing\n */\n\nimport { Xoshiro256, createSeed } from \"./xoshiro.js\";\nimport { crc32 } from \"./utils.js\";\n\n/**\n * Represents a fountain code part with metadata.\n */\nexport interface FountainPart {\n /** Sequence number (1-based) */\n seqNum: number;\n /** Total number of pure fragments */\n seqLen: number;\n /** Length of original message */\n messageLen: number;\n /** CRC32 checksum of original message */\n checksum: number;\n /** Fragment data */\n data: Uint8Array;\n}\n\n/**\n * Calculates the quotient of `a` and `b`, rounded toward positive infinity.\n *\n * Mirrors Rust `ur-0.4.1/src/fountain.rs::div_ceil`.\n */\nfunction divCeil(a: number, b: number): number {\n const d = Math.floor(a / b);\n const r = a % b;\n return r > 0 ? d + 1 : d;\n}\n\n/**\n * Computes the optimal fragment length for a given message length and\n * maximum fragment length.\n *\n * The algorithm:\n * fragment_count = ceil(data_length / max_fragment_length)\n * fragment_length = ceil(data_length / fragment_count)\n *\n * This produces fragments that are as balanced as possible while still\n * respecting `maxFragmentLen` as an upper bound on each fragment. For\n * example, a 10-byte message with `maxFragmentLen = 6` yields a fragment\n * length of 5 (so two even 5-byte fragments) rather than 6 (one full\n * fragment plus a 4-byte tail).\n *\n * Mirrors Rust `ur-0.4.1/src/fountain.rs::fragment_length` byte-for-byte.\n */\nexport function fragmentLength(dataLength: number, maxFragmentLength: number): number {\n const fragmentCount = divCeil(dataLength, maxFragmentLength);\n return divCeil(dataLength, fragmentCount);\n}\n\n/**\n * Splits `data` into a list of `fragmentLen`-sized chunks, zero-padding\n * the last chunk if necessary so that every chunk is exactly\n * `fragmentLen` bytes long.\n *\n * Note: `fragmentLen` is the **already-computed** fragment length (see\n * {@link fragmentLength}), not the user-facing maximum fragment length.\n *\n * Mirrors Rust `ur-0.4.1/src/fountain.rs::partition` byte-for-byte.\n */\nexport function partition(data: Uint8Array, fragmentLen: number): Uint8Array[] {\n if (fragmentLen < 1) {\n throw new Error(\"fragment length must be at least 1\");\n }\n const remainder = data.length % fragmentLen;\n const padding = remainder === 0 ? 0 : fragmentLen - remainder;\n const padded = new Uint8Array(data.length + padding);\n padded.set(data);\n // Trailing bytes are already zero by Uint8Array's default initialization.\n\n const fragments: Uint8Array[] = [];\n for (let start = 0; start < padded.length; start += fragmentLen) {\n fragments.push(padded.slice(start, start + fragmentLen));\n }\n return fragments;\n}\n\n/**\n * Convenience: compute the optimal fragment length for `message` given\n * `maxFragmentLen` and partition the message into that many fragments.\n *\n * Equivalent to:\n * ```ts\n * partition(message, fragmentLength(message.length, maxFragmentLen))\n * ```\n *\n * This is what {@link FountainEncoder} does internally when constructing\n * its fragment table.\n */\nexport function splitMessage(message: Uint8Array, maxFragmentLen: number): Uint8Array[] {\n if (maxFragmentLen < 1) {\n throw new Error(\"max fragment length must be at least 1\");\n }\n if (message.length === 0) {\n return [];\n }\n return partition(message, fragmentLength(message.length, maxFragmentLen));\n}\n\n/**\n * XOR two Uint8Arrays together.\n */\nexport function xorBytes(a: Uint8Array, b: Uint8Array): Uint8Array {\n const len = Math.max(a.length, b.length);\n const result = new Uint8Array(len);\n\n for (let i = 0; i < len; i++) {\n result[i] = (a[i] ?? 0) ^ (b[i] ?? 0);\n }\n\n return result;\n}\n\n/**\n * Chooses which fragments to mix for a given sequence number.\n *\n * This uses a seeded Xoshiro256** PRNG to deterministically select fragments,\n * ensuring encoder and decoder agree without explicit coordination.\n *\n * The algorithm matches the BC-UR reference implementation:\n * 1. For pure parts (seqNum <= seqLen), return single fragment index\n * 2. For mixed parts, use weighted sampling to choose degree\n * 3. Shuffle all indices and take the first 'degree' indices\n *\n * @param seqNum - The sequence number (1-based)\n * @param seqLen - Total number of pure fragments\n * @param checksum - CRC32 checksum of the message\n * @returns Array of fragment indices (0-based)\n */\nexport function chooseFragments(seqNum: number, seqLen: number, checksum: number): number[] {\n // Pure parts (seqNum <= seqLen) contain exactly one fragment\n if (seqNum <= seqLen) {\n return [seqNum - 1];\n }\n\n // Mixed parts use PRNG to select fragments\n const seed = createSeed(checksum, seqNum);\n const rng = new Xoshiro256(seed);\n\n // Choose degree using weighted sampler (1/k distribution)\n const degree = rng.chooseDegree(seqLen);\n\n // Create array of all indices [0, 1, 2, ..., seqLen-1]\n const allIndices: number[] = [];\n for (let i = 0; i < seqLen; i++) {\n allIndices.push(i);\n }\n\n // Shuffle all indices and take the first 'degree' indices\n const shuffled = rng.shuffled(allIndices);\n return shuffled.slice(0, degree);\n}\n\n/**\n * Mixes the selected fragments using XOR.\n */\nexport function mixFragments(fragments: Uint8Array[], indices: number[]): Uint8Array {\n if (indices.length === 0) {\n throw new Error(\"No fragments to mix\");\n }\n\n let result: Uint8Array = new Uint8Array(fragments[0].length);\n\n for (const index of indices) {\n const fragment = fragments[index];\n if (fragment === undefined) {\n throw new Error(`Fragment at index ${index} not found`);\n }\n result = xorBytes(result, fragment);\n }\n\n return result;\n}\n\n/**\n * Fountain encoder for creating multipart URs.\n */\nexport class FountainEncoder {\n private readonly fragments: Uint8Array[];\n private readonly messageLen: number;\n private readonly checksum: number;\n private seqNum = 0;\n\n /**\n * Creates a fountain encoder for the given message.\n *\n * @param message - The message to encode\n * @param maxFragmentLen - Maximum length of each fragment\n *\n * @throws if `message` is empty (mirrors Rust `Error::EmptyMessage`).\n * @throws if `maxFragmentLen < 1` (mirrors Rust `Error::InvalidFragmentLen`).\n */\n constructor(message: Uint8Array, maxFragmentLen: number) {\n if (message.length === 0) {\n throw new Error(\"expected non-empty message\");\n }\n if (maxFragmentLen < 1) {\n throw new Error(\"expected positive maximum fragment length\");\n }\n\n this.messageLen = message.length;\n this.checksum = crc32(message);\n // Mirrors Rust `Encoder::new`:\n // let fragment_length = fragment_length(message.len(), max_fragment_length);\n // let fragments = partition(message.to_vec(), fragment_length);\n const optimalLen = fragmentLength(message.length, maxFragmentLen);\n this.fragments = partition(message, optimalLen);\n }\n\n /**\n * Returns the number of pure fragments.\n */\n get seqLen(): number {\n return this.fragments.length;\n }\n\n /**\n * Returns whether the message fits in a single part.\n */\n isSinglePart(): boolean {\n return this.fragments.length === 1;\n }\n\n /**\n * Returns whether all pure parts have been emitted.\n */\n isComplete(): boolean {\n return this.seqNum >= this.seqLen;\n }\n\n /**\n * Generates the next fountain part.\n */\n nextPart(): FountainPart {\n this.seqNum++;\n\n const indices = chooseFragments(this.seqNum, this.seqLen, this.checksum);\n const data = mixFragments(this.fragments, indices);\n\n return {\n seqNum: this.seqNum,\n seqLen: this.seqLen,\n messageLen: this.messageLen,\n checksum: this.checksum,\n data,\n };\n }\n\n /**\n * Returns the current sequence number.\n */\n currentSeqNum(): number {\n return this.seqNum;\n }\n\n /**\n * Resets the encoder to start from the beginning.\n */\n reset(): void {\n this.seqNum = 0;\n }\n}\n\n/**\n * Fountain decoder for reassembling multipart URs.\n */\nexport class FountainDecoder {\n private seqLen: number | null = null;\n private messageLen: number | null = null;\n private checksum: number | null = null;\n private fragmentLen: number | null = null;\n\n // Storage for received data\n private readonly pureFragments = new Map<number, Uint8Array>();\n private readonly mixedParts = new Map<number, { indices: number[]; data: Uint8Array }>();\n // Set of already-received `indices` keys (joined by `,`) — Rust uses\n // `BTreeSet<Vec<usize>>` so two parts producing the same index set are\n // deduped even when they have different sequence numbers. Mirrors\n // `ur-0.4.1/src/fountain.rs::Decoder.received`.\n private readonly receivedIndexSets = new Set<string>();\n\n /**\n * Receives a fountain part and attempts to decode.\n *\n * @param part - The fountain part to receive\n * @returns `true` if this part contributed new information,\n * `false` if it was an exact duplicate of a part already seen\n * (or if the decoder was already complete).\n *\n * @throws if the part is empty or inconsistent with previously received\n * parts. Mirrors Rust `Error::EmptyPart` and `Error::InconsistentPart`.\n */\n receive(part: FountainPart): boolean {\n // Mirrors Rust `Decoder::receive`:\n // if self.complete() { return Ok(false); }\n if (this.isComplete()) {\n return false;\n }\n\n // Mirrors Rust's eager EmptyPart check.\n if (part.seqLen === 0 || part.data.length === 0 || part.messageLen === 0) {\n throw new Error(\"expected non-empty part\");\n }\n\n // Initialize on first part\n if (this.seqLen === null) {\n this.seqLen = part.seqLen;\n this.messageLen = part.messageLen;\n this.checksum = part.checksum;\n this.fragmentLen = part.data.length;\n } else if (\n // Mirrors Rust `Decoder::validate` exactly: every metadata field\n // (sequence_count, message_length, checksum, fragment_length) must\n // match across all received parts.\n part.seqLen !== this.seqLen ||\n part.messageLen !== this.messageLen ||\n part.checksum !== this.checksum ||\n part.data.length !== this.fragmentLen\n ) {\n throw new Error(\"part is inconsistent with previous ones\");\n }\n\n // Determine which fragments this part contains.\n const indices = chooseFragments(part.seqNum, this.seqLen, this.checksum ?? 0);\n // Rust sorts the indices implicitly via `BTreeSet` membership; we\n // explicitly sort the key so that two parts whose `chooseFragments`\n // output is the same multiset (regardless of order) collapse to the\n // same dedup key. In practice `chooseFragments` already produces a\n // deterministic shuffle, so this is just defensive.\n const indexSetKey = [...indices].sort((a, b) => a - b).join(\",\");\n if (this.receivedIndexSets.has(indexSetKey)) {\n return false;\n }\n this.receivedIndexSets.add(indexSetKey);\n\n if (indices.length === 1) {\n // Pure fragment (or degree-1 mixed that acts like pure).\n const index = indices[0];\n if (!this.pureFragments.has(index)) {\n this.pureFragments.set(index, part.data);\n }\n } else {\n // Mixed fragment - store for later reduction.\n this.mixedParts.set(part.seqNum, { indices, data: part.data });\n }\n\n // Try to reduce mixed parts.\n this.reduceMixedParts();\n\n return true;\n }\n\n /**\n * Attempts to extract pure fragments from mixed parts.\n */\n private reduceMixedParts(): void {\n let progress = true;\n\n while (progress) {\n progress = false;\n\n for (const [seqNum, mixed] of this.mixedParts) {\n // Find which indices we're missing\n const missing: number[] = [];\n let reduced = mixed.data;\n\n for (const index of mixed.indices) {\n const pure = this.pureFragments.get(index);\n if (pure !== undefined) {\n // XOR out the known fragment\n reduced = xorBytes(reduced, pure);\n } else {\n missing.push(index);\n }\n }\n\n if (missing.length === 0) {\n // All fragments known, remove this mixed part\n this.mixedParts.delete(seqNum);\n progress = true;\n } else if (missing.length === 1) {\n // Can extract the missing fragment\n const missingIndex = missing[0];\n this.pureFragments.set(missingIndex, reduced);\n this.mixedParts.delete(seqNum);\n progress = true;\n }\n }\n }\n }\n\n /**\n * Returns whether all fragments have been received.\n */\n isComplete(): boolean {\n if (this.seqLen === null) {\n return false;\n }\n\n return this.pureFragments.size === this.seqLen;\n }\n\n /**\n * Reconstructs the original message.\n *\n * @returns The original message, or null if not yet complete\n */\n message(): Uint8Array | null {\n if (!this.isComplete() || this.seqLen === null || this.messageLen === null) {\n return null;\n }\n\n // Calculate fragment size from first fragment\n const firstFragment = this.pureFragments.get(0);\n if (firstFragment === undefined) {\n return null;\n }\n\n const fragmentLen = firstFragment.length;\n const result = new Uint8Array(this.messageLen);\n\n // Assemble fragments\n for (let i = 0; i < this.seqLen; i++) {\n const fragment = this.pureFragments.get(i);\n if (fragment === undefined) {\n return null;\n }\n\n const start = i * fragmentLen;\n const end = Math.min(start + fragmentLen, this.messageLen);\n const len = end - start;\n\n result.set(fragment.slice(0, len), start);\n }\n\n // Verify checksum\n const actualChecksum = crc32(result);\n if (actualChecksum !== this.checksum) {\n throw new Error(`Checksum mismatch: expected ${this.checksum}, got ${actualChecksum}`);\n }\n\n return result;\n }\n\n /**\n * Returns the progress as a fraction (0 to 1).\n */\n progress(): number {\n if (this.seqLen === null) {\n return 0;\n }\n return this.pureFragments.size / this.seqLen;\n }\n\n /**\n * Resets the decoder.\n */\n reset(): void {\n this.seqLen = null;\n this.messageLen = null;\n this.checksum = null;\n this.fragmentLen = null;\n this.pureFragments.clear();\n this.mixedParts.clear();\n this.receivedIndexSets.clear();\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\nimport type { UR } from \"./ur.js\";\nimport { URError } from \"./error.js\";\nimport { FountainEncoder, type FountainPart } from \"./fountain.js\";\nimport { encodeBytewords, BytewordsStyle } from \"./utils.js\";\nimport { cbor } from \"@bcts/dcbor\";\n\n/**\n * Encodes a UR as multiple parts using fountain codes.\n *\n * This allows large CBOR structures to be split into multiple UR strings\n * that can be transmitted separately and reassembled. The encoder uses\n * fountain codes for resilient transmission over lossy channels.\n *\n * For single-part URs (small payloads), use the regular UR.string() method.\n *\n * @example\n * ```typescript\n * const ur = UR.new('bytes', cbor);\n * const encoder = new MultipartEncoder(ur, 100);\n *\n * // Generate all pure parts\n * while (!encoder.isComplete()) {\n * const part = encoder.nextPart();\n * console.log(part); // \"ur:bytes/1-10/...\"\n * }\n *\n * // Generate additional rateless parts for redundancy\n * for (let i = 0; i < 5; i++) {\n * const part = encoder.nextPart();\n * console.log(part); // \"ur:bytes/11-10/...\"\n * }\n * ```\n */\nexport class MultipartEncoder {\n private readonly _ur: UR;\n private readonly _fountainEncoder: FountainEncoder;\n private _currentIndex = 0;\n\n /**\n * Creates a new multipart encoder for the given UR.\n *\n * @param ur - The UR to encode\n * @param maxFragmentLen - Maximum length of each fragment in bytes\n * @throws {URError} If encoding fails\n *\n * @example\n * ```typescript\n * const encoder = new MultipartEncoder(ur, 100);\n * ```\n */\n constructor(ur: UR, maxFragmentLen: number) {\n if (maxFragmentLen < 1) {\n throw new URError(\"Max fragment length must be at least 1\");\n }\n this._ur = ur;\n\n // Create fountain encoder from CBOR data\n const cborData = ur.cbor().toData();\n this._fountainEncoder = new FountainEncoder(cborData, maxFragmentLen);\n }\n\n /**\n * Gets the next part of the encoding.\n *\n * Parts 1 through seqLen are \"pure\" fragments containing one piece each.\n * Parts beyond seqLen are \"mixed\" fragments using fountain codes for redundancy.\n *\n * @returns The next UR string part\n *\n * @example\n * ```typescript\n * const part = encoder.nextPart();\n * // Returns: \"ur:bytes/1-3/lsadaoaxjygonesw\"\n * ```\n */\n nextPart(): string {\n const part = this._fountainEncoder.nextPart();\n this._currentIndex++;\n return this._encodePart(part);\n }\n\n /**\n * Encodes a fountain part as a UR string.\n *\n * Always emits the multipart `ur:<type>/<seqNum>-<seqLen>/<bytewords>`\n * format — including for single-part messages (`1-1/...`). This mirrors\n * Rust's `bc_ur::MultipartEncoder::next_part`, which never short-circuits\n * to plain UR. Callers that want plain UR for tiny payloads should use\n * `UR.string()` directly instead of constructing a `MultipartEncoder`.\n */\n private _encodePart(part: FountainPart): string {\n const partData = this._encodePartData(part);\n const encoded = encodeBytewords(partData, BytewordsStyle.Minimal);\n return `ur:${this._ur.urTypeStr()}/${part.seqNum}-${part.seqLen}/${encoded}`;\n }\n\n /**\n * Encodes part metadata and data as CBOR for bytewords encoding.\n * Format: CBOR array [seqNum, seqLen, messageLen, checksum, data]\n */\n private _encodePartData(part: FountainPart): Uint8Array {\n // Create CBOR array with 5 elements: [seqNum, seqLen, messageLen, checksum, data]\n const cborArray = cbor([part.seqNum, part.seqLen, part.messageLen, part.checksum, part.data]);\n\n return cborArray.toData();\n }\n\n /**\n * Gets the current part index.\n */\n currentIndex(): number {\n return this._currentIndex;\n }\n\n /**\n * Gets the total number of pure parts.\n *\n * Note: Fountain codes can generate unlimited parts beyond this count\n * for additional redundancy.\n */\n partsCount(): number {\n return this._fountainEncoder.seqLen;\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\nimport { decodeCbor, MajorType, type Cbor } from \"@bcts/dcbor\";\nimport { InvalidSchemeError, InvalidTypeError, UnexpectedTypeError, URError } from \"./error.js\";\nimport { UR } from \"./ur.js\";\nimport { URType } from \"./ur-type.js\";\nimport { FountainDecoder, type FountainPart } from \"./fountain.js\";\nimport { decodeBytewords, BytewordsStyle } from \"./utils.js\";\n\n/**\n * Decodes multiple UR parts back into a single UR.\n *\n * This reassembles multipart URs that were encoded using fountain codes.\n * The decoder can handle out-of-order reception and packet loss.\n *\n * @example\n * ```typescript\n * const decoder = new MultipartDecoder();\n *\n * for (const urPart of urParts) {\n * decoder.receive(urPart);\n * if (decoder.isComplete()) {\n * const ur = decoder.message();\n * break;\n * }\n * }\n * ```\n */\nexport class MultipartDecoder {\n private _urType: URType | null = null;\n private _fountainDecoder: FountainDecoder | null = null;\n private _decodedMessage: UR | null = null;\n\n /**\n * Receives a UR part string.\n *\n * @param part - A UR part string (e.g., \"ur:bytes/1-10/...\" or \"ur:bytes/...\")\n * @throws {InvalidSchemeError} If the part doesn't start with \"ur:\"\n * @throws {UnexpectedTypeError} If the type doesn't match previous parts\n */\n receive(part: string): void {\n const { urType, partInfo } = this._parsePart(part);\n\n // Validate type consistency\n if (this._urType === null) {\n this._urType = urType;\n } else if (!this._urType.equals(urType)) {\n throw new UnexpectedTypeError(this._urType.string(), urType.string());\n }\n\n // Handle the part\n if (partInfo.isSinglePart) {\n // Single-part UR - decode immediately\n this._decodedMessage = UR.fromURString(part);\n } else {\n // Multipart UR - use fountain decoder\n this._fountainDecoder ??= new FountainDecoder();\n\n const fountainPart = this._decodeFountainPart(partInfo);\n this._fountainDecoder.receive(fountainPart);\n\n // Try to get the complete message\n if (this._fountainDecoder.isComplete()) {\n const message = this._fountainDecoder.message();\n if (message !== null) {\n const cbor = decodeCbor(message);\n this._decodedMessage = UR.new(this._urType, cbor);\n }\n }\n }\n }\n\n /**\n * Parses a UR part string to extract type and part info.\n */\n private _parsePart(part: string): { urType: URType; partInfo: PartInfo } {\n const lowercased = part.toLowerCase();\n\n if (!lowercased.startsWith(\"ur:\")) {\n throw new InvalidSchemeError();\n }\n\n const afterScheme = lowercased.substring(3);\n const components = afterScheme.split(\"/\");\n\n if (components.length === 0 || components[0] === \"\") {\n throw new InvalidTypeError();\n }\n\n const urType = new URType(components[0]);\n\n // Check if this is a multipart UR (format: type/seqNum-seqLen/data)\n if (components.length >= 3) {\n const seqPart = components[1];\n const seqMatch = /^(\\d+)-(\\d+)$/.exec(seqPart);\n\n if (seqMatch !== null) {\n const seqNum = parseInt(seqMatch[1], 10);\n const seqLen = parseInt(seqMatch[2], 10);\n const encodedData = components.slice(2).join(\"/\");\n\n return {\n urType,\n partInfo: {\n isSinglePart: false,\n seqNum,\n seqLen,\n encodedData,\n },\n };\n }\n }\n\n // Single-part UR\n return {\n urType,\n partInfo: { isSinglePart: true },\n };\n }\n\n /**\n * Decodes a multipart UR's fountain part data.\n *\n * The multipart body is a CBOR array: [seqNum, seqLen, messageLen, checksum, data]\n */\n private _decodeFountainPart(partInfo: MultipartInfo): FountainPart {\n // Decode bytewords to get CBOR data\n const cborData = decodeBytewords(partInfo.encodedData, BytewordsStyle.Minimal);\n\n // Decode the CBOR array\n const decoded = decodeCbor(cborData);\n\n // The decoded value should be an array with 5 elements\n if (decoded.type !== MajorType.Array) {\n throw new URError(\"Invalid multipart data: expected CBOR array\");\n }\n\n const items = decoded.value as Cbor[];\n if (items.length !== 5) {\n throw new URError(`Invalid multipart data: expected 5 elements, got ${items.length}`);\n }\n\n // Extract the fields: [seqNum, seqLen, messageLen, checksum, data]\n const seqNum = Number(items[0].value);\n const seqLen = Number(items[1].value);\n const messageLen = Number(items[2].value);\n const checksum = Number(items[3].value);\n const data = items[4].value as Uint8Array;\n\n // Verify seqNum and seqLen match the URL path values\n if (seqNum !== partInfo.seqNum || seqLen !== partInfo.seqLen) {\n throw new URError(\n `Multipart metadata mismatch: URL says ${partInfo.seqNum}-${partInfo.seqLen}, CBOR says ${seqNum}-${seqLen}`,\n );\n }\n\n return {\n seqNum,\n seqLen,\n messageLen,\n checksum,\n data,\n };\n }\n\n /**\n * Checks if the message is complete.\n */\n isComplete(): boolean {\n return this._decodedMessage !== null;\n }\n\n /**\n * Gets the decoded UR message.\n *\n * @returns The decoded UR, or null if not yet complete\n */\n message(): UR | null {\n return this._decodedMessage;\n }\n}\n\n/**\n * Part info for single-part URs.\n */\ninterface SinglePartInfo {\n isSinglePart: true;\n}\n\n/**\n * Part info for multipart URs.\n */\ninterface MultipartInfo {\n isSinglePart: false;\n seqNum: number;\n seqLen: number;\n encodedData: string;\n}\n\ntype PartInfo = SinglePartInfo | MultipartInfo;\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Namespace-style re-export of the bytewords helpers in `./utils`.\n *\n * Mirrors Rust's `bc_ur::bytewords` module (`bc-ur-rust/src/bytewords.rs`)\n * so that callers can write\n *\n * ```ts\n * import { bytewords } from \"@bcts/uniform-resources\";\n * bytewords.encode(data, bytewords.Style.Minimal);\n * bytewords.identifier(fourByteSlice);\n * ```\n *\n * matching the ergonomics of\n *\n * ```rust\n * use bc_ur::bytewords;\n * bytewords::encode(data, bytewords::Style::Minimal);\n * bytewords::identifier(four_byte_slice);\n * ```\n *\n * This is purely an alias module — every symbol below is the same\n * function/value already exported individually from the package root.\n */\n\nexport {\n BYTEWORDS,\n BYTEMOJIS,\n BytewordsStyle as Style,\n encodeBytewords as encode,\n decodeBytewords as decode,\n encodeBytewordsIdentifier as identifier,\n encodeBytemojisIdentifier as bytemojiIdentifier,\n encodeToWords,\n encodeToBytemojis,\n encodeToMinimalBytewords,\n isValidBytemoji,\n canonicalizeByteword,\n} from \"./utils\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAOA,IAAa,UAAb,cAA6B,MAAM;CACjC,YAAY,SAAiB;AAC3B,QAAM,QAAQ;AACd,OAAK,OAAO;;;;;;;;AAShB,IAAa,qBAAb,cAAwC,QAAQ;CAC9C,cAAc;AACZ,QAAM,oBAAoB;AAC1B,OAAK,OAAO;;;;;;;;AAShB,IAAa,uBAAb,cAA0C,QAAQ;CAChD,cAAc;AACZ,QAAM,uBAAuB;AAC7B,OAAK,OAAO;;;;;;;;AAShB,IAAa,mBAAb,cAAsC,QAAQ;CAC5C,cAAc;AACZ,QAAM,kBAAkB;AACxB,OAAK,OAAO;;;;;;AAOhB,IAAa,qBAAb,cAAwC,QAAQ;CAC9C,cAAc;AACZ,QAAM,0BAA0B;AAChC,OAAK,OAAO;;;;;;;;;AAUhB,IAAa,sBAAb,cAAyC,QAAQ;CAC/C,YAAY,UAAkB,OAAe;AAC3C,QAAM,oBAAoB,SAAS,cAAc,QAAQ;AACzD,OAAK,OAAO;;;;;;;;AAShB,IAAa,iBAAb,cAAoC,QAAQ;CAC1C,YAAY,SAAiB;AAC3B,QAAM,oBAAoB,QAAQ,GAAG;AACrC,OAAK,OAAO;;;;;;;;AAShB,IAAa,YAAb,cAA+B,QAAQ;CACrC,YAAY,SAAiB;AAC3B,QAAM,eAAe,QAAQ,GAAG;AAChC,OAAK,OAAO;;;;;;;AAQhB,IAAa,gBAAb,cAAmC,QAAQ;CACzC,YAAY,SAAiB;AAC3B,QAAM,qBAAqB,QAAQ,GAAG;AACtC,OAAK,OAAO;;;;;;AAShB,SAAgB,QAAQ,QAAkC;AACxD,QAAO,kBAAkB;;;;;;;;;;;;;;;ACpG3B,SAAgB,aAAa,MAAuB;CAClD,MAAM,OAAO,KAAK,WAAW,EAAE;AAE/B,KAAI,QAAQ,MAAM,QAAQ,IAAK,QAAO;AAEtC,KAAI,QAAQ,MAAM,QAAQ,GAAI,QAAO;AAErC,KAAI,SAAS,GAAI,QAAO;AACxB,QAAO;;;;;;;;;;;AAYT,SAAgB,cAAc,QAAyB;AACrD,QAAO,MAAM,KAAK,OAAO,CAAC,OAAO,SAAS,aAAa,KAAK,CAAC;;;;;AAM/D,SAAgB,eAAe,QAAwB;AACrD,KAAI,CAAC,cAAc,OAAO,CACxB,OAAM,IAAI,kBAAkB;AAE9B,QAAO;;;;;;AAOT,MAAa,YAAsB;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;AAKD,SAAS,qBAA0C;CACjD,MAAM,sBAAM,IAAI,KAAqB;AACrC,WAAU,SAAS,MAAM,UAAU;AACjC,MAAI,IAAI,MAAM,MAAM;GACpB;AACF,QAAO;;AAGT,MAAa,gBAAgB,oBAAoB;;;;;AAMjD,MAAa,YAAsB;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA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"}
1
+ {"version":3,"file":"index.cjs","names":["MajorType"],"sources":["../src/error.ts","../src/utils.ts","../src/ur-type.ts","../src/ur.ts","../src/ur-encodable.ts","../src/ur-decodable.ts","../src/ur-codable.ts","../src/xoshiro.ts","../src/fountain.ts","../src/multipart-encoder.ts","../src/multipart-decoder.ts","../src/bytewords-namespace.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Error type for UR encoding/decoding operations.\n */\nexport class URError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"URError\";\n }\n}\n\n/**\n * Error type for invalid UR schemes.\n *\n * Message matches Rust bc-ur-rust/src/error.rs: `invalid UR scheme`.\n */\nexport class InvalidSchemeError extends URError {\n constructor() {\n super(\"invalid UR scheme\");\n this.name = \"InvalidSchemeError\";\n }\n}\n\n/**\n * Error type for unspecified UR types.\n *\n * Message matches Rust bc-ur-rust/src/error.rs: `no UR type specified`.\n */\nexport class TypeUnspecifiedError extends URError {\n constructor() {\n super(\"no UR type specified\");\n this.name = \"TypeUnspecifiedError\";\n }\n}\n\n/**\n * Error type for invalid UR types.\n *\n * Message matches Rust bc-ur-rust/src/error.rs: `invalid UR type`.\n */\nexport class InvalidTypeError extends URError {\n constructor() {\n super(\"invalid UR type\");\n this.name = \"InvalidTypeError\";\n }\n}\n\n/**\n * Error type for non-single-part URs.\n */\nexport class NotSinglePartError extends URError {\n constructor() {\n super(\"UR is not a single-part\");\n this.name = \"NotSinglePartError\";\n }\n}\n\n/**\n * Error type for unexpected UR types.\n *\n * Message matches Rust bc-ur-rust/src/error.rs:\n * `expected UR type {expected}, but found {found}`.\n */\nexport class UnexpectedTypeError extends URError {\n constructor(expected: string, found: string) {\n super(`expected UR type ${expected}, but found ${found}`);\n this.name = \"UnexpectedTypeError\";\n }\n}\n\n/**\n * Error type for Bytewords encoding/decoding errors.\n *\n * Message matches Rust bc-ur-rust/src/error.rs: `Bytewords error ({0})`.\n */\nexport class BytewordsError extends URError {\n constructor(message: string) {\n super(`Bytewords error (${message})`);\n this.name = \"BytewordsError\";\n }\n}\n\n/**\n * Error type for CBOR encoding/decoding errors.\n *\n * Message matches Rust bc-ur-rust/src/error.rs: `CBOR error ({0})`.\n */\nexport class CBORError extends URError {\n constructor(message: string) {\n super(`CBOR error (${message})`);\n this.name = \"CBORError\";\n }\n}\n\n/**\n * Error type for UR decoder errors.\n * Matches Rust's Error::UR(String) variant.\n */\nexport class URDecodeError extends URError {\n constructor(message: string) {\n super(`UR decoder error (${message})`);\n this.name = \"URDecodeError\";\n }\n}\n\nexport type Result<T> = T | Error;\n\n/**\n * Helper function to check if a result is an error.\n */\nexport function isError(result: unknown): result is Error {\n return result instanceof Error;\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\nimport { BytewordsError, InvalidTypeError } from \"./error.js\";\n\n/**\n * Checks if a character is a valid UR type character.\n *\n * Mirrors Rust's `URTypeChar::is_ur_type` (`bc-ur-rust/src/utils.rs:6-19`):\n * lowercase a-z, digits 0-9, and the hyphen `-`.\n */\nexport function isURTypeChar(char: string): boolean {\n const code = char.charCodeAt(0);\n // Check for lowercase letters (a-z)\n if (code >= 97 && code <= 122) return true;\n // Check for digits (0-9)\n if (code >= 48 && code <= 57) return true;\n // Check for hyphen (-)\n if (code === 45) return true;\n return false;\n}\n\n/**\n * Checks if a string is a valid UR type.\n *\n * Mirrors Rust's `URTypeString::is_ur_type` (`bc-ur-rust/src/utils.rs:26-32`)\n * which is `self.chars().all(...)` — meaning **the empty string is accepted**\n * (a vacuously-true `all` over no chars). We mirror that here so that\n * `URType::new(\"\")` succeeds in both ports; the round-trip then fails at\n * decode-time with `TypeUnspecified`.\n */\nexport function isValidURType(urType: string): boolean {\n return Array.from(urType).every((char) => isURTypeChar(char));\n}\n\n/**\n * Validates and returns a UR type, or throws an error if invalid.\n */\nexport function validateURType(urType: string): string {\n if (!isValidURType(urType)) {\n throw new InvalidTypeError();\n }\n return urType;\n}\n\n/**\n * Bytewords for encoding/decoding bytes as words.\n * See: https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-004-bytewords.md\n */\nexport const BYTEWORDS: string[] = [\n \"able\",\n \"acid\",\n \"also\",\n \"apex\",\n \"aqua\",\n \"arch\",\n \"atom\",\n \"aunt\",\n \"away\",\n \"axis\",\n \"back\",\n \"bald\",\n \"barn\",\n \"belt\",\n \"beta\",\n \"bias\",\n \"blue\",\n \"body\",\n \"brag\",\n \"brew\",\n \"bulb\",\n \"buzz\",\n \"calm\",\n \"cash\",\n \"cats\",\n \"chef\",\n \"city\",\n \"claw\",\n \"code\",\n \"cola\",\n \"cook\",\n \"cost\",\n \"crux\",\n \"curl\",\n \"cusp\",\n \"cyan\",\n \"dark\",\n \"data\",\n \"days\",\n \"deli\",\n \"dice\",\n \"diet\",\n \"door\",\n \"down\",\n \"draw\",\n \"drop\",\n \"drum\",\n \"dull\",\n \"duty\",\n \"each\",\n \"easy\",\n \"echo\",\n \"edge\",\n \"epic\",\n \"even\",\n \"exam\",\n \"exit\",\n \"eyes\",\n \"fact\",\n \"fair\",\n \"fern\",\n \"figs\",\n \"film\",\n \"fish\",\n \"fizz\",\n \"flap\",\n \"flew\",\n \"flux\",\n \"foxy\",\n \"free\",\n \"frog\",\n \"fuel\",\n \"fund\",\n \"gala\",\n \"game\",\n \"gear\",\n \"gems\",\n \"gift\",\n \"girl\",\n \"glow\",\n \"good\",\n \"gray\",\n \"grim\",\n \"guru\",\n \"gush\",\n \"gyro\",\n \"half\",\n \"hang\",\n \"hard\",\n \"hawk\",\n \"heat\",\n \"help\",\n \"high\",\n \"hill\",\n \"holy\",\n \"hope\",\n \"horn\",\n \"huts\",\n \"iced\",\n \"idea\",\n \"idle\",\n \"inch\",\n \"inky\",\n \"into\",\n \"iris\",\n \"iron\",\n \"item\",\n \"jade\",\n \"jazz\",\n \"join\",\n \"jolt\",\n \"jowl\",\n \"judo\",\n \"jugs\",\n \"jump\",\n \"junk\",\n \"jury\",\n \"keep\",\n \"keno\",\n \"kept\",\n \"keys\",\n \"kick\",\n \"kiln\",\n \"king\",\n \"kite\",\n \"kiwi\",\n \"knob\",\n \"lamb\",\n \"lava\",\n \"lazy\",\n \"leaf\",\n \"legs\",\n \"liar\",\n \"limp\",\n \"lion\",\n \"list\",\n \"logo\",\n \"loud\",\n \"love\",\n \"luau\",\n \"luck\",\n \"lung\",\n \"main\",\n \"many\",\n \"math\",\n \"maze\",\n \"memo\",\n \"menu\",\n \"meow\",\n \"mild\",\n \"mint\",\n \"miss\",\n \"monk\",\n \"nail\",\n \"navy\",\n \"need\",\n \"news\",\n \"next\",\n \"noon\",\n \"note\",\n \"numb\",\n \"obey\",\n \"oboe\",\n \"omit\",\n \"onyx\",\n \"open\",\n \"oval\",\n \"owls\",\n \"paid\",\n \"part\",\n \"peck\",\n \"play\",\n \"plus\",\n \"poem\",\n \"pool\",\n \"pose\",\n \"puff\",\n \"puma\",\n \"purr\",\n \"quad\",\n \"quiz\",\n \"race\",\n \"ramp\",\n \"real\",\n \"redo\",\n \"rich\",\n \"road\",\n \"rock\",\n \"roof\",\n \"ruby\",\n \"ruin\",\n \"runs\",\n \"rust\",\n \"safe\",\n \"saga\",\n \"scar\",\n \"sets\",\n \"silk\",\n \"skew\",\n \"slot\",\n \"soap\",\n \"solo\",\n \"song\",\n \"stub\",\n \"surf\",\n \"swan\",\n \"taco\",\n \"task\",\n \"taxi\",\n \"tent\",\n \"tied\",\n \"time\",\n \"tiny\",\n \"toil\",\n \"tomb\",\n \"toys\",\n \"trip\",\n \"tuna\",\n \"twin\",\n \"ugly\",\n \"undo\",\n \"unit\",\n \"urge\",\n \"user\",\n \"vast\",\n \"very\",\n \"veto\",\n \"vial\",\n \"vibe\",\n \"view\",\n \"visa\",\n \"void\",\n \"vows\",\n \"wall\",\n \"wand\",\n \"warm\",\n \"wasp\",\n \"wave\",\n \"waxy\",\n \"webs\",\n \"what\",\n \"when\",\n \"whiz\",\n \"wolf\",\n \"work\",\n \"yank\",\n \"yawn\",\n \"yell\",\n \"yoga\",\n \"yurt\",\n \"zaps\",\n \"zero\",\n \"zest\",\n \"zinc\",\n \"zone\",\n \"zoom\",\n];\n\n/**\n * Create a reverse mapping for fast byteword lookup.\n */\nfunction createBytewordsMap(): Map<string, number> {\n const map = new Map<string, number>();\n BYTEWORDS.forEach((word, index) => {\n map.set(word, index);\n });\n return map;\n}\n\nexport const BYTEWORDS_MAP = createBytewordsMap();\n\n/**\n * Bytemojis for encoding/decoding bytes as emojis.\n * See: https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2024-008-bytemoji.md\n */\nexport const BYTEMOJIS: string[] = [\n \"😀\",\n \"😂\",\n \"😆\",\n \"😉\",\n \"🙄\",\n \"😋\",\n \"😎\",\n \"😍\",\n \"😘\",\n \"😭\",\n \"🫠\",\n \"🥱\",\n \"🤩\",\n \"😶\",\n \"🤨\",\n \"🫥\",\n \"🥵\",\n \"🥶\",\n \"😳\",\n \"🤪\",\n \"😵\",\n \"😡\",\n \"🤢\",\n \"😇\",\n \"🤠\",\n \"🤡\",\n \"🥳\",\n \"🥺\",\n \"😬\",\n \"🤑\",\n \"🙃\",\n \"🤯\",\n \"😈\",\n \"👹\",\n \"👺\",\n \"💀\",\n \"👻\",\n \"👽\",\n \"😺\",\n \"😹\",\n \"😻\",\n \"😽\",\n \"🙀\",\n \"😿\",\n \"🫶\",\n \"🤲\",\n \"🙌\",\n \"🤝\",\n \"👍\",\n \"👎\",\n \"👈\",\n \"👆\",\n \"💪\",\n \"👄\",\n \"🦷\",\n \"👂\",\n \"👃\",\n \"🧠\",\n \"👀\",\n \"🤚\",\n \"🦶\",\n \"🍎\",\n \"🍊\",\n \"🍋\",\n \"🍌\",\n \"🍉\",\n \"🍇\",\n \"🍓\",\n \"🫐\",\n \"🍒\",\n \"🍑\",\n \"🍍\",\n \"🥝\",\n \"🍆\",\n \"🥑\",\n \"🥦\",\n \"🍅\",\n \"🌽\",\n \"🥕\",\n \"🫒\",\n \"🧄\",\n \"🥐\",\n \"🥯\",\n \"🍞\",\n \"🧀\",\n \"🥚\",\n \"🍗\",\n \"🌭\",\n \"🍔\",\n \"🍟\",\n \"🍕\",\n \"🌮\",\n \"🥙\",\n \"🍱\",\n \"🍜\",\n \"🍤\",\n \"🍚\",\n \"🥠\",\n \"🍨\",\n \"🍦\",\n \"🎂\",\n \"🪴\",\n \"🌵\",\n \"🌱\",\n \"💐\",\n \"🍁\",\n \"🍄\",\n \"🌹\",\n \"🌺\",\n \"🌼\",\n \"🌻\",\n \"🌸\",\n \"💨\",\n \"🌊\",\n \"💧\",\n \"💦\",\n \"🌀\",\n \"🌈\",\n \"🌞\",\n \"🌝\",\n \"🌛\",\n \"🌜\",\n \"🌙\",\n \"🌎\",\n \"💫\",\n \"⭐\",\n \"🪐\",\n \"🌐\",\n \"💛\",\n \"💔\",\n \"💘\",\n \"💖\",\n \"💕\",\n \"🏁\",\n \"🚩\",\n \"💬\",\n \"💯\",\n \"🚫\",\n \"🔴\",\n \"🔷\",\n \"🟩\",\n \"🛑\",\n \"🔺\",\n \"🚗\",\n \"🚑\",\n \"🚒\",\n \"🚜\",\n \"🛵\",\n \"🚨\",\n \"🚀\",\n \"🚁\",\n \"🛟\",\n \"🚦\",\n \"🏰\",\n \"🎡\",\n \"🎢\",\n \"🎠\",\n \"🏠\",\n \"🔔\",\n \"🔑\",\n \"🚪\",\n \"🪑\",\n \"🎈\",\n \"💌\",\n \"📦\",\n \"📫\",\n \"📖\",\n \"📚\",\n \"📌\",\n \"🧮\",\n \"🔒\",\n \"💎\",\n \"📷\",\n \"⏰\",\n \"⏳\",\n \"📡\",\n \"💡\",\n \"💰\",\n \"🧲\",\n \"🧸\",\n \"🎁\",\n \"🎀\",\n \"🎉\",\n \"🪭\",\n \"👑\",\n \"🫖\",\n \"🔭\",\n \"🛁\",\n \"🏆\",\n \"🥁\",\n \"🎷\",\n \"🎺\",\n \"🏀\",\n \"🏈\",\n \"🎾\",\n \"🏓\",\n \"✨\",\n \"🔥\",\n \"💥\",\n \"👕\",\n \"👚\",\n \"👖\",\n \"🩳\",\n \"👗\",\n \"👔\",\n \"🧢\",\n \"👓\",\n \"🧶\",\n \"🧵\",\n \"💍\",\n \"👠\",\n \"👟\",\n \"🧦\",\n \"🧤\",\n \"👒\",\n \"👜\",\n \"🐱\",\n \"🐶\",\n \"🐭\",\n \"🐹\",\n \"🐰\",\n \"🦊\",\n \"🐻\",\n \"🐼\",\n \"🐨\",\n \"🐯\",\n \"🦁\",\n \"🐮\",\n \"🐷\",\n \"🐸\",\n \"🐵\",\n \"🐔\",\n \"🐥\",\n \"🦆\",\n \"🦉\",\n \"🐴\",\n \"🦄\",\n \"🐝\",\n \"🐛\",\n \"🦋\",\n \"🐌\",\n \"🐞\",\n \"🐢\",\n \"🐺\",\n \"🐍\",\n \"🪽\",\n \"🐙\",\n \"🦑\",\n \"🪼\",\n \"🦞\",\n \"🦀\",\n \"🐚\",\n \"🦭\",\n \"🐟\",\n \"🐬\",\n \"🐳\",\n];\n\n/**\n * Encodes an arbitrary byte slice as a string of space-separated bytewords.\n *\n * Mirrors `bytewords::encode_to_words` in `bc-ur-rust` (≥ v0.19.1). Does not\n * add a CRC32 checksum — use {@link encodeBytewords} for UR-style encoding.\n */\nexport function encodeToWords(data: Uint8Array): string {\n const words: string[] = [];\n for (const byte of data) {\n const word = BYTEWORDS[byte];\n if (word === undefined) throw new Error(`Invalid byte value: ${byte}`);\n words.push(word);\n }\n return words.join(\" \");\n}\n\n/**\n * Encodes an arbitrary byte slice as a string of space-separated bytemojis.\n *\n * Mirrors `bytewords::encode_to_bytemojis` in `bc-ur-rust` (≥ v0.19.1).\n */\nexport function encodeToBytemojis(data: Uint8Array): string {\n const emojis: string[] = [];\n for (const byte of data) {\n const emoji = BYTEMOJIS[byte];\n if (emoji === undefined) throw new Error(`Invalid byte value: ${byte}`);\n emojis.push(emoji);\n }\n return emojis.join(\" \");\n}\n\n/**\n * Encodes an arbitrary byte slice as minimal bytewords (first + last letter of\n * each word, concatenated with no separator).\n *\n * Mirrors `bytewords::encode_to_minimal_bytewords` in `bc-ur-rust`\n * (≥ v0.19.1). Does not add a CRC32 checksum.\n */\nexport function encodeToMinimalBytewords(data: Uint8Array): string {\n let out = \"\";\n for (const byte of data) {\n const word = BYTEWORDS[byte];\n if (word === undefined) throw new Error(`Invalid byte value: ${byte}`);\n out += word[0] + word[word.length - 1];\n }\n return out;\n}\n\n/**\n * Encodes a 4-byte slice as a string of bytewords for identification.\n *\n * Thin wrapper over {@link encodeToWords} that enforces the 4-byte length\n * contract historically used by `bc-ur-rust`'s `bytewords::identifier`.\n */\nexport function encodeBytewordsIdentifier(data: Uint8Array): string {\n if (data.length !== 4) {\n throw new Error(\"Identifier data must be exactly 4 bytes\");\n }\n return encodeToWords(data);\n}\n\n/**\n * Encodes a 4-byte slice as a string of bytemojis for identification.\n *\n * Thin wrapper over {@link encodeToBytemojis} that enforces the 4-byte length\n * contract historically used by `bc-ur-rust`'s `bytewords::bytemoji_identifier`.\n */\nexport function encodeBytemojisIdentifier(data: Uint8Array): string {\n if (data.length !== 4) {\n throw new Error(\"Identifier data must be exactly 4 bytes\");\n }\n return encodeToBytemojis(data);\n}\n\n/**\n * Returns `true` if `emoji` is one of the 256 bytemojis.\n *\n * Mirrors `bytewords::is_valid_bytemoji` in `bc-ur-rust` (≥ v0.19.1).\n */\nexport function isValidBytemoji(emoji: string): boolean {\n return BYTEMOJI_SET.has(emoji);\n}\n\n/**\n * Canonicalises a byteword token (2–4 ASCII letters, case-insensitive) to its\n * full 4-letter lowercase form. Returns `undefined` if the token is not a\n * valid byteword or any of its short forms.\n *\n * Mirrors `bytewords::canonicalize_byteword` in `bc-ur-rust` (≥ v0.19.1).\n *\n * - 2-letter tokens are matched against the first + last letter of each\n * byteword (identical to the minimal bytewords encoding).\n * - 3-letter tokens are matched against the first 3 and the last 3 letters of\n * each byteword; if both match different entries, the first-3 match wins\n * (matching rust's `or_else` priority).\n * - 4-letter tokens must exactly match a full byteword (after lower-casing).\n */\nexport function canonicalizeByteword(token: string): string | undefined {\n const lower = token.toLowerCase();\n switch (lower.length) {\n case 4:\n return BYTEWORDS_MAP.has(lower) ? lower : undefined;\n case 2:\n return BYTEWORD_FIRST_LAST_MAP.get(lower);\n case 3: {\n return BYTEWORD_FIRST_THREE_MAP.get(lower) ?? BYTEWORD_LAST_THREE_MAP.get(lower);\n }\n default:\n return undefined;\n }\n}\n\n/**\n * Bytewords encoding style.\n */\nexport enum BytewordsStyle {\n /** Full 4-letter words separated by spaces */\n Standard = \"standard\",\n /** Full 4-letter words separated by hyphens (URI-safe) */\n Uri = \"uri\",\n /** First and last character only (minimal) - used by UR encoding */\n Minimal = \"minimal\",\n}\n\n/**\n * Create a reverse mapping for minimal bytewords (first+last char) lookup.\n */\nfunction createMinimalBytewordsMap(): Map<string, number> {\n const map = new Map<string, number>();\n BYTEWORDS.forEach((word, index) => {\n // Minimal encoding uses first and last character\n const minimal = word[0] + word[3];\n map.set(minimal, index);\n });\n return map;\n}\n\nexport const MINIMAL_BYTEWORDS_MAP = createMinimalBytewordsMap();\n\n/**\n * Set of all 256 bytemojis for fast membership testing. Backs\n * {@link isValidBytemoji}.\n */\nconst BYTEMOJI_SET: ReadonlySet<string> = new Set(BYTEMOJIS);\n\n/**\n * Lookup from a 2-letter (first+last) byteword short-form to its full\n * lowercase 4-letter form. Backs {@link canonicalizeByteword}.\n */\nconst BYTEWORD_FIRST_LAST_MAP: ReadonlyMap<string, string> = (() => {\n const map = new Map<string, string>();\n for (const word of BYTEWORDS) {\n map.set(word[0] + word[word.length - 1], word);\n }\n return map;\n})();\n\n/**\n * Lookup from the first 3 letters of a byteword to its full lowercase 4-letter\n * form. Backs {@link canonicalizeByteword}.\n */\nconst BYTEWORD_FIRST_THREE_MAP: ReadonlyMap<string, string> = (() => {\n const map = new Map<string, string>();\n for (const word of BYTEWORDS) {\n map.set(word.slice(0, 3), word);\n }\n return map;\n})();\n\n/**\n * Lookup from the last 3 letters of a byteword to its full lowercase 4-letter\n * form. Backs {@link canonicalizeByteword}.\n */\nconst BYTEWORD_LAST_THREE_MAP: ReadonlyMap<string, string> = (() => {\n const map = new Map<string, string>();\n for (const word of BYTEWORDS) {\n map.set(word.slice(1), word);\n }\n return map;\n})();\n\n/**\n * CRC32 lookup table (IEEE polynomial).\n */\nconst CRC32_TABLE: number[] = (() => {\n const table: number[] = [];\n for (let i = 0; i < 256; i++) {\n let c = i;\n for (let j = 0; j < 8; j++) {\n c = (c & 1) !== 0 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table.push(c >>> 0);\n }\n return table;\n})();\n\n/**\n * Calculate CRC32 checksum of data.\n */\nexport function crc32(data: Uint8Array): number {\n let crc = 0xffffffff;\n for (const byte of data) {\n crc = (CRC32_TABLE[(crc ^ byte) & 0xff] ^ (crc >>> 8)) >>> 0;\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\n/**\n * Convert a 32-bit number to 4 bytes (big-endian).\n */\nfunction uint32ToBytes(value: number): Uint8Array {\n return new Uint8Array([\n (value >>> 24) & 0xff,\n (value >>> 16) & 0xff,\n (value >>> 8) & 0xff,\n value & 0xff,\n ]);\n}\n\n/**\n * Encode data as bytewords with the specified style.\n * Includes CRC32 checksum.\n */\nexport function encodeBytewords(\n data: Uint8Array,\n style: BytewordsStyle = BytewordsStyle.Minimal,\n): string {\n // Append CRC32 checksum\n const checksum = crc32(data);\n const checksumBytes = uint32ToBytes(checksum);\n const dataWithChecksum = new Uint8Array(data.length + 4);\n dataWithChecksum.set(data);\n dataWithChecksum.set(checksumBytes, data.length);\n\n const words: string[] = [];\n for (const byte of dataWithChecksum) {\n const word = BYTEWORDS[byte];\n if (word === undefined) throw new Error(`Invalid byte value: ${byte}`);\n\n switch (style) {\n case BytewordsStyle.Standard:\n words.push(word);\n break;\n case BytewordsStyle.Uri:\n words.push(word);\n break;\n case BytewordsStyle.Minimal:\n // First and last character\n words.push(word[0] + word[3]);\n break;\n }\n }\n\n switch (style) {\n case BytewordsStyle.Standard:\n return words.join(\" \");\n case BytewordsStyle.Uri:\n return words.join(\"-\");\n case BytewordsStyle.Minimal:\n return words.join(\"\");\n }\n}\n\n/**\n * Returns true if every code unit of `s` is in the ASCII range (0..=127).\n *\n * Mirrors Rust's `str::is_ascii` used at `ur::bytewords::decode` line 105.\n * We test the raw code units (rather than Array.from + codepoint) because\n * any non-BMP character has surrogate pairs both ≥ 0xD800, which already\n * exceed 0x7F.\n */\nfunction isAsciiString(s: string): boolean {\n for (let i = 0; i < s.length; i++) {\n if (s.charCodeAt(i) > 0x7f) return false;\n }\n return true;\n}\n\n/**\n * Decode bytewords string back to data.\n * Validates and removes CRC32 checksum.\n *\n * Errors mirror the upstream Rust `ur::bytewords::Error` enum\n * (`ur-0.4.1/src/bytewords.rs`):\n * - `NonAscii` — input contains non-ASCII characters (checked first).\n * - `InvalidLength` — minimal-style input has odd length.\n * - `InvalidWord` — a token does not map to a byteword index.\n * - `InvalidChecksum` — the trailing 4-byte CRC32 does not match.\n *\n * All variants are surfaced as {@link BytewordsError} with the same default\n * `Display` strings as Rust (e.g. \"invalid checksum\", \"non-ASCII\"), so\n * callers can branch on the error class rather than the bare `Error`\n * thrown by earlier revisions of this port.\n */\nexport function decodeBytewords(\n encoded: string,\n style: BytewordsStyle = BytewordsStyle.Minimal,\n): Uint8Array {\n // Rust rejects non-ASCII input up-front (`bytewords.rs:105-107`).\n if (!isAsciiString(encoded)) {\n throw new BytewordsError(\"bytewords string contains non-ASCII characters\");\n }\n const lowercased = encoded.toLowerCase();\n let bytes: number[];\n\n switch (style) {\n case BytewordsStyle.Standard: {\n const words = lowercased.split(\" \");\n bytes = words.map((word) => {\n const index = BYTEWORDS_MAP.get(word);\n if (index === undefined) {\n throw new BytewordsError(\"invalid word\");\n }\n return index;\n });\n break;\n }\n case BytewordsStyle.Uri: {\n // 4-character words separated by hyphens\n const words = lowercased.split(\"-\");\n bytes = words.map((word) => {\n const index = BYTEWORDS_MAP.get(word);\n if (index === undefined) {\n throw new BytewordsError(\"invalid word\");\n }\n return index;\n });\n break;\n }\n case BytewordsStyle.Minimal: {\n // 2-character minimal words with no separator\n if (lowercased.length % 2 !== 0) {\n throw new BytewordsError(\"invalid length\");\n }\n bytes = [];\n for (let i = 0; i < lowercased.length; i += 2) {\n const minimal = lowercased.slice(i, i + 2);\n const index = MINIMAL_BYTEWORDS_MAP.get(minimal);\n if (index === undefined) {\n throw new BytewordsError(\"invalid word\");\n }\n bytes.push(index);\n }\n break;\n }\n }\n\n if (bytes.length < 4) {\n throw new BytewordsError(\"invalid checksum\");\n }\n\n // Extract data and checksum\n const dataWithChecksum = new Uint8Array(bytes);\n const data = dataWithChecksum.slice(0, -4);\n const checksumBytes = dataWithChecksum.slice(-4);\n\n // Verify checksum\n const expectedChecksum = crc32(data);\n const actualChecksum =\n ((checksumBytes[0] << 24) |\n (checksumBytes[1] << 16) |\n (checksumBytes[2] << 8) |\n checksumBytes[3]) >>>\n 0;\n\n if (expectedChecksum !== actualChecksum) {\n throw new BytewordsError(\"invalid checksum\");\n }\n\n return data;\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\nimport { InvalidTypeError } from \"./error\";\nimport { isValidURType } from \"./utils\";\n\n/**\n * Represents a UR (Uniform Resource) type identifier.\n *\n * Valid UR types contain only lowercase letters, digits, and hyphens.\n *\n * @example\n * ```typescript\n * const urType = new URType('test');\n * console.log(urType.string()); // \"test\"\n * ```\n */\nexport class URType {\n private readonly _type: string;\n\n /**\n * Creates a new URType from the provided type string.\n *\n * @param urType - The UR type as a string\n * @throws {InvalidTypeError} If the type contains invalid characters\n *\n * @example\n * ```typescript\n * const urType = new URType('test');\n * ```\n */\n constructor(urType: string) {\n if (!isValidURType(urType)) {\n throw new InvalidTypeError();\n }\n this._type = urType;\n }\n\n /**\n * Returns the string representation of the URType.\n *\n * @example\n * ```typescript\n * const urType = new URType('test');\n * console.log(urType.string()); // \"test\"\n * ```\n */\n string(): string {\n return this._type;\n }\n\n /**\n * Checks equality with another URType based on the type string.\n */\n equals(other: URType): boolean {\n return this._type === other._type;\n }\n\n /**\n * Returns the string representation.\n */\n toString(): string {\n return this._type;\n }\n\n /**\n * Creates a URType from a string, throwing an error if invalid.\n *\n * @param value - The UR type string\n * @returns A new URType instance\n * @throws {InvalidTypeError} If the type is invalid\n */\n static from(value: string): URType {\n return new URType(value);\n }\n\n /**\n * Safely creates a URType, returning a typed `Result`-shaped\n * discriminated union instead of throwing.\n *\n * Mirrors Rust `impl TryFrom<&str> for URType` /\n * `impl TryFrom<String> for URType` (`bc-ur-rust/src/ur_type.rs`),\n * which return `Result<URType, Error>`. The TS shape is the\n * idiomatic discriminated form so callers can branch on `ok`\n * without `instanceof`:\n *\n * @example\n * ```typescript\n * const r = URType.tryFrom(\"test\");\n * if (r.ok) {\n * console.log(r.value.string()); // \"test\"\n * } else {\n * console.error(r.error.message);\n * }\n * ```\n *\n * @param value - The UR type string\n * @returns A typed Result: `{ ok: true; value: URType }` on success,\n * `{ ok: false; error: InvalidTypeError }` on failure.\n */\n static tryFrom(\n value: string,\n ): { ok: true; value: URType } | { ok: false; error: InvalidTypeError } {\n try {\n return { ok: true, value: new URType(value) };\n } catch (error) {\n return { ok: false, error: error as InvalidTypeError };\n }\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\nimport type { Cbor } from \"@bcts/dcbor\";\nimport { decodeCbor } from \"@bcts/dcbor\";\nimport {\n BytewordsError,\n CBORError,\n InvalidSchemeError,\n NotSinglePartError,\n TypeUnspecifiedError,\n UnexpectedTypeError,\n URDecodeError,\n} from \"./error.js\";\nimport { URType } from \"./ur-type.js\";\nimport { encodeBytewords, decodeBytewords, BytewordsStyle } from \"./utils.js\";\n\n/**\n * A Uniform Resource (UR) is a URI-encoded CBOR object.\n *\n * URs are defined in [BCR-2020-005: Uniform Resources](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md).\n *\n * @example\n * ```typescript\n * import { UR } from '@bcts/uniform-resources';\n * import { CBOR } from '@bcts/dcbor';\n *\n * // Create a UR from a CBOR object\n * const cbor = CBOR.fromArray([1, 2, 3]);\n * const ur = UR.new('test', cbor);\n *\n * // Encode to string\n * const urString = ur.string();\n * console.log(urString); // \"ur:test/...\"\n *\n * // Decode from string\n * const decodedUR = UR.fromURString(urString);\n * console.log(decodedUR.urTypeStr()); // \"test\"\n * ```\n */\nexport class UR {\n private readonly _urType: URType;\n private readonly _cbor: Cbor;\n\n /**\n * Creates a new UR from the provided type and CBOR data.\n *\n * @param urType - The UR type (will be validated)\n * @param cbor - The CBOR data to encode\n * @throws {InvalidTypeError} If the type is invalid\n *\n * @example\n * ```typescript\n * const ur = UR.new('bytes', CBOR.fromString('hello'));\n * ```\n */\n static new(urType: string | URType, cbor: Cbor): UR {\n const type = typeof urType === \"string\" ? new URType(urType) : urType;\n return new UR(type, cbor);\n }\n\n /**\n * Creates a new UR from a UR string.\n *\n * Mirrors Rust's `UR::from_ur_string` (`bc-ur-rust/src/ur.rs:25-38`):\n * 1. lowercase the entire string.\n * 2. strip the `\"ur:\"` prefix → {@link InvalidSchemeError} if absent.\n * 3. split on the first `/` → {@link TypeUnspecifiedError} if absent.\n * 4. validate the type via {@link URType} → {@link InvalidTypeError}.\n * 5. delegate the data section to the upstream-style decoder, which\n * classifies the UR as single- or multi-part. Multi-part input is\n * rejected with {@link NotSinglePartError}.\n * 6. decode the bytewords payload (CRC32 + minimal mapping) →\n * {@link BytewordsError} on failure.\n * 7. parse the resulting bytes as CBOR → {@link CBORError} on failure.\n *\n * @param urString - A UR string like \"ur:test/...\"\n * @throws {InvalidSchemeError} If the string doesn't start with \"ur:\"\n * @throws {TypeUnspecifiedError} If no `/` separator is present\n * @throws {InvalidTypeError} If the type contains invalid characters\n * @throws {NotSinglePartError} If the UR is multi-part\n * @throws {URDecodeError} For upstream-decoder errors (invalid indices, etc.)\n * @throws {BytewordsError} If bytewords decoding fails\n * @throws {CBORError} If CBOR parsing fails\n *\n * @example\n * ```typescript\n * const ur = UR.fromURString('ur:test/lsadaoaxjygonesw');\n * ```\n */\n static fromURString(urString: string): UR {\n const { urType, cbor } = URStringDecoder.decode(urString);\n return new UR(urType, cbor);\n }\n\n private constructor(urType: URType, cbor: Cbor) {\n this._urType = urType;\n this._cbor = cbor;\n }\n\n /**\n * Returns the UR type.\n */\n urType(): URType {\n return this._urType;\n }\n\n /**\n * Returns the UR type as a string.\n */\n urTypeStr(): string {\n return this._urType.string();\n }\n\n /**\n * Returns the CBOR data.\n */\n cbor(): Cbor {\n return this._cbor;\n }\n\n /**\n * Returns the string representation of the UR (lowercase, suitable for display).\n *\n * @example\n * ```typescript\n * const ur = UR.new('test', CBOR.fromArray([1, 2, 3]));\n * console.log(ur.string()); // \"ur:test/lsadaoaxjygonesw\"\n * ```\n */\n string(): string {\n const cborData = this._cbor.toData();\n return URStringEncoder.encode(this._urType.string(), cborData);\n }\n\n /**\n * Returns the QR string representation (uppercase, most efficient for QR codes).\n */\n qrString(): string {\n return this.string().toUpperCase();\n }\n\n /**\n * Returns the QR data as bytes (uppercase UR string as UTF-8).\n *\n * Mirrors Rust's `UR::qr_data` (`ur.rs:52`) which does\n * `self.qr_string().as_bytes().to_vec()` — the string's UTF-8 byte\n * representation. We use `TextEncoder` rather than per-codepoint\n * truncation so the behaviour stays correct if the QR string ever\n * contains non-ASCII characters.\n */\n qrData(): Uint8Array {\n return new TextEncoder().encode(this.qrString());\n }\n\n /**\n * Checks if the UR type matches the expected type.\n *\n * @param expectedType - The expected type\n * @throws {UnexpectedTypeError} If the types don't match\n */\n checkType(expectedType: string | URType): void {\n const expected = typeof expectedType === \"string\" ? new URType(expectedType) : expectedType;\n if (!this._urType.equals(expected)) {\n throw new UnexpectedTypeError(expected.string(), this._urType.string());\n }\n }\n\n /**\n * Returns the string representation.\n */\n toString(): string {\n return this.string();\n }\n\n /**\n * Checks equality with another UR.\n *\n * Mirrors Rust's derived `PartialEq for UR` which compares the inner\n * `ur_type` and the inner `cbor` field directly. We compare CBOR\n * bytewise — `Uint8Array` equality, not `Array#toString` (which would\n * coerce to a comma-joined string and could collide on pathological\n * inputs).\n */\n equals(other: UR): boolean {\n if (!this._urType.equals(other._urType)) return false;\n const a = this._cbor.toData();\n const b = other._cbor.toData();\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n }\n}\n\n/**\n * Encodes a UR string using Bytewords minimal encoding.\n * This handles single-part URs according to BCR-2020-005.\n */\nclass URStringEncoder {\n static encode(urType: string, cborData: Uint8Array): string {\n // Encode CBOR data using bytewords minimal style (with CRC32 checksum)\n const encoded = encodeBytewords(cborData, BytewordsStyle.Minimal);\n return `ur:${urType}/${encoded}`;\n }\n}\n\n/**\n * Decodes a UR string back to its components.\n *\n * Mirrors the validation pipeline of Rust's `UR::from_ur_string`\n * (`bc-ur-rust/src/ur.rs:25-38`) plus the upstream `ur::decode`\n * (`ur-0.4.1/src/ur.rs:238-266`):\n *\n * 1. lowercase\n * 2. strip `\"ur:\"` → {@link InvalidSchemeError}\n * 3. find `/` → {@link TypeUnspecifiedError}\n * 4. validate the type → {@link InvalidTypeError}\n * 5. classify single- vs multi-part by looking at the data section\n * 6. multi-part → {@link NotSinglePartError}\n * 7. invalid multi-part indices → {@link URDecodeError(\"Invalid indices\")}\n * 8. minimal bytewords decode → {@link BytewordsError}\n * 9. CBOR parse → {@link CBORError}\n */\nclass URStringDecoder {\n static decode(urString: string): { urType: URType; cbor: Cbor } {\n const lowercased = urString.toLowerCase();\n\n // Step 2: strip the scheme.\n if (!lowercased.startsWith(\"ur:\")) {\n throw new InvalidSchemeError();\n }\n const afterScheme = lowercased.substring(3);\n\n // Step 3: locate the first `/`. Matches Rust's `split_once('/')`.\n const slashIdx = afterScheme.indexOf(\"/\");\n if (slashIdx === -1) {\n throw new TypeUnspecifiedError();\n }\n const typeStr = afterScheme.substring(0, slashIdx);\n const dataSection = afterScheme.substring(slashIdx + 1);\n\n // Step 4: validate the type *before* any bytewords/CBOR work, so that a\n // malformed payload with an invalid type surfaces InvalidTypeError\n // rather than a downstream BytewordsError. Mirrors `ur.rs:31`.\n const urType = new URType(typeStr);\n\n // Step 5/6/7: classify the data section, the way `ur::decode` does\n // (`ur-0.4.1/src/ur.rs:249-265`). If the data section contains a `/`,\n // the prefix is the multi-part `<seqNum>-<seqLen>` indices.\n const lastSlash = dataSection.lastIndexOf(\"/\");\n if (lastSlash !== -1) {\n const indices = dataSection.substring(0, lastSlash);\n const dashIdx = indices.indexOf(\"-\");\n if (dashIdx === -1) {\n throw new URDecodeError(\"Invalid indices\");\n }\n const seqNumStr = indices.substring(0, dashIdx);\n const seqLenStr = indices.substring(dashIdx + 1);\n // Rust uses `parse::<u16>()`; accept non-empty strings of digits only.\n // (parseInt on `\"1a\"` returns 1, so we have to be strict about chars.)\n if (!/^\\d+$/.test(seqNumStr) || !/^\\d+$/.test(seqLenStr)) {\n throw new URDecodeError(\"Invalid indices\");\n }\n const seqNum = Number(seqNumStr);\n const seqLen = Number(seqLenStr);\n if (seqNum > 0xffff || seqLen > 0xffff) {\n throw new URDecodeError(\"Invalid indices\");\n }\n // Successfully parsed as multi-part — but `from_ur_string` only\n // accepts single-part input. Mirrors `ur.rs:33-35`.\n throw new NotSinglePartError();\n }\n\n // Step 8: minimal bytewords decode (CRC32 + minimal mapping).\n let cborData: Uint8Array;\n try {\n cborData = decodeBytewords(dataSection, BytewordsStyle.Minimal);\n } catch (error) {\n if (error instanceof BytewordsError) {\n throw error;\n }\n const message = error instanceof Error ? error.message : String(error);\n throw new BytewordsError(message);\n }\n\n // Step 9: CBOR parse.\n let cbor: Cbor;\n try {\n cbor = decodeCbor(cborData);\n } catch (error) {\n if (error instanceof CBORError) {\n throw error;\n }\n const message = error instanceof Error ? error.message : String(error);\n throw new CBORError(message);\n }\n\n return { urType, cbor };\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\nimport type { CborTaggedEncodable } from \"@bcts/dcbor\";\n\nimport { UR } from \"./ur.js\";\n\n/**\n * A type that can be encoded to a UR (Uniform Resource).\n *\n * Types implementing this interface should be able to convert themselves\n * to CBOR data and associate that with a UR type identifier.\n *\n * Mirrors Rust's `UREncodable` trait (`bc-ur-rust/src/ur_encodable.rs`),\n * which has a blanket impl `impl<T> UREncodable for T where T:\n * CBORTaggedEncodable`. TypeScript has no equivalent of blanket impls, so\n * implementers either write `ur()` / `urString()` directly *or* — for a\n * type that already implements `CborTaggedEncodable` — call the helper\n * functions {@link urFromEncodable} / {@link urStringFromEncodable} below\n * to get the same auto-derivation that Rust provides for free.\n *\n * @example\n * ```typescript\n * class MyType implements UREncodable, CborTaggedEncodable {\n * cborTags(): Tag[] {\n * return [createTag(40000, \"mytype\")];\n * }\n *\n * untaggedCbor(): Cbor { ... }\n * taggedCbor(): Cbor { return createTaggedCbor(this); }\n *\n * // Auto-derived from the first cbor tag's name, just like Rust.\n * ur(): UR { return urFromEncodable(this); }\n * urString(): string { return urStringFromEncodable(this); }\n * }\n * ```\n */\nexport interface UREncodable {\n /**\n * Returns the UR representation of the object.\n */\n ur(): UR;\n\n /**\n * Returns the UR string representation of the object.\n */\n urString(): string;\n}\n\n/**\n * Concrete equivalent of Rust's default `UREncodable::ur` impl\n * (`bc-ur-rust/src/ur_encodable.rs:8-18`):\n *\n * - Reads the first tag returned by `encodable.cborTags()`.\n * - Uses that tag's `name` as the UR type, throwing if no name is set —\n * matching Rust's `panic!(\"CBOR tag {} must have a name. Did you call\n * `register_tags()`?\", tag.value())`.\n * - Wraps the encodable's `untaggedCbor()` in a fresh {@link UR} bound to\n * that type.\n *\n * Use from a class implementing both `UREncodable` and\n * `CborTaggedEncodable` to skip writing the boilerplate yourself.\n */\nexport function urFromEncodable(encodable: CborTaggedEncodable): UR {\n const tags = encodable.cborTags();\n const tag = tags[0];\n if (tag === undefined) {\n throw new Error(\"UREncodable: cborTags() returned no tags\");\n }\n if (tag.name === undefined) {\n throw new Error(`CBOR tag ${tag.value} must have a name. Did you call register_tags()?`);\n }\n return UR.new(tag.name, encodable.untaggedCbor());\n}\n\n/**\n * Concrete equivalent of Rust's default `UREncodable::ur_string` impl\n * (`bc-ur-rust/src/ur_encodable.rs:21`): `self.ur().string()`.\n */\nexport function urStringFromEncodable(encodable: CborTaggedEncodable): string {\n return urFromEncodable(encodable).string();\n}\n\n/**\n * Helper function to check if an object implements UREncodable.\n */\nexport function isUREncodable(obj: unknown): obj is UREncodable {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"ur\" in obj &&\n \"urString\" in obj &&\n typeof (obj as Record<string, unknown>)[\"ur\"] === \"function\" &&\n typeof (obj as Record<string, unknown>)[\"urString\"] === \"function\"\n );\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\nimport type { CborTaggedDecodable } from \"@bcts/dcbor\";\n\nimport { UR } from \"./ur.js\";\n\n/**\n * A type that can be decoded from a UR (Uniform Resource).\n *\n * Types implementing this interface should be able to create themselves\n * from a UR containing their data.\n *\n * Mirrors Rust's `URDecodable` trait (`bc-ur-rust/src/ur_decodable.rs`),\n * which has a blanket impl `impl<T> URDecodable for T where T:\n * CBORTaggedDecodable`. TypeScript has no equivalent of blanket impls, so\n * implementers either write `fromUR()` directly *or* — for a type that\n * already implements `CborTaggedDecodable` — call the helper functions\n * {@link decodableFromUR} / {@link decodableFromURString} below to get the\n * same auto-derivation that Rust provides for free.\n *\n * @example\n * ```typescript\n * class MyType implements URDecodable, CborTaggedDecodable<MyType> {\n * cborTags(): Tag[] {\n * return [createTag(40000, \"mytype\")];\n * }\n * fromUntaggedCbor(cbor: Cbor): MyType { ... }\n * fromTaggedCbor(cbor: Cbor): MyType { ... }\n *\n * // Auto-derived from the first cbor tag's name, matching Rust.\n * fromUR(ur: UR): MyType { return decodableFromUR(this, ur); }\n * fromURString(s: string): MyType { return decodableFromURString(this, s); }\n * }\n * ```\n */\nexport interface URDecodable {\n /**\n * Creates an instance of this type from a UR.\n *\n * @param ur - The UR to decode from\n * @returns An instance of this type\n * @throws If the UR type is wrong or data is malformed\n */\n fromUR(ur: UR): unknown;\n\n /**\n * Creates an instance of this type from a UR string.\n *\n * This is a convenience method that parses the UR string and then\n * calls fromUR().\n *\n * @param urString - The UR string to decode from (e.g., \"ur:type/...\")\n * @returns An instance of this type\n * @throws If the UR string is invalid or data is malformed\n */\n fromURString?(urString: string): unknown;\n}\n\n/**\n * Concrete equivalent of Rust's default `URDecodable::from_ur` impl\n * (`bc-ur-rust/src/ur_decodable.rs:7-15`):\n *\n * 1. Read the first tag returned by `decodable.cborTags()`.\n * 2. Verify the UR's type matches that tag's name via `UR#checkType`\n * (this is what Rust's `ur.check_type(...)` does — surface\n * `UnexpectedTypeError` on mismatch).\n * 3. Delegate to `decodable.fromUntaggedCbor(ur.cbor())`.\n *\n * Use from a class implementing both `URDecodable` and\n * `CborTaggedDecodable<T>` to skip the type-check / delegate boilerplate.\n */\nexport function decodableFromUR<T>(decodable: CborTaggedDecodable<T>, ur: UR): T {\n const tags = decodable.cborTags();\n const tag = tags[0];\n if (tag === undefined) {\n throw new Error(\"URDecodable: cborTags() returned no tags\");\n }\n if (tag.name === undefined) {\n throw new Error(`CBOR tag ${tag.value} must have a name. Did you call register_tags()?`);\n }\n ur.checkType(tag.name);\n return decodable.fromUntaggedCbor(ur.cbor());\n}\n\n/**\n * Concrete equivalent of Rust's default `URDecodable::from_ur_string` impl\n * (`bc-ur-rust/src/ur_decodable.rs:17-22`):\n * `Self::from_ur(UR::from_ur_string(s)?)`.\n */\nexport function decodableFromURString<T>(decodable: CborTaggedDecodable<T>, urString: string): T {\n return decodableFromUR(decodable, UR.fromURString(urString));\n}\n\n/**\n * Helper function to check if an object implements URDecodable.\n */\nexport function isURDecodable(obj: unknown): obj is URDecodable {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"fromUR\" in obj &&\n typeof (obj as Record<string, unknown>)[\"fromUR\"] === \"function\"\n );\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\nimport type { UREncodable } from \"./ur-encodable.js\";\nimport type { URDecodable } from \"./ur-decodable.js\";\n\n/**\n * A type that can be both encoded to and decoded from a UR.\n *\n * This combines the UREncodable and URDecodable interfaces for types\n * that support bidirectional UR conversion.\n *\n * @example\n * ```typescript\n * class MyType implements URCodable {\n * ur(): UR {\n * // Encode to UR\n * }\n *\n * urString(): string {\n * // Return UR string\n * }\n *\n * fromUR(ur: UR): MyType {\n * // Decode from UR\n * }\n *\n * fromURString(urString: string): MyType {\n * // Decode from UR string (convenience method)\n * return this.fromUR(UR.fromURString(urString));\n * }\n * }\n * ```\n */\nexport interface URCodable extends UREncodable, URDecodable {}\n\n/**\n * Helper function to check if an object implements URCodable.\n */\nexport function isURCodable(obj: unknown): obj is URCodable {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"ur\" in obj &&\n \"urString\" in obj &&\n \"fromUR\" in obj &&\n typeof (obj as Record<string, unknown>)[\"ur\"] === \"function\" &&\n typeof (obj as Record<string, unknown>)[\"urString\"] === \"function\" &&\n typeof (obj as Record<string, unknown>)[\"fromUR\"] === \"function\"\n );\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Xoshiro256** PRNG implementation.\n *\n * This is a high-quality, fast pseudo-random number generator used\n * for deterministic fragment selection in fountain codes.\n *\n * Reference: https://prng.di.unimi.it/\n * BC-UR Reference: https://github.com/nicklockwood/fountain-codes\n */\n\nimport { sha256 } from \"@bcts/crypto\";\n\nconst MAX_UINT64 = BigInt(\"0xffffffffffffffff\");\n\n/**\n * Performs a left rotation on a 64-bit BigInt.\n */\nfunction rotl(x: bigint, k: number): bigint {\n const kBigInt = BigInt(k);\n return ((x << kBigInt) | (x >> (64n - kBigInt))) & MAX_UINT64;\n}\n\n/**\n * Xoshiro256** pseudo-random number generator.\n *\n * This PRNG is used for deterministic mixing in fountain codes,\n * allowing both encoder and decoder to agree on which fragments\n * are combined without transmitting that information.\n */\nexport class Xoshiro256 {\n private s: [bigint, bigint, bigint, bigint];\n\n /**\n * Creates a new Xoshiro256** instance from a 32-byte seed.\n *\n * The seed must be exactly 32 bytes (256 bits). The bytes are interpreted\n * using the BC-UR reference algorithm: each 8-byte chunk is read as\n * big-endian then stored as little-endian for the state.\n *\n * @param seed - The seed bytes (must be exactly 32 bytes)\n */\n constructor(seed: Uint8Array) {\n if (seed.length !== 32) {\n throw new Error(`Seed must be 32 bytes, got ${seed.length}`);\n }\n\n // BC-UR reference implementation:\n // For each 8-byte chunk, read as big-endian u64, then convert to little-endian bytes\n // This effectively swaps the byte order within each 8-byte segment\n const s: [bigint, bigint, bigint, bigint] = [0n, 0n, 0n, 0n];\n for (let i = 0; i < 4; i++) {\n // Read 8 bytes as big-endian u64\n let v = 0n;\n for (let n = 0; n < 8; n++) {\n v = (v << 8n) | BigInt(seed[8 * i + n] ?? 0);\n }\n s[i] = v;\n }\n\n this.s = s;\n }\n\n /**\n * Creates a Xoshiro256** instance from raw state values.\n * Useful for seeding with specific values.\n */\n static fromState(s0: bigint, s1: bigint, s2: bigint, s3: bigint): Xoshiro256 {\n const instance = Object.create(Xoshiro256.prototype) as Xoshiro256;\n instance.s = [s0, s1, s2, s3];\n return instance;\n }\n\n /**\n * Generates the next 64-bit random value.\n */\n next(): bigint {\n const result = (rotl((this.s[1] * 5n) & MAX_UINT64, 7) * 9n) & MAX_UINT64;\n\n const t = (this.s[1] << 17n) & MAX_UINT64;\n\n this.s[2] ^= this.s[0];\n this.s[3] ^= this.s[1];\n this.s[1] ^= this.s[2];\n this.s[0] ^= this.s[3];\n\n this.s[2] ^= t;\n this.s[3] = rotl(this.s[3], 45);\n\n return result;\n }\n\n /**\n * Generates a random double in [0, 1).\n * Matches BC-UR reference: self.next() as f64 / (u64::MAX as f64 + 1.0)\n */\n nextDouble(): number {\n const value = this.next();\n // u64::MAX as f64 + 1.0 = 18446744073709551616.0\n return Number(value) / 18446744073709551616.0;\n }\n\n /**\n * Generates a random integer in [low, high] (inclusive).\n * Matches BC-UR reference: (self.next_double() * ((high - low + 1) as f64)) as u64 + low\n */\n nextInt(low: number, high: number): number {\n const range = high - low + 1;\n return Math.floor(this.nextDouble() * range) + low;\n }\n\n /**\n * Generates a random byte [0, 255].\n *\n * Mirrors Rust `Xoshiro256::next_byte` (`ur-0.4.1/src/xoshiro.rs:91`):\n * `self.next_int(0, 255) as u8`\n * This goes through `next_double() * 256.0`, which effectively uses\n * the top 8 bits of the f64-converted u64 — NOT the low 8 bits\n * of the raw `next()` output. Earlier the TS port used `next() & 0xff`,\n * which produced a completely different byte sequence than Rust for\n * the same seeded RNG.\n */\n nextByte(): number {\n return this.nextInt(0, 255);\n }\n\n /**\n * Generates an array of random bytes.\n *\n * Mirrors Rust `Xoshiro256::next_bytes` (`ur-0.4.1/src/xoshiro.rs:95-97`):\n * `(0..n).map(|_| self.next_byte()).collect()`\n */\n nextData(count: number): Uint8Array {\n const result = new Uint8Array(count);\n for (let i = 0; i < count; i++) {\n result[i] = this.nextByte();\n }\n return result;\n }\n\n /**\n * Shuffles items by repeatedly picking random indices.\n * Matches BC-UR reference implementation.\n */\n shuffled<T>(items: T[]): T[] {\n const source = [...items];\n const shuffled: T[] = [];\n while (source.length > 0) {\n const index = this.nextInt(0, source.length - 1);\n const item = source.splice(index, 1)[0];\n if (item !== undefined) {\n shuffled.push(item);\n }\n }\n return shuffled;\n }\n\n /**\n * Chooses the degree (number of fragments to mix) using a weighted sampler.\n * Uses the robust soliton distribution with weights [1/1, 1/2, 1/3, ..., 1/n].\n * Matches BC-UR reference implementation.\n */\n chooseDegree(seqLen: number): number {\n // Create weights: [1/1, 1/2, 1/3, ..., 1/seqLen]\n const weights: number[] = [];\n for (let i = 1; i <= seqLen; i++) {\n weights.push(1.0 / i);\n }\n\n // Use Vose's alias method for weighted sampling\n const sampler = new WeightedSampler(weights);\n return sampler.next(this) + 1; // 1-indexed degree\n }\n}\n\n/**\n * Weighted sampler using Vose's alias method.\n * Allows O(1) sampling from a discrete probability distribution.\n */\nclass WeightedSampler {\n private readonly aliases: number[];\n private readonly probs: number[];\n\n constructor(weights: number[]) {\n const n = weights.length;\n\n // Mirrors Rust `Weighted::new` (`ur-0.4.1/src/sampler.rs:13-19`):\n // assert!(!weights.iter().any(|&p| p < 0.0), \"negative probability encountered\");\n // let summed = weights.iter().sum::<f64>();\n // assert!(summed > 0.0, \"probabilities don't sum to a positive value\");\n if (weights.some((w) => w < 0.0)) {\n throw new Error(\"negative probability encountered\");\n }\n const sum = weights.reduce((a, b) => a + b, 0);\n if (!(sum > 0.0)) {\n throw new Error(\"probabilities don't sum to a positive value\");\n }\n\n const normalized = weights.map((w) => (w * n) / sum);\n\n // Initialize alias table\n this.aliases = Array.from<number>({ length: n }).fill(0);\n this.probs = Array.from<number>({ length: n }).fill(0);\n\n // Partition into small and large\n const small: number[] = [];\n const large: number[] = [];\n\n for (let i = n - 1; i >= 0; i--) {\n if (normalized[i] < 1.0) {\n small.push(i);\n } else {\n large.push(i);\n }\n }\n\n // Build the alias table\n while (small.length > 0 && large.length > 0) {\n const a = small.pop();\n const g = large.pop();\n if (a === undefined || g === undefined) break;\n this.probs[a] = normalized[a] ?? 0;\n this.aliases[a] = g;\n const normalizedG = normalized[g] ?? 0;\n const normalizedA = normalized[a] ?? 0;\n normalized[g] = normalizedG + normalizedA - 1.0;\n if (normalized[g] !== undefined && normalized[g] < 1.0) {\n small.push(g);\n } else {\n large.push(g);\n }\n }\n\n while (large.length > 0) {\n const g = large.pop();\n if (g === undefined) break;\n this.probs[g] = 1.0;\n }\n\n while (small.length > 0) {\n const a = small.pop();\n if (a === undefined) break;\n this.probs[a] = 1.0;\n }\n }\n\n /**\n * Sample from the distribution.\n */\n next(rng: Xoshiro256): number {\n const r1 = rng.nextDouble();\n const r2 = rng.nextDouble();\n const n = this.probs.length;\n const i = Math.floor(n * r1);\n if (r2 < this.probs[i]) {\n return i;\n } else {\n return this.aliases[i];\n }\n }\n}\n\n/**\n * Creates a Xoshiro256 PRNG instance from message checksum and sequence number.\n *\n * This creates an 8-byte seed by concatenating seqNum and checksum (both in\n * big-endian), then hashes it with SHA-256 to get the 32-byte seed for Xoshiro.\n *\n * This matches the BC-UR reference implementation.\n */\nexport function createSeed(checksum: number, seqNum: number): Uint8Array {\n // Create 8-byte seed: seqNum (big-endian) || checksum (big-endian)\n const seed8 = new Uint8Array(8);\n\n // seqNum in big-endian (bytes 0-3)\n seed8[0] = (seqNum >>> 24) & 0xff;\n seed8[1] = (seqNum >>> 16) & 0xff;\n seed8[2] = (seqNum >>> 8) & 0xff;\n seed8[3] = seqNum & 0xff;\n\n // checksum in big-endian (bytes 4-7)\n seed8[4] = (checksum >>> 24) & 0xff;\n seed8[5] = (checksum >>> 16) & 0xff;\n seed8[6] = (checksum >>> 8) & 0xff;\n seed8[7] = checksum & 0xff;\n\n // Hash with SHA-256 to get 32 bytes\n return sha256(seed8);\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Fountain code implementation for multipart URs.\n *\n * This implements a hybrid fixed-rate and rateless fountain code system\n * as specified in BCR-2020-005 and BCR-2024-001.\n *\n * Key concepts:\n * - Parts 1-seqLen are \"pure\" fragments (fixed-rate)\n * - Parts > seqLen are \"mixed\" fragments using XOR (rateless)\n * - Xoshiro256** PRNG ensures encoder/decoder agree on mixing\n */\n\nimport { Xoshiro256, createSeed } from \"./xoshiro.js\";\nimport { crc32 } from \"./utils.js\";\n\n/**\n * Represents a fountain code part with metadata.\n */\nexport interface FountainPart {\n /** Sequence number (1-based) */\n seqNum: number;\n /** Total number of pure fragments */\n seqLen: number;\n /** Length of original message */\n messageLen: number;\n /** CRC32 checksum of original message */\n checksum: number;\n /** Fragment data */\n data: Uint8Array;\n}\n\n/**\n * Calculates the quotient of `a` and `b`, rounded toward positive infinity.\n *\n * Mirrors Rust `ur-0.4.1/src/fountain.rs::div_ceil`.\n */\nfunction divCeil(a: number, b: number): number {\n const d = Math.floor(a / b);\n const r = a % b;\n return r > 0 ? d + 1 : d;\n}\n\n/**\n * Computes the optimal fragment length for a given message length and\n * maximum fragment length.\n *\n * The algorithm:\n * fragment_count = ceil(data_length / max_fragment_length)\n * fragment_length = ceil(data_length / fragment_count)\n *\n * This produces fragments that are as balanced as possible while still\n * respecting `maxFragmentLen` as an upper bound on each fragment. For\n * example, a 10-byte message with `maxFragmentLen = 6` yields a fragment\n * length of 5 (so two even 5-byte fragments) rather than 6 (one full\n * fragment plus a 4-byte tail).\n *\n * Mirrors Rust `ur-0.4.1/src/fountain.rs::fragment_length` byte-for-byte.\n */\nexport function fragmentLength(dataLength: number, maxFragmentLength: number): number {\n const fragmentCount = divCeil(dataLength, maxFragmentLength);\n return divCeil(dataLength, fragmentCount);\n}\n\n/**\n * Splits `data` into a list of `fragmentLen`-sized chunks, zero-padding\n * the last chunk if necessary so that every chunk is exactly\n * `fragmentLen` bytes long.\n *\n * Note: `fragmentLen` is the **already-computed** fragment length (see\n * {@link fragmentLength}), not the user-facing maximum fragment length.\n *\n * Mirrors Rust `ur-0.4.1/src/fountain.rs::partition` byte-for-byte.\n */\nexport function partition(data: Uint8Array, fragmentLen: number): Uint8Array[] {\n if (fragmentLen < 1) {\n throw new Error(\"fragment length must be at least 1\");\n }\n const remainder = data.length % fragmentLen;\n const padding = remainder === 0 ? 0 : fragmentLen - remainder;\n const padded = new Uint8Array(data.length + padding);\n padded.set(data);\n // Trailing bytes are already zero by Uint8Array's default initialization.\n\n const fragments: Uint8Array[] = [];\n for (let start = 0; start < padded.length; start += fragmentLen) {\n fragments.push(padded.slice(start, start + fragmentLen));\n }\n return fragments;\n}\n\n/**\n * Convenience: compute the optimal fragment length for `message` given\n * `maxFragmentLen` and partition the message into that many fragments.\n *\n * Equivalent to:\n * ```ts\n * partition(message, fragmentLength(message.length, maxFragmentLen))\n * ```\n *\n * This is what {@link FountainEncoder} does internally when constructing\n * its fragment table.\n */\nexport function splitMessage(message: Uint8Array, maxFragmentLen: number): Uint8Array[] {\n if (maxFragmentLen < 1) {\n throw new Error(\"max fragment length must be at least 1\");\n }\n if (message.length === 0) {\n return [];\n }\n return partition(message, fragmentLength(message.length, maxFragmentLen));\n}\n\n/**\n * XOR two Uint8Arrays together.\n */\nexport function xorBytes(a: Uint8Array, b: Uint8Array): Uint8Array {\n const len = Math.max(a.length, b.length);\n const result = new Uint8Array(len);\n\n for (let i = 0; i < len; i++) {\n result[i] = (a[i] ?? 0) ^ (b[i] ?? 0);\n }\n\n return result;\n}\n\n/**\n * Chooses which fragments to mix for a given sequence number.\n *\n * This uses a seeded Xoshiro256** PRNG to deterministically select fragments,\n * ensuring encoder and decoder agree without explicit coordination.\n *\n * The algorithm matches the BC-UR reference implementation:\n * 1. For pure parts (seqNum <= seqLen), return single fragment index\n * 2. For mixed parts, use weighted sampling to choose degree\n * 3. Shuffle all indices and take the first 'degree' indices\n *\n * @param seqNum - The sequence number (1-based)\n * @param seqLen - Total number of pure fragments\n * @param checksum - CRC32 checksum of the message\n * @returns Array of fragment indices (0-based)\n */\nexport function chooseFragments(seqNum: number, seqLen: number, checksum: number): number[] {\n // Pure parts (seqNum <= seqLen) contain exactly one fragment\n if (seqNum <= seqLen) {\n return [seqNum - 1];\n }\n\n // Mixed parts use PRNG to select fragments\n const seed = createSeed(checksum, seqNum);\n const rng = new Xoshiro256(seed);\n\n // Choose degree using weighted sampler (1/k distribution)\n const degree = rng.chooseDegree(seqLen);\n\n // Create array of all indices [0, 1, 2, ..., seqLen-1]\n const allIndices: number[] = [];\n for (let i = 0; i < seqLen; i++) {\n allIndices.push(i);\n }\n\n // Shuffle all indices and take the first 'degree' indices\n const shuffled = rng.shuffled(allIndices);\n return shuffled.slice(0, degree);\n}\n\n/**\n * Mixes the selected fragments using XOR.\n */\nexport function mixFragments(fragments: Uint8Array[], indices: number[]): Uint8Array {\n if (indices.length === 0) {\n throw new Error(\"No fragments to mix\");\n }\n\n let result: Uint8Array = new Uint8Array(fragments[0].length);\n\n for (const index of indices) {\n const fragment = fragments[index];\n if (fragment === undefined) {\n throw new Error(`Fragment at index ${index} not found`);\n }\n result = xorBytes(result, fragment);\n }\n\n return result;\n}\n\n/**\n * Fountain encoder for creating multipart URs.\n */\nexport class FountainEncoder {\n private readonly fragments: Uint8Array[];\n private readonly messageLen: number;\n private readonly checksum: number;\n private seqNum = 0;\n\n /**\n * Creates a fountain encoder for the given message.\n *\n * @param message - The message to encode\n * @param maxFragmentLen - Maximum length of each fragment\n *\n * @throws if `message` is empty (mirrors Rust `Error::EmptyMessage`).\n * @throws if `maxFragmentLen < 1` (mirrors Rust `Error::InvalidFragmentLen`).\n */\n constructor(message: Uint8Array, maxFragmentLen: number) {\n if (message.length === 0) {\n throw new Error(\"expected non-empty message\");\n }\n if (maxFragmentLen < 1) {\n throw new Error(\"expected positive maximum fragment length\");\n }\n\n this.messageLen = message.length;\n this.checksum = crc32(message);\n // Mirrors Rust `Encoder::new`:\n // let fragment_length = fragment_length(message.len(), max_fragment_length);\n // let fragments = partition(message.to_vec(), fragment_length);\n const optimalLen = fragmentLength(message.length, maxFragmentLen);\n this.fragments = partition(message, optimalLen);\n }\n\n /**\n * Returns the number of pure fragments.\n */\n get seqLen(): number {\n return this.fragments.length;\n }\n\n /**\n * Returns whether the message fits in a single part.\n */\n isSinglePart(): boolean {\n return this.fragments.length === 1;\n }\n\n /**\n * Returns whether all pure parts have been emitted.\n */\n isComplete(): boolean {\n return this.seqNum >= this.seqLen;\n }\n\n /**\n * Generates the next fountain part.\n */\n nextPart(): FountainPart {\n this.seqNum++;\n\n const indices = chooseFragments(this.seqNum, this.seqLen, this.checksum);\n const data = mixFragments(this.fragments, indices);\n\n return {\n seqNum: this.seqNum,\n seqLen: this.seqLen,\n messageLen: this.messageLen,\n checksum: this.checksum,\n data,\n };\n }\n\n /**\n * Returns the current sequence number.\n */\n currentSeqNum(): number {\n return this.seqNum;\n }\n\n /**\n * Resets the encoder to start from the beginning.\n */\n reset(): void {\n this.seqNum = 0;\n }\n}\n\n/**\n * Fountain decoder for reassembling multipart URs.\n */\nexport class FountainDecoder {\n private seqLen: number | null = null;\n private messageLen: number | null = null;\n private checksum: number | null = null;\n private fragmentLen: number | null = null;\n\n // Storage for received data\n private readonly pureFragments = new Map<number, Uint8Array>();\n private readonly mixedParts = new Map<number, { indices: number[]; data: Uint8Array }>();\n // Set of already-received `indices` keys (joined by `,`) — Rust uses\n // `BTreeSet<Vec<usize>>` so two parts producing the same index set are\n // deduped even when they have different sequence numbers. Mirrors\n // `ur-0.4.1/src/fountain.rs::Decoder.received`.\n private readonly receivedIndexSets = new Set<string>();\n\n /**\n * Receives a fountain part and attempts to decode.\n *\n * @param part - The fountain part to receive\n * @returns `true` if this part contributed new information,\n * `false` if it was an exact duplicate of a part already seen\n * (or if the decoder was already complete).\n *\n * @throws if the part is empty or inconsistent with previously received\n * parts. Mirrors Rust `Error::EmptyPart` and `Error::InconsistentPart`.\n */\n receive(part: FountainPart): boolean {\n // Mirrors Rust `Decoder::receive`:\n // if self.complete() { return Ok(false); }\n if (this.isComplete()) {\n return false;\n }\n\n // Mirrors Rust's eager EmptyPart check.\n if (part.seqLen === 0 || part.data.length === 0 || part.messageLen === 0) {\n throw new Error(\"expected non-empty part\");\n }\n\n // Initialize on first part\n if (this.seqLen === null) {\n this.seqLen = part.seqLen;\n this.messageLen = part.messageLen;\n this.checksum = part.checksum;\n this.fragmentLen = part.data.length;\n } else if (\n // Mirrors Rust `Decoder::validate` exactly: every metadata field\n // (sequence_count, message_length, checksum, fragment_length) must\n // match across all received parts.\n part.seqLen !== this.seqLen ||\n part.messageLen !== this.messageLen ||\n part.checksum !== this.checksum ||\n part.data.length !== this.fragmentLen\n ) {\n throw new Error(\"part is inconsistent with previous ones\");\n }\n\n // Determine which fragments this part contains.\n const indices = chooseFragments(part.seqNum, this.seqLen, this.checksum ?? 0);\n // Rust sorts the indices implicitly via `BTreeSet` membership; we\n // explicitly sort the key so that two parts whose `chooseFragments`\n // output is the same multiset (regardless of order) collapse to the\n // same dedup key. In practice `chooseFragments` already produces a\n // deterministic shuffle, so this is just defensive.\n const indexSetKey = [...indices].sort((a, b) => a - b).join(\",\");\n if (this.receivedIndexSets.has(indexSetKey)) {\n return false;\n }\n this.receivedIndexSets.add(indexSetKey);\n\n if (indices.length === 1) {\n // Pure fragment (or degree-1 mixed that acts like pure).\n const index = indices[0];\n if (!this.pureFragments.has(index)) {\n this.pureFragments.set(index, part.data);\n }\n } else {\n // Mixed fragment - store for later reduction.\n this.mixedParts.set(part.seqNum, { indices, data: part.data });\n }\n\n // Try to reduce mixed parts.\n this.reduceMixedParts();\n\n return true;\n }\n\n /**\n * Attempts to extract pure fragments from mixed parts.\n */\n private reduceMixedParts(): void {\n let progress = true;\n\n while (progress) {\n progress = false;\n\n for (const [seqNum, mixed] of this.mixedParts) {\n // Find which indices we're missing\n const missing: number[] = [];\n let reduced = mixed.data;\n\n for (const index of mixed.indices) {\n const pure = this.pureFragments.get(index);\n if (pure !== undefined) {\n // XOR out the known fragment\n reduced = xorBytes(reduced, pure);\n } else {\n missing.push(index);\n }\n }\n\n if (missing.length === 0) {\n // All fragments known, remove this mixed part\n this.mixedParts.delete(seqNum);\n progress = true;\n } else if (missing.length === 1) {\n // Can extract the missing fragment\n const missingIndex = missing[0];\n this.pureFragments.set(missingIndex, reduced);\n this.mixedParts.delete(seqNum);\n progress = true;\n }\n }\n }\n }\n\n /**\n * Returns whether all fragments have been received.\n */\n isComplete(): boolean {\n if (this.seqLen === null) {\n return false;\n }\n\n return this.pureFragments.size === this.seqLen;\n }\n\n /**\n * Reconstructs the original message.\n *\n * @returns The original message, or null if not yet complete\n */\n message(): Uint8Array | null {\n if (!this.isComplete() || this.seqLen === null || this.messageLen === null) {\n return null;\n }\n\n // Calculate fragment size from first fragment\n const firstFragment = this.pureFragments.get(0);\n if (firstFragment === undefined) {\n return null;\n }\n\n const fragmentLen = firstFragment.length;\n const result = new Uint8Array(this.messageLen);\n\n // Assemble fragments\n for (let i = 0; i < this.seqLen; i++) {\n const fragment = this.pureFragments.get(i);\n if (fragment === undefined) {\n return null;\n }\n\n const start = i * fragmentLen;\n const end = Math.min(start + fragmentLen, this.messageLen);\n const len = end - start;\n\n result.set(fragment.slice(0, len), start);\n }\n\n // Verify checksum\n const actualChecksum = crc32(result);\n if (actualChecksum !== this.checksum) {\n throw new Error(`Checksum mismatch: expected ${this.checksum}, got ${actualChecksum}`);\n }\n\n return result;\n }\n\n /**\n * Returns the progress as a fraction (0 to 1).\n */\n progress(): number {\n if (this.seqLen === null) {\n return 0;\n }\n return this.pureFragments.size / this.seqLen;\n }\n\n /**\n * Resets the decoder.\n */\n reset(): void {\n this.seqLen = null;\n this.messageLen = null;\n this.checksum = null;\n this.fragmentLen = null;\n this.pureFragments.clear();\n this.mixedParts.clear();\n this.receivedIndexSets.clear();\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\nimport type { UR } from \"./ur.js\";\nimport { URError } from \"./error.js\";\nimport { FountainEncoder, type FountainPart } from \"./fountain.js\";\nimport { encodeBytewords, BytewordsStyle } from \"./utils.js\";\nimport { cbor } from \"@bcts/dcbor\";\n\n/**\n * Encodes a UR as multiple parts using fountain codes.\n *\n * This allows large CBOR structures to be split into multiple UR strings\n * that can be transmitted separately and reassembled. The encoder uses\n * fountain codes for resilient transmission over lossy channels.\n *\n * For single-part URs (small payloads), use the regular UR.string() method.\n *\n * @example\n * ```typescript\n * const ur = UR.new('bytes', cbor);\n * const encoder = new MultipartEncoder(ur, 100);\n *\n * // Generate all pure parts\n * while (!encoder.isComplete()) {\n * const part = encoder.nextPart();\n * console.log(part); // \"ur:bytes/1-10/...\"\n * }\n *\n * // Generate additional rateless parts for redundancy\n * for (let i = 0; i < 5; i++) {\n * const part = encoder.nextPart();\n * console.log(part); // \"ur:bytes/11-10/...\"\n * }\n * ```\n */\nexport class MultipartEncoder {\n private readonly _ur: UR;\n private readonly _fountainEncoder: FountainEncoder;\n private _currentIndex = 0;\n\n /**\n * Creates a new multipart encoder for the given UR.\n *\n * @param ur - The UR to encode\n * @param maxFragmentLen - Maximum length of each fragment in bytes\n * @throws {URError} If encoding fails\n *\n * @example\n * ```typescript\n * const encoder = new MultipartEncoder(ur, 100);\n * ```\n */\n constructor(ur: UR, maxFragmentLen: number) {\n if (maxFragmentLen < 1) {\n throw new URError(\"Max fragment length must be at least 1\");\n }\n this._ur = ur;\n\n // Create fountain encoder from CBOR data\n const cborData = ur.cbor().toData();\n this._fountainEncoder = new FountainEncoder(cborData, maxFragmentLen);\n }\n\n /**\n * Gets the next part of the encoding.\n *\n * Parts 1 through seqLen are \"pure\" fragments containing one piece each.\n * Parts beyond seqLen are \"mixed\" fragments using fountain codes for redundancy.\n *\n * @returns The next UR string part\n *\n * @example\n * ```typescript\n * const part = encoder.nextPart();\n * // Returns: \"ur:bytes/1-3/lsadaoaxjygonesw\"\n * ```\n */\n nextPart(): string {\n const part = this._fountainEncoder.nextPart();\n this._currentIndex++;\n return this._encodePart(part);\n }\n\n /**\n * Encodes a fountain part as a UR string.\n *\n * Always emits the multipart `ur:<type>/<seqNum>-<seqLen>/<bytewords>`\n * format — including for single-part messages (`1-1/...`). This mirrors\n * Rust's `bc_ur::MultipartEncoder::next_part`, which never short-circuits\n * to plain UR. Callers that want plain UR for tiny payloads should use\n * `UR.string()` directly instead of constructing a `MultipartEncoder`.\n */\n private _encodePart(part: FountainPart): string {\n const partData = this._encodePartData(part);\n const encoded = encodeBytewords(partData, BytewordsStyle.Minimal);\n return `ur:${this._ur.urTypeStr()}/${part.seqNum}-${part.seqLen}/${encoded}`;\n }\n\n /**\n * Encodes part metadata and data as CBOR for bytewords encoding.\n * Format: CBOR array [seqNum, seqLen, messageLen, checksum, data]\n */\n private _encodePartData(part: FountainPart): Uint8Array {\n // Create CBOR array with 5 elements: [seqNum, seqLen, messageLen, checksum, data]\n const cborArray = cbor([part.seqNum, part.seqLen, part.messageLen, part.checksum, part.data]);\n\n return cborArray.toData();\n }\n\n /**\n * Gets the current part index.\n */\n currentIndex(): number {\n return this._currentIndex;\n }\n\n /**\n * Gets the total number of pure parts.\n *\n * Note: Fountain codes can generate unlimited parts beyond this count\n * for additional redundancy.\n */\n partsCount(): number {\n return this._fountainEncoder.seqLen;\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\nimport { decodeCbor, MajorType, type Cbor } from \"@bcts/dcbor\";\nimport { InvalidSchemeError, InvalidTypeError, UnexpectedTypeError, URError } from \"./error.js\";\nimport { UR } from \"./ur.js\";\nimport { URType } from \"./ur-type.js\";\nimport { FountainDecoder, type FountainPart } from \"./fountain.js\";\nimport { decodeBytewords, BytewordsStyle } from \"./utils.js\";\n\n/**\n * Decodes multiple UR parts back into a single UR.\n *\n * This reassembles multipart URs that were encoded using fountain codes.\n * The decoder can handle out-of-order reception and packet loss.\n *\n * @example\n * ```typescript\n * const decoder = new MultipartDecoder();\n *\n * for (const urPart of urParts) {\n * decoder.receive(urPart);\n * if (decoder.isComplete()) {\n * const ur = decoder.message();\n * break;\n * }\n * }\n * ```\n */\nexport class MultipartDecoder {\n private _urType: URType | null = null;\n private _fountainDecoder: FountainDecoder | null = null;\n private _decodedMessage: UR | null = null;\n\n /**\n * Receives a UR part string.\n *\n * @param part - A UR part string (e.g., \"ur:bytes/1-10/...\" or \"ur:bytes/...\")\n * @throws {InvalidSchemeError} If the part doesn't start with \"ur:\"\n * @throws {UnexpectedTypeError} If the type doesn't match previous parts\n */\n receive(part: string): void {\n const { urType, partInfo } = this._parsePart(part);\n\n // Validate type consistency\n if (this._urType === null) {\n this._urType = urType;\n } else if (!this._urType.equals(urType)) {\n throw new UnexpectedTypeError(this._urType.string(), urType.string());\n }\n\n // Handle the part\n if (partInfo.isSinglePart) {\n // Single-part UR - decode immediately\n this._decodedMessage = UR.fromURString(part);\n } else {\n // Multipart UR - use fountain decoder\n this._fountainDecoder ??= new FountainDecoder();\n\n const fountainPart = this._decodeFountainPart(partInfo);\n this._fountainDecoder.receive(fountainPart);\n\n // Try to get the complete message\n if (this._fountainDecoder.isComplete()) {\n const message = this._fountainDecoder.message();\n if (message !== null) {\n const cbor = decodeCbor(message);\n this._decodedMessage = UR.new(this._urType, cbor);\n }\n }\n }\n }\n\n /**\n * Parses a UR part string to extract type and part info.\n */\n private _parsePart(part: string): { urType: URType; partInfo: PartInfo } {\n const lowercased = part.toLowerCase();\n\n if (!lowercased.startsWith(\"ur:\")) {\n throw new InvalidSchemeError();\n }\n\n const afterScheme = lowercased.substring(3);\n const components = afterScheme.split(\"/\");\n\n if (components.length === 0 || components[0] === \"\") {\n throw new InvalidTypeError();\n }\n\n const urType = new URType(components[0]);\n\n // Check if this is a multipart UR (format: type/seqNum-seqLen/data)\n if (components.length >= 3) {\n const seqPart = components[1];\n const seqMatch = /^(\\d+)-(\\d+)$/.exec(seqPart);\n\n if (seqMatch !== null) {\n const seqNum = parseInt(seqMatch[1], 10);\n const seqLen = parseInt(seqMatch[2], 10);\n const encodedData = components.slice(2).join(\"/\");\n\n return {\n urType,\n partInfo: {\n isSinglePart: false,\n seqNum,\n seqLen,\n encodedData,\n },\n };\n }\n }\n\n // Single-part UR\n return {\n urType,\n partInfo: { isSinglePart: true },\n };\n }\n\n /**\n * Decodes a multipart UR's fountain part data.\n *\n * The multipart body is a CBOR array: [seqNum, seqLen, messageLen, checksum, data]\n */\n private _decodeFountainPart(partInfo: MultipartInfo): FountainPart {\n // Decode bytewords to get CBOR data\n const cborData = decodeBytewords(partInfo.encodedData, BytewordsStyle.Minimal);\n\n // Decode the CBOR array\n const decoded = decodeCbor(cborData);\n\n // The decoded value should be an array with 5 elements\n if (decoded.type !== MajorType.Array) {\n throw new URError(\"Invalid multipart data: expected CBOR array\");\n }\n\n const items = decoded.value as Cbor[];\n if (items.length !== 5) {\n throw new URError(`Invalid multipart data: expected 5 elements, got ${items.length}`);\n }\n\n // Extract the fields: [seqNum, seqLen, messageLen, checksum, data]\n const seqNum = Number(items[0].value);\n const seqLen = Number(items[1].value);\n const messageLen = Number(items[2].value);\n const checksum = Number(items[3].value);\n const data = items[4].value as Uint8Array;\n\n // Verify seqNum and seqLen match the URL path values\n if (seqNum !== partInfo.seqNum || seqLen !== partInfo.seqLen) {\n throw new URError(\n `Multipart metadata mismatch: URL says ${partInfo.seqNum}-${partInfo.seqLen}, CBOR says ${seqNum}-${seqLen}`,\n );\n }\n\n return {\n seqNum,\n seqLen,\n messageLen,\n checksum,\n data,\n };\n }\n\n /**\n * Checks if the message is complete.\n */\n isComplete(): boolean {\n return this._decodedMessage !== null;\n }\n\n /**\n * Gets the decoded UR message.\n *\n * @returns The decoded UR, or null if not yet complete\n */\n message(): UR | null {\n return this._decodedMessage;\n }\n}\n\n/**\n * Part info for single-part URs.\n */\ninterface SinglePartInfo {\n isSinglePart: true;\n}\n\n/**\n * Part info for multipart URs.\n */\ninterface MultipartInfo {\n isSinglePart: false;\n seqNum: number;\n seqLen: number;\n encodedData: string;\n}\n\ntype PartInfo = SinglePartInfo | MultipartInfo;\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Namespace-style re-export of the bytewords helpers in `./utils`.\n *\n * Mirrors Rust's `bc_ur::bytewords` module (`bc-ur-rust/src/bytewords.rs`)\n * so that callers can write\n *\n * ```ts\n * import { bytewords } from \"@bcts/uniform-resources\";\n * bytewords.encode(data, bytewords.Style.Minimal);\n * bytewords.identifier(fourByteSlice);\n * ```\n *\n * matching the ergonomics of\n *\n * ```rust\n * use bc_ur::bytewords;\n * bytewords::encode(data, bytewords::Style::Minimal);\n * bytewords::identifier(four_byte_slice);\n * ```\n *\n * This is purely an alias module — every symbol below is the same\n * function/value already exported individually from the package root.\n */\n\nexport {\n BYTEWORDS,\n BYTEMOJIS,\n BytewordsStyle as Style,\n encodeBytewords as encode,\n decodeBytewords as decode,\n encodeBytewordsIdentifier as identifier,\n encodeBytemojisIdentifier as bytemojiIdentifier,\n encodeToWords,\n encodeToBytemojis,\n encodeToMinimalBytewords,\n isValidBytemoji,\n canonicalizeByteword,\n} from \"./utils\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAOA,IAAa,UAAb,cAA6B,MAAM;CACjC,YAAY,SAAiB;EAC3B,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;;;;;;AAOA,IAAa,qBAAb,cAAwC,QAAQ;CAC9C,cAAc;EACZ,MAAM,mBAAmB;EACzB,KAAK,OAAO;CACd;AACF;;;;;;AAOA,IAAa,uBAAb,cAA0C,QAAQ;CAChD,cAAc;EACZ,MAAM,sBAAsB;EAC5B,KAAK,OAAO;CACd;AACF;;;;;;AAOA,IAAa,mBAAb,cAAsC,QAAQ;CAC5C,cAAc;EACZ,MAAM,iBAAiB;EACvB,KAAK,OAAO;CACd;AACF;;;;AAKA,IAAa,qBAAb,cAAwC,QAAQ;CAC9C,cAAc;EACZ,MAAM,yBAAyB;EAC/B,KAAK,OAAO;CACd;AACF;;;;;;;AAQA,IAAa,sBAAb,cAAyC,QAAQ;CAC/C,YAAY,UAAkB,OAAe;EAC3C,MAAM,oBAAoB,SAAS,cAAc,OAAO;EACxD,KAAK,OAAO;CACd;AACF;;;;;;AAOA,IAAa,iBAAb,cAAoC,QAAQ;CAC1C,YAAY,SAAiB;EAC3B,MAAM,oBAAoB,QAAQ,EAAE;EACpC,KAAK,OAAO;CACd;AACF;;;;;;AAOA,IAAa,YAAb,cAA+B,QAAQ;CACrC,YAAY,SAAiB;EAC3B,MAAM,eAAe,QAAQ,EAAE;EAC/B,KAAK,OAAO;CACd;AACF;;;;;AAMA,IAAa,gBAAb,cAAmC,QAAQ;CACzC,YAAY,SAAiB;EAC3B,MAAM,qBAAqB,QAAQ,EAAE;EACrC,KAAK,OAAO;CACd;AACF;;;;AAOA,SAAgB,QAAQ,QAAkC;CACxD,OAAO,kBAAkB;AAC3B;;;;;;;;;;;;;;ACrGA,SAAgB,aAAa,MAAuB;CAClD,MAAM,OAAO,KAAK,WAAW,CAAC;CAE9B,IAAI,QAAQ,MAAM,QAAQ,KAAK,OAAO;CAEtC,IAAI,QAAQ,MAAM,QAAQ,IAAI,OAAO;CAErC,IAAI,SAAS,IAAI,OAAO;CACxB,OAAO;AACT;;;;;;;;;;AAWA,SAAgB,cAAc,QAAyB;CACrD,OAAO,MAAM,KAAK,MAAM,EAAE,OAAO,SAAS,aAAa,IAAI,CAAC;AAC9D;;;;AAKA,SAAgB,eAAe,QAAwB;CACrD,IAAI,CAAC,cAAc,MAAM,GACvB,MAAM,IAAI,iBAAiB;CAE7B,OAAO;AACT;;;;;AAMA,MAAa,YAAsB;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;;;AAKA,SAAS,qBAA0C;CACjD,MAAM,sBAAM,IAAI,IAAoB;CACpC,UAAU,SAAS,MAAM,UAAU;EACjC,IAAI,IAAI,MAAM,KAAK;CACrB,CAAC;CACD,OAAO;AACT;AAEA,MAAa,gBAAgB,mBAAmB;;;;;AAMhD,MAAa,YAAsB;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;C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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/error.ts","../src/ur-type.ts","../src/ur.ts","../src/ur-encodable.ts","../src/ur-decodable.ts","../src/ur-codable.ts","../src/multipart-encoder.ts","../src/multipart-decoder.ts","../src/utils.ts","../src/bytewords-namespace.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/error.ts","../src/ur-type.ts","../src/ur.ts","../src/ur-encodable.ts","../src/ur-decodable.ts","../src/ur-codable.ts","../src/multipart-encoder.ts","../src/multipart-decoder.ts","../src/utils.ts","../src/bytewords-namespace.ts"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/error.ts","../src/ur-type.ts","../src/ur.ts","../src/ur-encodable.ts","../src/ur-decodable.ts","../src/ur-codable.ts","../src/multipart-encoder.ts","../src/multipart-decoder.ts","../src/utils.ts","../src/bytewords-namespace.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/error.ts","../src/ur-type.ts","../src/ur.ts","../src/ur-encodable.ts","../src/ur-decodable.ts","../src/ur-codable.ts","../src/multipart-encoder.ts","../src/multipart-decoder.ts","../src/utils.ts","../src/bytewords-namespace.ts"],"mappings":"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"}