@unicitylabs/sphere-sdk 0.9.1-dev.6 → 0.9.1-dev.7

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../node_modules/@noble/hashes/src/utils.ts","../../../../node_modules/@noble/hashes/src/_md.ts","../../../../node_modules/@noble/hashes/src/sha2.ts","../../../../token-engine/sdk.ts","../../../../token-engine/token-blob.ts","../../../../core/crypto.ts","../../../../core/errors.ts","../../../../wallet-api/errors.ts","../../../../wallet-api/challenge.ts","../../../../wallet-api/codec.ts","../../../../wallet-api/client.ts","../../../../impl/shared/wallet-api/WalletApiTokenStorageProvider.ts","../../../../transport/delivery-provider.ts","../../../../node_modules/@noble/hashes/src/hmac.ts","../../../../node_modules/@noble/hashes/src/hkdf.ts","../../../../node_modules/@noble/ciphers/src/utils.ts","../../../../node_modules/@noble/ciphers/src/_arx.ts","../../../../node_modules/@noble/ciphers/src/_poly1305.ts","../../../../node_modules/@noble/ciphers/src/chacha.ts","../../../../core/field-encryption.ts","../../../../core/logger.ts","../../../../impl/shared/wallet-api/WalletApiMailboxProvider.ts","../../../../impl/shared/wallet-api/composition.ts"],"sourcesContent":["/**\n * Utilities for hex, bytes, CSPRNG.\n * @module\n */\n/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n/**\n * Bytes API type helpers for old + new TypeScript.\n *\n * TS 5.6 has `Uint8Array`, while TS 5.9+ made it generic `Uint8Array<ArrayBuffer>`.\n * We can't use specific return type, because TS 5.6 will error.\n * We can't use generic return type, because most TS 5.9 software will expect specific type.\n *\n * Maps typed-array input leaves to broad forms.\n * These are compatibility adapters, not ownership guarantees.\n *\n * - `TArg` keeps byte inputs broad.\n * - `TRet` marks byte outputs for TS 5.6 and TS 5.9+ compatibility.\n */\nexport type TypedArg<T> = T extends BigInt64Array\n ? BigInt64Array\n : T extends BigUint64Array\n ? BigUint64Array\n : T extends Float32Array\n ? Float32Array\n : T extends Float64Array\n ? Float64Array\n : T extends Int16Array\n ? Int16Array\n : T extends Int32Array\n ? Int32Array\n : T extends Int8Array\n ? Int8Array\n : T extends Uint16Array\n ? Uint16Array\n : T extends Uint32Array\n ? Uint32Array\n : T extends Uint8ClampedArray\n ? Uint8ClampedArray\n : T extends Uint8Array\n ? Uint8Array\n : never;\n/** Maps typed-array output leaves to narrow TS-compatible forms. */\nexport type TypedRet<T> = T extends BigInt64Array\n ? ReturnType<typeof BigInt64Array.of>\n : T extends BigUint64Array\n ? ReturnType<typeof BigUint64Array.of>\n : T extends Float32Array\n ? ReturnType<typeof Float32Array.of>\n : T extends Float64Array\n ? ReturnType<typeof Float64Array.of>\n : T extends Int16Array\n ? ReturnType<typeof Int16Array.of>\n : T extends Int32Array\n ? ReturnType<typeof Int32Array.of>\n : T extends Int8Array\n ? ReturnType<typeof Int8Array.of>\n : T extends Uint16Array\n ? ReturnType<typeof Uint16Array.of>\n : T extends Uint32Array\n ? ReturnType<typeof Uint32Array.of>\n : T extends Uint8ClampedArray\n ? ReturnType<typeof Uint8ClampedArray.of>\n : T extends Uint8Array\n ? ReturnType<typeof Uint8Array.of>\n : never;\n/** Recursively adapts byte-carrying API input types. See {@link TypedArg}. */\nexport type TArg<T> =\n | T\n | ([TypedArg<T>] extends [never]\n ? T extends (...args: infer A) => infer R\n ? ((...args: { [K in keyof A]: TRet<A[K]> }) => TArg<R>) & {\n [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TArg<T[K]>;\n }\n : T extends [infer A, ...infer R]\n ? [TArg<A>, ...{ [K in keyof R]: TArg<R[K]> }]\n : T extends readonly [infer A, ...infer R]\n ? readonly [TArg<A>, ...{ [K in keyof R]: TArg<R[K]> }]\n : T extends (infer A)[]\n ? TArg<A>[]\n : T extends readonly (infer A)[]\n ? readonly TArg<A>[]\n : T extends Promise<infer A>\n ? Promise<TArg<A>>\n : T extends object\n ? { [K in keyof T]: TArg<T[K]> }\n : T\n : TypedArg<T>);\n/** Recursively adapts byte-carrying API output types. See {@link TypedArg}. */\nexport type TRet<T> = T extends unknown\n ? T &\n ([TypedRet<T>] extends [never]\n ? T extends (...args: infer A) => infer R\n ? ((...args: { [K in keyof A]: TArg<A[K]> }) => TRet<R>) & {\n [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TRet<T[K]>;\n }\n : T extends [infer A, ...infer R]\n ? [TRet<A>, ...{ [K in keyof R]: TRet<R[K]> }]\n : T extends readonly [infer A, ...infer R]\n ? readonly [TRet<A>, ...{ [K in keyof R]: TRet<R[K]> }]\n : T extends (infer A)[]\n ? TRet<A>[]\n : T extends readonly (infer A)[]\n ? readonly TRet<A>[]\n : T extends Promise<infer A>\n ? Promise<TRet<A>>\n : T extends object\n ? { [K in keyof T]: TRet<T[K]> }\n : T\n : TypedRet<T>)\n : never;\n/**\n * Checks if something is Uint8Array. Be careful: nodejs Buffer will return true.\n * @param a - value to test\n * @returns `true` when the value is a Uint8Array-compatible view.\n * @example\n * Check whether a value is a Uint8Array-compatible view.\n * ```ts\n * isBytes(new Uint8Array([1, 2, 3]));\n * ```\n */\nexport function isBytes(a: unknown): a is Uint8Array {\n // Plain `instanceof Uint8Array` is too strict for some Buffer / proxy / cross-realm cases.\n // The fallback still requires a real ArrayBuffer view, so plain\n // JSON-deserialized `{ constructor: ... }` spoofing is rejected, and\n // `BYTES_PER_ELEMENT === 1` keeps the fallback on byte-oriented views.\n return (\n a instanceof Uint8Array ||\n (ArrayBuffer.isView(a) &&\n a.constructor.name === 'Uint8Array' &&\n 'BYTES_PER_ELEMENT' in a &&\n a.BYTES_PER_ELEMENT === 1)\n );\n}\n\n/**\n * Asserts something is a non-negative integer.\n * @param n - number to validate\n * @param title - label included in thrown errors\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Validate a non-negative integer option.\n * ```ts\n * anumber(32, 'length');\n * ```\n */\nexport function anumber(n: number, title: string = ''): void {\n if (typeof n !== 'number') {\n const prefix = title && `\"${title}\" `;\n throw new TypeError(`${prefix}expected number, got ${typeof n}`);\n }\n if (!Number.isSafeInteger(n) || n < 0) {\n const prefix = title && `\"${title}\" `;\n throw new RangeError(`${prefix}expected integer >= 0, got ${n}`);\n }\n}\n\n/**\n * Asserts something is Uint8Array.\n * @param value - value to validate\n * @param length - optional exact length constraint\n * @param title - label included in thrown errors\n * @returns The validated byte array.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Validate that a value is a byte array.\n * ```ts\n * abytes(new Uint8Array([1, 2, 3]));\n * ```\n */\nexport function abytes(\n value: TArg<Uint8Array>,\n length?: number,\n title: string = ''\n): TRet<Uint8Array> {\n const bytes = isBytes(value);\n const len = value?.length;\n const needsLen = length !== undefined;\n if (!bytes || (needsLen && len !== length)) {\n const prefix = title && `\"${title}\" `;\n const ofLen = needsLen ? ` of length ${length}` : '';\n const got = bytes ? `length=${len}` : `type=${typeof value}`;\n const message = prefix + 'expected Uint8Array' + ofLen + ', got ' + got;\n if (!bytes) throw new TypeError(message);\n throw new RangeError(message);\n }\n return value as TRet<Uint8Array>;\n}\n\n/**\n * Copies bytes into a fresh Uint8Array.\n * Buffer-style slices can alias the same backing store, so callers that need ownership should copy.\n * @param bytes - source bytes to clone\n * @returns Freshly allocated copy of `bytes`.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Clone a byte array before mutating it.\n * ```ts\n * const copy = copyBytes(new Uint8Array([1, 2, 3]));\n * ```\n */\nexport function copyBytes(bytes: TArg<Uint8Array>): TRet<Uint8Array> {\n // `Uint8Array.from(...)` would also accept arrays / other typed arrays. Keep this helper strict\n // because callers use it at byte-validation boundaries before mutating the detached copy.\n return Uint8Array.from(abytes(bytes)) as TRet<Uint8Array>;\n}\n\n/**\n * Asserts something is a wrapped hash constructor.\n * @param h - hash constructor to validate\n * @throws On wrong argument types or invalid hash wrapper shape. {@link TypeError}\n * @throws On invalid hash metadata ranges or values. {@link RangeError}\n * @throws If the hash metadata allows empty outputs or block sizes. {@link Error}\n * @example\n * Validate a callable hash wrapper.\n * ```ts\n * import { ahash } from '@noble/hashes/utils.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * ahash(sha256);\n * ```\n */\nexport function ahash(h: TArg<CHash>): void {\n if (typeof h !== 'function' || typeof h.create !== 'function')\n throw new TypeError('Hash must wrapped by utils.createHasher');\n anumber(h.outputLen);\n anumber(h.blockLen);\n // HMAC and KDF callers treat these as real byte lengths; allowing zero lets fake wrappers pass\n // validation and can produce empty outputs instead of failing fast.\n if (h.outputLen < 1) throw new Error('\"outputLen\" must be >= 1');\n if (h.blockLen < 1) throw new Error('\"blockLen\" must be >= 1');\n}\n\n/**\n * Asserts a hash instance has not been destroyed or finished.\n * @param instance - hash instance to validate\n * @param checkFinished - whether to reject finalized instances\n * @throws If the hash instance has already been destroyed or finalized. {@link Error}\n * @example\n * Validate that a hash instance is still usable.\n * ```ts\n * import { aexists } from '@noble/hashes/utils.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const hash = sha256.create();\n * aexists(hash);\n * ```\n */\nexport function aexists(instance: any, checkFinished = true): void {\n if (instance.destroyed) throw new Error('Hash instance has been destroyed');\n if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called');\n}\n\n/**\n * Asserts output is a sufficiently-sized byte array.\n * @param out - destination buffer\n * @param instance - hash instance providing output length\n * Oversized buffers are allowed; downstream code only promises to fill the first `outputLen` bytes.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Validate a caller-provided digest buffer.\n * ```ts\n * import { aoutput } from '@noble/hashes/utils.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const hash = sha256.create();\n * aoutput(new Uint8Array(hash.outputLen), hash);\n * ```\n */\nexport function aoutput(out: any, instance: any): void {\n abytes(out, undefined, 'digestInto() output');\n const min = instance.outputLen;\n if (out.length < min) {\n throw new RangeError('\"digestInto() output\" expected to be of length >=' + min);\n }\n}\n\n/** Generic type encompassing 8/16/32-byte array views, but not 64-bit variants. */\n// prettier-ignore\nexport type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array |\n Uint16Array | Int16Array | Uint32Array | Int32Array;\n\n/**\n * Casts a typed array view to Uint8Array.\n * @param arr - source typed array\n * @returns Uint8Array view over the same buffer.\n * @example\n * Reinterpret a typed array as bytes.\n * ```ts\n * u8(new Uint32Array([1, 2]));\n * ```\n */\nexport function u8(arr: TArg<TypedArray>): TRet<Uint8Array> {\n return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength) as TRet<Uint8Array>;\n}\n\n/**\n * Casts a typed array view to Uint32Array.\n * `arr.byteOffset` must already be 4-byte aligned or the platform\n * Uint32Array constructor will throw.\n * @param arr - source typed array\n * @returns Uint32Array view over the same buffer.\n * @example\n * Reinterpret a byte array as 32-bit words.\n * ```ts\n * u32(new Uint8Array(8));\n * ```\n */\nexport function u32(arr: TArg<TypedArray>): TRet<Uint32Array> {\n return new Uint32Array(\n arr.buffer,\n arr.byteOffset,\n Math.floor(arr.byteLength / 4)\n ) as TRet<Uint32Array>;\n}\n\n/**\n * Zeroizes typed arrays in place. Warning: JS provides no guarantees.\n * @param arrays - arrays to overwrite with zeros\n * @example\n * Zeroize sensitive buffers in place.\n * ```ts\n * clean(new Uint8Array([1, 2, 3]));\n * ```\n */\nexport function clean(...arrays: TArg<TypedArray[]>): void {\n for (let i = 0; i < arrays.length; i++) {\n arrays[i].fill(0);\n }\n}\n\n/**\n * Creates a DataView for byte-level manipulation.\n * @param arr - source typed array\n * @returns DataView over the same buffer region.\n * @example\n * Create a DataView over an existing buffer.\n * ```ts\n * createView(new Uint8Array(4));\n * ```\n */\nexport function createView(arr: TArg<TypedArray>): DataView {\n return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/**\n * Rotate-right operation for uint32 values.\n * @param word - source word\n * @param shift - shift amount in bits\n * @returns Rotated word.\n * @example\n * Rotate a 32-bit word to the right.\n * ```ts\n * rotr(0x12345678, 8);\n * ```\n */\nexport function rotr(word: number, shift: number): number {\n return (word << (32 - shift)) | (word >>> shift);\n}\n\n/**\n * Rotate-left operation for uint32 values.\n * @param word - source word\n * @param shift - shift amount in bits\n * @returns Rotated word.\n * @example\n * Rotate a 32-bit word to the left.\n * ```ts\n * rotl(0x12345678, 8);\n * ```\n */\nexport function rotl(word: number, shift: number): number {\n return (word << shift) | ((word >>> (32 - shift)) >>> 0);\n}\n\n/** Whether the current platform is little-endian. */\nexport const isLE: boolean = /* @__PURE__ */ (() =>\n new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();\n\n/**\n * Byte-swap operation for uint32 values.\n * @param word - source word\n * @returns Word with reversed byte order.\n * @example\n * Reverse the byte order of a 32-bit word.\n * ```ts\n * byteSwap(0x11223344);\n * ```\n */\nexport function byteSwap(word: number): number {\n return (\n ((word << 24) & 0xff000000) |\n ((word << 8) & 0xff0000) |\n ((word >>> 8) & 0xff00) |\n ((word >>> 24) & 0xff)\n );\n}\n/**\n * Conditionally byte-swaps one 32-bit word on big-endian platforms.\n * @param n - source word\n * @returns Original or byte-swapped word depending on platform endianness.\n * @example\n * Normalize a 32-bit word for host endianness.\n * ```ts\n * swap8IfBE(0x11223344);\n * ```\n */\nexport const swap8IfBE: (n: number) => number = isLE\n ? (n: number) => n\n : (n: number) => byteSwap(n) >>> 0;\n\n/**\n * Byte-swaps every word of a Uint32Array in place.\n * @param arr - array to mutate\n * @returns The same array after mutation; callers pass live state arrays here.\n * @example\n * Reverse the byte order of every word in place.\n * ```ts\n * byteSwap32(new Uint32Array([0x11223344]));\n * ```\n */\nexport function byteSwap32(arr: TArg<Uint32Array>): TRet<Uint32Array> {\n for (let i = 0; i < arr.length; i++) {\n arr[i] = byteSwap(arr[i]);\n }\n return arr as TRet<Uint32Array>;\n}\n\n/**\n * Conditionally byte-swaps a Uint32Array on big-endian platforms.\n * @param u - array to normalize for host endianness\n * @returns Original or byte-swapped array depending on platform endianness.\n * On big-endian runtimes this mutates `u` in place via `byteSwap32(...)`.\n * @example\n * Normalize a word array for host endianness.\n * ```ts\n * swap32IfBE(new Uint32Array([0x11223344]));\n * ```\n */\nexport const swap32IfBE: (u: TArg<Uint32Array>) => TRet<Uint32Array> = isLE\n ? (u: TArg<Uint32Array>) => u as TRet<Uint32Array>\n : byteSwap32;\n\n// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex\nconst hasHexBuiltin: boolean = /* @__PURE__ */ (() =>\n // @ts-ignore\n typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')();\n\n// Array where index 0xf0 (240) is mapped to string 'f0'\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>\n i.toString(16).padStart(2, '0')\n);\n\n/**\n * Convert byte array to hex string.\n * Uses the built-in function when available and assumes it matches the tested\n * fallback semantics.\n * @param bytes - bytes to encode\n * @returns Lowercase hexadecimal string.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Convert bytes to lowercase hexadecimal.\n * ```ts\n * bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])); // 'cafe0123'\n * ```\n */\nexport function bytesToHex(bytes: TArg<Uint8Array>): string {\n abytes(bytes);\n // @ts-ignore\n if (hasHexBuiltin) return bytes.toHex();\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n\n// We use optimized technique to convert hex string to byte array\nconst asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 } as const;\nfunction asciiToBase16(ch: number): number | undefined {\n if (ch >= asciis._0 && ch <= asciis._9) return ch - asciis._0; // '2' => 50-48\n if (ch >= asciis.A && ch <= asciis.F) return ch - (asciis.A - 10); // 'B' => 66-(65-10)\n if (ch >= asciis.a && ch <= asciis.f) return ch - (asciis.a - 10); // 'b' => 98-(97-10)\n return;\n}\n\n/**\n * Convert hex string to byte array. Uses built-in function, when available.\n * @param hex - hexadecimal string to decode\n * @returns Decoded bytes.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Decode lowercase hexadecimal into bytes.\n * ```ts\n * hexToBytes('cafe0123'); // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n * ```\n */\nexport function hexToBytes(hex: string): TRet<Uint8Array> {\n if (typeof hex !== 'string') throw new TypeError('hex string expected, got ' + typeof hex);\n if (hasHexBuiltin) {\n try {\n return (Uint8Array as any).fromHex(hex);\n } catch (error) {\n if (error instanceof SyntaxError) throw new RangeError(error.message);\n throw error;\n }\n }\n const hl = hex.length;\n const al = hl / 2;\n if (hl % 2) throw new RangeError('hex string expected, got unpadded hex of length ' + hl);\n const array = new Uint8Array(al);\n for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n const n1 = asciiToBase16(hex.charCodeAt(hi));\n const n2 = asciiToBase16(hex.charCodeAt(hi + 1));\n if (n1 === undefined || n2 === undefined) {\n const char = hex[hi] + hex[hi + 1];\n throw new RangeError(\n 'hex string expected, got non-hex character \"' + char + '\" at index ' + hi\n );\n }\n array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163\n }\n return array;\n}\n\n/**\n * There is no setImmediate in browser and setTimeout is slow.\n * This yields to the Promise/microtask scheduler queue, not to timers or the\n * full macrotask event loop.\n * @example\n * Yield to the next scheduler tick.\n * ```ts\n * await nextTick();\n * ```\n */\nexport const nextTick = async (): Promise<void> => {};\n\n/**\n * Returns control to the Promise/microtask scheduler every `tick`\n * milliseconds to avoid blocking long loops.\n * @param iters - number of loop iterations to run\n * @param tick - maximum time slice in milliseconds\n * @param cb - callback executed on each iteration\n * @example\n * Run a loop that periodically yields back to the event loop.\n * ```ts\n * await asyncLoop(2, 0, () => {});\n * ```\n */\nexport async function asyncLoop(\n iters: number,\n tick: number,\n cb: (i: number) => void\n): Promise<void> {\n let ts = Date.now();\n for (let i = 0; i < iters; i++) {\n cb(i);\n // Date.now() is not monotonic, so in case if clock goes backwards we return return control too\n const diff = Date.now() - ts;\n if (diff >= 0 && diff < tick) continue;\n await nextTick();\n ts += diff;\n }\n}\n\n// Global symbols, but ts doesn't see them: https://github.com/microsoft/TypeScript/issues/31535\ndeclare const TextEncoder: any;\n\n/**\n * Converts string to bytes using UTF8 encoding.\n * Built-in doesn't validate input to be string: we do the check.\n * Non-ASCII details are delegated to the platform `TextEncoder`.\n * @param str - string to encode\n * @returns UTF-8 encoded bytes.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Encode a string as UTF-8 bytes.\n * ```ts\n * utf8ToBytes('abc'); // Uint8Array.from([97, 98, 99])\n * ```\n */\nexport function utf8ToBytes(str: string): TRet<Uint8Array> {\n if (typeof str !== 'string') throw new TypeError('string expected');\n return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n\n/** KDFs can accept string or Uint8Array for user convenience. */\nexport type KDFInput = string | Uint8Array;\n\n/**\n * Helper for KDFs: consumes Uint8Array or string.\n * String inputs are UTF-8 encoded; byte-array inputs stay aliased to the caller buffer.\n * @param data - user-provided KDF input\n * @param errorTitle - label included in thrown errors\n * @returns Byte representation of the input.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Normalize KDF input to bytes.\n * ```ts\n * kdfInputToBytes('password');\n * ```\n */\nexport function kdfInputToBytes(data: TArg<KDFInput>, errorTitle = ''): TRet<Uint8Array> {\n if (typeof data === 'string') return utf8ToBytes(data);\n return abytes(data, undefined, errorTitle);\n}\n\n/**\n * Copies several Uint8Arrays into one.\n * @param arrays - arrays to concatenate\n * @returns Concatenated byte array.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Concatenate multiple byte arrays.\n * ```ts\n * concatBytes(new Uint8Array([1]), new Uint8Array([2]));\n * ```\n */\nexport function concatBytes(...arrays: TArg<Uint8Array[]>): TRet<Uint8Array> {\n let sum = 0;\n for (let i = 0; i < arrays.length; i++) {\n const a = arrays[i];\n abytes(a);\n sum += a.length;\n }\n const res = new Uint8Array(sum);\n for (let i = 0, pad = 0; i < arrays.length; i++) {\n const a = arrays[i];\n res.set(a, pad);\n pad += a.length;\n }\n return res;\n}\n\ntype EmptyObj = {};\n/**\n * Merges default options and passed options.\n * @param defaults - base option object\n * @param opts - user overrides\n * @returns Merged option object. The merge mutates `defaults` in place.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Merge user overrides onto default options.\n * ```ts\n * checkOpts({ dkLen: 32 }, { asyncTick: 10 });\n * ```\n */\nexport function checkOpts<T1 extends EmptyObj, T2 extends EmptyObj>(\n defaults: T1,\n opts?: T2\n): T1 & T2 {\n if (opts !== undefined && {}.toString.call(opts) !== '[object Object]')\n throw new TypeError('options must be object or undefined');\n const merged = Object.assign(defaults, opts);\n return merged as T1 & T2;\n}\n\n/** Common interface for all hash instances. */\nexport interface Hash<T> {\n /** Bytes processed per compression block. */\n blockLen: number;\n /** Bytes produced by `digest()`. */\n outputLen: number;\n /** Whether the instance supports XOF-style variable-length output via `xof()` / `xofInto()`. */\n canXOF: boolean;\n /**\n * Absorbs more message bytes into the running hash state.\n * @param buf - message chunk to absorb\n * @returns The same hash instance for chaining.\n */\n update(buf: TArg<Uint8Array>): this;\n /**\n * Finalizes the hash into a caller-provided buffer.\n * @param buf - destination buffer\n * @returns Nothing. Implementations write into `buf` in place.\n */\n digestInto(buf: TArg<Uint8Array>): void;\n /**\n * Finalizes the hash and returns a freshly allocated digest.\n * @returns Digest bytes.\n */\n digest(): TRet<Uint8Array>;\n /** Wipes internal state and makes the instance unusable. */\n destroy(): void;\n /**\n * Copies the current hash state into an existing or new instance.\n * @param to - Optional destination instance to reuse.\n * @returns Cloned hash state.\n */\n _cloneInto(to?: T): T;\n /**\n * Creates an independent copy of the current hash state.\n * @returns Cloned hash instance.\n */\n clone(): T;\n}\n\n/** Pseudorandom generator interface. */\nexport interface PRG {\n /**\n * Mixes more entropy into the generator state.\n * @param seed - fresh entropy bytes\n * @returns Nothing. Implementations update internal state in place.\n */\n addEntropy(seed: TArg<Uint8Array>): void;\n /**\n * Generates pseudorandom output bytes.\n * @param length - number of bytes to generate\n * @returns Generated pseudorandom bytes.\n */\n randomBytes(length: number): TRet<Uint8Array>;\n /** Wipes generator state and makes the instance unusable. */\n clean(): void;\n}\n\n/**\n * XOF: streaming API to read digest in chunks.\n * Same as 'squeeze' in keccak/k12 and 'seek' in blake3, but more generic name.\n * When hash used in XOF mode it is up to user to call '.destroy' afterwards, since we cannot\n * destroy state, next call can require more bytes.\n */\nexport type HashXOF<T extends Hash<T>> = Hash<T> & {\n /**\n * Reads more bytes from the XOF stream.\n * @param bytes - number of bytes to read\n * @returns Requested digest bytes.\n */\n xof(bytes: number): TRet<Uint8Array>;\n /**\n * Reads more bytes from the XOF stream into a caller-provided buffer.\n * @param buf - destination buffer\n * @returns Filled output buffer.\n */\n xofInto(buf: TArg<Uint8Array>): TRet<Uint8Array>;\n};\n\n/** Hash constructor or factory type. */\nexport type HasherCons<T, Opts = undefined> = Opts extends undefined ? () => T : (opts?: Opts) => T;\n/** Optional hash metadata. */\nexport type HashInfo = {\n /** DER-encoded object identifier bytes for the hash algorithm. */\n oid?: TRet<Uint8Array>;\n};\n/** Callable hash function type. */\nexport type CHash<T extends Hash<T> = Hash<any>, Opts = undefined> = {\n /** Digest size in bytes. */\n outputLen: number;\n /** Input block size in bytes. */\n blockLen: number;\n /** Whether `.create()` returns a hash instance that can be used as an XOF stream. */\n canXOF: boolean;\n} & HashInfo &\n (Opts extends undefined\n ? {\n (msg: TArg<Uint8Array>): TRet<Uint8Array>;\n create(): T;\n }\n : {\n (msg: TArg<Uint8Array>, opts?: TArg<Opts>): TRet<Uint8Array>;\n create(opts?: Opts): T;\n });\n/** Callable extendable-output hash function type. */\nexport type CHashXOF<T extends HashXOF<T> = HashXOF<any>, Opts = undefined> = CHash<T, Opts>;\n\n/**\n * Creates a callable hash function from a stateful class constructor.\n * @param hashCons - hash constructor or factory\n * @param info - optional metadata such as DER OID\n * @returns Frozen callable hash wrapper with `.create()`.\n * Wrapper construction eagerly calls `hashCons(undefined)` once to read\n * `outputLen` / `blockLen`, so constructor side effects happen at module\n * init time.\n * @example\n * Wrap a stateful hash constructor into a callable helper.\n * ```ts\n * import { createHasher } from '@noble/hashes/utils.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const wrapped = createHasher(sha256.create, { oid: sha256.oid });\n * wrapped(new Uint8Array([1]));\n * ```\n */\nexport function createHasher<T extends Hash<T>, Opts = undefined>(\n hashCons: HasherCons<T, Opts>,\n info: TArg<HashInfo> = {}\n): TRet<CHash<T, Opts>> {\n const hashC: any = (msg: TArg<Uint8Array>, opts?: TArg<Opts>) =>\n hashCons(opts as Opts)\n .update(msg)\n .digest();\n const tmp = hashCons(undefined);\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.canXOF = tmp.canXOF;\n hashC.create = (opts?: Opts) => hashCons(opts);\n Object.assign(hashC, info);\n return Object.freeze(hashC) as TRet<CHash<T, Opts>>;\n}\n\n/**\n * Cryptographically secure PRNG backed by `crypto.getRandomValues`.\n * @param bytesLength - number of random bytes to generate\n * @returns Random bytes.\n * The platform `getRandomValues()` implementation still defines any\n * single-call length cap, and this helper rejects oversize requests\n * with a stable library `RangeError` instead of host-specific errors.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @throws If the current runtime does not provide `crypto.getRandomValues`. {@link Error}\n * @example\n * Generate a fresh random key or nonce.\n * ```ts\n * const key = randomBytes(16);\n * ```\n */\nexport function randomBytes(bytesLength = 32): TRet<Uint8Array> {\n // Match the repo's other length-taking helpers instead of relying on Uint8Array coercion.\n anumber(bytesLength, 'bytesLength');\n const cr = typeof globalThis === 'object' ? (globalThis as any).crypto : null;\n if (typeof cr?.getRandomValues !== 'function')\n throw new Error('crypto.getRandomValues must be defined');\n // Web Cryptography API Level 2 §10.1.1:\n // if `byteLength > 65536`, throw `QuotaExceededError`.\n // Keep the guard explicit so callers can see the quota in code\n // instead of discovering it by reading the spec or host errors.\n // This wrapper surfaces the same quota as a stable library RangeError.\n if (bytesLength > 65536)\n throw new RangeError(`\"bytesLength\" expected <= 65536, got ${bytesLength}`);\n return cr.getRandomValues(new Uint8Array(bytesLength));\n}\n\n/**\n * Creates OID metadata for NIST hashes with prefix `06 09 60 86 48 01 65 03 04 02`.\n * @param suffix - final OID byte for the selected hash.\n * The helper accepts any byte even though only the documented NIST hash\n * suffixes are meaningful downstream.\n * @returns Object containing the DER-encoded OID.\n * @example\n * Build OID metadata for a NIST hash.\n * ```ts\n * oidNist(0x01);\n * ```\n */\nexport const oidNist = (suffix: number): TRet<Required<HashInfo>> => ({\n // Current NIST hashAlgs suffixes used here fit in one DER subidentifier octet.\n // Larger suffix values would need base-128 OID encoding and a different length byte.\n oid: Uint8Array.from([0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, suffix]),\n});\n","/**\n * Internal Merkle-Damgard hash utils.\n * @module\n */\nimport {\n abytes,\n aexists,\n aoutput,\n clean,\n createView,\n type Hash,\n type TArg,\n type TRet,\n} from './utils.ts';\n\n/**\n * Shared 32-bit conditional boolean primitive reused by SHA-256, SHA-1, and MD5 `F`.\n * Returns bits from `b` when `a` is set, otherwise from `c`.\n * The XOR form is equivalent to MD5's `F(X,Y,Z) = XY v not(X)Z` because the masked terms never\n * set the same bit.\n * @param a - selector word\n * @param b - word chosen when selector bit is set\n * @param c - word chosen when selector bit is clear\n * @returns Mixed 32-bit word.\n * @example\n * Combine three words with the shared 32-bit choice primitive.\n * ```ts\n * Chi(0xffffffff, 0x12345678, 0x87654321);\n * ```\n */\nexport function Chi(a: number, b: number, c: number): number {\n return (a & b) ^ (~a & c);\n}\n\n/**\n * Shared 32-bit majority primitive reused by SHA-256 and SHA-1.\n * Returns bits shared by at least two inputs.\n * @param a - first input word\n * @param b - second input word\n * @param c - third input word\n * @returns Mixed 32-bit word.\n * @example\n * Combine three words with the shared 32-bit majority primitive.\n * ```ts\n * Maj(0xffffffff, 0x12345678, 0x87654321);\n * ```\n */\nexport function Maj(a: number, b: number, c: number): number {\n return (a & b) ^ (a & c) ^ (b & c);\n}\n\n/**\n * Merkle-Damgard hash construction base class.\n * Could be used to create MD5, RIPEMD, SHA1, SHA2.\n * Accepts only byte-aligned `Uint8Array` input, even when the underlying spec describes bit\n * strings with partial-byte tails.\n * @param blockLen - internal block size in bytes\n * @param outputLen - digest size in bytes\n * @param padOffset - trailing length field size in bytes\n * @param isLE - whether length and state words are encoded in little-endian\n * @example\n * Use a concrete subclass to get the shared Merkle-Damgard update/digest flow.\n * ```ts\n * import { _SHA1 } from '@noble/hashes/legacy.js';\n * const hash = new _SHA1();\n * hash.update(new Uint8Array([97, 98, 99]));\n * hash.digest();\n * ```\n */\nexport abstract class HashMD<T extends HashMD<T>> implements Hash<T> {\n // Subclasses must treat `buf` as read-only: `update()` may pass a direct view over caller input\n // when it can process whole blocks without buffering first.\n protected abstract process(buf: DataView, offset: number): void;\n protected abstract get(): number[];\n protected abstract set(...args: number[]): void;\n abstract destroy(): void;\n protected abstract roundClean(): void;\n\n readonly blockLen: number;\n readonly outputLen: number;\n readonly canXOF = false;\n readonly padOffset: number;\n readonly isLE: boolean;\n\n // For partial updates less than block size\n protected buffer: Uint8Array;\n protected view: DataView;\n protected finished = false;\n protected length = 0;\n protected pos = 0;\n protected destroyed = false;\n\n constructor(blockLen: number, outputLen: number, padOffset: number, isLE: boolean) {\n this.blockLen = blockLen;\n this.outputLen = outputLen;\n this.padOffset = padOffset;\n this.isLE = isLE;\n this.buffer = new Uint8Array(blockLen);\n this.view = createView(this.buffer);\n }\n update(data: TArg<Uint8Array>): this {\n aexists(this);\n abytes(data);\n const { view, buffer, blockLen } = this;\n const len = data.length;\n for (let pos = 0; pos < len; ) {\n const take = Math.min(blockLen - this.pos, len - pos);\n // Fast path only when there is no buffered partial block: `take === blockLen` implies\n // `this.pos === 0`, so we can process full blocks directly from the input view.\n if (take === blockLen) {\n const dataView = createView(data);\n for (; blockLen <= len - pos; pos += blockLen) this.process(dataView, pos);\n continue;\n }\n buffer.set(data.subarray(pos, pos + take), this.pos);\n this.pos += take;\n pos += take;\n if (this.pos === blockLen) {\n this.process(view, 0);\n this.pos = 0;\n }\n }\n this.length += data.length;\n this.roundClean();\n return this;\n }\n digestInto(out: TArg<Uint8Array>): void {\n aexists(this);\n aoutput(out, this);\n this.finished = true;\n // Padding\n // We can avoid allocation of buffer for padding completely if it\n // was previously not allocated here. But it won't change performance.\n const { buffer, view, blockLen, isLE } = this;\n let { pos } = this;\n // append the bit '1' to the message\n buffer[pos++] = 0b10000000;\n clean(this.buffer.subarray(pos));\n // we have less than padOffset left in buffer, so we cannot put length in\n // current block, need process it and pad again\n if (this.padOffset > blockLen - pos) {\n this.process(view, 0);\n pos = 0;\n }\n // Pad until full block byte with zeros\n for (let i = pos; i < blockLen; i++) buffer[i] = 0;\n // `padOffset` reserves the whole length field. For SHA-384/512 the high 64 bits stay zero from\n // the padding fill above, and JS will overflow before user input can make that half non-zero.\n // So we only need to write the low 64 bits here.\n view.setBigUint64(blockLen - 8, BigInt(this.length * 8), isLE);\n this.process(view, 0);\n const oview = createView(out);\n const len = this.outputLen;\n // NOTE: we do division by 4 later, which must be fused in single op with modulo by JIT\n if (len % 4) throw new Error('_sha2: outputLen must be aligned to 32bit');\n const outLen = len / 4;\n const state = this.get();\n if (outLen > state.length) throw new Error('_sha2: outputLen bigger than state');\n for (let i = 0; i < outLen; i++) oview.setUint32(4 * i, state[i], isLE);\n }\n digest(): TRet<Uint8Array> {\n const { buffer, outputLen } = this;\n this.digestInto(buffer);\n // Copy before destroy(): subclasses wipe `buffer` during cleanup, but `digest()` must return\n // fresh bytes to the caller.\n const res = buffer.slice(0, outputLen);\n this.destroy();\n return res as TRet<Uint8Array>;\n }\n _cloneInto(to?: T): T {\n to ||= new (this.constructor as any)() as T;\n to.set(...this.get());\n const { blockLen, buffer, length, finished, destroyed, pos } = this;\n to.destroyed = destroyed;\n to.finished = finished;\n to.length = length;\n to.pos = pos;\n // Only partial-block bytes need copying: when `length % blockLen === 0`, `pos === 0` and\n // later `update()` / `digestInto()` overwrite `to.buffer` from the start before reading it.\n if (length % blockLen) to.buffer.set(buffer);\n return to as unknown as any;\n }\n clone(): T {\n return this._cloneInto();\n }\n}\n\n/**\n * Initial SHA-2 state: fractional parts of square roots of first 16 primes 2..53.\n * Check out `test/misc/sha2-gen-iv.js` for recomputation guide.\n */\n\n/** Initial SHA256 state from RFC 6234 §6.1: the first 32 bits of the fractional parts of the\n * square roots of the first eight prime numbers. Exported as a shared table; callers must treat\n * it as read-only because constructors copy words from it by index. */\nexport const SHA256_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n]);\n\n/** Initial SHA224 state `H(0)` from RFC 6234 §6.1. Exported as a shared table; callers must\n * treat it as read-only because constructors copy words from it by index. */\nexport const SHA224_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4,\n]);\n\n/** Initial SHA384 state from RFC 6234 §6.3: eight RFC 64-bit `H(0)` words stored as sixteen\n * big-endian 32-bit halves. Derived from the fractional parts of the square roots of the ninth\n * through sixteenth prime numbers. Exported as a shared table; callers must treat it as read-only\n * because constructors copy halves from it by index. */\nexport const SHA384_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0xcbbb9d5d, 0xc1059ed8, 0x629a292a, 0x367cd507, 0x9159015a, 0x3070dd17, 0x152fecd8, 0xf70e5939,\n 0x67332667, 0xffc00b31, 0x8eb44a87, 0x68581511, 0xdb0c2e0d, 0x64f98fa7, 0x47b5481d, 0xbefa4fa4,\n]);\n\n/** Initial SHA512 state from RFC 6234 §6.3: eight RFC 64-bit `H(0)` words stored as sixteen\n * big-endian 32-bit halves. Derived from the fractional parts of the square roots of the first\n * eight prime numbers. Exported as a shared table; callers must treat it as read-only because\n * constructors copy halves from it by index. */\nexport const SHA512_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b, 0xa54ff53a, 0x5f1d36f1,\n 0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179,\n]);\n","/**\n * SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256.\n * SHA256 is the fastest hash implementable in JS, even faster than Blake3.\n * Check out {@link https://www.rfc-editor.org/rfc/rfc4634 | RFC 4634} and\n * {@link https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf | FIPS 180-4}.\n * @module\n */\nimport { Chi, HashMD, Maj, SHA224_IV, SHA256_IV, SHA384_IV, SHA512_IV } from './_md.ts';\nimport * as u64 from './_u64.ts';\nimport { type CHash, clean, createHasher, oidNist, rotr, type TRet } from './utils.ts';\n\n/**\n * SHA-224 / SHA-256 round constants from RFC 6234 §5.1: the first 32 bits\n * of the cube roots of the first 64 primes (2..311).\n */\n// prettier-ignore\nconst SHA256_K = /* @__PURE__ */ Uint32Array.from([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n]);\n\n/** Reusable SHA-224 / SHA-256 message schedule buffer `W_t` from RFC 6234 §6.2 step 1. */\nconst SHA256_W = /* @__PURE__ */ new Uint32Array(64);\n\n/** Internal SHA-224 / SHA-256 compression engine from RFC 6234 §6.2. */\nabstract class SHA2_32B<T extends SHA2_32B<T>> extends HashMD<T> {\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n protected abstract A: number;\n protected abstract B: number;\n protected abstract C: number;\n protected abstract D: number;\n protected abstract E: number;\n protected abstract F: number;\n protected abstract G: number;\n protected abstract H: number;\n\n constructor(outputLen: number) {\n super(64, outputLen, 8, false);\n }\n protected get(): [number, number, number, number, number, number, number, number] {\n const { A, B, C, D, E, F, G, H } = this;\n return [A, B, C, D, E, F, G, H];\n }\n // prettier-ignore\n protected set(\n A: number, B: number, C: number, D: number, E: number, F: number, G: number, H: number\n ): void {\n this.A = A | 0;\n this.B = B | 0;\n this.C = C | 0;\n this.D = D | 0;\n this.E = E | 0;\n this.F = F | 0;\n this.G = G | 0;\n this.H = H | 0;\n }\n protected process(view: DataView, offset: number): void {\n // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array\n for (let i = 0; i < 16; i++, offset += 4) SHA256_W[i] = view.getUint32(offset, false);\n for (let i = 16; i < 64; i++) {\n const W15 = SHA256_W[i - 15];\n const W2 = SHA256_W[i - 2];\n const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);\n const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);\n SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;\n }\n // Compression function main loop, 64 rounds\n let { A, B, C, D, E, F, G, H } = this;\n for (let i = 0; i < 64; i++) {\n const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);\n const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;\n const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);\n const T2 = (sigma0 + Maj(A, B, C)) | 0;\n H = G;\n G = F;\n F = E;\n E = (D + T1) | 0;\n D = C;\n C = B;\n B = A;\n A = (T1 + T2) | 0;\n }\n // Add the compressed chunk to the current hash value\n A = (A + this.A) | 0;\n B = (B + this.B) | 0;\n C = (C + this.C) | 0;\n D = (D + this.D) | 0;\n E = (E + this.E) | 0;\n F = (F + this.F) | 0;\n G = (G + this.G) | 0;\n H = (H + this.H) | 0;\n this.set(A, B, C, D, E, F, G, H);\n }\n protected roundClean(): void {\n clean(SHA256_W);\n }\n destroy(): void {\n // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves\n // update()/digest() callable on reused instances.\n this.destroyed = true;\n this.set(0, 0, 0, 0, 0, 0, 0, 0);\n clean(this.buffer);\n }\n}\n\n/** Internal SHA-256 hash class grounded in RFC 6234 §6.2. */\nexport class _SHA256 extends SHA2_32B<_SHA256> {\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n protected A: number = SHA256_IV[0] | 0;\n protected B: number = SHA256_IV[1] | 0;\n protected C: number = SHA256_IV[2] | 0;\n protected D: number = SHA256_IV[3] | 0;\n protected E: number = SHA256_IV[4] | 0;\n protected F: number = SHA256_IV[5] | 0;\n protected G: number = SHA256_IV[6] | 0;\n protected H: number = SHA256_IV[7] | 0;\n constructor() {\n super(32);\n }\n}\n\n/** Internal SHA-224 hash class grounded in RFC 6234 §6.2 and §8.5. */\nexport class _SHA224 extends SHA2_32B<_SHA224> {\n protected A: number = SHA224_IV[0] | 0;\n protected B: number = SHA224_IV[1] | 0;\n protected C: number = SHA224_IV[2] | 0;\n protected D: number = SHA224_IV[3] | 0;\n protected E: number = SHA224_IV[4] | 0;\n protected F: number = SHA224_IV[5] | 0;\n protected G: number = SHA224_IV[6] | 0;\n protected H: number = SHA224_IV[7] | 0;\n constructor() {\n super(28);\n }\n}\n\n// SHA2-512 is slower than sha256 in js because u64 operations are slow.\n\n// SHA-384 / SHA-512 round constants from RFC 6234 §5.2:\n// 80 full 64-bit words split into high/low halves.\n// prettier-ignore\nconst K512 = /* @__PURE__ */ (() => u64.split([\n '0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc',\n '0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118',\n '0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2',\n '0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694',\n '0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65',\n '0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5',\n '0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4',\n '0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70',\n '0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df',\n '0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b',\n '0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30',\n '0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8',\n '0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8',\n '0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3',\n '0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec',\n '0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b',\n '0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178',\n '0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b',\n '0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c',\n '0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817'\n].map(n => BigInt(n))))();\nconst SHA512_Kh = /* @__PURE__ */ (() => K512[0])();\nconst SHA512_Kl = /* @__PURE__ */ (() => K512[1])();\n\n// Reusable high-half schedule buffer for the RFC 6234 §6.4 64-bit `W_t` words.\nconst SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);\n// Reusable low-half schedule buffer for the RFC 6234 §6.4 64-bit `W_t` words.\nconst SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);\n\n/** Internal SHA-384 / SHA-512 compression engine from RFC 6234 §6.4. */\nabstract class SHA2_64B<T extends SHA2_64B<T>> extends HashMD<T> {\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n // h -- high 32 bits, l -- low 32 bits\n protected abstract Ah: number;\n protected abstract Al: number;\n protected abstract Bh: number;\n protected abstract Bl: number;\n protected abstract Ch: number;\n protected abstract Cl: number;\n protected abstract Dh: number;\n protected abstract Dl: number;\n protected abstract Eh: number;\n protected abstract El: number;\n protected abstract Fh: number;\n protected abstract Fl: number;\n protected abstract Gh: number;\n protected abstract Gl: number;\n protected abstract Hh: number;\n protected abstract Hl: number;\n\n constructor(outputLen: number) {\n super(128, outputLen, 16, false);\n }\n // prettier-ignore\n protected get(): [\n number, number, number, number, number, number, number, number,\n number, number, number, number, number, number, number, number\n ] {\n const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;\n return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];\n }\n // prettier-ignore\n protected set(\n Ah: number, Al: number, Bh: number, Bl: number, Ch: number, Cl: number, Dh: number, Dl: number,\n Eh: number, El: number, Fh: number, Fl: number, Gh: number, Gl: number, Hh: number, Hl: number\n ): void {\n this.Ah = Ah | 0;\n this.Al = Al | 0;\n this.Bh = Bh | 0;\n this.Bl = Bl | 0;\n this.Ch = Ch | 0;\n this.Cl = Cl | 0;\n this.Dh = Dh | 0;\n this.Dl = Dl | 0;\n this.Eh = Eh | 0;\n this.El = El | 0;\n this.Fh = Fh | 0;\n this.Fl = Fl | 0;\n this.Gh = Gh | 0;\n this.Gl = Gl | 0;\n this.Hh = Hh | 0;\n this.Hl = Hl | 0;\n }\n protected process(view: DataView, offset: number): void {\n // Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array\n for (let i = 0; i < 16; i++, offset += 4) {\n SHA512_W_H[i] = view.getUint32(offset);\n SHA512_W_L[i] = view.getUint32((offset += 4));\n }\n for (let i = 16; i < 80; i++) {\n // s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7)\n const W15h = SHA512_W_H[i - 15] | 0;\n const W15l = SHA512_W_L[i - 15] | 0;\n const s0h = u64.rotrSH(W15h, W15l, 1) ^ u64.rotrSH(W15h, W15l, 8) ^ u64.shrSH(W15h, W15l, 7);\n const s0l = u64.rotrSL(W15h, W15l, 1) ^ u64.rotrSL(W15h, W15l, 8) ^ u64.shrSL(W15h, W15l, 7);\n // s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6)\n const W2h = SHA512_W_H[i - 2] | 0;\n const W2l = SHA512_W_L[i - 2] | 0;\n const s1h = u64.rotrSH(W2h, W2l, 19) ^ u64.rotrBH(W2h, W2l, 61) ^ u64.shrSH(W2h, W2l, 6);\n const s1l = u64.rotrSL(W2h, W2l, 19) ^ u64.rotrBL(W2h, W2l, 61) ^ u64.shrSL(W2h, W2l, 6);\n // SHA512_W[i] = s0 + s1 + SHA512_W[i - 7] + SHA512_W[i - 16];\n const SUMl = u64.add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);\n const SUMh = u64.add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);\n SHA512_W_H[i] = SUMh | 0;\n SHA512_W_L[i] = SUMl | 0;\n }\n let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;\n // Compression function main loop, 80 rounds\n for (let i = 0; i < 80; i++) {\n // S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41)\n const sigma1h = u64.rotrSH(Eh, El, 14) ^ u64.rotrSH(Eh, El, 18) ^ u64.rotrBH(Eh, El, 41);\n const sigma1l = u64.rotrSL(Eh, El, 14) ^ u64.rotrSL(Eh, El, 18) ^ u64.rotrBL(Eh, El, 41);\n //const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;\n const CHIh = (Eh & Fh) ^ (~Eh & Gh);\n const CHIl = (El & Fl) ^ (~El & Gl);\n // T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i]\n // prettier-ignore\n const T1ll = u64.add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);\n const T1h = u64.add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);\n const T1l = T1ll | 0;\n // S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39)\n const sigma0h = u64.rotrSH(Ah, Al, 28) ^ u64.rotrBH(Ah, Al, 34) ^ u64.rotrBH(Ah, Al, 39);\n const sigma0l = u64.rotrSL(Ah, Al, 28) ^ u64.rotrBL(Ah, Al, 34) ^ u64.rotrBL(Ah, Al, 39);\n const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch);\n const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl);\n Hh = Gh | 0;\n Hl = Gl | 0;\n Gh = Fh | 0;\n Gl = Fl | 0;\n Fh = Eh | 0;\n Fl = El | 0;\n ({ h: Eh, l: El } = u64.add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));\n Dh = Ch | 0;\n Dl = Cl | 0;\n Ch = Bh | 0;\n Cl = Bl | 0;\n Bh = Ah | 0;\n Bl = Al | 0;\n const All = u64.add3L(T1l, sigma0l, MAJl);\n Ah = u64.add3H(All, T1h, sigma0h, MAJh);\n Al = All | 0;\n }\n // Add the compressed chunk to the current hash value\n ({ h: Ah, l: Al } = u64.add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));\n ({ h: Bh, l: Bl } = u64.add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));\n ({ h: Ch, l: Cl } = u64.add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));\n ({ h: Dh, l: Dl } = u64.add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));\n ({ h: Eh, l: El } = u64.add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));\n ({ h: Fh, l: Fl } = u64.add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));\n ({ h: Gh, l: Gl } = u64.add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));\n ({ h: Hh, l: Hl } = u64.add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));\n this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);\n }\n protected roundClean(): void {\n clean(SHA512_W_H, SHA512_W_L);\n }\n destroy(): void {\n // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves\n // update()/digest() callable on reused instances.\n this.destroyed = true;\n clean(this.buffer);\n this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);\n }\n}\n\n/** Internal SHA-512 hash class grounded in RFC 6234 §6.3 and §6.4. */\nexport class _SHA512 extends SHA2_64B<_SHA512> {\n protected Ah: number = SHA512_IV[0] | 0;\n protected Al: number = SHA512_IV[1] | 0;\n protected Bh: number = SHA512_IV[2] | 0;\n protected Bl: number = SHA512_IV[3] | 0;\n protected Ch: number = SHA512_IV[4] | 0;\n protected Cl: number = SHA512_IV[5] | 0;\n protected Dh: number = SHA512_IV[6] | 0;\n protected Dl: number = SHA512_IV[7] | 0;\n protected Eh: number = SHA512_IV[8] | 0;\n protected El: number = SHA512_IV[9] | 0;\n protected Fh: number = SHA512_IV[10] | 0;\n protected Fl: number = SHA512_IV[11] | 0;\n protected Gh: number = SHA512_IV[12] | 0;\n protected Gl: number = SHA512_IV[13] | 0;\n protected Hh: number = SHA512_IV[14] | 0;\n protected Hl: number = SHA512_IV[15] | 0;\n\n constructor() {\n super(64);\n }\n}\n\n/** Internal SHA-384 hash class grounded in RFC 6234 §6.3 and §6.4. */\nexport class _SHA384 extends SHA2_64B<_SHA384> {\n protected Ah: number = SHA384_IV[0] | 0;\n protected Al: number = SHA384_IV[1] | 0;\n protected Bh: number = SHA384_IV[2] | 0;\n protected Bl: number = SHA384_IV[3] | 0;\n protected Ch: number = SHA384_IV[4] | 0;\n protected Cl: number = SHA384_IV[5] | 0;\n protected Dh: number = SHA384_IV[6] | 0;\n protected Dl: number = SHA384_IV[7] | 0;\n protected Eh: number = SHA384_IV[8] | 0;\n protected El: number = SHA384_IV[9] | 0;\n protected Fh: number = SHA384_IV[10] | 0;\n protected Fl: number = SHA384_IV[11] | 0;\n protected Gh: number = SHA384_IV[12] | 0;\n protected Gl: number = SHA384_IV[13] | 0;\n protected Hh: number = SHA384_IV[14] | 0;\n protected Hl: number = SHA384_IV[15] | 0;\n\n constructor() {\n super(48);\n }\n}\n\n/**\n * Truncated SHA512/256 and SHA512/224.\n * SHA512_IV is XORed with 0xa5a5a5a5a5a5a5a5, then used as \"intermediary\" IV of SHA512/t.\n * Then t hashes string to produce result IV.\n * See the repo-side derivation recipe in `test/misc/sha2-gen-iv.js`.\n * These IV literals are checked against that script rather than a dedicated\n * local RFC section.\n */\n\n/** SHA-512/224 IV derived by the SHA-512/t recipe in `test/misc/sha2-gen-iv.js` and\n * stored as sixteen big-endian 32-bit halves. */\nconst T224_IV = /* @__PURE__ */ Uint32Array.from([\n 0x8c3d37c8, 0x19544da2, 0x73e19966, 0x89dcd4d6, 0x1dfab7ae, 0x32ff9c82, 0x679dd514, 0x582f9fcf,\n 0x0f6d2b69, 0x7bd44da8, 0x77e36f73, 0x04c48942, 0x3f9d85a8, 0x6a1d36c8, 0x1112e6ad, 0x91d692a1,\n]);\n\n/** SHA-512/256 IV derived by the SHA-512/t recipe in `test/misc/sha2-gen-iv.js` and\n * stored as sixteen big-endian 32-bit halves. */\nconst T256_IV = /* @__PURE__ */ Uint32Array.from([\n 0x22312194, 0xfc2bf72c, 0x9f555fa3, 0xc84c64c2, 0x2393b86b, 0x6f53b151, 0x96387719, 0x5940eabd,\n 0x96283ee2, 0xa88effe3, 0xbe5e1e25, 0x53863992, 0x2b0199fc, 0x2c85b8aa, 0x0eb72ddc, 0x81c52ca2,\n]);\n\n/** Internal SHA-512/224 hash class using the derived `T224_IV` and the shared\n * RFC 6234 §6.4 compression engine. */\nexport class _SHA512_224 extends SHA2_64B<_SHA512_224> {\n protected Ah: number = T224_IV[0] | 0;\n protected Al: number = T224_IV[1] | 0;\n protected Bh: number = T224_IV[2] | 0;\n protected Bl: number = T224_IV[3] | 0;\n protected Ch: number = T224_IV[4] | 0;\n protected Cl: number = T224_IV[5] | 0;\n protected Dh: number = T224_IV[6] | 0;\n protected Dl: number = T224_IV[7] | 0;\n protected Eh: number = T224_IV[8] | 0;\n protected El: number = T224_IV[9] | 0;\n protected Fh: number = T224_IV[10] | 0;\n protected Fl: number = T224_IV[11] | 0;\n protected Gh: number = T224_IV[12] | 0;\n protected Gl: number = T224_IV[13] | 0;\n protected Hh: number = T224_IV[14] | 0;\n protected Hl: number = T224_IV[15] | 0;\n\n constructor() {\n super(28);\n }\n}\n\n/** Internal SHA-512/256 hash class using the derived `T256_IV` and the shared\n * RFC 6234 §6.4 compression engine. */\nexport class _SHA512_256 extends SHA2_64B<_SHA512_256> {\n protected Ah: number = T256_IV[0] | 0;\n protected Al: number = T256_IV[1] | 0;\n protected Bh: number = T256_IV[2] | 0;\n protected Bl: number = T256_IV[3] | 0;\n protected Ch: number = T256_IV[4] | 0;\n protected Cl: number = T256_IV[5] | 0;\n protected Dh: number = T256_IV[6] | 0;\n protected Dl: number = T256_IV[7] | 0;\n protected Eh: number = T256_IV[8] | 0;\n protected El: number = T256_IV[9] | 0;\n protected Fh: number = T256_IV[10] | 0;\n protected Fl: number = T256_IV[11] | 0;\n protected Gh: number = T256_IV[12] | 0;\n protected Gl: number = T256_IV[13] | 0;\n protected Hh: number = T256_IV[14] | 0;\n protected Hl: number = T256_IV[15] | 0;\n\n constructor() {\n super(32);\n }\n}\n\n/**\n * SHA2-256 hash function from RFC 4634. In JS it's the fastest: even faster than Blake3. Some info:\n *\n * - Trying 2^128 hashes would get 50% chance of collision, using birthday attack.\n * - BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.\n * - Each sha256 hash is executing 2^18 bit operations.\n * - Good 2024 ASICs can do 200Th/sec with 3500 watts of power, corresponding to 2^36 hashes/joule.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-256.\n * ```ts\n * sha256(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha256: TRet<CHash<_SHA256>> = /* @__PURE__ */ createHasher(\n () => new _SHA256(),\n /* @__PURE__ */ oidNist(0x01)\n);\n/**\n * SHA2-224 hash function from RFC 4634.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-224.\n * ```ts\n * sha224(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha224: TRet<CHash<_SHA224>> = /* @__PURE__ */ createHasher(\n () => new _SHA224(),\n /* @__PURE__ */ oidNist(0x04)\n);\n\n/**\n * SHA2-512 hash function from RFC 4634.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-512.\n * ```ts\n * sha512(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha512: TRet<CHash<_SHA512>> = /* @__PURE__ */ createHasher(\n () => new _SHA512(),\n /* @__PURE__ */ oidNist(0x03)\n);\n/**\n * SHA2-384 hash function from RFC 4634.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-384.\n * ```ts\n * sha384(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha384: TRet<CHash<_SHA384>> = /* @__PURE__ */ createHasher(\n () => new _SHA384(),\n /* @__PURE__ */ oidNist(0x02)\n);\n\n/**\n * SHA2-512/256 \"truncated\" hash function, with improved resistance to length extension attacks.\n * See the paper on {@link https://eprint.iacr.org/2010/548.pdf | truncated SHA512}.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-512/256.\n * ```ts\n * sha512_256(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha512_256: TRet<CHash<_SHA512_256>> = /* @__PURE__ */ createHasher(\n () => new _SHA512_256(),\n /* @__PURE__ */ oidNist(0x06)\n);\n/**\n * SHA2-512/224 \"truncated\" hash function, with improved resistance to length extension attacks.\n * See the paper on {@link https://eprint.iacr.org/2010/548.pdf | truncated SHA512}.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-512/224.\n * ```ts\n * sha512_224(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha512_224: TRet<CHash<_SHA512_224>> = /* @__PURE__ */ createHasher(\n () => new _SHA512_224(),\n /* @__PURE__ */ oidNist(0x05)\n);\n","/**\n * token-engine/sdk.ts — the SINGLE place that imports @unicitylabs/state-transition-sdk.\n *\n * The v1 cut-over is done: the canonical package name now resolves to the v2 SDK\n * (the migration-era `state-transition-sdk-v2` npm alias is gone, and v1 with it).\n *\n * Everything else in token-engine/ imports SDK symbols from `./sdk`, never from the package directly.\n * ESLint `no-restricted-imports` forbids importing the SDK anywhere except this file.\n *\n * Import path note: subpaths are `…/lib/<path>.js` (no `/src/`); no root barrel.\n */\n\n// ── client / aggregator / proof / network / trust base ──────────────────────\nexport { StateTransitionClient } from '@unicitylabs/state-transition-sdk/lib/StateTransitionClient.js';\nexport { AggregatorClient } from '@unicitylabs/state-transition-sdk/lib/api/AggregatorClient.js';\nexport type { IAggregatorClient } from '@unicitylabs/state-transition-sdk/lib/api/IAggregatorClient.js';\nexport { NetworkId } from '@unicitylabs/state-transition-sdk/lib/api/NetworkId.js';\nexport { CertificationData } from '@unicitylabs/state-transition-sdk/lib/api/CertificationData.js';\nexport { CertificationResponse, CertificationStatus } from '@unicitylabs/state-transition-sdk/lib/api/CertificationResponse.js';\nexport { StateId } from '@unicitylabs/state-transition-sdk/lib/api/StateId.js';\nexport { InclusionProof } from '@unicitylabs/state-transition-sdk/lib/api/InclusionProof.js';\nexport { InclusionProofResponse } from '@unicitylabs/state-transition-sdk/lib/api/InclusionProofResponse.js';\nexport { RootTrustBase } from '@unicitylabs/state-transition-sdk/lib/api/bft/RootTrustBase.js';\nexport { waitInclusionProof } from '@unicitylabs/state-transition-sdk/lib/util/InclusionProofUtils.js';\nexport { InclusionProofVerificationStatus } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/rule/InclusionProofVerificationRule.js';\n\n// ── token / transactions ────────────────────────────────────────────────────\nexport { Token } from '@unicitylabs/state-transition-sdk/lib/transaction/Token.js';\nexport { MintTransaction } from '@unicitylabs/state-transition-sdk/lib/transaction/MintTransaction.js';\nexport { TransferTransaction } from '@unicitylabs/state-transition-sdk/lib/transaction/TransferTransaction.js';\nexport { CertifiedMintTransaction } from '@unicitylabs/state-transition-sdk/lib/transaction/CertifiedMintTransaction.js';\nexport { CertifiedTransferTransaction } from '@unicitylabs/state-transition-sdk/lib/transaction/CertifiedTransferTransaction.js';\nexport { TokenId } from '@unicitylabs/state-transition-sdk/lib/transaction/TokenId.js';\nexport { TokenType } from '@unicitylabs/state-transition-sdk/lib/transaction/TokenType.js';\nexport { TokenSalt } from '@unicitylabs/state-transition-sdk/lib/transaction/TokenSalt.js';\nexport type { ITransaction } from '@unicitylabs/state-transition-sdk/lib/transaction/ITransaction.js';\nexport { MintJustificationVerifierService } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/MintJustificationVerifierService.js';\n\n// ── predicates / unlock scripts ─────────────────────────────────────────────\nexport type { IPredicate } from '@unicitylabs/state-transition-sdk/lib/predicate/IPredicate.js';\nexport type { IUnlockScript } from '@unicitylabs/state-transition-sdk/lib/predicate/IUnlockScript.js';\nexport { EncodedPredicate } from '@unicitylabs/state-transition-sdk/lib/predicate/EncodedPredicate.js';\nexport { SignaturePredicate } from '@unicitylabs/state-transition-sdk/lib/predicate/builtin/SignaturePredicate.js';\nexport { SignaturePredicateUnlockScript } from '@unicitylabs/state-transition-sdk/lib/predicate/builtin/SignaturePredicateUnlockScript.js';\nexport { BurnPredicate } from '@unicitylabs/state-transition-sdk/lib/predicate/builtin/BurnPredicate.js';\nexport { PredicateVerifierService } from '@unicitylabs/state-transition-sdk/lib/predicate/verification/PredicateVerifierService.js';\n\n// ── crypto / hashing ────────────────────────────────────────────────────────\nexport { SigningService } from '@unicitylabs/state-transition-sdk/lib/crypto/secp256k1/SigningService.js';\nexport { Signature } from '@unicitylabs/state-transition-sdk/lib/crypto/secp256k1/Signature.js';\nexport { MintSigningService } from '@unicitylabs/state-transition-sdk/lib/crypto/MintSigningService.js';\nexport { HashAlgorithm } from '@unicitylabs/state-transition-sdk/lib/crypto/hash/HashAlgorithm.js';\nexport { DataHash } from '@unicitylabs/state-transition-sdk/lib/crypto/hash/DataHash.js';\nexport { DataHasher } from '@unicitylabs/state-transition-sdk/lib/crypto/hash/DataHasher.js';\nexport { DataHasherFactory } from '@unicitylabs/state-transition-sdk/lib/crypto/hash/DataHasherFactory.js';\n\n// ── CBOR serialization ──────────────────────────────────────────────────────\nexport { CborSerializer } from '@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborSerializer.js';\nexport { CborDeserializer } from '@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborDeserializer.js';\nexport { CborError } from '@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborError.js';\n\n// ── payment / value / split ─────────────────────────────────────────────────\nexport type { IPaymentData } from '@unicitylabs/state-transition-sdk/lib/payment/IPaymentData.js';\nexport { Asset } from '@unicitylabs/state-transition-sdk/lib/payment/asset/Asset.js';\nexport { AssetId } from '@unicitylabs/state-transition-sdk/lib/payment/asset/AssetId.js';\nexport { PaymentAssetCollection } from '@unicitylabs/state-transition-sdk/lib/payment/asset/PaymentAssetCollection.js';\nexport { TokenSplit } from '@unicitylabs/state-transition-sdk/lib/payment/TokenSplit.js';\nexport { SplitTokenRequest } from '@unicitylabs/state-transition-sdk/lib/payment/SplitTokenRequest.js';\nexport { SplitToken } from '@unicitylabs/state-transition-sdk/lib/payment/SplitToken.js';\nexport { SplitAssetProof } from '@unicitylabs/state-transition-sdk/lib/payment/SplitAssetProof.js';\nexport { SplitMintJustification } from '@unicitylabs/state-transition-sdk/lib/payment/SplitMintJustification.js';\nexport { SplitMintJustificationVerifier } from '@unicitylabs/state-transition-sdk/lib/payment/SplitMintJustificationVerifier.js';\n\n// ── verification result types ───────────────────────────────────────────────\nexport { VerificationStatus } from '@unicitylabs/state-transition-sdk/lib/verification/VerificationStatus.js';\nexport { VerificationResult } from '@unicitylabs/state-transition-sdk/lib/verification/VerificationResult.js';\n\n// ── unicity-id (nametag) ────────────────────────────────────────────────────\nexport { UnicityId } from '@unicitylabs/state-transition-sdk/lib/unicity-id/UnicityId.js';\nexport { UnicityIdMintTransaction } from '@unicitylabs/state-transition-sdk/lib/unicity-id/UnicityIdMintTransaction.js';\nexport { CertifiedUnicityIdMintTransaction } from '@unicitylabs/state-transition-sdk/lib/unicity-id/CertifiedUnicityIdMintTransaction.js';\nexport { UnicityIdToken } from '@unicitylabs/state-transition-sdk/lib/unicity-id/UnicityIdToken.js';\n\n// ── util ────────────────────────────────────────────────────────────────────\nexport { HexConverter } from '@unicitylabs/state-transition-sdk/lib/util/HexConverter.js';\nexport { BigintConverter } from '@unicitylabs/state-transition-sdk/lib/util/BigintConverter.js';\nexport { BitString } from '@unicitylabs/state-transition-sdk/lib/util/BitString.js';\n","/**\n * token-engine/token-blob.ts — storage/transport codec for a wallet token.\n *\n * A {@link TokenBlob} is `{ v, network, tokenId, token }` where `token` is the v2\n * `Token.toCBOR()` bytes and `tokenId` is the genesis-stable id (stored so dedup /\n * listing / tombstone keys need no engine call). This codec wraps it in a\n * sphere-private CBOR envelope so the wallet's own storage format can version\n * independently of the SDK's token CBOR. The decoded value is re-derivable from\n * `token`, so it is NOT stored here.\n */\n\nimport { CborDeserializer, CborError, CborSerializer } from './sdk';\nimport type { TokenBlob } from './types';\n\n/** Sphere-private CBOR tag (distinct from SpherePaymentData's 39050). */\nconst TOKEN_BLOB_TAG = 39051n;\n/** Current blob envelope version. */\nexport const TOKEN_BLOB_VERSION = 1;\n\n/** Encode a blob as `tag(39051)[ v, network, tokenId, token ]`. */\nexport function encodeTokenBlob(blob: TokenBlob): Uint8Array {\n return CborSerializer.encodeTag(\n TOKEN_BLOB_TAG,\n CborSerializer.encodeArray(\n CborSerializer.encodeUnsignedInteger(BigInt(blob.v)),\n CborSerializer.encodeUnsignedInteger(BigInt(blob.network)),\n CborSerializer.encodeTextString(blob.tokenId),\n CborSerializer.encodeByteString(blob.token),\n ),\n );\n}\n\n/** Decode a blob produced by {@link encodeTokenBlob}. */\nexport function decodeTokenBlob(bytes: Uint8Array): TokenBlob {\n const tag = CborDeserializer.decodeTag(bytes);\n if (tag.tag !== TOKEN_BLOB_TAG) {\n throw new CborError(`Invalid TokenBlob tag: ${tag.tag}`);\n }\n const fields = CborDeserializer.decodeArray(tag.data, 4);\n const v = Number(CborDeserializer.decodeUnsignedInteger(fields[0]));\n if (v !== TOKEN_BLOB_VERSION) {\n throw new CborError(`Unsupported TokenBlob version: ${v}`);\n }\n return {\n v,\n network: Number(CborDeserializer.decodeUnsignedInteger(fields[1])),\n tokenId: CborDeserializer.decodeTextString(fields[2]),\n token: CborDeserializer.decodeByteString(fields[3]),\n };\n}\n\n/**\n * The wallet-api WIRE bytes for a blob (ARCHITECTURE §5.2/§8.2): the backend\n * stores, content-addresses and validates the INNER `token` bytes (the v2\n * `Token.toCBOR()` form — `Token.fromCBOR` at §8.2 step 3). The sphere-private\n * 39051 envelope never crosses the §16 API. Tolerant on input: envelope bytes\n * unwrap to their inner `token` bytes; anything else is already wire format\n * and passes through. (The phase-2 harness caught the envelope leaking onto\n * the wire — the real backend 422s it at §8.2 step 3 with \"Invalid CBOR tag\n * for Token: 39051\"; only the test fake's matching wrongness had masked it.)\n */\nexport function unwrapTokenBlobBytes(bytes: Uint8Array): Uint8Array {\n try {\n return decodeTokenBlob(bytes).token;\n } catch {\n return bytes;\n }\n}\n","/**\n * Cryptographic utilities for SDK2\n *\n * Provides BIP39 mnemonic and BIP32 key derivation functions.\n * Platform-independent - no browser-specific APIs.\n */\n\nimport * as bip39 from 'bip39';\nimport CryptoJS from 'crypto-js';\nimport elliptic from 'elliptic';\nimport { encodeBech32 } from './bech32';\nimport { SphereError } from './errors';\n\n// =============================================================================\n// Constants\n// =============================================================================\n\nconst ec = new elliptic.ec('secp256k1');\n\n/** secp256k1 curve order */\nconst CURVE_ORDER = BigInt(\n '0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141'\n);\n\n/** Default derivation path for Unicity (BIP44) */\nexport const DEFAULT_DERIVATION_PATH = \"m/44'/0'/0'\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface MasterKey {\n privateKey: string;\n chainCode: string;\n}\n\nexport interface DerivedKey {\n privateKey: string;\n chainCode: string;\n}\n\nexport interface KeyPair {\n privateKey: string;\n publicKey: string;\n}\n\nexport interface AddressInfo extends KeyPair {\n address: string;\n path: string;\n index: number;\n}\n\n// =============================================================================\n// BIP39 Mnemonic Functions\n// =============================================================================\n\n/**\n * Generate a new BIP39 mnemonic phrase\n * @param strength - Entropy bits (128 = 12 words, 256 = 24 words)\n */\nexport function generateMnemonic(strength: 128 | 256 = 128): string {\n return bip39.generateMnemonic(strength);\n}\n\n/**\n * Validate a BIP39 mnemonic phrase\n */\nexport function validateMnemonic(mnemonic: string): boolean {\n return bip39.validateMnemonic(mnemonic);\n}\n\n/**\n * Convert mnemonic to seed (64-byte hex string)\n * @param mnemonic - BIP39 mnemonic phrase\n * @param passphrase - Optional passphrase for additional security\n */\nexport async function mnemonicToSeed(\n mnemonic: string,\n passphrase: string = ''\n): Promise<string> {\n const seedBuffer = await bip39.mnemonicToSeed(mnemonic, passphrase);\n return Buffer.from(seedBuffer).toString('hex');\n}\n\n/**\n * Synchronous version of mnemonicToSeed\n */\nexport function mnemonicToSeedSync(\n mnemonic: string,\n passphrase: string = ''\n): string {\n const seedBuffer = bip39.mnemonicToSeedSync(mnemonic, passphrase);\n return Buffer.from(seedBuffer).toString('hex');\n}\n\n/**\n * Convert mnemonic to entropy (for recovery purposes)\n */\nexport function mnemonicToEntropy(mnemonic: string): string {\n return bip39.mnemonicToEntropy(mnemonic);\n}\n\n/**\n * Convert entropy to mnemonic\n */\nexport function entropyToMnemonic(entropy: string): string {\n return bip39.entropyToMnemonic(entropy);\n}\n\n// =============================================================================\n// BIP32 Key Derivation\n// =============================================================================\n\n/**\n * Generate master key from seed (BIP32 standard)\n * Uses HMAC-SHA512 with key \"Bitcoin seed\"\n */\nexport function generateMasterKey(seedHex: string): MasterKey {\n const I = CryptoJS.HmacSHA512(\n CryptoJS.enc.Hex.parse(seedHex),\n CryptoJS.enc.Utf8.parse('Bitcoin seed')\n ).toString();\n\n const IL = I.substring(0, 64); // Left 32 bytes - master private key\n const IR = I.substring(64); // Right 32 bytes - master chain code\n\n // Validate master key\n const masterKeyBigInt = BigInt('0x' + IL);\n if (masterKeyBigInt === 0n || masterKeyBigInt >= CURVE_ORDER) {\n throw new SphereError('Invalid master key generated', 'VALIDATION_ERROR');\n }\n\n return {\n privateKey: IL,\n chainCode: IR,\n };\n}\n\n/**\n * Derive child key using BIP32 standard\n * @param parentPrivKey - Parent private key (64 hex chars)\n * @param parentChainCode - Parent chain code (64 hex chars)\n * @param index - Child index (>= 0x80000000 for hardened)\n */\nexport function deriveChildKey(\n parentPrivKey: string,\n parentChainCode: string,\n index: number\n): DerivedKey {\n const isHardened = index >= 0x80000000;\n let data: string;\n\n if (isHardened) {\n // Hardened derivation: 0x00 || parentPrivKey || index\n const indexHex = index.toString(16).padStart(8, '0');\n data = '00' + parentPrivKey + indexHex;\n } else {\n // Non-hardened derivation: compressedPubKey || index\n const keyPair = ec.keyFromPrivate(parentPrivKey, 'hex');\n const compressedPubKey = keyPair.getPublic(true, 'hex');\n const indexHex = index.toString(16).padStart(8, '0');\n data = compressedPubKey + indexHex;\n }\n\n // HMAC-SHA512 with chain code as key\n const I = CryptoJS.HmacSHA512(\n CryptoJS.enc.Hex.parse(data),\n CryptoJS.enc.Hex.parse(parentChainCode)\n ).toString();\n\n const IL = I.substring(0, 64); // Left 32 bytes\n const IR = I.substring(64); // Right 32 bytes (new chain code)\n\n // Add IL to parent key mod n (curve order)\n const ilBigInt = BigInt('0x' + IL);\n const parentKeyBigInt = BigInt('0x' + parentPrivKey);\n\n // Check IL is valid (less than curve order)\n if (ilBigInt >= CURVE_ORDER) {\n throw new SphereError('Invalid key: IL >= curve order', 'VALIDATION_ERROR');\n }\n\n const childKeyBigInt = (ilBigInt + parentKeyBigInt) % CURVE_ORDER;\n\n // Check child key is valid (not zero)\n if (childKeyBigInt === 0n) {\n throw new SphereError('Invalid key: child key is zero', 'VALIDATION_ERROR');\n }\n\n const childPrivKey = childKeyBigInt.toString(16).padStart(64, '0');\n\n return {\n privateKey: childPrivKey,\n chainCode: IR,\n };\n}\n\n/**\n * Derive key at a full BIP32/BIP44 path\n * @param masterPrivKey - Master private key\n * @param masterChainCode - Master chain code\n * @param path - BIP44 path like \"m/44'/0'/0'/0/0\"\n */\nexport function deriveKeyAtPath(\n masterPrivKey: string,\n masterChainCode: string,\n path: string\n): DerivedKey {\n const pathParts = path.replace('m/', '').split('/');\n\n let currentKey = masterPrivKey;\n let currentChainCode = masterChainCode;\n\n for (const part of pathParts) {\n const isHardened = part.endsWith(\"'\") || part.endsWith('h');\n const indexStr = part.replace(/['h]$/, '');\n let index = parseInt(indexStr, 10);\n\n if (isHardened) {\n index += 0x80000000; // Add hardened offset\n }\n\n const derived = deriveChildKey(currentKey, currentChainCode, index);\n currentKey = derived.privateKey;\n currentChainCode = derived.chainCode;\n }\n\n return {\n privateKey: currentKey,\n chainCode: currentChainCode,\n };\n}\n\n// =============================================================================\n// Key Pair Operations\n// =============================================================================\n\n/**\n * Get public key from private key\n * @param privateKey - Private key as hex string\n * @param compressed - Return compressed public key (default: true)\n */\nexport function getPublicKey(privateKey: string, compressed: boolean = true): string {\n const keyPair = ec.keyFromPrivate(privateKey, 'hex');\n return keyPair.getPublic(compressed, 'hex');\n}\n\n/**\n * Create key pair from private key\n */\nexport function createKeyPair(privateKey: string): KeyPair {\n return {\n privateKey,\n publicKey: getPublicKey(privateKey),\n };\n}\n\n// =============================================================================\n// Hash Functions\n// =============================================================================\n\n/**\n * Compute SHA256 hash\n */\nexport function sha256(data: string, inputEncoding: 'hex' | 'utf8' = 'hex'): string {\n const parsed =\n inputEncoding === 'hex'\n ? CryptoJS.enc.Hex.parse(data)\n : CryptoJS.enc.Utf8.parse(data);\n return CryptoJS.SHA256(parsed).toString();\n}\n\n/**\n * Compute RIPEMD160 hash\n */\nexport function ripemd160(data: string, inputEncoding: 'hex' | 'utf8' = 'hex'): string {\n const parsed =\n inputEncoding === 'hex'\n ? CryptoJS.enc.Hex.parse(data)\n : CryptoJS.enc.Utf8.parse(data);\n return CryptoJS.RIPEMD160(parsed).toString();\n}\n\n/**\n * Compute HASH160 (SHA256 -> RIPEMD160)\n */\nexport function hash160(data: string): string {\n const sha = sha256(data, 'hex');\n return ripemd160(sha, 'hex');\n}\n\n/**\n * Compute double SHA256\n */\nexport function doubleSha256(data: string, inputEncoding: 'hex' | 'utf8' = 'hex'): string {\n const first = sha256(data, inputEncoding);\n return sha256(first, 'hex');\n}\n\n/**\n * Alias for hash160 (L1 SDK compatibility)\n */\nexport const computeHash160 = hash160;\n\n/**\n * Convert hex string to Uint8Array for witness program\n */\nexport function hash160ToBytes(hash160Hex: string): Uint8Array {\n const matches = hash160Hex.match(/../g);\n if (!matches) return new Uint8Array(0);\n return Uint8Array.from(matches.map((x) => parseInt(x, 16)));\n}\n\n/**\n * Generate bech32 address from public key\n * @param publicKey - Compressed public key as hex string\n * @param prefix - Address prefix (default: \"alpha\")\n * @param witnessVersion - Witness version (default: 0 for P2WPKH)\n * @returns Bech32 encoded address\n */\nexport function publicKeyToAddress(\n publicKey: string,\n prefix: string = 'alpha',\n witnessVersion: number = 0\n): string {\n const pubKeyHash = hash160(publicKey);\n const programBytes = hash160ToBytes(pubKeyHash);\n return encodeBech32(prefix, witnessVersion, programBytes);\n}\n\n/**\n * Get address info from private key\n */\nexport function privateKeyToAddressInfo(\n privateKey: string,\n prefix: string = 'alpha'\n): { address: string; publicKey: string } {\n const publicKey = getPublicKey(privateKey);\n const address = publicKeyToAddress(publicKey, prefix);\n return { address, publicKey };\n}\n\n// =============================================================================\n// Utility Functions\n// =============================================================================\n\n/**\n * Convert hex string to Uint8Array\n */\nexport function hexToBytes(hex: string): Uint8Array {\n const matches = hex.match(/../g);\n if (!matches) {\n return new Uint8Array(0);\n }\n return Uint8Array.from(matches.map((x) => parseInt(x, 16)));\n}\n\n/**\n * Convert Uint8Array to hex string\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/**\n * Generate random bytes as hex string\n */\nexport function randomBytes(length: number): string {\n const words = CryptoJS.lib.WordArray.random(length);\n return words.toString(CryptoJS.enc.Hex);\n}\n\n// =============================================================================\n// High-Level Functions\n// =============================================================================\n\n/**\n * Generate identity from mnemonic\n * Returns master key derived from mnemonic seed\n */\nexport async function identityFromMnemonic(\n mnemonic: string,\n passphrase: string = ''\n): Promise<MasterKey> {\n if (!validateMnemonic(mnemonic)) {\n throw new SphereError('Invalid mnemonic phrase', 'INVALID_IDENTITY');\n }\n const seedHex = await mnemonicToSeed(mnemonic, passphrase);\n return generateMasterKey(seedHex);\n}\n\n/**\n * Synchronous version of identityFromMnemonic\n */\nexport function identityFromMnemonicSync(\n mnemonic: string,\n passphrase: string = ''\n): MasterKey {\n if (!validateMnemonic(mnemonic)) {\n throw new SphereError('Invalid mnemonic phrase', 'INVALID_IDENTITY');\n }\n const seedHex = mnemonicToSeedSync(mnemonic, passphrase);\n return generateMasterKey(seedHex);\n}\n\n/**\n * Derive address info at a specific path\n * @param masterKey - Master key with privateKey and chainCode\n * @param basePath - Base derivation path (e.g., \"m/44'/0'/0'\")\n * @param index - Address index\n * @param isChange - Whether this is a change address (chain 1 vs 0)\n * @param prefix - Address prefix (default: \"alpha\")\n */\nexport function deriveAddressInfo(\n masterKey: MasterKey,\n basePath: string,\n index: number,\n isChange: boolean = false,\n prefix: string = 'alpha'\n): AddressInfo {\n const chain = isChange ? 1 : 0;\n const fullPath = `${basePath}/${chain}/${index}`;\n\n const derived = deriveKeyAtPath(masterKey.privateKey, masterKey.chainCode, fullPath);\n const publicKey = getPublicKey(derived.privateKey);\n const address = publicKeyToAddress(publicKey, prefix);\n\n return {\n privateKey: derived.privateKey,\n publicKey,\n address,\n path: fullPath,\n index,\n };\n}\n\n/**\n * Generate full address info from private key with index and path\n * (L1 SDK compatibility)\n */\nexport function generateAddressInfo(\n privateKey: string,\n index: number,\n path: string,\n prefix: string = 'alpha'\n): AddressInfo {\n const { address, publicKey } = privateKeyToAddressInfo(privateKey, prefix);\n return {\n privateKey,\n publicKey,\n address,\n path,\n index,\n };\n}\n\n// =============================================================================\n// Message Signing (secp256k1 ECDSA with recoverable signature)\n// =============================================================================\n\n/** Prefix prepended to all signed messages (Bitcoin-like signed message format) */\nexport const SIGN_MESSAGE_PREFIX = 'Sphere Signed Message:\\n';\n\n/** Encode an integer as a Bitcoin-style compact varint */\nfunction varint(n: number): Uint8Array {\n if (n < 253) return new Uint8Array([n]);\n const buf = new Uint8Array(3);\n buf[0] = 253;\n buf[1] = n & 0xff;\n buf[2] = (n >> 8) & 0xff;\n return buf;\n}\n\n/**\n * Hash a message for signing using the Bitcoin-like double-SHA256 scheme:\n * SHA256(SHA256(varint(prefix.length) + prefix + varint(msg.length) + msg))\n *\n * @returns 64-char lowercase hex hash\n */\nexport function hashSignMessage(message: string): string {\n const prefix = new TextEncoder().encode(SIGN_MESSAGE_PREFIX);\n const msg = new TextEncoder().encode(message);\n const prefixLen = varint(prefix.length);\n const msgLen = varint(msg.length);\n const full = new Uint8Array(prefixLen.length + prefix.length + msgLen.length + msg.length);\n let off = 0;\n full.set(prefixLen, off); off += prefixLen.length;\n full.set(prefix, off); off += prefix.length;\n full.set(msgLen, off); off += msgLen.length;\n full.set(msg, off);\n const hex = Array.from(full).map(b => b.toString(16).padStart(2, '0')).join('');\n const h1 = CryptoJS.SHA256(CryptoJS.enc.Hex.parse(hex)).toString();\n return CryptoJS.SHA256(CryptoJS.enc.Hex.parse(h1)).toString();\n}\n\n/**\n * Sign a message with a secp256k1 private key.\n *\n * Returns a 130-character hex string: v (2 chars) + r (64 chars) + s (64 chars).\n * The recovery byte `v` is `31 + recoveryParam` (0-3).\n *\n * @param privateKeyHex - 64-char hex private key\n * @param message - plaintext message to sign\n */\nexport function signMessage(privateKeyHex: string, message: string): string {\n const keyPair = ec.keyFromPrivate(privateKeyHex, 'hex');\n const hashHex = hashSignMessage(message);\n const hashBytes = Buffer.from(hashHex, 'hex');\n const sig = keyPair.sign(hashBytes, { canonical: true });\n\n // Find recovery parameter\n const pub = keyPair.getPublic();\n let recoveryParam = -1;\n for (let i = 0; i < 4; i++) {\n try {\n if (ec.recoverPubKey(hashBytes, sig, i).eq(pub)) {\n recoveryParam = i;\n break;\n }\n } catch { /* try next */ }\n }\n if (recoveryParam === -1) {\n throw new SphereError('Could not find recovery parameter', 'SIGNING_ERROR');\n }\n\n const v = (31 + recoveryParam).toString(16).padStart(2, '0');\n const r = sig.r.toString('hex').padStart(64, '0');\n const s = sig.s.toString('hex').padStart(64, '0');\n return v + r + s;\n}\n\n/**\n * Verify a signed message against a compressed secp256k1 public key.\n *\n * @param message - The original plaintext message\n * @param signature - 130-char hex signature (v + r + s)\n * @param expectedPubkey - 66-char compressed public key hex\n * @returns `true` if the signature is valid and matches the expected public key\n */\nexport function verifySignedMessage(\n message: string,\n signature: string,\n expectedPubkey: string,\n): boolean {\n if (signature.length !== 130) return false;\n\n const v = parseInt(signature.slice(0, 2), 16) - 31;\n const r = signature.slice(2, 66);\n const s = signature.slice(66, 130);\n\n if (v < 0 || v > 3) return false;\n\n const hashHex = hashSignMessage(message);\n const hashBytes = Buffer.from(hashHex, 'hex');\n\n try {\n const recovered = ec.recoverPubKey(hashBytes, { r, s }, v);\n const recoveredHex = recovered.encode('hex', true); // compressed\n return recoveredHex === expectedPubkey;\n } catch {\n return false;\n }\n}\n\n/**\n * Recover the compressed secp256k1 public key from a signed message.\n *\n * Use this when the server needs to identify the signer (not just verify\n * a signature against a known pubkey). Combined with `sphere.resolve(pubkey)`\n * it gives a fully cryptographically-attributable identity for backend auth,\n * without trusting any client-supplied identifier claim.\n *\n * @param message - The plaintext that was signed\n * @param signature - 130-char hex (v + r + s) as produced by `signMessage`\n * @returns - Compressed 66-char hex pubkey\n * @throws - On malformed signature length or out-of-range recovery byte\n */\nexport function recoverPubkeyFromSignature(message: string, signature: string): string {\n if (signature.length !== 130) {\n throw new SphereError(\n `Invalid signature length: expected 130 hex chars, got ${signature.length}`,\n 'SIGNING_ERROR',\n );\n }\n\n const v = parseInt(signature.slice(0, 2), 16) - 31;\n const r = signature.slice(2, 66);\n const s = signature.slice(66, 130);\n\n if (v < 0 || v > 3) {\n throw new SphereError(\n `Invalid recovery byte: v=${v} out of range [0..3]`,\n 'SIGNING_ERROR',\n );\n }\n\n const hashHex = hashSignMessage(message);\n const hashBytes = Buffer.from(hashHex, 'hex');\n\n const recovered = ec.recoverPubKey(hashBytes, { r, s }, v);\n return recovered.encode('hex', true);\n}\n\n// Re-export elliptic instance for advanced use cases\nexport { ec };\n","/**\n * SDK Error Types\n *\n * Structured error codes for programmatic error handling in UI.\n * UI can switch on error.code to show appropriate user-facing messages.\n *\n * @example\n * ```ts\n * import { SphereError } from '@unicitylabs/sphere-sdk';\n *\n * try {\n * await sphere.payments.send({ ... });\n * } catch (err) {\n * if (err instanceof SphereError) {\n * switch (err.code) {\n * case 'INSUFFICIENT_BALANCE': showToast('Not enough funds'); break;\n * case 'INVALID_RECIPIENT': showToast('Recipient not found'); break;\n * case 'TRANSPORT_ERROR': showToast('Network connection issue'); break;\n * case 'TIMEOUT': showToast('Request timed out, try again'); break;\n * default: showToast(err.message);\n * }\n * }\n * }\n * ```\n */\n\nexport type SphereErrorCode =\n | 'NOT_INITIALIZED'\n | 'ALREADY_INITIALIZED'\n | 'INVALID_CONFIG'\n | 'INVALID_IDENTITY'\n | 'INSUFFICIENT_BALANCE'\n | 'INVALID_RECIPIENT'\n | 'TRANSFER_FAILED'\n // The source state was consumed by a DIFFERENT transaction (lost race, not a\n // resume) — raised as TransferConflictError (token-engine/errors.ts, Part E.2).\n | 'TRANSFER_CONFLICT'\n | 'STORAGE_ERROR'\n | 'TRANSPORT_ERROR'\n | 'AGGREGATOR_ERROR'\n | 'VALIDATION_ERROR'\n | 'NETWORK_ERROR'\n | 'TIMEOUT'\n | 'DECRYPTION_ERROR'\n | 'MODULE_NOT_AVAILABLE'\n | 'SIGNING_ERROR'\n // Token Spend Queue error codes\n | 'SEND_QUEUE_TIMEOUT'\n | 'SEND_INSUFFICIENT_BALANCE'\n | 'SEND_RESERVATION_CANCELLED'\n | 'SEND_QUEUE_FULL'\n | 'MODULE_DESTROYED'\n | 'REENTRANT_GATE'\n // Invoice / Accounting error codes\n | 'INVOICE_NO_TARGETS'\n | 'INVOICE_INVALID_ADDRESS'\n | 'INVOICE_NO_ASSETS'\n | 'INVOICE_INVALID_ASSET'\n | 'INVOICE_INVALID_AMOUNT'\n | 'INVOICE_INVALID_COIN'\n | 'INVOICE_INVALID_NFT'\n | 'INVOICE_PAST_DUE_DATE'\n | 'INVOICE_DUPLICATE_ADDRESS'\n | 'INVOICE_DUPLICATE_COIN'\n | 'INVOICE_DUPLICATE_NFT'\n | 'INVOICE_MINT_FAILED'\n | 'INVOICE_INVALID_PROOF'\n | 'INVOICE_WRONG_TOKEN_TYPE'\n | 'INVOICE_INVALID_DATA'\n | 'INVOICE_ALREADY_EXISTS'\n | 'INVOICE_NOT_FOUND'\n | 'INVOICE_NOT_TARGET'\n | 'INVOICE_ALREADY_CLOSED'\n | 'INVOICE_ALREADY_CANCELLED'\n | 'INVOICE_ORACLE_REQUIRED'\n | 'INVOICE_TERMINATED'\n | 'INVOICE_INVALID_TARGET'\n | 'INVOICE_INVALID_ASSET_INDEX'\n | 'INVOICE_RETURN_EXCEEDS_BALANCE'\n | 'INVOICE_INVALID_DELIVERY_METHOD'\n | 'INVOICE_INVALID_REFUND_ADDRESS'\n | 'INVOICE_INVALID_CONTACT'\n | 'INVOICE_INVALID_ID'\n | 'INVOICE_TOO_MANY_TARGETS'\n | 'INVOICE_TOO_MANY_ASSETS'\n | 'INVOICE_MEMO_TOO_LONG'\n | 'INVOICE_TERMS_TOO_LARGE'\n | 'INVOICE_NOT_TERMINATED'\n | 'INVOICE_NOT_CANCELLED'\n | 'INVOICE_STORAGE_FAILED'\n | 'RATE_LIMITED'\n | 'COMMUNICATIONS_UNAVAILABLE'\n // Swap error codes\n | 'SWAP_INVALID_DEAL'\n | 'SWAP_INVALID_MANIFEST'\n | 'SWAP_NOT_FOUND'\n | 'SWAP_WRONG_STATE'\n | 'SWAP_RESOLVE_FAILED'\n | 'SWAP_DM_SEND_FAILED'\n | 'SWAP_ESCROW_REJECTED'\n | 'SWAP_DEPOSIT_FAILED'\n | 'SWAP_PAYOUT_VERIFICATION_FAILED'\n | 'SWAP_ALREADY_EXISTS'\n | 'SWAP_ALREADY_COMPLETED'\n | 'SWAP_ALREADY_CANCELLED'\n | 'SWAP_TIMEOUT'\n | 'SWAP_LIMIT_EXCEEDED'\n | 'SWAP_ALREADY_INITIALIZED'\n | 'SWAP_MODULE_DESTROYED'\n | 'SWAP_NOT_INITIALIZED';\n\nexport class SphereError extends Error {\n readonly code: SphereErrorCode;\n readonly cause?: unknown;\n\n constructor(message: string, code: SphereErrorCode, cause?: unknown) {\n super(message);\n this.name = 'SphereError';\n this.code = code;\n this.cause = cause;\n }\n}\n\n/**\n * Type guard to check if an error is a SphereError\n */\nexport function isSphereError(err: unknown): err is SphereError {\n return err instanceof SphereError;\n}\n","/**\n * wallet-api/errors.ts — the client's typed error surface (S1).\n *\n * HTTP error mapping follows ARCHITECTURE §16: `{ error: { code, message } }`\n * with 401 auth · 403 ownership/addressee · 404 unknown · 409 conflict\n * (lineage/ownership) · 413 too large · 422 validation · 429 rate-limit/quota.\n */\n\nexport type WalletApiErrorCode =\n /** Construction/config problems (bad base URL, missing identity). */\n | 'CONFIG'\n /** The server challenge failed template verification — never signed. */\n | 'CHALLENGE_TEMPLATE'\n /** 401 — session invalid and re-auth also failed. */\n | 'UNAUTHORIZED'\n /** 403 — ownership/addressee check failed. */\n | 'FORBIDDEN'\n /** 404 — unknown resource. */\n | 'NOT_FOUND'\n /** 409 — lineage/ownership conflict (e.g. evidenced-tombstone re-add — §5.3). */\n | 'CONFLICT'\n /** 413 — blob too large. */\n | 'TOO_LARGE'\n /** 422 — validation failure (malformed body, failed §8.2 pipeline). */\n | 'VALIDATION'\n /** 429 — rate limit / quota. */\n | 'RATE_LIMITED'\n /** Transport-level failure (fetch threw, connection refused, …). */\n | 'NETWORK'\n /** The response did not match the §16 contract (parse/shape failure). */\n | 'PROTOCOL'\n /** Any other non-2xx status. */\n | 'SERVER';\n\nconst STATUS_TO_CODE: Record<number, WalletApiErrorCode> = {\n 401: 'UNAUTHORIZED',\n 403: 'FORBIDDEN',\n 404: 'NOT_FOUND',\n 409: 'CONFLICT',\n 413: 'TOO_LARGE',\n 422: 'VALIDATION',\n 429: 'RATE_LIMITED',\n};\n\nexport class WalletApiError extends Error {\n readonly code: WalletApiErrorCode;\n /** HTTP status when the error came from a response. */\n readonly status?: number;\n\n constructor(message: string, code: WalletApiErrorCode, status?: number, cause?: unknown) {\n super(message);\n this.name = 'WalletApiError';\n this.code = code;\n this.status = status;\n if (cause !== undefined) (this as { cause?: unknown }).cause = cause;\n }\n\n static fromStatus(status: number, message: string): WalletApiError {\n return new WalletApiError(message, STATUS_TO_CODE[status] ?? 'SERVER', status);\n }\n}\n\n/**\n * The auth challenge failed template verification (S1): wrong domain prefix,\n * foreign pubkey, or implausible timestamps. The spend key never signs\n * server-chosen text that fails this check.\n */\nexport class ChallengeTemplateError extends WalletApiError {\n constructor(message: string) {\n super(message, 'CHALLENGE_TEMPLATE');\n this.name = 'ChallengeTemplateError';\n }\n}\n","/**\n * wallet-api/challenge.ts — auth-challenge template verification (S1,\n * ARCHITECTURE §4).\n *\n * The spend key NEVER signs arbitrary server-chosen text. Before signing, the\n * client verifies the challenge:\n * 1. begins with the fixed domain-separation prefix\n * `unicity:wallet-api:auth:v1\\n`;\n * 2. embeds the client's OWN pubkey (and the nonce returned alongside it);\n * 3. carries plausible timestamps (`issuedAt` near now, `expiresAt` in the\n * future, a sane validity window).\n *\n * The accepted grammar matches the REAL backend (wallet-api M1,\n * src/auth/service.ts): the prefix followed by a single-line JSON object with\n * `network`, `pubkey`, `nonce`, `issuedAt`, `expiresAt` (ISO-8601). This\n * grammar is the client's acceptance contract: a server whose challenge does\n * not parse is refused, by design. The fake server\n * (tests/support/fake-wallet-api.ts) produces exactly this form.\n */\n\nimport { ChallengeTemplateError } from './errors';\n\n/** Fixed domain-separation prefix (ARCHITECTURE §4 step 1). */\nexport const AUTH_CHALLENGE_PREFIX = 'unicity:wallet-api:auth:v1\\n';\n\n/** Allowed clock skew between client and server (ms). */\nconst MAX_CLOCK_SKEW_MS = 5 * 60 * 1000;\n\n/** Maximum plausible challenge validity window (server default: NONCE_TTL = 5 min). */\nconst MAX_VALIDITY_WINDOW_MS = 60 * 60 * 1000;\n\nexport interface ChallengeExpectation {\n /** The client's own compressed pubkey hex — the challenge MUST embed it. */\n pubkey: string;\n /** The nonce returned by `POST /v1/auth/challenge` alongside the challenge. */\n nonce: string;\n /** The client's network — refused if the challenge names a different one. */\n network: string;\n /** Current time, ms since epoch. */\n nowMs: number;\n}\n\nfunction parseFields(body: string): Map<string, string> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(body);\n } catch {\n throw new ChallengeTemplateError('Challenge body is not the single-line JSON object the backend emits');\n }\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw new ChallengeTemplateError('Challenge body must be a JSON object');\n }\n const fields = new Map<string, string>();\n for (const [key, value] of Object.entries(parsed)) {\n if (typeof value !== 'string') {\n throw new ChallengeTemplateError(`Challenge field \"${key}\" must be a string`);\n }\n fields.set(key, value);\n }\n return fields;\n}\n\nfunction requireField(fields: Map<string, string>, key: string): string {\n const value = fields.get(key);\n if (value === undefined || value === '') {\n throw new ChallengeTemplateError(`Challenge is missing the \"${key}\" field`);\n }\n return value;\n}\n\nfunction parseTimestamp(value: string, key: string): number {\n const ms = Date.parse(value);\n if (Number.isNaN(ms)) {\n throw new ChallengeTemplateError(`Challenge \"${key}\" is not a parseable timestamp: ${value}`);\n }\n return ms;\n}\n\n/**\n * Verify a server auth challenge before signing. Throws\n * {@link ChallengeTemplateError} on ANY violation — the caller MUST refuse to\n * sign in that case.\n */\nexport function verifyChallengeTemplate(challenge: string, expect: ChallengeExpectation): void {\n if (typeof challenge !== 'string' || !challenge.startsWith(AUTH_CHALLENGE_PREFIX)) {\n throw new ChallengeTemplateError('Challenge does not start with the unicity:wallet-api:auth:v1 domain prefix');\n }\n const fields = parseFields(challenge.slice(AUTH_CHALLENGE_PREFIX.length));\n\n const pubkey = requireField(fields, 'pubkey');\n if (pubkey.toLowerCase() !== expect.pubkey.toLowerCase()) {\n throw new ChallengeTemplateError('Challenge embeds a different pubkey than this wallet');\n }\n\n const nonce = requireField(fields, 'nonce');\n if (nonce !== expect.nonce) {\n throw new ChallengeTemplateError('Challenge nonce does not match the nonce issued with it');\n }\n\n const network = requireField(fields, 'network');\n if (network !== expect.network) {\n throw new ChallengeTemplateError(`Challenge is for network \"${network}\", expected \"${expect.network}\"`);\n }\n\n const issuedAt = parseTimestamp(requireField(fields, 'issuedAt'), 'issuedAt');\n const expiresAt = parseTimestamp(requireField(fields, 'expiresAt'), 'expiresAt');\n\n if (issuedAt > expect.nowMs + MAX_CLOCK_SKEW_MS) {\n throw new ChallengeTemplateError('Challenge issuedAt is in the future');\n }\n if (expiresAt <= expect.nowMs - MAX_CLOCK_SKEW_MS) {\n throw new ChallengeTemplateError('Challenge is already expired');\n }\n if (expiresAt <= issuedAt || expiresAt - issuedAt > MAX_VALIDITY_WINDOW_MS) {\n throw new ChallengeTemplateError('Challenge validity window is implausible');\n }\n}\n","/**\n * wallet-api/codec.ts — runtime wire ⇄ domain conversion for §16 responses.\n *\n * Hand-rolled validators (repo convention — no zod dependency). The hard rule\n * (ARCHITECTURE §11): asset amounts are decimal strings on the wire and\n * `bigint` in domain types — never a JS `number` (they exceed 2^53). Cursors,\n * seqs and the syncEpoch are parsed the same way; the codec tolerates either\n * a decimal string (the Postgres `bigint`-over-`pg` wire form) or a safe\n * integer number for those counters, but amounts MUST be strings.\n */\n\nimport type { InventoryItem } from '../storage/storage-provider';\nimport { WalletApiError } from './errors';\nimport type {\n BlobUrlEntry,\n CoinBalance,\n HistoryPage,\n HistoryWireRecord,\n IntentRecord,\n InventoryPage,\n MailboxClaimResult,\n MailboxEntry,\n MailboxPage,\n PaymentRequestRecord,\n PaymentRequestsPage,\n UploadUrlEntry,\n} from './types';\n\nfunction protocolError(message: string): WalletApiError {\n return new WalletApiError(message, 'PROTOCOL');\n}\n\nfunction asRecord(value: unknown, what: string): Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw protocolError(`${what} is not an object`);\n }\n return value as Record<string, unknown>;\n}\n\nfunction asArray(value: unknown, what: string): unknown[] {\n if (!Array.isArray(value)) throw protocolError(`${what} is not an array`);\n return value;\n}\n\nfunction asString(value: unknown, what: string): string {\n if (typeof value !== 'string') throw protocolError(`${what} is not a string`);\n return value;\n}\n\n/** Counter (cursor/seq/syncEpoch): decimal string or safe integer → bigint. */\nexport function parseCounter(value: unknown, what: string): bigint {\n if (typeof value === 'string' && /^[0-9]+$/.test(value)) return BigInt(value);\n if (typeof value === 'number' && Number.isSafeInteger(value) && value >= 0) return BigInt(value);\n throw protocolError(`${what} is not a non-negative integer counter`);\n}\n\n/** Amount: decimal string ONLY (§11) → bigint. */\nexport function parseAmount(value: unknown, what: string): bigint {\n if (typeof value === 'string' && /^[0-9]+$/.test(value)) return BigInt(value);\n throw protocolError(`${what} is not a decimal-string amount`);\n}\n\nfunction parseAssets(value: unknown, what: string): InventoryItem['assets'] {\n if (value === undefined || value === null) return undefined;\n return asArray(value, what).map((raw, i) => {\n const rec = asRecord(raw, `${what}[${i}]`);\n return {\n coinId: asString(rec.coinId, `${what}[${i}].coinId`),\n amount: parseAmount(rec.amount, `${what}[${i}].amount`),\n };\n });\n}\n\nfunction parseInventoryItem(raw: unknown, what: string): InventoryItem {\n const rec = asRecord(raw, what);\n const status = asString(rec.status, `${what}.status`);\n if (status !== 'active' && status !== 'removed') {\n throw protocolError(`${what}.status is neither 'active' nor 'removed'`);\n }\n return {\n tokenId: asString(rec.tokenId, `${what}.tokenId`),\n status,\n assets: parseAssets(rec.assets, `${what}.assets`),\n seq: parseCounter(rec.seq, `${what}.seq`),\n };\n}\n\n/** `GET /v1/inventory` → {@link InventoryPage} (§16). */\nexport function parseInventoryPage(body: unknown): InventoryPage {\n const rec = asRecord(body, 'inventory response');\n if (typeof rec.more !== 'boolean') throw protocolError('inventory response .more is not a boolean');\n return {\n cursor: parseCounter(rec.cursor, 'inventory response .cursor'),\n syncEpoch: parseCounter(rec.syncEpoch, 'inventory response .syncEpoch'),\n more: rec.more,\n items: asArray(rec.items, 'inventory response .items').map((raw, i) =>\n parseInventoryItem(raw, `items[${i}]`)\n ),\n };\n}\n\n/** `GET /v1/balances` → {@link CoinBalance}[] (§16). */\nexport function parseBalances(body: unknown): CoinBalance[] {\n const rec = asRecord(body, 'balances response');\n return asArray(rec.balances, 'balances response .balances').map((raw, i) => {\n const b = asRecord(raw, `balances[${i}]`);\n const tokenCount = b.tokenCount;\n if (typeof tokenCount !== 'number' || !Number.isSafeInteger(tokenCount) || tokenCount < 0) {\n throw protocolError(`balances[${i}].tokenCount is not a non-negative integer`);\n }\n return {\n coinId: asString(b.coinId, `balances[${i}].coinId`),\n total: parseAmount(b.total, `balances[${i}].total`),\n tokenCount,\n };\n });\n}\n\n/** `POST /v1/tokens/blob-urls` → {@link BlobUrlEntry}[] (§16). */\nexport function parseBlobUrls(body: unknown): BlobUrlEntry[] {\n const rec = asRecord(body, 'blob-urls response');\n return asArray(rec.urls, 'blob-urls response .urls').map((raw, i) => {\n const u = asRecord(raw, `urls[${i}]`);\n return {\n tokenId: asString(u.tokenId, `urls[${i}].tokenId`),\n getUrl: asString(u.getUrl, `urls[${i}].getUrl`),\n };\n });\n}\n\n/** `POST /v1/tokens/upload-urls` → {@link UploadUrlEntry}[] (§16). */\nexport function parseUploadUrls(body: unknown): UploadUrlEntry[] {\n const rec = asRecord(body, 'upload-urls response');\n return asArray(rec.urls, 'upload-urls response .urls').map((raw, i) => {\n const u = asRecord(raw, `urls[${i}]`);\n return {\n sha256: asString(u.sha256, `urls[${i}].sha256`),\n key: asString(u.key, `urls[${i}].key`),\n putUrl: asString(u.putUrl, `urls[${i}].putUrl`),\n };\n });\n}\n\n/** `POST /v1/inventory/apply` → cursor (§16). */\nexport function parseApplyResult(body: unknown): bigint {\n const rec = asRecord(body, 'apply response');\n return parseCounter(rec.cursor, 'apply response .cursor');\n}\n\n/** `GET /v1/intents` → {@link IntentRecord}[] (§16). */\nexport function parseIntents(body: unknown): IntentRecord[] {\n const rec = asRecord(body, 'intents response');\n return asArray(rec.intents, 'intents response .intents').map((raw, i) => {\n const it = asRecord(raw, `intents[${i}]`);\n const status = asString(it.status, `intents[${i}].status`);\n if (status !== 'open' && status !== 'completed' && status !== 'aborted') {\n throw protocolError(`intents[${i}].status is not a known intent status`);\n }\n const createdAt = Date.parse(asString(it.createdAt, `intents[${i}].createdAt`));\n if (Number.isNaN(createdAt)) throw protocolError(`intents[${i}].createdAt is not a timestamp`);\n return {\n transferId: asString(it.transferId, `intents[${i}].transferId`),\n payload: asString(it.payload, `intents[${i}].payload`),\n status,\n createdAt,\n };\n });\n}\n\n// ── mailbox (§6/§16) ──────────────────────────────────────────────────────────\n\n/** `POST /v1/mailbox` → entryId (§16). */\nexport function parseDepositResult(body: unknown): string {\n const rec = asRecord(body, 'mailbox deposit response');\n return asString(rec.entryId, 'mailbox deposit response .entryId');\n}\n\nfunction parseMailboxEntry(raw: unknown, what: string): MailboxEntry {\n const rec = asRecord(raw, what);\n const status = asString(rec.status, `${what}.status`);\n if (status !== 'unclaimed' && status !== 'claimed' && status !== 'rejected') {\n throw protocolError(`${what}.status is not a known mailbox entry status`);\n }\n const createdAt = Date.parse(asString(rec.createdAt, `${what}.createdAt`));\n if (Number.isNaN(createdAt)) throw protocolError(`${what}.createdAt is not a timestamp`);\n return {\n entryId: asString(rec.entryId, `${what}.entryId`),\n seq: parseCounter(rec.seq, `${what}.seq`),\n status,\n transferId: asString(rec.transferId, `${what}.transferId`),\n tokenId: asString(rec.tokenId, `${what}.tokenId`),\n assets: (parseAssets(rec.assets, `${what}.assets`) ?? []).map((a) => ({ ...a })),\n senderPubkey: asString(rec.senderPubkey, `${what}.senderPubkey`),\n ...(rec.memo !== undefined && rec.memo !== null\n ? { memo: asString(rec.memo, `${what}.memo`) }\n : {}),\n createdAt,\n ...(rec.getUrl !== undefined && rec.getUrl !== null\n ? { getUrl: asString(rec.getUrl, `${what}.getUrl`) }\n : {}),\n ...(rec.blobCollected === true ? { blobCollected: true } : {}),\n };\n}\n\n/** `GET /v1/mailbox?since=` → {@link MailboxPage} (§16). */\nexport function parseMailboxPage(body: unknown): MailboxPage {\n const rec = asRecord(body, 'mailbox response');\n if (typeof rec.more !== 'boolean') throw protocolError('mailbox response .more is not a boolean');\n return {\n readPointer: parseCounter(rec.readPointer, 'mailbox response .readPointer'),\n syncEpoch: parseCounter(rec.syncEpoch, 'mailbox response .syncEpoch'),\n more: rec.more,\n entries: asArray(rec.entries, 'mailbox response .entries').map((raw, i) =>\n parseMailboxEntry(raw, `entries[${i}]`)\n ),\n };\n}\n\n/** `POST /v1/mailbox/claim` → {@link MailboxClaimResult} (§16). */\nexport function parseClaimResult(body: unknown): MailboxClaimResult {\n const rec = asRecord(body, 'mailbox claim response');\n return {\n claimed: asArray(rec.claimed, 'claim response .claimed').map((raw, i) =>\n asString(raw, `claimed[${i}]`)\n ),\n alreadyClaimed: asArray(rec.alreadyClaimed, 'claim response .alreadyClaimed').map((raw, i) => {\n const a = asRecord(raw, `alreadyClaimed[${i}]`);\n if (typeof a.intoInventory !== 'boolean') {\n throw protocolError(`alreadyClaimed[${i}].intoInventory is not a boolean`);\n }\n return { entryId: asString(a.entryId, `alreadyClaimed[${i}].entryId`), intoInventory: a.intoInventory };\n }),\n failed: asArray(rec.failed, 'claim response .failed').map((raw, i) => {\n const f = asRecord(raw, `failed[${i}]`);\n return { entryId: asString(f.entryId, `failed[${i}].entryId`), code: asString(f.code, `failed[${i}].code`) };\n }),\n };\n}\n\n/** `POST /v1/mailbox/reject` → rejected entry ids (§16). */\nexport function parseRejectResult(body: unknown): string[] {\n const rec = asRecord(body, 'mailbox reject response');\n return asArray(rec.rejected, 'reject response .rejected').map((raw, i) => asString(raw, `rejected[${i}]`));\n}\n\n// ── payment requests (§10/§16) ────────────────────────────────────────────────\n\n/** One §16 payment request → {@link PaymentRequestRecord} (create/respond/list). */\nexport function parsePaymentRequestRecord(raw: unknown, what: string): PaymentRequestRecord {\n const rec = asRecord(raw, what);\n const status = asString(rec.status, `${what}.status`);\n if (status !== 'open' && status !== 'paid' && status !== 'declined' && status !== 'expired') {\n throw protocolError(`${what}.status is not a known payment-request status`);\n }\n const createdAt = Date.parse(asString(rec.createdAt, `${what}.createdAt`));\n if (Number.isNaN(createdAt)) throw protocolError(`${what}.createdAt is not a timestamp`);\n let expiresAt: number | undefined;\n if (rec.expiresAt !== undefined && rec.expiresAt !== null) {\n expiresAt = Date.parse(asString(rec.expiresAt, `${what}.expiresAt`));\n if (Number.isNaN(expiresAt)) throw protocolError(`${what}.expiresAt is not a timestamp`);\n }\n if (rec.transferId !== null && typeof rec.transferId !== 'string') {\n throw protocolError(`${what}.transferId is neither a string nor null`);\n }\n return {\n id: asString(rec.id, `${what}.id`),\n seq: parseCounter(rec.seq, `${what}.seq`),\n fromPubkey: asString(rec.fromPubkey, `${what}.fromPubkey`),\n toPubkey: asString(rec.toPubkey, `${what}.toPubkey`),\n assets: (parseAssets(rec.assets, `${what}.assets`) ?? []).map((a) => ({ ...a })),\n ...(rec.memo !== undefined && rec.memo !== null\n ? { memo: asString(rec.memo, `${what}.memo`) }\n : {}),\n status,\n transferId: rec.transferId,\n createdAt,\n ...(expiresAt !== undefined ? { expiresAt } : {}),\n };\n}\n\n/**\n * `GET /v1/payment-requests?role=` → {@link PaymentRequestsPage} (§16). The\n * cursor family is role-bound: incoming pages carry the `?since=` seq counter,\n * outgoing pages an opaque keyset string (null once drained) — a page whose\n * cursor does not match its role is a protocol violation.\n */\nexport function parsePaymentRequestsPage(\n body: unknown,\n role: 'incoming' | 'outgoing'\n): PaymentRequestsPage {\n const rec = asRecord(body, 'payment-requests response');\n if (typeof rec.more !== 'boolean') throw protocolError('payment-requests response .more is not a boolean');\n const requests = asArray(rec.requests, 'payment-requests response .requests').map((raw, i) =>\n parsePaymentRequestRecord(raw, `requests[${i}]`)\n );\n const syncEpoch = parseCounter(rec.syncEpoch, 'payment-requests response .syncEpoch');\n if (role === 'incoming') {\n return {\n role,\n requests,\n more: rec.more,\n cursor: parseCounter(rec.cursor, 'payment-requests response .cursor'),\n syncEpoch,\n };\n }\n if (rec.cursor !== null && typeof rec.cursor !== 'string') {\n throw protocolError('payment-requests response .cursor is neither a keyset string nor null');\n }\n return { role, requests, more: rec.more, cursor: rec.cursor, syncEpoch };\n}\n\n// ── history (§10/§16) ─────────────────────────────────────────────────────────\n\nfunction parseHistoryRecord(raw: unknown, what: string): HistoryWireRecord {\n const rec = asRecord(raw, what);\n return {\n dedupKey: asString(rec.dedupKey, `${what}.dedupKey`),\n id: asString(rec.id, `${what}.id`),\n type: asString(rec.type, `${what}.type`),\n ts: asString(rec.ts, `${what}.ts`),\n assets: asArray(rec.assets, `${what}.assets`).map((a, i) => {\n const asset = asRecord(a, `${what}.assets[${i}]`);\n // Amounts stay decimal strings on this surface — display data (§10).\n parseAmount(asset.amount, `${what}.assets[${i}].amount`);\n return {\n coinId: asString(asset.coinId, `${what}.assets[${i}].coinId`),\n amount: asString(asset.amount, `${what}.assets[${i}].amount`),\n };\n }),\n ...(typeof rec.transferId === 'string' ? { transferId: rec.transferId } : {}),\n ...(typeof rec.tokenId === 'string' ? { tokenId: rec.tokenId } : {}),\n ...(typeof rec.counterpartyPubkey === 'string' ? { counterpartyPubkey: rec.counterpartyPubkey } : {}),\n ...(typeof rec.memo === 'string' ? { memo: rec.memo } : {}),\n ...(typeof rec.counterpartyNametag === 'string' ? { counterpartyNametag: rec.counterpartyNametag } : {}),\n };\n}\n\n/** `GET /v1/history` → {@link HistoryPage} (§16). */\nexport function parseHistoryPage(body: unknown): HistoryPage {\n const rec = asRecord(body, 'history response');\n if (typeof rec.more !== 'boolean') throw protocolError('history response .more is not a boolean');\n if (rec.cursor !== null && typeof rec.cursor !== 'string') {\n throw protocolError('history response .cursor is not a string or null');\n }\n return {\n records: asArray(rec.records, 'history response .records').map((raw, i) =>\n parseHistoryRecord(raw, `records[${i}]`)\n ),\n more: rec.more,\n cursor: rec.cursor,\n syncEpoch: parseCounter(rec.syncEpoch, 'history response .syncEpoch'),\n };\n}\n\n/** Auth responses (§4). */\nexport function parseAuthChallenge(body: unknown): { nonce: string; challenge: string } {\n const rec = asRecord(body, 'auth/challenge response');\n return {\n nonce: asString(rec.nonce, 'auth/challenge response .nonce'),\n challenge: asString(rec.challenge, 'auth/challenge response .challenge'),\n };\n}\n\nexport function parseAuthTokens(body: unknown): { jwt: string; refreshToken: string } {\n const rec = asRecord(body, 'auth token response');\n return {\n jwt: asString(rec.jwt, 'auth token response .jwt'),\n refreshToken: asString(rec.refreshToken, 'auth token response .refreshToken'),\n };\n}\n\n/** `POST /v1/ws-ticket` (§9). */\nexport function parseWsTicket(body: unknown): string {\n const rec = asRecord(body, 'ws-ticket response');\n return asString(rec.ticket, 'ws-ticket response .ticket');\n}\n\n/** WS wake frame (§9): `{ type:'wake', stream, syncEpoch }`. */\nexport function parseWakeFrame(raw: string): { stream: 'inventory' | 'mailbox' | 'payment_requests'; syncEpoch: bigint } | null {\n let body: unknown;\n try {\n body = JSON.parse(raw);\n } catch {\n return null;\n }\n if (typeof body !== 'object' || body === null) return null;\n const rec = body as Record<string, unknown>;\n if (rec.type !== 'wake') return null;\n const stream = rec.stream;\n if (stream !== 'inventory' && stream !== 'mailbox' && stream !== 'payment_requests') return null;\n try {\n return { stream, syncEpoch: parseCounter(rec.syncEpoch, 'wake .syncEpoch') };\n } catch {\n return null;\n }\n}\n","/**\n * wallet-api/client.ts — `WalletApiClient` (sdk-changes S1).\n *\n * A small typed client for the wallet-api backend: challenge→sign→JWT with a\n * rotating refresh token, typed REST for the §16 endpoints, and the WS wake\n * channel (ticket flow — §9). Injected into providers (DI; no singletons).\n *\n * Cross-cutting rules (S1):\n * - **Challenge template verification** — the spend key never signs text that\n * fails `verifyChallengeTemplate` (prefix + own pubkey + plausible\n * timestamps). See ./challenge.ts.\n * - **Credential hygiene** — the refresh token lives only in the injected\n * {@link KeyValueStore} (never a URL, never logged). A rotation-reuse\n * revocation or refresh expiry falls back to a fresh challenge→sign cycle —\n * silent, since the wallet key is available at unlock. Non-loopback base\n * URLs MUST be `https:` (ARCHITECTURE §4 transport rule), enforced at\n * construction.\n * - **Amounts are decimal strings end-to-end**, parsed with `BigInt` (§11) —\n * see ./codec.ts.\n *\n * The client also keeps the NORMATIVE LOCAL COPY of open intents (E.3): the\n * server is the primary, but intents are the one server table not\n * re-derivable from blobs — after a server restore (`syncEpoch` change,\n * ARCHITECTURE §5.4) the client re-PUTs its locally-known open intents\n * (idempotent) before anything resumes. `putIntent` persists locally before\n * the server PUT; the local copy survives a failed PUT as the restore\n * backstop.\n */\n\nimport { sha256 } from '@noble/hashes/sha2.js';\n\nimport { signMessage } from '../core/crypto';\nimport { WalletApiError } from './errors';\nimport { verifyChallengeTemplate } from './challenge';\nimport {\n parseApplyResult,\n parseAuthChallenge,\n parseAuthTokens,\n parseBalances,\n parseBlobUrls,\n parseClaimResult,\n parseDepositResult,\n parseHistoryPage,\n parseIntents,\n parseInventoryPage,\n parseMailboxPage,\n parsePaymentRequestRecord,\n parsePaymentRequestsPage,\n parseRejectResult,\n parseUploadUrls,\n parseWakeFrame,\n parseWsTicket,\n} from './codec';\nimport type {\n ApplyDeltaRequest,\n BlobUrlEntry,\n CoinBalance,\n CreatePaymentRequestInput,\n FetchLike,\n FetchResponseLike,\n HistoryPage,\n HistoryWireRecord,\n IntentRecord,\n InventoryPage,\n KeyValueStore,\n ListPaymentRequestsParams,\n MailboxClaimResult,\n MailboxDepositRequest,\n MailboxPage,\n PaymentRequestRecord,\n PaymentRequestsPage,\n RespondPaymentRequestInput,\n UploadUrlEntry,\n UploadUrlRequest,\n WakeCallback,\n WakeSocketHandle,\n WalletApiClientConfig,\n WalletApiIdentity,\n WebSocketFactoryLike,\n} from './types';\n\ninterface LocalIntent {\n payload: string;\n status: 'open' | 'completed' | 'aborted';\n createdAt: number;\n}\n\nfunction isLoopbackHost(hostname: string): boolean {\n return (\n hostname === 'localhost' ||\n hostname.endsWith('.localhost') ||\n /^127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(hostname) ||\n hostname === '::1' ||\n hostname === '[::1]'\n );\n}\n\n/** Enforce the §4 transport rule: non-loopback MUST be https. */\nfunction assertSecureBaseUrl(baseUrl: string): URL {\n let url: URL;\n try {\n url = new URL(baseUrl);\n } catch {\n throw new WalletApiError(`Invalid wallet-api base URL: ${baseUrl}`, 'CONFIG');\n }\n if (url.protocol !== 'https:' && !(url.protocol === 'http:' && isLoopbackHost(url.hostname))) {\n throw new WalletApiError(\n 'wallet-api base URL must be https (plain http is allowed only on loopback — ARCHITECTURE §4)',\n 'CONFIG'\n );\n }\n return url;\n}\n\n/** Platform-neutral bytes→base64 (browser btoa + Node ≥16 global btoa). */\nfunction bytesToBase64(bytes: Uint8Array): string {\n let bin = '';\n for (const b of bytes) bin += String.fromCharCode(b);\n return btoa(bin);\n}\n\nfunction defaultWebSocketFactory(url: string): import('./types').WebSocketLike {\n const Ctor = (globalThis as { WebSocket?: new (url: string) => import('./types').WebSocketLike }).WebSocket;\n if (!Ctor) {\n throw new WalletApiError(\n 'No global WebSocket available — inject webSocketFactory (e.g. the \"ws\" package on Node < 22)',\n 'CONFIG'\n );\n }\n return new Ctor(url);\n}\n\nexport class WalletApiClient {\n /** Network name (also the blob-key prefix `<network>/t/<sha256>` — §5.2). */\n readonly network: string;\n\n private readonly baseUrl: string;\n private readonly deviceId: string;\n private readonly storage: KeyValueStore;\n private readonly fetchFn: FetchLike;\n private readonly wsFactory: WebSocketFactoryLike;\n private readonly now: () => number;\n\n private identity: WalletApiIdentity | null = null;\n private jwt: string | null = null;\n /** Serializes concurrent re-auth attempts. */\n private authInFlight: Promise<void> | null = null;\n\n constructor(config: WalletApiClientConfig) {\n const url = assertSecureBaseUrl(config.baseUrl);\n this.baseUrl = url.toString().replace(/\\/$/, '');\n if (!config.network) throw new WalletApiError('network is required', 'CONFIG');\n this.network = config.network;\n this.deviceId = config.deviceId;\n this.storage = config.storage;\n if (!config.fetchFn && !(globalThis as { fetch?: FetchLike }).fetch) {\n throw new WalletApiError('No fetch available — inject fetchFn', 'CONFIG');\n }\n // Resolve the global lazily THROUGH globalThis so the implementation keeps\n // its original receiver (browser fetch throws \"Illegal invocation\" when\n // called detached).\n this.fetchFn =\n config.fetchFn ?? ((u, init) => (globalThis as unknown as { fetch: FetchLike }).fetch(u, init));\n this.wsFactory = config.webSocketFactory ?? defaultWebSocketFactory;\n this.now = config.now ?? (() => Date.now());\n }\n\n /** Bind the wallet identity this client authenticates as. Resets the session. */\n setIdentity(identity: WalletApiIdentity): void {\n this.identity = identity;\n this.jwt = null;\n }\n\n // ── storage keys (scoped per network + pubkey + device) ────────────────────\n\n private requireIdentity(): WalletApiIdentity {\n if (!this.identity) throw new WalletApiError('No identity set — call setIdentity() first', 'CONFIG');\n return this.identity;\n }\n\n private scopedKey(kind: string): string {\n const { chainPubkey } = this.requireIdentity();\n return `wallet-api:${kind}:${this.network}:${chainPubkey}`;\n }\n\n private refreshTokenKey(): string {\n return `${this.scopedKey('refresh')}:${this.deviceId}`;\n }\n\n // ── auth (ARCHITECTURE §4) ──────────────────────────────────────────────────\n\n /**\n * Establish a session: try the stored refresh token first (rotating), fall\n * back to a fresh challenge→sign→verify cycle. Safe to call repeatedly.\n */\n async signIn(): Promise<void> {\n if (this.authInFlight) return this.authInFlight;\n this.authInFlight = this.signInInner().finally(() => {\n this.authInFlight = null;\n });\n return this.authInFlight;\n }\n\n private async signInInner(): Promise<void> {\n if (await this.tryRefresh()) return;\n await this.challengeSignIn();\n }\n\n /**\n * `POST /v1/auth/refresh` with the stored token; rotates on success. Any\n * 4xx (expired, revoked, rotation-reuse revocation) clears the stored token\n * and reports `false` — the caller falls back to a challenge cycle.\n */\n private async tryRefresh(): Promise<boolean> {\n const stored = await this.storage.get(this.refreshTokenKey());\n if (!stored) return false;\n const res = await this.rawFetch('POST', '/v1/auth/refresh', { refreshToken: stored });\n if (res.status === 200) {\n const tokens = parseAuthTokens(await this.readJson(res, 'auth/refresh'));\n this.jwt = tokens.jwt;\n await this.storage.set(this.refreshTokenKey(), tokens.refreshToken);\n return true;\n }\n // Stale/revoked/reused token — discard it; a fresh challenge cycle follows.\n await this.storage.remove(this.refreshTokenKey());\n return false;\n }\n\n /** The challenge→verify cycle (§4 steps 1–3) with template verification (S1). */\n private async challengeSignIn(): Promise<void> {\n const identity = this.requireIdentity();\n const challengeRes = await this.rawFetch('POST', '/v1/auth/challenge', {\n pubkey: identity.chainPubkey,\n });\n if (challengeRes.status !== 200) throw await this.toError(challengeRes, 'auth/challenge');\n const { nonce, challenge } = parseAuthChallenge(await this.readJson(challengeRes, 'auth/challenge'));\n\n // The spend key never signs unverified server-chosen text (S1).\n verifyChallengeTemplate(challenge, {\n pubkey: identity.chainPubkey,\n nonce,\n network: this.network,\n nowMs: this.now(),\n });\n\n const signature = signMessage(identity.privateKey, challenge);\n const verifyRes = await this.rawFetch('POST', '/v1/auth/verify', {\n nonce,\n signature,\n deviceId: this.deviceId,\n });\n if (verifyRes.status !== 200) throw await this.toError(verifyRes, 'auth/verify');\n const tokens = parseAuthTokens(await this.readJson(verifyRes, 'auth/verify'));\n this.jwt = tokens.jwt;\n await this.storage.set(this.refreshTokenKey(), tokens.refreshToken);\n }\n\n /** Revoke the session server-side and drop all local credentials. */\n async logout(): Promise<void> {\n if (this.jwt) {\n try {\n await this.rawFetch('POST', '/v1/auth/logout', {}, this.jwt);\n } finally {\n this.jwt = null;\n }\n }\n await this.storage.remove(this.refreshTokenKey());\n }\n\n // ── request core ────────────────────────────────────────────────────────────\n\n private async rawFetch(\n method: string,\n path: string,\n body?: unknown,\n jwt?: string\n ): Promise<FetchResponseLike> {\n const headers: Record<string, string> = {};\n if (body !== undefined) headers['content-type'] = 'application/json';\n if (jwt) headers['authorization'] = `Bearer ${jwt}`;\n try {\n return await this.fetchFn(`${this.baseUrl}${path}`, {\n method,\n headers,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n } catch (err) {\n throw new WalletApiError(`wallet-api request failed: ${method} ${path}`, 'NETWORK', undefined, err);\n }\n }\n\n private async readJson(res: FetchResponseLike, what: string): Promise<unknown> {\n const text = await res.text();\n if (text === '') return null;\n try {\n return JSON.parse(text);\n } catch (err) {\n throw new WalletApiError(`${what}: response is not JSON`, 'PROTOCOL', res.status, err);\n }\n }\n\n private async toError(res: FetchResponseLike, what: string): Promise<WalletApiError> {\n let message = `${what} failed with status ${res.status}`;\n try {\n const body = (await this.readJson(res, what)) as { error?: { code?: string; message?: string } } | null;\n if (body?.error?.message) message = `${what}: ${body.error.code ?? ''} ${body.error.message}`.trim();\n } catch {\n // keep the generic message\n }\n return WalletApiError.fromStatus(res.status, message);\n }\n\n /**\n * Authenticated JSON request. A 401 triggers one silent re-auth\n * (refresh → challenge fallback) and one retry.\n */\n private async requestJson(method: string, path: string, body?: unknown): Promise<unknown> {\n if (!this.jwt) await this.signIn();\n let res = await this.rawFetch(method, path, body, this.jwt!);\n if (res.status === 401) {\n this.jwt = null;\n await this.signIn();\n res = await this.rawFetch(method, path, body, this.jwt!);\n }\n if (res.status === 204) return null;\n if (!res.ok) throw await this.toError(res, `${method} ${path}`);\n return this.readJson(res, `${method} ${path}`);\n }\n\n // ── inventory / blobs (§16) ─────────────────────────────────────────────────\n\n /** `GET /v1/inventory?since=` — one page; the caller loops while `more`. */\n async listInventory(since?: bigint): Promise<InventoryPage> {\n const query = since !== undefined ? `?since=${since.toString()}` : '';\n const page = parseInventoryPage(await this.requestJson('GET', `/v1/inventory${query}`));\n await this.noteSyncEpoch(page.syncEpoch);\n return page;\n }\n\n /** `GET /v1/balances` — active rows only. */\n async getBalances(): Promise<CoinBalance[]> {\n return parseBalances(await this.requestJson('GET', '/v1/balances'));\n }\n\n /** `POST /v1/tokens/blob-urls` — owner's active *or tombstoned* rows (§5.3 recovery). */\n async getBlobUrls(tokenIds: string[]): Promise<BlobUrlEntry[]> {\n return parseBlobUrls(await this.requestJson('POST', '/v1/tokens/blob-urls', { tokenIds }));\n }\n\n /** `POST /v1/tokens/upload-urls` — checksum/length-bound presigned PUTs (§5.2). */\n async getUploadUrls(blobs: UploadUrlRequest[]): Promise<UploadUrlEntry[]> {\n return parseUploadUrls(await this.requestJson('POST', '/v1/tokens/upload-urls', { blobs }));\n }\n\n /**\n * `POST /v1/inventory/apply` (§5.3). Also marks the local intent copy\n * completed — the server completes the intent in the same transaction (§16).\n */\n async applyInventoryDelta(req: ApplyDeltaRequest): Promise<bigint> {\n const cursor = parseApplyResult(\n await this.requestJson('POST', '/v1/inventory/apply', {\n transferId: req.transferId,\n spent: req.spent,\n added: req.added,\n ...(req.externalDelivery !== undefined ? { externalDelivery: req.externalDelivery } : {}),\n })\n );\n await this.setLocalIntentStatus(req.transferId, 'completed');\n return cursor;\n }\n\n /** Download blob bytes from a signed GET URL (the URL itself is the credential). */\n async fetchBlob(getUrl: string): Promise<Uint8Array> {\n let res: FetchResponseLike;\n try {\n res = await this.fetchFn(getUrl, { method: 'GET' });\n } catch (err) {\n throw new WalletApiError('blob download failed', 'NETWORK', undefined, err);\n }\n if (!res.ok) throw WalletApiError.fromStatus(res.status, `blob download failed with status ${res.status}`);\n return new Uint8Array(await res.arrayBuffer());\n }\n\n /**\n * Upload blob bytes to a signed PUT URL. A `412 Precondition Failed` means\n * the identical blob already exists (content addressing, `If-None-Match: *`\n * — §5.2) and is treated as success.\n *\n * The §5.2 presign binds `x-amz-checksum-sha256` and `if-none-match` (plus\n * `content-length`) as SIGNED HEADERS — a real S3 endpoint rejects the\n * SigV4 signature unless the uploader sends them verbatim. (Caught by the\n * phase-2 harness on first contact with real MinIO — the in-process fake\n * had only validated the body, not the signed headers.)\n */\n async uploadBlob(putUrl: string, bytes: Uint8Array): Promise<void> {\n let res: FetchResponseLike;\n try {\n res = await this.fetchFn(putUrl, {\n method: 'PUT',\n headers: {\n 'content-type': 'application/octet-stream',\n 'x-amz-checksum-sha256': bytesToBase64(sha256(bytes)),\n 'if-none-match': '*',\n },\n body: bytes,\n });\n } catch (err) {\n throw new WalletApiError('blob upload failed', 'NETWORK', undefined, err);\n }\n if (res.ok || res.status === 412) return;\n throw WalletApiError.fromStatus(res.status, `blob upload failed with status ${res.status}`);\n }\n\n // ── mailbox (§6/§16) ────────────────────────────────────────────────────────\n\n /**\n * `POST /v1/mailbox` — deposit an already-uploaded finished blob to the\n * recipient's mailbox. Idempotent by content-derived `entry_id` (§6): an\n * existing entry in any status returns `200` with its id, provided the\n * request's recipient and key match the stored entry (a mismatch is `409`).\n */\n async depositMailbox(req: MailboxDepositRequest): Promise<string> {\n return parseDepositResult(\n await this.requestJson('POST', '/v1/mailbox', {\n recipientPubkey: req.recipientPubkey,\n key: req.key,\n transferId: req.transferId,\n stateHash: req.stateHash,\n tokenId: req.tokenId,\n ...(req.memo !== undefined ? { memo: req.memo } : {}),\n })\n );\n }\n\n /**\n * `GET /v1/mailbox?since=<seq>` — entries of EVERY status are listable for\n * any client-chosen `since`; a claimed entry carries a working `getUrl`\n * while its blob is within retention, `blobCollected: true` afterwards (§6).\n */\n async listMailbox(since?: bigint): Promise<MailboxPage> {\n const query = since !== undefined ? `?since=${since.toString()}` : '';\n const page = parseMailboxPage(await this.requestJson('GET', `/v1/mailbox${query}`));\n await this.noteSyncEpoch(page.syncEpoch);\n return page;\n }\n\n /**\n * `POST /v1/mailbox/claim` — addressee-only, idempotent ownership handoff\n * (§6). `intoInventory:false` is the delivery-only claim: the entry resolves\n * and the pointer advances with ZERO inventory writes.\n */\n async claimMailbox(entryIds: string[], intoInventory: boolean): Promise<MailboxClaimResult> {\n return parseClaimResult(\n await this.requestJson('POST', '/v1/mailbox/claim', { entryIds, intoInventory })\n );\n }\n\n /**\n * `POST /v1/mailbox/reject` — addressee-only; terminal for DISCOVERY only:\n * the entry counts toward read-pointer contiguity but remains claimable and\n * its blob is retained (§6 — reject is never a destruction path).\n */\n async rejectMailbox(entryIds: string[]): Promise<string[]> {\n return parseRejectResult(await this.requestJson('POST', '/v1/mailbox/reject', { entryIds }));\n }\n\n // ── history (§10/§16) ───────────────────────────────────────────────────────\n\n /**\n * `POST /v1/history` — client-asserted records, deduped by `dedupKey` (the\n * server never writes history rows — §10). `memo`/`counterpartyNametag`\n * MUST already be S6 envelopes.\n */\n async postHistoryRecords(records: HistoryWireRecord[]): Promise<void> {\n await this.requestJson('POST', '/v1/history', { records });\n }\n\n /** `GET /v1/history?before=&limit=` — newest-first keyset pages (§10). */\n async listHistory(options: { before?: string; limit?: number } = {}): Promise<HistoryPage> {\n const params = new URLSearchParams();\n if (options.before !== undefined) params.set('before', options.before);\n if (options.limit !== undefined) params.set('limit', String(options.limit));\n const qs = params.toString();\n return parseHistoryPage(await this.requestJson('GET', `/v1/history${qs ? `?${qs}` : ''}`));\n }\n\n // ── payment requests (§10/§16) ──────────────────────────────────────────────\n\n /**\n * `POST /v1/payment-requests` — create a request addressed to a payer (the\n * payer's account is auto-provisioned even if they never authenticated —\n * §4/§9; the per-payer open cap → 429, §5.5). `memo` MUST already be an S6\n * `enc1.` envelope (§8.3) — only the requester's wallet key decrypts it.\n */\n async createPaymentRequest(input: CreatePaymentRequestInput): Promise<PaymentRequestRecord> {\n return parsePaymentRequestRecord(\n await this.requestJson('POST', '/v1/payment-requests', {\n toPubkey: input.toPubkey,\n // Amounts are decimal strings in every JSON body (§11).\n assets: input.assets.map((a) => ({ coinId: a.coinId, amount: a.amount.toString() })),\n ...(input.memo !== undefined ? { memo: input.memo } : {}),\n ...(input.expiresAt !== undefined ? { expiresAt: new Date(input.expiresAt).toISOString() } : {}),\n }),\n 'payment-request create response'\n );\n }\n\n /**\n * `GET /v1/payment-requests?role=…` (§16): `'incoming'` is the payer's\n * gap-free `?since=<seq>` stream (cursor = bigint, the standard §16 since\n * contract); `'outgoing'` is the requester's newest-first\n * `?before=<opaque keyset>` backfill (cursor = string | null). The two\n * cursor families never mix — the server 422s a mismatched parameter, and\n * the parameter types make it unrepresentable here.\n */\n async listPaymentRequests<R extends 'incoming' | 'outgoing'>(\n params: Extract<ListPaymentRequestsParams, { role: R }>\n ): Promise<Extract<PaymentRequestsPage, { role: R }>> {\n // Widened to the plain union — generic Extract<> members don't narrow.\n const p: ListPaymentRequestsParams = params;\n const query = new URLSearchParams();\n query.set('role', p.role);\n if (p.status !== undefined) query.set('status', p.status);\n if (p.role === 'incoming') {\n if (p.since !== undefined) query.set('since', p.since.toString());\n } else if (p.before !== undefined) {\n query.set('before', p.before);\n }\n const page = parsePaymentRequestsPage(\n await this.requestJson('GET', `/v1/payment-requests?${query.toString()}`),\n p.role\n );\n await this.noteSyncEpoch(page.syncEpoch);\n // The codec already discriminated the page by role; Extract<> re-states\n // the role-bound cursor family to the caller.\n return page as Extract<PaymentRequestsPage, { role: R }>;\n }\n\n /**\n * `POST /v1/payment-requests/{id}/respond` — addressee-only (§10, non-\n * addressee → 403); only an `open` request may be responded to (else 409).\n * `paid` REQUIRES and links the fulfilling send's transferId, `declined`\n * carries none — the pairing is enforced by {@link RespondPaymentRequestInput}.\n */\n async respondPaymentRequest(id: string, response: RespondPaymentRequestInput): Promise<PaymentRequestRecord> {\n return parsePaymentRequestRecord(\n await this.requestJson('POST', `/v1/payment-requests/${id}/respond`, response),\n 'payment-request respond response'\n );\n }\n\n // ── intents (E.3) ───────────────────────────────────────────────────────────\n\n private intentsKey(): string {\n return this.scopedKey('intents');\n }\n\n private async readLocalIntents(): Promise<Record<string, LocalIntent>> {\n const raw = await this.storage.get(this.intentsKey());\n if (!raw) return {};\n try {\n return JSON.parse(raw) as Record<string, LocalIntent>;\n } catch {\n return {};\n }\n }\n\n private async writeLocalIntents(intents: Record<string, LocalIntent>): Promise<void> {\n await this.storage.set(this.intentsKey(), JSON.stringify(intents));\n }\n\n private async setLocalIntentStatus(transferId: string, status: LocalIntent['status']): Promise<void> {\n const intents = await this.readLocalIntents();\n const intent = intents[transferId];\n if (!intent || intent.status === status) return;\n if (intent.status === 'completed') return; // completed never reverts (§16)\n intent.status = status;\n await this.writeLocalIntents(intents);\n }\n\n /**\n * Persist a (client-encrypted — S6) intent payload: LOCAL copy first, then\n * `PUT /v1/intents/{transferId}` and await the server ack (E.3 — the engine\n * MUST NOT be called before this resolves). A failed server PUT throws, but\n * the local copy stays as the restore backstop and is re-PUT by\n * {@link resyncOpenIntents}.\n */\n async putIntent(transferId: string, payloadEnvelope: string): Promise<void> {\n const intents = await this.readLocalIntents();\n if (!intents[transferId]) {\n intents[transferId] = { payload: payloadEnvelope, status: 'open', createdAt: this.now() };\n await this.writeLocalIntents(intents);\n }\n await this.requestJson('PUT', `/v1/intents/${transferId}`, { payload: payloadEnvelope });\n }\n\n /** `GET /v1/intents?status=` — server-side intent list. */\n async listIntents(status: 'open' | 'aborted'): Promise<IntentRecord[]> {\n return parseIntents(await this.requestJson('GET', `/v1/intents?status=${status}`));\n }\n\n /** `POST /v1/intents/{id}/abort` — soft, recoverable (§16). */\n async abortIntent(transferId: string): Promise<void> {\n await this.requestJson('POST', `/v1/intents/${transferId}/abort`);\n await this.setLocalIntentStatus(transferId, 'aborted');\n }\n\n /** `POST /v1/intents/{id}/complete` — the uniform client-side close (E.3). */\n async completeIntent(transferId: string): Promise<void> {\n await this.requestJson('POST', `/v1/intents/${transferId}/complete`);\n await this.setLocalIntentStatus(transferId, 'completed');\n }\n\n /** The locally-known open intents (the E.3 restore backstop). */\n async listLocalOpenIntents(): Promise<IntentRecord[]> {\n const intents = await this.readLocalIntents();\n return Object.entries(intents)\n .filter(([, i]) => i.status === 'open')\n .map(([transferId, i]) => ({ transferId, payload: i.payload, status: 'open' as const, createdAt: i.createdAt }));\n }\n\n /**\n * Re-PUT every locally-known open intent (idempotent — the server PUT is\n * write-once while open/completed). Called after a `syncEpoch` change\n * (server restore — §5.4): intents are the one server table not\n * re-derivable from blobs.\n */\n async resyncOpenIntents(): Promise<void> {\n for (const intent of await this.listLocalOpenIntents()) {\n await this.requestJson('PUT', `/v1/intents/${intent.transferId}`, { payload: intent.payload });\n }\n }\n\n // ── syncEpoch (§5.4/§9) ─────────────────────────────────────────────────────\n\n private syncEpochKey(): string {\n return this.scopedKey('syncEpoch');\n }\n\n /**\n * Track the server `syncEpoch` carried by cursor-bearing responses and\n * wakes. On a change (server restore), re-PUT locally-known open intents\n * before anything resumes (E.3). Storage-provider cursor invalidation is\n * the provider's own duty (S2) — it observes the same epoch values.\n */\n private async noteSyncEpoch(epoch: bigint): Promise<void> {\n const stored = await this.storage.get(this.syncEpochKey());\n if (stored === epoch.toString()) return;\n await this.storage.set(this.syncEpochKey(), epoch.toString());\n if (stored !== null) {\n await this.resyncOpenIntents();\n }\n }\n\n // ── realtime (§9) ───────────────────────────────────────────────────────────\n\n /**\n * Open the wake channel: `POST /v1/ws-ticket` (JWT-authed, single-use,\n * short TTL) then `GET /v1/ws?ticket=…` — the JWT never appears in a URL.\n * Wakes are nudges only; correctness comes from the `?since=` cursors.\n */\n async connectWakeSocket(onWake: WakeCallback): Promise<WakeSocketHandle> {\n const ticket = parseWsTicket(await this.requestJson('POST', '/v1/ws-ticket'));\n const wsBase = this.baseUrl.replace(/^http/, 'ws');\n const ws = this.wsFactory(`${wsBase}/v1/ws?ticket=${encodeURIComponent(ticket)}`);\n\n await new Promise<void>((resolve, reject) => {\n ws.onopen = () => resolve();\n ws.onerror = (err) => reject(new WalletApiError('wake socket failed to connect', 'NETWORK', undefined, err));\n ws.onclose = () => reject(new WalletApiError('wake socket closed before connecting', 'NETWORK'));\n });\n\n ws.onerror = null;\n ws.onclose = null;\n ws.onmessage = (ev) => {\n const frame = parseWakeFrame(typeof ev.data === 'string' ? ev.data : String(ev.data));\n if (!frame) return;\n void this.noteSyncEpoch(frame.syncEpoch);\n onWake(frame);\n };\n\n return { close: () => ws.close() };\n }\n}\n","/**\n * WalletApiTokenStorageProvider — the lazy, thin-wallet storage provider over\n * the wallet-api backend (sdk-changes S2; ARCHITECTURE §5/§16).\n *\n * Platform-neutral (browser + Node) over the injected {@link WalletApiClient}.\n * The wallet renders balances from the server's value-indexed inventory view;\n * blobs are fetched on demand only to spend (signed GET URLs). Key behaviors:\n *\n * - **Tombstone-aware delta sync** (§5.1): `?since=` deltas include\n * `status:'removed'` rows — the only way a stale device learns about\n * spends/handoffs; the provider applies them (drops the entries from its\n * active view) and loops while `more`.\n * - **Paginated full pull** is finished with an immediate\n * `?since=<page-1 cursor>` closing delta, whose tombstones repair any flips\n * that happened between pages (§5.1).\n * - **`syncEpoch` change** (server restore — §5.4): discard all persisted\n * cursors, full pull, then re-PUT locally-known open intents (E.3, via the\n * client) before anything resumes.\n * - **Write-behind with empty-import protection** (§5.1 client guards): a\n * removal is pushed only after a successful inventory load and only for a\n * confirmed on-chain spend (a `_tombstones` entry) — a fresh device or a\n * failed load can never appear to \"empty\" the wallet, and a merely-absent\n * token is never removed.\n * - **`recoverRemoved()`** (§5.3 recovery): tombstones the client cannot match\n * to a known spend are re-fetched via blob-urls (which work for own\n * tombstoned rows), re-verified locally, and re-added (reactivation). A\n * server `409` is an evidenced tombstone — \"actually spent\" — and is kept.\n * - **Blob upload** via upload-urls with client-side sha256; a `412` from the\n * content-addressed store means the blob already exists = success (§5.2).\n */\n\nimport { sha256 } from '@noble/hashes/sha2.js';\nimport type {\n ApplyDeltaAdded,\n ApplyDeltaOptions,\n InventoryItem,\n InventoryView,\n LoadResult,\n RecoverRemovedResult,\n SaveResult,\n SyncResult,\n TokenStorageProvider,\n TxfStorageDataBase,\n} from '../../../storage';\nimport type { TokenBlob } from '../../../token-engine/types';\nimport {\n TOKEN_BLOB_VERSION,\n decodeTokenBlob,\n unwrapTokenBlobBytes,\n} from '../../../token-engine/token-blob';\nimport type { FullIdentity, ProviderStatus } from '../../../types';\nimport { WalletApiClient, WalletApiError } from '../../../wallet-api';\nimport type { KeyValueStore } from '../../../wallet-api';\n\nexport interface WalletApiTokenStorageConfig {\n /** The authenticated wallet-api client (S1). DI — never a singleton. */\n client: WalletApiClient;\n /** Persists the inventory cursor, syncEpoch and own-spend set per identity. */\n stateStore: KeyValueStore;\n /**\n * Optional local token verification used by `recoverRemoved()` before\n * re-adding a tombstoned blob (S2: \"re-verifies locally\"). Wire the engine's\n * `verify` here at composition; the default accepts any blob that decodes\n * and matches its tokenId.\n */\n verifyToken?: (blob: TokenBlob) => Promise<boolean>;\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');\n}\n\nfunction hexToBytes(hex: string): Uint8Array {\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < out.length; i++) out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n return out;\n}\n\nfunction newTransferId(): string {\n return (globalThis as { crypto: { randomUUID(): string } }).crypto.randomUUID();\n}\n\n/** A stored v2 token entry (the UI token record with a hex CBOR blob). */\nfunction isV2BlobEntry(entry: unknown): entry is { sdkData: string } {\n if (typeof entry !== 'object' || entry === null || 'genesis' in entry) return false;\n const sdkData = (entry as { sdkData?: unknown }).sdkData;\n return (\n typeof sdkData === 'string' &&\n sdkData.length >= 2 &&\n sdkData.length % 2 === 0 &&\n /^[0-9a-f]+$/i.test(sdkData)\n );\n}\n\nexport class WalletApiTokenStorageProvider implements TokenStorageProvider<TxfStorageDataBase> {\n readonly id = 'wallet-api-token-storage';\n readonly name = 'Wallet API Token Storage';\n readonly type = 'cloud' as const;\n\n private readonly client: WalletApiClient;\n private readonly stateStore: KeyValueStore;\n private readonly verifyToken?: (blob: TokenBlob) => Promise<boolean>;\n\n private status: ProviderStatus = 'disconnected';\n private identity: FullIdentity | null = null;\n\n /** Local mirror of the inventory view — active rows and tombstones. */\n private readonly view = new Map<string, InventoryItem>();\n /**\n * Empty-import protection (§5.1): no removal is ever pushed before this\n * flips on the first successful inventory load.\n */\n private hadSuccessfulLoad = false;\n\n constructor(config: WalletApiTokenStorageConfig) {\n this.client = config.client;\n this.stateStore = config.stateStore;\n this.verifyToken = config.verifyToken;\n }\n\n // ── provider lifecycle ──────────────────────────────────────────────────────\n\n setIdentity(identity: FullIdentity): void {\n this.identity = identity;\n this.client.setIdentity({ privateKey: identity.privateKey, chainPubkey: identity.chainPubkey });\n this.view.clear();\n this.hadSuccessfulLoad = false;\n }\n\n async initialize(): Promise<boolean> {\n this.status = 'connected';\n return true;\n }\n\n async shutdown(): Promise<void> {\n this.status = 'disconnected';\n }\n\n async connect(): Promise<void> {\n await this.initialize();\n }\n\n async disconnect(): Promise<void> {\n this.status = 'disconnected';\n }\n\n isConnected(): boolean {\n return this.status === 'connected';\n }\n\n getStatus(): ProviderStatus {\n return this.status;\n }\n\n // ── persisted sync state (per network + identity) ───────────────────────────\n\n private stateKey(kind: string): string {\n if (!this.identity) {\n throw new WalletApiError('No identity set — call setIdentity() first', 'CONFIG');\n }\n return `wallet-api-storage:${kind}:${this.client.network}:${this.identity.chainPubkey}`;\n }\n\n private async readCursor(): Promise<bigint | null> {\n const raw = await this.stateStore.get(this.stateKey('cursor'));\n return raw !== null && /^[0-9]+$/.test(raw) ? BigInt(raw) : null;\n }\n\n private async readSyncEpoch(): Promise<bigint | null> {\n const raw = await this.stateStore.get(this.stateKey('syncEpoch'));\n return raw !== null && /^[0-9]+$/.test(raw) ? BigInt(raw) : null;\n }\n\n private async persistSyncState(cursor: bigint, syncEpoch: bigint): Promise<void> {\n await this.stateStore.set(this.stateKey('cursor'), cursor.toString());\n await this.stateStore.set(this.stateKey('syncEpoch'), syncEpoch.toString());\n }\n\n /** TokenIds this provider itself spent — `recoverRemoved()` skips these. */\n private async readKnownSpends(): Promise<Set<string>> {\n const raw = await this.stateStore.get(this.stateKey('knownSpends'));\n if (!raw) return new Set();\n try {\n return new Set(JSON.parse(raw) as string[]);\n } catch {\n return new Set();\n }\n }\n\n private async addKnownSpends(tokenIds: string[]): Promise<void> {\n if (tokenIds.length === 0) return;\n const known = await this.readKnownSpends();\n for (const id of tokenIds) known.add(id);\n await this.stateStore.set(this.stateKey('knownSpends'), JSON.stringify([...known]));\n }\n\n // ── inventory sync (§5.1) ───────────────────────────────────────────────────\n\n private applyItems(items: InventoryItem[]): void {\n for (const item of items) {\n // Tombstones drop the entry from the active view but stay recorded —\n // recoverRemoved() needs them (§5.3 recovery).\n this.view.set(item.tokenId, item);\n }\n }\n\n /** Full pull + the §5.1 closing delta; replaces the whole local view. */\n private async fullPull(): Promise<void> {\n this.view.clear();\n let page = await this.client.listInventory(undefined);\n const firstPageCursor = page.cursor;\n this.applyItems(page.items);\n while (page.more) {\n page = await this.client.listInventory(page.cursor);\n this.applyItems(page.items);\n }\n // Closing delta from the page-1 cursor: its tombstones repair any flips\n // that happened between pages (§5.1 — a paginated full pull spans snapshots).\n let delta = await this.client.listInventory(firstPageCursor);\n this.applyItems(delta.items);\n while (delta.more) {\n delta = await this.client.listInventory(delta.cursor);\n this.applyItems(delta.items);\n }\n await this.persistSyncState(delta.cursor, delta.syncEpoch);\n }\n\n /**\n * Delta loop from the persisted cursor. Returns `true` when the server's\n * `syncEpoch` no longer matches the persisted one — the cursors are invalid\n * (server restore, §5.4) and the caller must resync from scratch.\n */\n private async deltaLoop(since: bigint): Promise<boolean> {\n const knownEpoch = await this.readSyncEpoch();\n let page = await this.client.listInventory(since);\n if (knownEpoch !== null && page.syncEpoch !== knownEpoch) return true;\n this.applyItems(page.items);\n while (page.more) {\n page = await this.client.listInventory(page.cursor);\n if (knownEpoch !== null && page.syncEpoch !== knownEpoch) return true;\n this.applyItems(page.items);\n }\n await this.persistSyncState(page.cursor, page.syncEpoch);\n return false;\n }\n\n /** §5.4: discard cursors → full pull → re-PUT locally-known open intents. */\n private async handleSyncEpochChange(): Promise<void> {\n await this.stateStore.remove(this.stateKey('cursor'));\n await this.stateStore.remove(this.stateKey('syncEpoch'));\n await this.fullPull();\n await this.client.resyncOpenIntents();\n }\n\n /** Converge the local view with the server (delta when possible). */\n private async syncInventory(): Promise<void> {\n const cursor = await this.readCursor();\n if (cursor === null) {\n await this.fullPull();\n } else if (await this.deltaLoop(cursor)) {\n await this.handleSyncEpochChange();\n }\n this.hadSuccessfulLoad = true;\n }\n\n // ── lazy inventory port (S2) ────────────────────────────────────────────────\n\n /**\n * Without `since`: converge with the server, then return the full active\n * view (`more:false`) — a fresh device renders balances with zero blob\n * downloads. With `since`: a true server delta page (tombstones included),\n * also applied to the local view.\n */\n async listInventory(since?: bigint): Promise<InventoryView> {\n if (since === undefined) {\n await this.syncInventory();\n return this.snapshotView();\n }\n const knownEpoch = await this.readSyncEpoch();\n const page = await this.client.listInventory(since);\n if (knownEpoch !== null && page.syncEpoch !== knownEpoch) {\n // The caller's cursor predates a server restore — resync and hand back\n // the converged snapshot instead of a meaningless delta (§5.4).\n await this.handleSyncEpochChange();\n this.hadSuccessfulLoad = true;\n return this.snapshotView();\n }\n this.applyItems(page.items);\n if (!page.more) {\n const stored = await this.readCursor();\n if (stored === null || page.cursor > stored) {\n await this.persistSyncState(page.cursor, page.syncEpoch);\n }\n }\n return page;\n }\n\n private async snapshotView(): Promise<InventoryView> {\n const items = [...this.view.values()].filter((i) => i.status === 'active');\n const cursor = (await this.readCursor()) ?? 0n;\n const syncEpoch = (await this.readSyncEpoch()) ?? 0n;\n return { cursor, syncEpoch, more: false, items };\n }\n\n /** Fetch + decode one blob on demand via a short-lived signed GET (§5.1). */\n async getToken(tokenId: string): Promise<TokenBlob> {\n const urls = await this.client.getBlobUrls([tokenId]);\n const entry = urls.find((u) => u.tokenId === tokenId);\n if (!entry) {\n throw new WalletApiError(`No blob URL for token ${tokenId} (not owned here)`, 'NOT_FOUND');\n }\n const bytes = await this.client.fetchBlob(entry.getUrl);\n const blob = this.wrapWireBlob(tokenId, bytes);\n if (blob.tokenId !== tokenId) {\n throw new WalletApiError(\n `Blob tokenId mismatch: requested ${tokenId}, blob carries ${blob.tokenId}`,\n 'PROTOCOL'\n );\n }\n return blob;\n }\n\n /**\n * The §16 wire serves RAW token bytes (§5.2/§8.2 — the sphere 39051\n * envelope never crosses the API): re-wrap them for the engine-facing\n * {@link TokenBlob} surface. Envelope bytes (older rows, fake-world seeds)\n * still decode — their embedded tokenId is then checked by the caller. The\n * `network` of a raw wrap is not recoverable without the engine; consumers\n * derive it from the decoded token (`engine.decodeToken` re-wraps), so it\n * is never read from this value.\n */\n private wrapWireBlob(tokenId: string, bytes: Uint8Array): TokenBlob {\n try {\n return decodeTokenBlob(bytes);\n } catch {\n return { v: TOKEN_BLOB_VERSION, network: 0, tokenId, token: bytes };\n }\n }\n\n /**\n * Record a spend (§5.3) — idempotent by `transferId` server-side. MUST be\n * called after the mailbox deposit of the same `transferId` (the backend\n * evidence-checks removals against it). Refreshes the local view from the\n * resulting delta.\n */\n async applyDelta(\n transferId: string,\n spent: string[],\n added: ApplyDeltaAdded[],\n opts?: ApplyDeltaOptions\n ): Promise<void> {\n await this.client.applyInventoryDelta({\n transferId,\n spent,\n added,\n ...(opts?.externalDelivery !== undefined ? { externalDelivery: opts.externalDelivery } : {}),\n });\n await this.addKnownSpends(spent);\n await this.syncInventory();\n }\n\n // ── recovery (§5.3, sdk-changes S2) ─────────────────────────────────────────\n\n /**\n * Re-add tombstoned tokens this client cannot match to a known spend (a\n * wiped view — stolen JWT or a buggy client). Blobs are retained server-side\n * and blob-urls works for own tombstoned rows; each candidate is re-fetched,\n * locally verified, and re-added (reactivation). A `409` is the server's\n * verdict that the tombstone is an evidenced spend — kept as spent.\n */\n async recoverRemoved(): Promise<RecoverRemovedResult> {\n await this.syncInventory();\n const knownSpends = await this.readKnownSpends();\n const result: RecoverRemovedResult = { recovered: [], spent: [], skipped: [] };\n\n const candidates = [...this.view.values()].filter(\n (i) => i.status === 'removed' && !knownSpends.has(i.tokenId)\n );\n for (const item of candidates) {\n const blobBytes = await this.fetchRemovedBlob(item.tokenId);\n if (blobBytes === null || !(await this.locallyValid(item.tokenId, blobBytes))) {\n result.skipped.push(item.tokenId);\n continue;\n }\n // Content-addressed key of the exact bytes we verified (§5.2).\n const key = `${this.client.network}/t/${bytesToHex(sha256(blobBytes))}`;\n try {\n await this.client.applyInventoryDelta({\n transferId: newTransferId(),\n spent: [],\n added: [{ tokenId: item.tokenId, key }],\n });\n result.recovered.push(item.tokenId);\n } catch (err) {\n if (err instanceof WalletApiError && err.code === 'CONFLICT') {\n // Evidenced tombstone (or the token moved on) — actually spent (§5.3).\n result.spent.push(item.tokenId);\n await this.addKnownSpends([item.tokenId]);\n } else {\n throw err;\n }\n }\n }\n\n await this.syncInventory();\n return result;\n }\n\n private async fetchRemovedBlob(tokenId: string): Promise<Uint8Array | null> {\n const urls = await this.client.getBlobUrls([tokenId]);\n const entry = urls.find((u) => u.tokenId === tokenId);\n if (!entry) return null;\n try {\n return await this.client.fetchBlob(entry.getUrl);\n } catch {\n return null;\n }\n }\n\n private async locallyValid(tokenId: string, bytes: Uint8Array): Promise<boolean> {\n const blob = this.wrapWireBlob(tokenId, bytes);\n if (blob.tokenId !== tokenId) return false;\n if (this.verifyToken) return this.verifyToken(blob);\n return true;\n }\n\n // ── whole-blob surface (thin: the hot path is the lazy port above) ──────────\n\n /**\n * Thin view: converges with the server and reports tombstones, but carries\n * NO token entries — blobs are fetched on demand via `getToken()`\n * (sdk-changes S2: `load()` no longer eagerly pulls every blob).\n */\n async load(): Promise<LoadResult<TxfStorageDataBase>> {\n try {\n await this.syncInventory();\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'inventory sync failed',\n source: 'remote',\n timestamp: Date.now(),\n };\n }\n const data: TxfStorageDataBase = {\n _meta: {\n version: 1,\n address: this.identity?.l1Address ?? '',\n formatVersion: '2.0',\n updatedAt: Date.now(),\n },\n _tombstones: [...this.view.values()]\n .filter((i) => i.status === 'removed')\n .map((i) => ({ tokenId: i.tokenId, stateHash: '', timestamp: Date.now() })),\n };\n return { success: true, data, source: 'remote', timestamp: Date.now() };\n }\n\n /**\n * Write-behind push of a whole-blob snapshot:\n * - unknown tokens are uploaded (content-addressed, 412 = already present)\n * and added via one idempotent apply;\n * - removals are pushed ONLY for confirmed spends (`_tombstones` entries)\n * and ONLY after a successful inventory load (empty-import protection,\n * §5.1) — a merely-absent token is never removed.\n * A failed sync fails the save: pushing against an unknown server view\n * could only do harm.\n */\n async save(data: TxfStorageDataBase): Promise<SaveResult> {\n try {\n await this.syncInventory();\n const tombstoneIds = new Set((data._tombstones ?? []).map((t) => t.tokenId));\n await this.pushAdditions(data, tombstoneIds);\n await this.pushRemovals(tombstoneIds);\n await this.syncInventory();\n return { success: true, timestamp: Date.now() };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'wallet-api save failed',\n timestamp: Date.now(),\n };\n }\n }\n\n private async pushAdditions(data: TxfStorageDataBase, excluded: Set<string>): Promise<void> {\n const toAdd: { tokenId: string; bytes: Uint8Array }[] = [];\n for (const [key, value] of Object.entries(data)) {\n if (!/^_[0-9a-f]{4,}$/i.test(key) || !isV2BlobEntry(value)) continue;\n const tokenId = key.slice(1);\n // Skip tokens the server already knows: an equal-state re-push of an\n // active row is a lineage 409 (§5.3), and tombstoned tokens re-enter\n // via recoverRemoved(), never via write-behind.\n if (excluded.has(tokenId) || this.view.has(tokenId)) continue;\n // §5.2/§8.2: the wire carries the RAW token bytes — the stored sdkData\n // is the sphere envelope; unwrap it at the wallet-api boundary.\n toAdd.push({ tokenId, bytes: unwrapTokenBlobBytes(hexToBytes(value.sdkData)) });\n }\n if (toAdd.length === 0) return;\n\n const urls = await this.client.getUploadUrls(\n toAdd.map((t) => ({ sha256: bytesToHex(sha256(t.bytes)), size: t.bytes.length }))\n );\n const added: ApplyDeltaAdded[] = [];\n for (const token of toAdd) {\n const sha = bytesToHex(sha256(token.bytes));\n const url = urls.find((u) => u.sha256 === sha);\n if (!url) {\n throw new WalletApiError(`upload-urls response missing sha256 ${sha}`, 'PROTOCOL');\n }\n await this.client.uploadBlob(url.putUrl, token.bytes); // 412 = already present = success (§5.2)\n added.push({ tokenId: token.tokenId, key: url.key });\n }\n await this.client.applyInventoryDelta({ transferId: newTransferId(), spent: [], added });\n }\n\n private async pushRemovals(tombstoneIds: Set<string>): Promise<void> {\n // Empty-import protection (§5.1): never push a removal before the first\n // successful inventory load; a spent token is removed only against a\n // confirmed on-chain spend (a tombstone), never mere absence.\n if (!this.hadSuccessfulLoad || tombstoneIds.size === 0) return;\n const spent = [...tombstoneIds].filter((id) => this.view.get(id)?.status === 'active');\n if (spent.length === 0) return;\n await this.client.applyInventoryDelta({ transferId: newTransferId(), spent, added: [] });\n await this.addKnownSpends(spent);\n }\n\n async sync(localData: TxfStorageDataBase): Promise<SyncResult<TxfStorageDataBase>> {\n const result = await this.save(localData);\n return {\n success: result.success,\n merged: localData,\n added: 0,\n removed: 0,\n conflicts: 0,\n error: result.error,\n };\n }\n}\n\nexport function createWalletApiTokenStorageProvider(\n config: WalletApiTokenStorageConfig\n): WalletApiTokenStorageProvider {\n return new WalletApiTokenStorageProvider(config);\n}\n","/**\n * transport/delivery-provider.ts — the `DeliveryProvider` port (sdk-changes S7,\n * covenant §3.1-6).\n *\n * The seam that keeps the delivery rail swappable. In Unicity, a transfer —\n * after certification — is just a file handoff, so the port is deliberately\n * tiny: hand a finished token blob to a recipient, pull incoming deliveries,\n * acknowledge them. `WalletApiMailboxProvider`\n * (impl/shared/wallet-api/WalletApiMailboxProvider.ts) is the reference\n * implementation; anything that can move a file can implement it (the port\n * shape must not preclude the old Nostr transport or a future federated\n * transport — neither is a deliverable here).\n *\n * Normative shapes (sdk-changes S7):\n * - `DeliveryReceipt = { deliveryId }`\n * - `IncomingDelivery = { deliveryId, transferId?, senderPubkey?, memo?,\n * fetchBlob(), cursor }`\n * - `deliveryId` is the **content-derived** entry id —\n * `hex(SHA-256(tokenId bytes ‖ stateHash bytes))` — NEVER a server-assigned\n * row id or seq (covenant §3.1-4; the contract suite asserts it). It is\n * computed client-side ({@link computeDeliveryId}) and must equal the\n * backend's `entry_id` (ARCHITECTURE §6).\n * - **Custody is a composition-time property, not a per-call flag**:\n * implementations take `custody: 'inventory' | 'external'` at construction\n * and every ack sends the corresponding `intoInventory` — delivery-only\n * safety must never depend on remembering an option at a call site.\n * - Implementations MUST keep a **persistent `(tokenId, stateHash)` seen-set**\n * for incoming deliveries: the recipient-side replay guard is part of the\n * port contract, not a server promise (the recipient never trusts the\n * backend — ARCHITECTURE §8.2). `deliveryId` is the canonical hash encoding\n * of exactly that pair, so a persistent deliveryId set satisfies this.\n */\n\nimport { sha256 } from '@noble/hashes/sha2.js';\n\n\n// =============================================================================\n// Normative shapes (sdk-changes S7)\n// =============================================================================\n\n/** Receipt for a delivered blob. `deliveryId` is content-derived — see module doc. */\nexport interface DeliveryReceipt {\n deliveryId: string;\n}\n\n/** Options for {@link DeliveryProvider.deliver}. */\nexport interface DeliverOptions {\n /**\n * The send's transferId (the E.3 intent id / realization seed). Recorded\n * with the delivery so the recipient can group multi-token payments and the\n * backend can evidence-check the sender's removals (ARCHITECTURE §5.3/§6).\n */\n transferId: string;\n /** Optional human memo. Implementations encrypt it client-side (S6). */\n memo?: string;\n}\n\n/** One incoming delivery pulled from the feed. */\nexport interface IncomingDelivery {\n /** Content-derived id — `hex(SHA-256(tokenId bytes ‖ stateHash bytes))`. */\n deliveryId: string;\n /** The sender's transferId, when the transport carries it. */\n transferId?: string;\n /** The sender's pubkey, when the transport carries it. */\n senderPubkey?: string;\n /** Decrypted memo (S6), when present and decryptable. */\n memo?: string;\n /** Fetch the finished token blob bytes (the encoded TokenBlob). */\n fetchBlob(): Promise<Uint8Array>;\n /** Transport-local resume cursor (opaque to callers). */\n cursor: string;\n}\n\nexport type DeliveryDisposition = 'claimed' | 'rejected';\n\n/**\n * Custody mode (composition-time): `'inventory'` — acknowledged deliveries\n * enter the wallet-api inventory (the full wallet-api preset); `'external'` —\n * the app's own storage keeps custody and acks perform ZERO inventory writes\n * (the delivery-only preset, ARCHITECTURE §6 \"delivery-only claim\").\n */\nexport type DeliveryCustody = 'inventory' | 'external';\n\n// =============================================================================\n// The port\n// =============================================================================\n\nexport interface DeliveryProvider {\n /** Composition-time custody property — never a per-call flag (S7). */\n readonly custody: DeliveryCustody;\n\n /**\n * Bind the wallet identity (optional — implementations that authenticate or\n * encrypt per-wallet need it; mirrors `TokenStorageProvider.setIdentity`).\n */\n setIdentity?(identity: { privateKey: string; chainPubkey: string }): void;\n\n /**\n * Hand a finished token blob to a recipient. `recipientPubkey` is the\n * recipient's CHAIN pubkey (33-byte compressed secp256k1, hex) — the\n * canonical Unicity identity (ARCHITECTURE §4); transports that address\n * recipients differently resolve it themselves.\n *\n * MUST be idempotent per (token, state): re-delivering the same finished\n * blob — including after the recipient claimed — succeeds and returns the\n * same content-derived `deliveryId` (ARCHITECTURE §6 deposit idempotency).\n */\n deliver(recipientPubkey: string, blob: Uint8Array, options: DeliverOptions): Promise<DeliveryReceipt>;\n\n /**\n * Pull-based feed of incoming deliveries since the given transport-local\n * cursor (or the provider's persisted cursor when omitted). Yields only\n * deliveries not yet in the persistent seen-set; completes when the feed is\n * drained — callers re-invoke on poll/wake. Feeds the existing\n * transport-agnostic `handleV2Transfer` (sdk-changes S3).\n */\n incoming(sinceCursor?: string): AsyncIterable<IncomingDelivery>;\n\n /**\n * Acknowledge a delivery: `'claimed'` accepts it (with the provider's\n * composition-time custody), `'rejected'` marks it locally-unverifiable —\n * terminal for discovery only (the entry stays claimable server-side and\n * its blob is retained — ARCHITECTURE §6). Both record the delivery in the\n * persistent seen-set.\n */\n ack(deliveryId: string, disposition: DeliveryDisposition): Promise<void>;\n\n /**\n * Optional wake hook: `callback` fires when new deliveries may be available\n * (e.g. a WS nudge — never a correctness dependency, ARCHITECTURE §9).\n * Returns an unsubscribe function.\n */\n onWake?(callback: () => void): () => void;\n\n /**\n * Late-bind the backend-true (tokenId, stateHash) derivation —\n * `ITokenEngine.deliveryKeys`. Compositions are engine-less (the engine is\n * built later); the module that owns both (PaymentsModule) binds this at\n * init. Implementations that derive ids (S7) MUST use it and fail loudly if\n * unbound; transports that don't derive may omit the method.\n */\n bindDeliveryKeys?(derive: (blobBytes: Uint8Array) => Promise<{ tokenId: string; stateHash: string }>): void;\n}\n\n// =============================================================================\n// deliveryId derivation (the backend's entry_id formula — ARCHITECTURE §6)\n// =============================================================================\n\nfunction hexToBytes(hex: string): Uint8Array {\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < out.length; i++) out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n return out;\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');\n}\n\n/**\n * The content-derived delivery id:\n * `hex(SHA-256(tokenId bytes ‖ stateHash bytes))` — identical to the\n * backend's `entry_id` (ARCHITECTURE §6), computed client-side so no\n * implementation can substitute a server row id (covenant §3.1-4).\n *\n * @param tokenIdHex - genesis-stable 64-hex token id\n * @param stateHashHex - the SDK's per-state hash (DataHash imprint, hex) — the\n * backend's `state_hash` (wallet-api validation/chain.ts); NEVER a plain\n * sha256 over the token bytes (that variant 422s on deposit).\n */\nexport function computeDeliveryId(tokenIdHex: string, stateHashHex: string): string {\n const tokenId = hexToBytes(tokenIdHex);\n const stateHash = hexToBytes(stateHashHex);\n const joined = new Uint8Array(tokenId.length + stateHash.length);\n joined.set(tokenId, 0);\n joined.set(stateHash, tokenId.length);\n return bytesToHex(sha256(joined));\n}\n\n/** Full delivery keys: the engine-derived pair + the composed deliveryId. */\nexport interface DeliveryBlobKeys {\n /** Genesis-stable 64-hex token id (from the TokenBlob envelope). */\n tokenId: string;\n /** Per-state hash: `hex(SHA-256(inner token bytes))` — changes every transfer. */\n stateHash: string;\n /** {@link computeDeliveryId} of the two above. */\n deliveryId: string;\n}\n\n/**\n * Derive (tokenId, stateHash, deliveryId) from encoded TokenBlob bytes.\n * Throws when the bytes are not a decodable TokenBlob.\n */\n/**\n * Compose full delivery keys from an engine-derived (tokenId, stateHash) pair.\n * The pair MUST come from `ITokenEngine.deliveryKeys` (the backend-true SDK\n * derivation) — the port module deliberately cannot decode tokens itself.\n */\nexport function composeDeliveryKeys(keys: { tokenId: string; stateHash: string }): DeliveryBlobKeys {\n return { ...keys, deliveryId: computeDeliveryId(keys.tokenId, keys.stateHash) };\n}\n","/**\n * HMAC: RFC2104 message authentication code.\n * @module\n */\nimport {\n abytes,\n aexists,\n ahash,\n aoutput,\n clean,\n type CHash,\n type Hash,\n type TArg,\n type TRet,\n} from './utils.ts';\n\n/**\n * Internal class for HMAC.\n * Accepts any byte key, although RFC 2104 §3 recommends keys at least\n * `HashLen` bytes long.\n */\nexport class _HMAC<T extends Hash<T>> implements Hash<_HMAC<T>> {\n oHash: T;\n iHash: T;\n blockLen: number;\n outputLen: number;\n canXOF = false;\n private finished = false;\n private destroyed = false;\n\n constructor(hash: TArg<CHash>, key: TArg<Uint8Array>) {\n ahash(hash);\n abytes(key, undefined, 'key');\n this.iHash = hash.create() as T;\n if (typeof this.iHash.update !== 'function')\n throw new Error('Expected instance of class which extends utils.Hash');\n this.blockLen = this.iHash.blockLen;\n this.outputLen = this.iHash.outputLen;\n const blockLen = this.blockLen;\n const pad = new Uint8Array(blockLen);\n // blockLen can be bigger than outputLen\n pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);\n for (let i = 0; i < pad.length; i++) pad[i] ^= 0x36;\n this.iHash.update(pad);\n // By doing update (processing of the first block) of the outer hash here,\n // we can re-use it between multiple calls via clone.\n this.oHash = hash.create() as T;\n // Undo internal XOR && apply outer XOR\n for (let i = 0; i < pad.length; i++) pad[i] ^= 0x36 ^ 0x5c;\n this.oHash.update(pad);\n clean(pad);\n }\n update(buf: TArg<Uint8Array>): this {\n aexists(this);\n this.iHash.update(buf);\n return this;\n }\n digestInto(out: TArg<Uint8Array>): void {\n aexists(this);\n aoutput(out, this);\n this.finished = true;\n const buf = out.subarray(0, this.outputLen);\n // Reuse the first outputLen bytes for the inner digest; the outer hash consumes them before\n // overwriting that same prefix with the final tag, leaving any oversized tail untouched.\n this.iHash.digestInto(buf);\n this.oHash.update(buf);\n this.oHash.digestInto(buf);\n this.destroy();\n }\n digest(): TRet<Uint8Array> {\n const out = new Uint8Array(this.oHash.outputLen);\n this.digestInto(out);\n return out as TRet<Uint8Array>;\n }\n _cloneInto(to?: _HMAC<T>): _HMAC<T> {\n // Create new instance without calling constructor since the key\n // is already in state and we don't know it.\n to ||= Object.create(Object.getPrototypeOf(this), {});\n const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;\n to = to as this;\n to.finished = finished;\n to.destroyed = destroyed;\n to.blockLen = blockLen;\n to.outputLen = outputLen;\n to.oHash = oHash._cloneInto(to.oHash);\n to.iHash = iHash._cloneInto(to.iHash);\n return to;\n }\n clone(): _HMAC<T> {\n return this._cloneInto();\n }\n destroy(): void {\n this.destroyed = true;\n this.oHash.destroy();\n this.iHash.destroy();\n }\n}\n\n/**\n * HMAC: RFC2104 message authentication code.\n * @param hash - function that would be used e.g. sha256\n * @param key - authentication key bytes\n * @param message - message bytes to authenticate\n * @returns Authentication tag bytes.\n * @example\n * Compute an RFC 2104 HMAC.\n * ```ts\n * import { hmac } from '@noble/hashes/hmac.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const mac = hmac(sha256, new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6]));\n * ```\n */\ntype HmacFn = {\n (hash: TArg<CHash>, key: TArg<Uint8Array>, message: TArg<Uint8Array>): TRet<Uint8Array>;\n create(hash: TArg<CHash>, key: TArg<Uint8Array>): TRet<_HMAC<any>>;\n};\nexport const hmac: TRet<HmacFn> = /* @__PURE__ */ (() => {\n const hmac_ = ((\n hash: TArg<CHash>,\n key: TArg<Uint8Array>,\n message: TArg<Uint8Array>\n ): TRet<Uint8Array> => new _HMAC<any>(hash, key).update(message).digest()) as TRet<HmacFn>;\n hmac_.create = (hash: TArg<CHash>, key: TArg<Uint8Array>): TRet<_HMAC<any>> =>\n new _HMAC<any>(hash, key) as TRet<_HMAC<any>>;\n return hmac_;\n})();\n","/**\n * HKDF (RFC 5869): extract + expand in one step.\n * See {@link https://soatok.blog/2021/11/17/understanding-hkdf/}.\n * @module\n */\nimport { hmac } from './hmac.ts';\nimport { abytes, ahash, anumber, type CHash, clean, type TArg, type TRet } from './utils.ts';\n\n/**\n * HKDF-extract from spec. Less important part. `HKDF-Extract(IKM, salt) -> PRK`\n * Arguments position differs from spec (IKM is first one, since it is not optional)\n * Local validation only checks `hash`; `ikm` / `salt` byte validation is delegated to `hmac()`.\n * @param hash - hash function that would be used (e.g. sha256)\n * @param ikm - input keying material, the initial key\n * @param salt - optional salt value (a non-secret random value)\n * @returns Pseudorandom key derived from input keying material.\n * @example\n * Run the HKDF extract step.\n * ```ts\n * import { extract } from '@noble/hashes/hkdf.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * extract(sha256, new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6]));\n * ```\n */\nexport function extract(\n hash: TArg<CHash>,\n ikm: TArg<Uint8Array>,\n salt?: TArg<Uint8Array>\n): TRet<Uint8Array> {\n ahash(hash);\n // NOTE: some libraries treat zero-length array as 'not provided';\n // we don't, since we have undefined as 'not provided'\n // https://github.com/RustCrypto/KDFs/issues/15\n if (salt === undefined) salt = new Uint8Array(hash.outputLen);\n return hmac(hash, salt, ikm);\n}\n\n// Shared mutable scratch byte for the RFC 5869 block counter `N`.\n// Safe to reuse because `expand()` is synchronous and resets it with `clean(...)` before returning.\nconst HKDF_COUNTER = /* @__PURE__ */ Uint8Array.of(0);\n// Shared RFC 5869 empty string for both `info === undefined` and the first-block `T(0)` input.\nconst EMPTY_BUFFER = /* @__PURE__ */ Uint8Array.of();\n\n/**\n * HKDF-expand from the spec. The most important part. `HKDF-Expand(PRK, info, L) -> OKM`\n * @param hash - hash function that would be used (e.g. sha256)\n * @param prk - a pseudorandom key of at least HashLen octets\n * (usually, the output from the extract step)\n * @param info - optional context and application specific information (can be a zero-length string)\n * @param length - length of output keying material in bytes.\n * RFC 5869 §2.3 allows `0..255*HashLen`, so `0` returns an empty OKM.\n * @returns Output keying material with the requested length.\n * @throws If the requested output length exceeds the HKDF limit\n * for the selected hash. {@link Error}\n * @example\n * Run the HKDF expand step.\n * ```ts\n * import { expand } from '@noble/hashes/hkdf.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * expand(sha256, new Uint8Array(32), new Uint8Array([1, 2, 3]), 16);\n * ```\n */\nexport function expand(\n hash: TArg<CHash>,\n prk: TArg<Uint8Array>,\n info?: TArg<Uint8Array>,\n length: number = 32\n): TRet<Uint8Array> {\n ahash(hash);\n anumber(length, 'length');\n abytes(prk, undefined, 'prk');\n const olen = hash.outputLen;\n // RFC 5869 §2.3: PRK is \"a pseudorandom key of at least HashLen octets\".\n if (prk.length < olen) throw new Error('\"prk\" must be at least HashLen octets');\n // RFC 5869 §2.3 only bounds `L` by `<= 255*HashLen`; `L=0` is valid and yields empty OKM.\n if (length > 255 * olen) throw new Error('Length must be <= 255*HashLen');\n const blocks = Math.ceil(length / olen);\n if (info === undefined) info = EMPTY_BUFFER;\n else abytes(info, undefined, 'info');\n // first L(ength) octets of T\n const okm = new Uint8Array(blocks * olen);\n // Re-use HMAC instance between blocks\n const HMAC = hmac.create(hash, prk);\n const HMACTmp = HMAC._cloneInto();\n const T = new Uint8Array(HMAC.outputLen);\n for (let counter = 0; counter < blocks; counter++) {\n HKDF_COUNTER[0] = counter + 1;\n // T(0) = empty string (zero length)\n // T(N) = HMAC-Hash(PRK, T(N-1) | info | N)\n HMACTmp.update(counter === 0 ? EMPTY_BUFFER : T)\n .update(info)\n .update(HKDF_COUNTER)\n .digestInto(T);\n okm.set(T, olen * counter);\n HMAC._cloneInto(HMACTmp);\n }\n HMAC.destroy();\n HMACTmp.destroy();\n clean(T, HKDF_COUNTER);\n return okm.slice(0, length) as TRet<Uint8Array>;\n}\n\n/**\n * HKDF (RFC 5869): derive keys from an initial input.\n * Combines hkdf_extract + hkdf_expand in one step\n * @param hash - hash function that would be used (e.g. sha256)\n * @param ikm - input keying material, the initial key\n * @param salt - optional salt value (a non-secret random value)\n * @param info - optional context and application specific information bytes\n * @param length - length of output keying material in bytes.\n * RFC 5869 §2.3 allows `0..255*HashLen`, so `0` returns an empty OKM.\n * @returns Output keying material derived from the input key.\n * @throws If the requested output length exceeds the HKDF limit\n * for the selected hash. {@link Error}\n * @example\n * HKDF (RFC 5869): derive keys from an initial input.\n * ```ts\n * import { hkdf } from '@noble/hashes/hkdf.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * import { randomBytes, utf8ToBytes } from '@noble/hashes/utils.js';\n * const inputKey = randomBytes(32);\n * const salt = randomBytes(32);\n * const info = utf8ToBytes('application-key');\n * const okm = hkdf(sha256, inputKey, salt, info, 32);\n * ```\n */\nexport const hkdf = (\n hash: TArg<CHash>,\n ikm: TArg<Uint8Array>,\n salt: TArg<Uint8Array | undefined>,\n info: TArg<Uint8Array | undefined>,\n length: number\n): TRet<Uint8Array> => expand(hash, extract(hash, ikm, salt), info, length);\n","/**\n * Utilities for hex, bytes, CSPRNG.\n * @module\n */\n/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */\n\n/**\n * Bytes API type helpers for old + new TypeScript.\n *\n * TS 5.6 has `Uint8Array`, while TS 5.9+ made it generic `Uint8Array<ArrayBuffer>`.\n * We can't use specific return type, because TS 5.6 will error.\n * We can't use generic return type, because most TS 5.9 software will expect specific type.\n *\n * Maps typed-array input leaves to broad forms.\n * These are compatibility adapters, not ownership guarantees.\n *\n * - `TArg` keeps byte inputs broad.\n * - `TRet` marks byte outputs for TS 5.6 and TS 5.9+ compatibility.\n */\nexport type TypedArg<T> = T extends BigInt64Array\n ? BigInt64Array\n : T extends BigUint64Array\n ? BigUint64Array\n : T extends Float32Array\n ? Float32Array\n : T extends Float64Array\n ? Float64Array\n : T extends Int16Array\n ? Int16Array\n : T extends Int32Array\n ? Int32Array\n : T extends Int8Array\n ? Int8Array\n : T extends Uint16Array\n ? Uint16Array\n : T extends Uint32Array\n ? Uint32Array\n : T extends Uint8ClampedArray\n ? Uint8ClampedArray\n : T extends Uint8Array\n ? Uint8Array\n : never;\n/** Maps typed-array output leaves to narrow TS-compatible forms. */\nexport type TypedRet<T> = T extends BigInt64Array\n ? ReturnType<typeof BigInt64Array.of>\n : T extends BigUint64Array\n ? ReturnType<typeof BigUint64Array.of>\n : T extends Float32Array\n ? ReturnType<typeof Float32Array.of>\n : T extends Float64Array\n ? ReturnType<typeof Float64Array.of>\n : T extends Int16Array\n ? ReturnType<typeof Int16Array.of>\n : T extends Int32Array\n ? ReturnType<typeof Int32Array.of>\n : T extends Int8Array\n ? ReturnType<typeof Int8Array.of>\n : T extends Uint16Array\n ? ReturnType<typeof Uint16Array.of>\n : T extends Uint32Array\n ? ReturnType<typeof Uint32Array.of>\n : T extends Uint8ClampedArray\n ? ReturnType<typeof Uint8ClampedArray.of>\n : T extends Uint8Array\n ? ReturnType<typeof Uint8Array.of>\n : never;\n/** Recursively adapts byte-carrying API input types. See {@link TypedArg}. */\nexport type TArg<T> =\n | T\n | ([TypedArg<T>] extends [never]\n ? T extends (...args: infer A) => infer R\n ? ((...args: { [K in keyof A]: TRet<A[K]> }) => TArg<R>) & {\n [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TArg<T[K]>;\n }\n : T extends [infer A, ...infer R]\n ? [TArg<A>, ...{ [K in keyof R]: TArg<R[K]> }]\n : T extends readonly [infer A, ...infer R]\n ? readonly [TArg<A>, ...{ [K in keyof R]: TArg<R[K]> }]\n : T extends (infer A)[]\n ? TArg<A>[]\n : T extends readonly (infer A)[]\n ? readonly TArg<A>[]\n : T extends Promise<infer A>\n ? Promise<TArg<A>>\n : T extends object\n ? { [K in keyof T]: TArg<T[K]> }\n : T\n : TypedArg<T>);\n/** Recursively adapts byte-carrying API output types. See {@link TypedArg}. */\nexport type TRet<T> = T extends unknown\n ? T &\n ([TypedRet<T>] extends [never]\n ? T extends (...args: infer A) => infer R\n ? ((...args: { [K in keyof A]: TArg<A[K]> }) => TRet<R>) & {\n [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TRet<T[K]>;\n }\n : T extends [infer A, ...infer R]\n ? [TRet<A>, ...{ [K in keyof R]: TRet<R[K]> }]\n : T extends readonly [infer A, ...infer R]\n ? readonly [TRet<A>, ...{ [K in keyof R]: TRet<R[K]> }]\n : T extends (infer A)[]\n ? TRet<A>[]\n : T extends readonly (infer A)[]\n ? readonly TRet<A>[]\n : T extends Promise<infer A>\n ? Promise<TRet<A>>\n : T extends object\n ? { [K in keyof T]: TRet<T[K]> }\n : T\n : TypedRet<T>)\n : never;\n\n/**\n * Checks if something is Uint8Array. Be careful: nodejs Buffer will return true.\n * @param a - Value to inspect.\n * @returns `true` when the value is a Uint8Array view, including Node's `Buffer`.\n * @example\n * Guards a value before treating it as raw key material.\n *\n * ```ts\n * isBytes(new Uint8Array());\n * ```\n */\nexport function isBytes(a: unknown): a is Uint8Array {\n // Plain `instanceof Uint8Array` is too strict for some Buffer / proxy /\n // cross-realm cases. The fallback still requires a real ArrayBuffer view\n // so plain JSON-deserialized `{ constructor: ... }`\n // spoofing is rejected, and `BYTES_PER_ELEMENT === 1` keeps the fallback on byte-oriented views.\n return (\n a instanceof Uint8Array ||\n (ArrayBuffer.isView(a) &&\n a.constructor.name === 'Uint8Array' &&\n 'BYTES_PER_ELEMENT' in a &&\n a.BYTES_PER_ELEMENT === 1)\n );\n}\n\n/**\n * Asserts something is boolean.\n * @param b - Value to validate.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Validates a boolean option before branching on it.\n *\n * ```ts\n * abool(true);\n * ```\n */\nexport function abool(b: boolean): void {\n if (typeof b !== 'boolean') throw new TypeError(`boolean expected, not ${b}`);\n}\n\n/**\n * Asserts something is a non-negative safe integer.\n * @param n - Value to validate.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Validates a non-negative length or counter.\n *\n * ```ts\n * anumber(1);\n * ```\n */\nexport function anumber(n: number): void {\n if (typeof n !== 'number') throw new TypeError('number expected, got ' + typeof n);\n if (!Number.isSafeInteger(n) || n < 0)\n throw new RangeError('positive integer expected, got ' + n);\n}\n\n/**\n * Asserts something is Uint8Array.\n * @param value - Value to validate.\n * @param length - Expected byte length.\n * @param title - Optional label used in error messages.\n * @returns The validated byte array.\n * On Node, `Buffer` is accepted too because it is a Uint8Array view.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument lengths. {@link RangeError}\n * @example\n * Validates a fixed-length nonce or key buffer.\n *\n * ```ts\n * abytes(new Uint8Array([1, 2]), 2);\n * ```\n */\nexport function abytes(\n value: TArg<Uint8Array>,\n length?: number,\n title: string = ''\n): TRet<Uint8Array> {\n const bytes = isBytes(value);\n const len = value?.length;\n const needsLen = length !== undefined;\n if (!bytes || (needsLen && len !== length)) {\n const prefix = title && `\"${title}\" `;\n const ofLen = needsLen ? ` of length ${length}` : '';\n const got = bytes ? `length=${len}` : `type=${typeof value}`;\n const message = prefix + 'expected Uint8Array' + ofLen + ', got ' + got;\n if (!bytes) throw new TypeError(message);\n throw new RangeError(message);\n }\n return value as TRet<Uint8Array>;\n}\n\n/**\n * Asserts a hash- or MAC-like instance has not been destroyed or finished.\n * @param instance - Stateful instance to validate.\n * @param checkFinished - Whether to reject finished instances.\n * When `false`, only `destroyed` is checked.\n * @throws If the hash instance has already been destroyed or finalized. {@link Error}\n * @example\n * Guards against calling `update()` or `digest()` on a finished hash.\n *\n * ```ts\n * aexists({ destroyed: false, finished: false });\n * ```\n */\nexport function aexists(instance: any, checkFinished = true): void {\n if (instance.destroyed) throw new Error('Hash instance has been destroyed');\n if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called');\n}\n\n/**\n * Asserts output is a properly-sized byte array.\n * @param out - Output buffer to validate.\n * @param instance - Hash-like instance providing `outputLen`.\n * This is the relaxed `digestInto()`-style contract: output must be at least `outputLen`,\n * unlike one-shot cipher helpers elsewhere in the repo that often require exact lengths.\n * @throws On wrong argument types. {@link TypeError}\n * @param onlyAligned - Whether `out` must be 4-byte aligned for zero-allocation word views.\n * @throws On wrong output buffer lengths. {@link RangeError}\n * @throws On wrong output buffer alignment. {@link Error}\n * @example\n * Verifies that a caller-provided output buffer is large enough.\n *\n * ```ts\n * aoutput(new Uint8Array(16), { outputLen: 16 });\n * ```\n */\nexport function aoutput(out: any, instance: any, onlyAligned = false): void {\n abytes(out, undefined, 'output');\n const min = instance.outputLen;\n if (out.length < min) {\n throw new RangeError('digestInto() expects output buffer of length at least ' + min);\n }\n if (onlyAligned && !isAligned32(out)) throw new Error('invalid output, must be aligned');\n}\n\n/** One-shot hash helper with `.create()`. */\nexport type IHash = {\n (data: string | TArg<Uint8Array>): TRet<Uint8Array>;\n /** Input block size in bytes. */\n blockLen: number;\n /** Digest size in bytes. */\n outputLen: number;\n /** Creates a fresh incremental hash instance of the same algorithm. */\n create: any;\n};\n\n/** One-shot MAC helper with `.create()`. */\nexport type CMac<H extends IHash2 = IHash2, A extends any[] = []> = {\n (msg: TArg<Uint8Array>, key: TArg<Uint8Array>): TRet<Uint8Array>;\n /** Input block size in bytes. */\n blockLen: number;\n /** Digest size in bytes. */\n outputLen: number;\n /**\n * Creates a fresh incremental MAC instance of the same algorithm.\n * @param key - MAC key bytes.\n * @param args - Additional constructor arguments, when the MAC wrapper needs them.\n * @returns Fresh incremental MAC instance.\n */\n create(key: TArg<Uint8Array>, ...args: A): H;\n};\n\n/** Generic type encompassing 8/16/32-bit typed arrays, but not 64-bit. */\n// prettier-ignore\nexport type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array |\n Uint16Array | Int16Array | Uint32Array | Int32Array;\n\n/**\n * Casts a typed-array view to Uint8Array.\n * @param arr - Typed-array view to reinterpret.\n * @returns Uint8Array view over the same bytes.\n * @example\n * Views 32-bit words as raw bytes without copying.\n *\n * ```ts\n * u8(new Uint32Array([1]));\n * ```\n */\nexport function u8(arr: TArg<TypedArray>): TRet<Uint8Array> {\n return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength) as TRet<Uint8Array>;\n}\n\n/**\n * Casts a typed-array view to Uint32Array.\n * @param arr - Typed-array view to reinterpret.\n * @returns Uint32Array view over the same bytes. Callers are expected to provide a\n * 4-byte-aligned offset; trailing `1..3` bytes are silently dropped.\n * @example\n * Views a byte buffer as 32-bit words for block processing.\n *\n * ```ts\n * u32(new Uint8Array(4));\n * ```\n */\nexport function u32(arr: TArg<TypedArray>): TRet<Uint32Array> {\n return new Uint32Array(\n arr.buffer,\n arr.byteOffset,\n Math.floor(arr.byteLength / 4)\n ) as TRet<Uint32Array>;\n}\n\n/**\n * Zeroizes typed arrays in place.\n * Warning: JS provides no guarantees.\n * @param arrays - Arrays to wipe.\n * @example\n * Wipes a temporary key buffer after use.\n *\n * ```ts\n * const bytes = new Uint8Array([1]);\n * clean(bytes);\n * ```\n */\nexport function clean(...arrays: TArg<TypedArray[]>): void {\n for (let i = 0; i < arrays.length; i++) {\n arrays[i].fill(0);\n }\n}\n\n/**\n * Creates a DataView for byte-level manipulation.\n * @param arr - Typed-array view to wrap.\n * @returns DataView over the same bytes.\n * @example\n * Creates an endian-aware view for length encoding.\n *\n * ```ts\n * createView(new Uint8Array(4));\n * ```\n */\nexport function createView(arr: TArg<TypedArray>): DataView {\n return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n\n/**\n * Whether the current platform is little-endian.\n * Most are; some IBM systems are not.\n */\nexport const isLE: boolean = /* @__PURE__ */ (() =>\n new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();\n\n/**\n * Reverses byte order of one 32-bit word.\n * @param word - Unsigned 32-bit word to swap.\n * @returns The same word with bytes reversed.\n * @example\n * Swaps a big-endian word into little-endian byte order.\n *\n * ```ts\n * byteSwap(0x11223344);\n * ```\n */\nexport const byteSwap = (word: number): number =>\n ((word << 24) & 0xff000000) |\n ((word << 8) & 0xff0000) |\n ((word >>> 8) & 0xff00) |\n ((word >>> 24) & 0xff);\n\n/**\n * Normalizes one 32-bit word to the little-endian representation expected by cipher cores.\n * @param n - Unsigned 32-bit word to normalize.\n * @returns Little-endian normalized word on big-endian hosts, else the input word unchanged.\n * @example\n * Normalizes a host-endian word before passing it into an ARX/AES core.\n *\n * ```ts\n * swap8IfBE(0x11223344);\n * ```\n */\nexport const swap8IfBE: (n: number) => number = isLE\n ? (n: number) => n\n : (n: number) => byteSwap(n) >>> 0;\n\n/**\n * Byte-swaps every word of a Uint32Array in place.\n * @param arr - Uint32Array whose words should be swapped.\n * @returns The same array after in-place byte swapping.\n * @example\n * Swaps every 32-bit word in a word-view buffer.\n *\n * ```ts\n * byteSwap32(new Uint32Array([0x11223344]));\n * ```\n */\nexport const byteSwap32 = (arr: TArg<Uint32Array>): TRet<Uint32Array> => {\n for (let i = 0; i < arr.length; i++) arr[i] = byteSwap(arr[i]);\n return arr as TRet<Uint32Array>;\n};\n\n/**\n * Normalizes a Uint32Array view to the little-endian representation expected by cipher cores.\n * @param u - Word view to normalize in place.\n * @returns Little-endian normalized word view.\n * @example\n * Normalizes a word-view buffer before block processing.\n *\n * ```ts\n * swap32IfBE(new Uint32Array([0x11223344]));\n * ```\n */\nexport const swap32IfBE: (u: TArg<Uint32Array>) => TRet<Uint32Array> = isLE\n ? (u: TArg<Uint32Array>) => u as TRet<Uint32Array>\n : byteSwap32;\n\n// Built-in hex conversion:\n// {@link https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex | caniuse entry}\nconst hasHexBuiltin: boolean = /* @__PURE__ */ (() =>\n // @ts-ignore\n typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')();\n\n// Array where index 0xf0 (240) is mapped to string 'f0'\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>\n i.toString(16).padStart(2, '0')\n);\n\n/**\n * Convert byte array to hex string. Uses built-in function, when available.\n * @param bytes - Bytes to encode.\n * @returns Lowercase hexadecimal string.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Formats ciphertext bytes for logs or test vectors.\n *\n * ```ts\n * bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])); // 'cafe0123'\n * ```\n */\nexport function bytesToHex(bytes: TArg<Uint8Array>): string {\n abytes(bytes);\n // @ts-ignore\n if (hasHexBuiltin) return bytes.toHex();\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n\n// We use optimized technique to convert hex string to byte array\nconst asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 } as const;\nfunction asciiToBase16(ch: number): number | undefined {\n if (ch >= asciis._0 && ch <= asciis._9) return ch - asciis._0; // '2' => 50-48\n if (ch >= asciis.A && ch <= asciis.F) return ch - (asciis.A - 10); // 'B' => 66-(65-10)\n if (ch >= asciis.a && ch <= asciis.f) return ch - (asciis.a - 10); // 'b' => 98-(97-10)\n return;\n}\n\n/**\n * Convert hex string to byte array. Uses built-in function, when available.\n * @param hex - Hexadecimal string to decode.\n * @returns Decoded bytes.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On malformed hexadecimal input. {@link RangeError}\n * @example\n * Parses a hex test vector into bytes.\n *\n * ```ts\n * hexToBytes('cafe0123'); // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n * ```\n */\nexport function hexToBytes(hex: string): TRet<Uint8Array> {\n if (typeof hex !== 'string') throw new TypeError('hex string expected, got ' + typeof hex);\n if (hasHexBuiltin) {\n try {\n return (Uint8Array as any).fromHex(hex);\n } catch (error) {\n if (error instanceof SyntaxError) throw new RangeError(error.message);\n throw error;\n }\n }\n const hl = hex.length;\n const al = hl / 2;\n if (hl % 2) throw new RangeError('hex string expected, got unpadded hex of length ' + hl);\n const array = new Uint8Array(al);\n for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n const n1 = asciiToBase16(hex.charCodeAt(hi));\n const n2 = asciiToBase16(hex.charCodeAt(hi + 1));\n if (n1 === undefined || n2 === undefined) {\n const char = hex[hi] + hex[hi + 1];\n throw new RangeError(\n 'hex string expected, got non-hex character \"' + char + '\" at index ' + hi\n );\n }\n array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163\n }\n return array as TRet<Uint8Array>;\n}\n\n// Used in micro\n/**\n * Converts a big-endian hex string into bigint.\n * @param hex - Hexadecimal string without `0x`.\n * @returns Parsed bigint value. The empty string is treated as `0n`.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Parses a big-endian field element or counter from hex.\n *\n * ```ts\n * hexToNumber('ff');\n * ```\n */\nexport function hexToNumber(hex: string): bigint {\n if (typeof hex !== 'string') throw new TypeError('hex string expected, got ' + typeof hex);\n return BigInt(hex === '' ? '0' : '0x' + hex); // Big Endian\n}\n\n// Used in ff1\n// BE: Big Endian, LE: Little Endian\n/**\n * Converts big-endian bytes into bigint.\n * @param bytes - Big-endian bytes.\n * @returns Parsed bigint value. Empty input is treated as `0n`.\n * @throws On invalid byte input passed to the internal hex conversion. {@link TypeError}\n * @example\n * Reads a big-endian integer from serialized bytes.\n *\n * ```ts\n * bytesToNumberBE(new Uint8Array([1, 0]));\n * ```\n */\nexport function bytesToNumberBE(bytes: TArg<Uint8Array>): bigint {\n return hexToNumber(bytesToHex(bytes));\n}\n\n// Used in micro, ff1\n/**\n * Converts a number into big-endian bytes of fixed length.\n * @param n - Number to encode.\n * @param len - Output length in bytes.\n * @returns Big-endian bytes padded to `len`.\n * Validation is indirect through `hexToBytes(...)`, so negative values, `len = 0`,\n * and values that do not fit surface through the downstream hex parser instead of a\n * dedicated range guard here.\n * @throws On wrong argument types. {@link TypeError}\n * @throws If the requested output length cannot represent the encoded value. {@link RangeError}\n * @example\n * Encodes a counter as fixed-width big-endian bytes.\n *\n * ```ts\n * numberToBytesBE(1, 2);\n * ```\n */\nexport function numberToBytesBE(n: number | bigint, len: number): TRet<Uint8Array> {\n // Reject coercible non-numeric inputs before string/hex conversion changes behavior.\n if (typeof n === 'number') anumber(n);\n else if (typeof n !== 'bigint') throw new TypeError(`number or bigint expected, got ${typeof n}`);\n anumber(len);\n return hexToBytes(n.toString(16).padStart(len * 2, '0'));\n}\n\n// Global symbols, but ts doesn't see them:\n// {@link https://github.com/microsoft/TypeScript/issues/31535 | TypeScript issue 31535}\ndeclare const TextEncoder: any;\ndeclare const TextDecoder: any;\n\n/**\n * Converts string to bytes using UTF8 encoding.\n * @param str - String to encode.\n * @returns UTF-8 bytes in a detached fresh Uint8Array copy.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Encodes application text before encryption or MACing.\n *\n * ```ts\n * utf8ToBytes('abc'); // new Uint8Array([97, 98, 99])\n * ```\n */\nexport function utf8ToBytes(str: string): TRet<Uint8Array> {\n if (typeof str !== 'string') throw new TypeError('string expected');\n return new Uint8Array(new TextEncoder().encode(str)) as TRet<Uint8Array>; // {@link https://bugzil.la/1681809 | Firefox bug 1681809}\n}\n\n/**\n * Converts bytes to string using UTF8 encoding.\n * @param bytes - UTF-8 bytes.\n * @returns Decoded string. Input validation is delegated to `TextDecoder`, and malformed\n * UTF-8 is replacement-decoded instead of rejected.\n * @example\n * Decodes UTF-8 plaintext back into a string.\n *\n * ```ts\n * bytesToUtf8(new Uint8Array([97, 98, 99])); // 'abc'\n * ```\n */\nexport function bytesToUtf8(bytes: TArg<Uint8Array>): string {\n return new TextDecoder().decode(bytes);\n}\n\n/**\n * Checks if two U8A use same underlying buffer and overlaps.\n * This is invalid and can corrupt data.\n * @param a - First byte view.\n * @param b - Second byte view.\n * @returns `true` when the views overlap in memory.\n * @example\n * Detects whether two slices alias the same backing buffer.\n *\n * ```ts\n * overlapBytes(new Uint8Array(4), new Uint8Array(4));\n * ```\n */\nexport function overlapBytes(a: TArg<Uint8Array>, b: TArg<Uint8Array>): boolean {\n // Zero-length views cannot overwrite anything, even if their offset sits inside another range.\n if (!a.byteLength || !b.byteLength) return false;\n return (\n a.buffer === b.buffer && // best we can do, may fail with an obscure Proxy\n a.byteOffset < b.byteOffset + b.byteLength && // a starts before b end\n b.byteOffset < a.byteOffset + a.byteLength // b starts before a end\n );\n}\n\n/**\n * If input and output overlap and input starts before output, we will overwrite end of input before\n * we start processing it, so this is not supported for most ciphers\n * (except chacha/salsa, which were designed for this)\n * @param input - Input bytes.\n * @param output - Output bytes.\n * @throws If the output view would overwrite unread input bytes. {@link Error}\n * @example\n * Rejects an in-place layout that would overwrite unread input bytes.\n *\n * ```ts\n * complexOverlapBytes(new Uint8Array(4), new Uint8Array(4));\n * ```\n */\nexport function complexOverlapBytes(input: TArg<Uint8Array>, output: TArg<Uint8Array>): void {\n // This is very cursed. It works somehow, but I'm completely unsure,\n // reasoning about overlapping aligned windows is very hard.\n if (overlapBytes(input, output) && input.byteOffset < output.byteOffset)\n throw new Error('complex overlap of input and output is not supported');\n}\n\n/**\n * Copies several Uint8Arrays into one.\n * @param arrays - Byte arrays to concatenate.\n * @returns Combined byte array.\n * @throws On wrong argument types inside the byte-array list. {@link TypeError}\n * @example\n * Builds a `nonce || ciphertext` style buffer.\n *\n * ```ts\n * concatBytes(new Uint8Array([1]), new Uint8Array([2]));\n * ```\n */\nexport function concatBytes(...arrays: TArg<Uint8Array[]>): TRet<Uint8Array> {\n let sum = 0;\n for (let i = 0; i < arrays.length; i++) {\n const a = arrays[i];\n abytes(a);\n sum += a.length;\n }\n const res = new Uint8Array(sum);\n for (let i = 0, pad = 0; i < arrays.length; i++) {\n const a = arrays[i];\n res.set(a, pad);\n pad += a.length;\n }\n return res as TRet<Uint8Array>;\n}\n\n// Used in ARX only\ntype EmptyObj = {};\n/**\n * Merges user options into defaults.\n * @param defaults - Default option values.\n * @param opts - User-provided overrides.\n * @returns Combined options object.\n * The merge mutates `defaults` in place and returns the same object.\n * @throws If options are missing or not an object. {@link Error}\n * @example\n * Applies user overrides to the default cipher options.\n *\n * ```ts\n * checkOpts({ rounds: 20 }, { rounds: 8 });\n * ```\n */\nexport function checkOpts<T1 extends EmptyObj, T2 extends EmptyObj>(\n defaults: T1,\n opts: T2\n): T1 & T2 {\n if (opts == null || typeof opts !== 'object') throw new Error('options must be defined');\n const merged = Object.assign(defaults, opts);\n return merged as T1 & T2;\n}\n\n/**\n * Compares two byte arrays in kinda constant time once lengths already match.\n * @param a - First byte array.\n * @param b - Second byte array.\n * @returns `true` when the arrays contain the same bytes. Different lengths still return early.\n * @example\n * Compares an expected authentication tag with the received one.\n *\n * ```ts\n * equalBytes(new Uint8Array([1]), new Uint8Array([1]));\n * ```\n */\nexport function equalBytes(a: TArg<Uint8Array>, b: TArg<Uint8Array>): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];\n return diff === 0;\n}\n\n// TODO: remove\n/** Incremental hash interface used internally. */\nexport interface IHash2 {\n /** Bytes processed per compression block. */\n blockLen: number;\n /** Bytes produced by the final digest. */\n outputLen: number;\n /**\n * Absorbs one more chunk into the hash state.\n * @param buf - Data chunk to hash.\n * @returns The same hash instance for chaining.\n */\n update(buf: string | TArg<Uint8Array>): this;\n /**\n * Writes the final digest into a caller-provided buffer.\n * @param buf - Destination buffer for the digest bytes.\n * @returns Nothing. Implementations write into `buf` in place.\n */\n digestInto(buf: TArg<Uint8Array>): void;\n /**\n * Finalizes the hash and returns a fresh digest buffer.\n * @returns Digest bytes.\n */\n digest(): TRet<Uint8Array>;\n /**\n * Resets internal state. Makes Hash instance unusable.\n * Reset is impossible for keyed hashes if key is consumed into state. If digest is not consumed\n * by user, they will need to manually call `destroy()` when zeroing is necessary.\n */\n destroy(): void;\n}\n\n/**\n * Wraps a keyed MAC constructor into a one-shot helper with `.create()`.\n * @param keyLen - Valid probe-key length used to read static metadata once.\n * The probe key is only used for `outputLen` / `blockLen`, so callers with several valid key sizes\n * can pass any representative size as long as those values stay fixed.\n * @param macCons - Keyed MAC constructor or factory.\n * @param fromMsg - Optional adapter that derives extra constructor args from the one-shot message.\n * @returns Callable MAC helper with `.create()`.\n */\nexport function wrapMacConstructor<H extends IHash2, A extends any[] = []>(\n keyLen: number,\n macCons: TArg<(key: Uint8Array, ...args: A) => H>,\n fromMsg?: TArg<(msg: Uint8Array) => A>\n): TRet<CMac<H, A>> {\n const mac = macCons as (key: TArg<Uint8Array>, ...args: A) => H;\n const getArgs = (fromMsg || (() => [] as unknown as A)) as (msg: TArg<Uint8Array>) => A;\n const macC: any = (msg: TArg<Uint8Array>, key: TArg<Uint8Array>): TRet<Uint8Array> =>\n mac(key, ...getArgs(msg))\n .update(msg)\n .digest();\n const tmp = mac(new Uint8Array(keyLen), ...getArgs(new Uint8Array(0)));\n macC.outputLen = tmp.outputLen;\n macC.blockLen = tmp.blockLen;\n macC.create = (key: TArg<Uint8Array>, ...args: A) => mac(key, ...args);\n return macC as TRet<CMac<H, A>>;\n}\n\n// This will allow to re-use with composable things like packed & base encoders\n// Also, we probably can make tags composable\n\n/** Sync cipher: takes byte array and returns byte array. */\nexport type Cipher = {\n /**\n * Encrypts plaintext bytes.\n * @param plaintext - Data to encrypt.\n * @returns Ciphertext bytes.\n */\n encrypt(plaintext: TArg<Uint8Array>): TRet<Uint8Array>;\n /**\n * Decrypts ciphertext bytes.\n * @param ciphertext - Data to decrypt.\n * @returns Plaintext bytes.\n */\n decrypt(ciphertext: TArg<Uint8Array>): TRet<Uint8Array>;\n};\n\n/** Async cipher e.g. from built-in WebCrypto. */\nexport type AsyncCipher = {\n /**\n * Encrypts plaintext bytes.\n * @param plaintext - Data to encrypt.\n * @returns Promise resolving to ciphertext bytes.\n */\n encrypt(plaintext: TArg<Uint8Array>): Promise<TRet<Uint8Array>>;\n /**\n * Decrypts ciphertext bytes.\n * @param ciphertext - Data to decrypt.\n * @returns Promise resolving to plaintext bytes.\n */\n decrypt(ciphertext: TArg<Uint8Array>): Promise<TRet<Uint8Array>>;\n};\n\n/** Cipher with `output` argument which can optimize by doing 1 less allocation. */\nexport type CipherWithOutput = Cipher & {\n /**\n * Encrypts plaintext bytes into an optional caller-provided buffer.\n * @param plaintext - Data to encrypt.\n * @param output - Optional destination buffer.\n * @returns Ciphertext bytes.\n */\n encrypt(plaintext: TArg<Uint8Array>, output?: TArg<Uint8Array>): TRet<Uint8Array>;\n /**\n * Decrypts ciphertext bytes into an optional caller-provided buffer.\n * @param ciphertext - Data to decrypt.\n * @param output - Optional destination buffer.\n * @returns Plaintext bytes.\n */\n decrypt(ciphertext: TArg<Uint8Array>, output?: TArg<Uint8Array>): TRet<Uint8Array>;\n};\n\n/**\n * Params are outside of return type, so it is accessible before calling constructor.\n * If function support multiple nonceLength's, we return the best one.\n */\nexport type CipherParams = {\n /** Cipher block size in bytes. */\n blockSize: number;\n /** Nonce length in bytes when the cipher uses a fixed nonce size. */\n nonceLength?: number;\n /** Authentication-tag length in bytes for AEAD modes. */\n tagLength?: number;\n /** Whether nonce length is variable at runtime. */\n varSizeNonce?: boolean;\n};\n/**\n * ARX AEAD cipher, like salsa or chacha.\n * @param key - Secret key bytes.\n * @param nonce - Nonce bytes.\n * @param AAD - Optional associated data.\n * @returns Cipher instance with caller-managed output buffers.\n */\nexport type ARXCipher = ((\n key: TArg<Uint8Array>,\n nonce: TArg<Uint8Array>,\n AAD?: TArg<Uint8Array>\n) => CipherWithOutput) & {\n blockSize: number;\n nonceLength: number;\n tagLength: number;\n};\n/**\n * Cipher constructor signature.\n * @param key - Secret key bytes.\n * @param args - Additional constructor arguments, such as nonce or IV.\n * @returns Cipher instance.\n */\nexport type CipherCons<T extends any[]> = (key: TArg<Uint8Array>, ...args: T) => Cipher;\n/**\n * Wraps a cipher: validates args, ensures encrypt() can only be called once.\n * Used internally by the exported cipher constructors.\n * Output-buffer support is inferred from the wrapped `encrypt` / `decrypt`\n * arity (`fn.length === 2`), and tag-bearing constructors are expected to use\n * `args[1]` for optional AAD.\n * @__NO_SIDE_EFFECTS__\n * @param params - Static cipher metadata. See {@link CipherParams}.\n * @param constructor - Cipher constructor.\n * @returns Wrapped constructor with validation.\n */\nexport const wrapCipher = <C extends CipherCons<any>, P extends CipherParams>(\n params: P,\n constructor: C\n): C & P => {\n function wrappedCipher(key: TArg<Uint8Array>, ...args: any[]): TRet<CipherWithOutput> {\n // Validate key\n abytes(key, undefined, 'key');\n\n // Validate nonce if nonceLength is present\n if (params.nonceLength !== undefined) {\n const nonce = args[0];\n abytes(nonce, params.varSizeNonce ? undefined : params.nonceLength, 'nonce');\n }\n\n // Validate AAD if tagLength present\n const tagl = params.tagLength;\n if (tagl && args[1] !== undefined) abytes(args[1], undefined, 'AAD');\n\n const cipher = constructor(key, ...args);\n const checkOutput = (fnLength: number, output?: TArg<Uint8Array>) => {\n if (output !== undefined) {\n if (fnLength !== 2) throw new Error('cipher output not supported');\n abytes(output, undefined, 'output');\n }\n };\n // Create wrapped cipher with validation and single-use encryption\n let called = false;\n const wrCipher = {\n encrypt(data: TArg<Uint8Array>, output?: TArg<Uint8Array>) {\n if (called) throw new Error('cannot encrypt() twice with same key + nonce');\n called = true;\n abytes(data);\n checkOutput(cipher.encrypt.length, output);\n return (cipher as CipherWithOutput).encrypt(data, output);\n },\n decrypt(data: TArg<Uint8Array>, output?: TArg<Uint8Array>) {\n abytes(data);\n if (tagl && data.length < tagl)\n throw new Error('\"ciphertext\" expected length bigger than tagLength=' + tagl);\n checkOutput(cipher.decrypt.length, output);\n return (cipher as CipherWithOutput).decrypt(data, output);\n },\n };\n\n return wrCipher as TRet<CipherWithOutput>;\n }\n\n Object.assign(wrappedCipher, params);\n return wrappedCipher as C & P;\n};\n\n/**\n * Represents a Salsa or ChaCha xor stream.\n * @param key - Secret key bytes.\n * @param nonce - Nonce bytes.\n * @param data - Input bytes to xor with the keystream.\n * @param output - Optional destination buffer.\n * @param counter - Optional starting block counter.\n * @returns Output bytes.\n */\nexport type XorStream = (\n key: TArg<Uint8Array>,\n nonce: TArg<Uint8Array>,\n data: TArg<Uint8Array>,\n output?: TArg<Uint8Array>,\n counter?: number\n) => TRet<Uint8Array>;\n\n/**\n * By default, returns u8a of length.\n * When out is available, it checks it for validity and uses it.\n * @param expectedLength - Required output length.\n * @param out - Optional destination buffer.\n * @param onlyAligned - Whether `out` must be 4-byte aligned.\n * @returns Output buffer ready for writing.\n * @throws On wrong argument types. {@link TypeError}\n * @throws If the provided output buffer has the wrong size or alignment. {@link Error}\n * @example\n * Reuses a caller-provided output buffer when lengths match.\n *\n * ```ts\n * getOutput(16, new Uint8Array(16));\n * ```\n */\nexport function getOutput(\n expectedLength: number,\n out?: TArg<Uint8Array>,\n onlyAligned = true\n): TRet<Uint8Array> {\n if (out === undefined) return new Uint8Array(expectedLength) as TRet<Uint8Array>;\n // Keep Buffer/cross-realm Uint8Array support here instead of trusting a shape-compatible object.\n abytes(out, undefined, 'output');\n if (out.length !== expectedLength)\n throw new Error(\n '\"output\" expected Uint8Array of length ' + expectedLength + ', got: ' + out.length\n );\n if (onlyAligned && !isAligned32(out)) throw new Error('invalid output, must be aligned');\n return out as TRet<Uint8Array>;\n}\n\n/**\n * Encodes data and AAD bit lengths into a 16-byte buffer.\n * @param dataLength - Data length in bits.\n * @param aadLength - AAD length in bits.\n * The serialized block is still `aadLength || dataLength`, matching GCM/Poly1305\n * conventions even though the helper parameter order is `(dataLength, aadLength)`.\n * @param isLE - Whether to encode lengths as little-endian.\n * @returns 16-byte length block.\n * @throws On wrong argument types passed to the endian validator. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @example\n * Builds the length block appended by GCM and Poly1305.\n *\n * ```ts\n * u64Lengths(16, 8, true);\n * ```\n */\nexport function u64Lengths(dataLength: number, aadLength: number, isLE: boolean): TRet<Uint8Array> {\n // Reject coercible non-number lengths like '10' and true before BigInt(...) accepts them.\n anumber(dataLength);\n anumber(aadLength);\n abool(isLE);\n const num = new Uint8Array(16);\n const view = createView(num);\n view.setBigUint64(0, BigInt(aadLength), isLE);\n view.setBigUint64(8, BigInt(dataLength), isLE);\n return num as TRet<Uint8Array>;\n}\n\n/**\n * Checks whether a byte array is aligned to a 4-byte offset.\n * @param bytes - Byte array to inspect.\n * @returns `true` when the view is 4-byte aligned.\n * @example\n * Checks whether a buffer can be safely viewed as Uint32Array.\n *\n * ```ts\n * isAligned32(new Uint8Array(4));\n * ```\n */\nexport function isAligned32(bytes: TArg<Uint8Array>): boolean {\n return bytes.byteOffset % 4 === 0;\n}\n\n/**\n * Copies bytes into a new Uint8Array.\n * @param bytes - Bytes to copy.\n * @returns Copied byte array.\n * @throws On wrong argument types. {@link TypeError}\n * @example\n * Copies input into an aligned Uint8Array before block processing.\n *\n * ```ts\n * copyBytes(new Uint8Array([1, 2]));\n * ```\n */\nexport function copyBytes(bytes: TArg<Uint8Array>): TRet<Uint8Array> {\n // `Uint8Array.from(...)` would also accept arrays / other typed arrays. Keep this helper strict\n // because callers use it at byte-validation boundaries before mutating the detached copy.\n return Uint8Array.from(abytes(bytes)) as TRet<Uint8Array>;\n}\n\n/**\n * Cryptographically secure PRNG.\n * Uses internal OS-level `crypto.getRandomValues`.\n * @param bytesLength - Number of bytes to produce.\n * Validation is delegated to `Uint8Array(bytesLength)` and `getRandomValues`, so\n * non-integers, negative lengths, and oversize requests surface backend/runtime errors.\n * @returns Random byte array.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On wrong argument ranges or values. {@link RangeError}\n * @throws If the runtime does not expose `crypto.getRandomValues`. {@link Error}\n * @example\n * Generates a fresh nonce or key.\n *\n * ```ts\n * randomBytes(16);\n * ```\n */\nexport function randomBytes(bytesLength = 32): TRet<Uint8Array> {\n // Validate upfront so fractional / coercible lengths do not silently\n // truncate through Uint8Array().\n anumber(bytesLength);\n const cr = typeof globalThis === 'object' ? (globalThis as any).crypto : null;\n if (typeof cr?.getRandomValues !== 'function')\n throw new Error('crypto.getRandomValues must be defined');\n return cr.getRandomValues(new Uint8Array(bytesLength)) as TRet<Uint8Array>;\n}\n\n/**\n * The pseudorandom number generator doesn't wipe current state:\n * instead, it generates new one based on previous state + entropy.\n * Not reseed/rekey, since AES CTR DRBG does rekey on each randomBytes,\n * which is in fact `reseed`, since it changes counter too.\n */\nexport interface PRG {\n /**\n * Mixes fresh entropy into the current generator state.\n * @param seed - Entropy bytes to absorb.\n */\n addEntropy(seed: TArg<Uint8Array>): void;\n /**\n * Produces a requested number of pseudorandom bytes.\n * @param bytesLength - Number of bytes to generate.\n * @returns Random byte array.\n */\n randomBytes(bytesLength: number): TRet<Uint8Array>;\n /** Destroys the generator state. */\n clean(): void;\n}\n\n/** Removes the nonce argument from a cipher constructor type. */\nexport type RemoveNonce<T extends (...args: any) => any> = T extends (\n arg0: any,\n arg1: any,\n ...rest: infer R\n) => infer Ret\n ? (key: TArg<Uint8Array>, ...args: R) => Ret\n : never;\n/**\n * Cipher constructor that requires a nonce argument.\n * @param key - Secret key bytes.\n * @param nonce - Nonce bytes.\n * @param args - Additional cipher-specific arguments.\n * @returns Cipher instance.\n */\nexport type CipherWithNonce = ((\n key: TArg<Uint8Array>,\n nonce: TArg<Uint8Array>,\n ...args: any[]\n) => Cipher | AsyncCipher) & {\n nonceLength: number;\n};\n\n/**\n * Uses CSPRNG for nonce, nonce injected in ciphertext.\n * For `encrypt`, a `nonceBytes`-length buffer is fetched from CSPRNG and\n * prepended to encrypted ciphertext. For `decrypt`, first `nonceBytes` of ciphertext\n * are treated as nonce. The wrapper always allocates a fresh `nonce || ciphertext`\n * buffer on encrypt and intentionally does not support caller-provided destination buffers.\n * Too-short decrypt inputs are split into short/empty nonce views and then delegated\n * to the wrapped cipher instead of being rejected here first.\n *\n * NOTE: Under the same key, using random nonces (e.g. `managedNonce`) with AES-GCM and ChaCha\n * should be limited to `2**23` (8M) messages to get a collision chance of\n * `2**-50`. Stretching to `2**32` (4B) messages would raise that chance to\n * `2**-33`, still negligible but creeping up.\n * @param fn - Cipher constructor that expects a nonce.\n * @param randomBytes_ - Random-byte source used for nonce generation.\n * @returns Cipher constructor that prepends the nonce to ciphertext.\n * @throws On wrong argument types. {@link TypeError}\n * @throws On invalid nonce lengths observed at wrapper construction or use. {@link RangeError}\n * @example\n * Prepends a fresh random nonce to every ciphertext.\n *\n * ```ts\n * import { gcm } from '@noble/ciphers/aes.js';\n * import { managedNonce, randomBytes } from '@noble/ciphers/utils.js';\n * const wrapped = managedNonce(gcm);\n * const key = randomBytes(16);\n * const ciphertext = wrapped(key).encrypt(new Uint8Array([1, 2, 3]));\n * wrapped(key).decrypt(ciphertext);\n * ```\n */\nexport function managedNonce<T extends CipherWithNonce>(\n fn: T,\n randomBytes_: typeof randomBytes = randomBytes\n): TRet<RemoveNonce<T>> {\n const { nonceLength } = fn;\n anumber(nonceLength);\n const addNonce = (\n nonce: TArg<Uint8Array>,\n ciphertext: TArg<Uint8Array>,\n plaintext: TArg<Uint8Array>\n ) => {\n const out = concatBytes(nonce, ciphertext);\n // Wrapped ciphers may alias caller plaintext on encrypt(); never zero\n // caller-owned buffers here.\n if (!overlapBytes(plaintext, ciphertext)) ciphertext.fill(0);\n return out;\n };\n // NOTE: we cannot support DST here, it would be mistake:\n // - we don't know how much dst length cipher requires\n // - nonce may unalign dst and break everything\n // - we create new u8a anyway (concatBytes)\n // - previously we passed all args to cipher, but that was mistake!\n const res = ((key: TArg<Uint8Array>, ...args: any[]): any => ({\n encrypt(plaintext: TArg<Uint8Array>) {\n abytes(plaintext);\n const nonce = randomBytes_(nonceLength);\n const encrypted = fn(key, nonce, ...args).encrypt(plaintext);\n // @ts-ignore\n if (encrypted instanceof Promise)\n return encrypted.then((ct) => addNonce(nonce, ct, plaintext));\n return addNonce(nonce, encrypted, plaintext);\n },\n decrypt(ciphertext: TArg<Uint8Array>) {\n abytes(ciphertext);\n const nonce = ciphertext.subarray(0, nonceLength);\n const decrypted = ciphertext.subarray(nonceLength);\n return fn(key, nonce, ...args).decrypt(decrypted);\n },\n })) as RemoveNonce<T> & { blockSize?: number; tagLength?: number };\n // Auto-nonce wrappers still preserve the wrapped payload geometry.\n if ('blockSize' in fn) res.blockSize = (fn as any).blockSize;\n if ('tagLength' in fn) res.tagLength = (fn as any).tagLength;\n return res as TRet<RemoveNonce<T>>;\n}\n\n/** `Uint8Array.of()` return type helper for TS 5.9. */\nexport type Uint8ArrayBuffer = TRet<Uint8Array>;\n","/**\n * Basic utils for ARX (add-rotate-xor) salsa and chacha ciphers.\n\nRFC8439 requires multi-step cipher stream, where\nauthKey starts with counter: 0, actual msg with counter: 1.\n\nFor this, we need a way to re-use nonce / counter:\n\n const counter = new Uint8Array(4);\n chacha(..., counter, ...); // counter is now 1\n chacha(..., counter, ...); // counter is now 2\n\nThis is complicated:\n\n- 32-bit counters are enough, no need for 64-bit: max ArrayBuffer size in JS is 4GB\n- Original papers don't allow mutating counters\n- Counter overflow is undefined [^1]\n- Idea A: allow providing (nonce | counter) instead of just nonce, re-use it\n- Caveat: Cannot be re-used through all cases:\n- * chacha has (counter | nonce)\n- * xchacha has (nonce16 | counter | nonce16)\n- Idea B: separate nonce / counter and provide separate API for counter re-use\n- Caveat: there are different counter sizes depending on an algorithm.\n- salsa & chacha also differ in structures of key & sigma:\n salsa20: s[0] | k(4) | s[1] | nonce(2) | cnt(2) | s[2] | k(4) | s[3]\n chacha: s(4) | k(8) | cnt(1) | nonce(3)\n chacha20orig: s(4) | k(8) | cnt(2) | nonce(2)\n- Idea C: helper method such as `setSalsaState(key, nonce, sigma, data)`\n- Caveat: we can't re-use counter array\n\nxchacha uses the subkey and remaining 8 byte nonce with ChaCha20 as normal\n(prefixed by 4 NUL bytes, since RFC8439 specifies a 12-byte nonce).\nCounter overflow is undefined; see {@link https://mailarchive.ietf.org/arch/msg/cfrg/gsOnTJzcbgG6OqD8Sc0GO5aR_tU/ | the CFRG thread}.\nCurrent noble policy is strict non-wrap for the shared 32-bit counter path:\nexported ARX ciphers reject initial `0xffffffff` and stop before any implicit\nwrap back to zero.\nSee {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha#appendix-A.2 | the XChaCha appendix} for the extended-nonce construction.\n\n * @module\n */\nimport {\n type PRG,\n type TArg,\n type TRet,\n type XorStream,\n abool,\n abytes,\n anumber,\n checkOpts,\n clean,\n copyBytes,\n getOutput,\n isAligned32,\n isLE,\n randomBytes,\n swap32IfBE,\n u32,\n} from './utils.ts';\n\n// Replaces `TextEncoder` for ASCII literals, which is enough for sigma constants.\n// Non-ASCII input would not match UTF-8 `TextEncoder` output.\nconst encodeStr = (str: string) => Uint8Array.from(str.split(''), (c) => c.charCodeAt(0));\n// Raw `createCipher(...)` exports consume these native-endian `u32(...)` views directly.\n// Public `wrapCipher(...)` APIs reject non-little-endian platforms before reaching this path.\n// RFC 8439 §2.3 / RFC 7539 §2.3 only define the 256-bit-key constants; this 16-byte sigma is\n// kept for legacy allowShortKeys Salsa/ChaCha variants.\nconst sigma16_32 = /* @__PURE__ */ (() => swap32IfBE(u32(encodeStr('expand 16-byte k'))))();\n// RFC 8439 §2.3 / RFC 7539 §2.3 define words 0-3 as\n// `0x61707865 0x3320646e 0x79622d32 0x6b206574`, i.e. `expand 32-byte k`.\nconst sigma32_32 = /* @__PURE__ */ (() => swap32IfBE(u32(encodeStr('expand 32-byte k'))))();\n\n/**\n * Rotates a 32-bit word left.\n * @param a - Input word.\n * @param b - Rotation count in bits.\n * @returns Rotated 32-bit word.\n * @example\n * Moves the top byte of `0x12345678` into the low byte position.\n * ```ts\n * rotl(0x12345678, 8);\n * ```\n */\nexport function rotl(a: number, b: number): number {\n return (a << b) | (a >>> (32 - b));\n}\n\n/**\n * ARX core function operating on 32-bit words. Ciphers must use u32 for efficiency.\n * @param sigma - Sigma constants for the selected cipher layout.\n * @param key - Expanded key words.\n * @param nonce - Nonce and counter words prepared for the round function.\n * @param output - Output block written in place.\n * @param counter - Block counter value.\n * @param rounds - Optional round count override.\n */\nexport type CipherCoreFn = (\n sigma: TArg<Uint32Array>,\n key: TArg<Uint32Array>,\n nonce: TArg<Uint32Array>,\n output: TArg<Uint32Array>,\n counter: number,\n rounds?: number\n) => void;\n\n/**\n * Nonce-extension function used by XChaCha and XSalsa.\n * @param sigma - Sigma constants for the selected cipher layout.\n * @param key - Expanded key words.\n * @param input - Input nonce words used for subkey derivation.\n * @param output - Output buffer written with the derived nonce words.\n */\nexport type ExtendNonceFn = (\n sigma: TArg<Uint32Array>,\n key: TArg<Uint32Array>,\n input: TArg<Uint32Array>,\n output: TArg<Uint32Array>\n) => void;\n\n/** ARX cipher options.\n * * `allowShortKeys` for 16-byte keys\n * * `counterLength` in bytes\n * * `counterRight`: right: `nonce|counter`; left: `counter|nonce`\n * */\nexport type CipherOpts = {\n /** Whether 16-byte keys are accepted for legacy Salsa and ChaCha variants. */\n allowShortKeys?: boolean;\n /** Optional nonce-expansion hook used by extended-nonce variants. */\n extendNonceFn?: ExtendNonceFn;\n /** Counter length in bytes inside the nonce/counter layout. */\n counterLength?: number;\n /** Whether the layout is `nonce|counter` instead of `counter|nonce`. */\n counterRight?: boolean;\n /** Number of core rounds to execute. */\n rounds?: number;\n};\n\n// Salsa and Chacha block length is always 512-bit\nconst BLOCK_LEN = 64;\n// RFC 8439 §2.2 / RFC 7539 §2.2: the ChaCha state has 16 32-bit words.\nconst BLOCK_LEN32 = 16;\n\n// Counter policy for the shared public `counter` argument:\n// - RFC/IETF ChaCha20 uses a 32-bit counter.\n// - OpenSSL/Node `chacha20` instead treat the full 16-byte IV as a 128-bit\n// counter state and carry into the next word.\n// - Raw `chacha20orig`, `salsa20`, `xsalsa20`, and `xchacha20` use 64-bit counters in libsodium\n// and libtomcrypt, while some libs (for example libtomcrypt's RFC/IETF path) reject the max\n// boundary instead of carrying.\n// - AEAD wrappers diverge too: libsodium `xchacha20poly1305` uses the IETF payload counter from\n// block 1, while `secretstream_xchacha20poly1305` is a different protocol with rekey/reset.\n// Noble intentionally throws instead of silently picking one wrap model for users. In the default\n// path, even a 32-bit boundary would take 2^32 blocks * 64 bytes = 256 GiB, which is practically\n// unreachable for normal JS callers; advanced users who pass `counter` explicitly can implement\n// whatever wider carry / wrap policy they need on top.\nconst MAX_COUNTER = /* @__PURE__ */ (() => 2 ** 32 - 1)();\nconst U32_EMPTY = /* @__PURE__ */ Uint32Array.of();\nfunction runCipher(\n core: TArg<CipherCoreFn>,\n sigma: TArg<Uint32Array>,\n key: TArg<Uint32Array>,\n nonce: TArg<Uint32Array>,\n data: TArg<Uint8Array>,\n output: TArg<Uint8Array>,\n counter: number,\n rounds: number\n): void {\n const len = data.length;\n const block = new Uint8Array(BLOCK_LEN);\n const b32 = u32(block);\n // Make sure that buffers aligned to 4 bytes\n const isAligned = isLE && isAligned32(data) && isAligned32(output);\n const d32 = isAligned ? u32(data) : U32_EMPTY;\n const o32 = isAligned ? u32(output) : U32_EMPTY;\n // RFC 8439 §2.4.1 / RFC 7539 §2.4.1 allow XORing one keystream block at a time and\n // truncating the final partial block instead of materializing the whole keystream.\n if (!isLE) {\n for (let pos = 0; pos < len; counter++) {\n core(\n sigma as TRet<Uint32Array>,\n key as TRet<Uint32Array>,\n nonce as TRet<Uint32Array>,\n b32,\n counter,\n rounds\n );\n // RFC 8439 §2.4 / RFC 7539 §2.4 serialize keystream words in little-endian order.\n swap32IfBE(b32);\n if (counter >= MAX_COUNTER) throw new Error('arx: counter overflow');\n const take = Math.min(BLOCK_LEN, len - pos);\n for (let j = 0, posj; j < take; j++) {\n posj = pos + j;\n output[posj] = data[posj] ^ block[j];\n }\n pos += take;\n }\n return;\n }\n for (let pos = 0; pos < len; counter++) {\n core(\n sigma as TRet<Uint32Array>,\n key as TRet<Uint32Array>,\n nonce as TRet<Uint32Array>,\n b32,\n counter,\n rounds\n );\n // See MAX_COUNTER policy note above: never silently wrap the shared public counter.\n if (counter >= MAX_COUNTER) throw new Error('arx: counter overflow');\n const take = Math.min(BLOCK_LEN, len - pos);\n // aligned to 4 bytes\n if (isAligned && take === BLOCK_LEN) {\n const pos32 = pos / 4;\n if (pos % 4 !== 0) throw new Error('arx: invalid block position');\n for (let j = 0, posj: number; j < BLOCK_LEN32; j++) {\n posj = pos32 + j;\n o32[posj] = d32[posj] ^ b32[j];\n }\n pos += BLOCK_LEN;\n continue;\n }\n for (let j = 0, posj; j < take; j++) {\n posj = pos + j;\n output[posj] = data[posj] ^ block[j];\n }\n pos += take;\n }\n}\n\n/**\n * Creates an ARX stream cipher from a 32-bit core permutation.\n * Used internally to build the exported Salsa and ChaCha stream ciphers.\n * @param core - Core function that fills one keystream block.\n * @param opts - Cipher layout and nonce-extension options. See {@link CipherOpts}.\n * @returns Stream cipher function over byte arrays.\n * @throws If the core callback, key size, counter, or output sizing is invalid. {@link Error}\n */\nexport function createCipher(core: TArg<CipherCoreFn>, opts: TArg<CipherOpts>): TRet<XorStream> {\n const { allowShortKeys, extendNonceFn, counterLength, counterRight, rounds } = checkOpts(\n { allowShortKeys: false, counterLength: 8, counterRight: false, rounds: 20 },\n opts\n );\n if (typeof core !== 'function') throw new Error('core must be a function');\n anumber(counterLength);\n anumber(rounds);\n abool(counterRight);\n abool(allowShortKeys);\n return (\n key: TArg<Uint8Array>,\n nonce: TArg<Uint8Array>,\n data: TArg<Uint8Array>,\n output?: TArg<Uint8Array>,\n counter = 0\n ): TRet<Uint8Array> => {\n abytes(key, undefined, 'key');\n abytes(nonce, undefined, 'nonce');\n abytes(data, undefined, 'data');\n const len = data.length;\n // Raw XorStream APIs return ciphertext/plaintext bytes directly, so caller-provided outputs\n // must match the logical result length exactly instead of returning an oversized workspace.\n output = getOutput(len, output, false);\n anumber(counter);\n // See MAX_COUNTER policy note above: reject advanced explicit-counter requests before any wrap.\n if (counter < 0 || counter >= MAX_COUNTER) throw new Error('arx: counter overflow');\n const toClean = [];\n\n // Key & sigma\n // key=16 -> sigma16, k=key|key\n // key=32 -> sigma32, k=key\n let l = key.length;\n let k: Uint8Array;\n let sigma: Uint32Array;\n if (l === 32) {\n // Copy caller keys too: big-endian normalization, extended-nonce subkey derivation, and\n // final clean(...) all mutate or wipe the temporary buffer in place.\n toClean.push((k = copyBytes(key)));\n sigma = sigma32_32;\n } else if (l === 16 && allowShortKeys) {\n k = new Uint8Array(32);\n k.set(key);\n k.set(key, 16);\n sigma = sigma16_32;\n toClean.push(k);\n } else {\n abytes(key, 32, 'arx key');\n throw new Error('invalid key size');\n // throw new Error(`\"arx key\" expected Uint8Array of length 32, got length=${l}`);\n }\n\n // Nonce\n // salsa20: 8 (8-byte counter)\n // chacha20orig: 8 (8-byte counter)\n // chacha20: 12 (4-byte counter)\n // xsalsa20: 24 (16 -> hsalsa, 8 -> old nonce)\n // xchacha20: 24 (16 -> hchacha, 8 -> old nonce)\n // Copy before taking u32(...) views on misaligned inputs, and on big-endian so later\n // swap32IfBE(...) never mutates caller nonce bytes in place.\n if (!isLE || !isAligned32(nonce)) toClean.push((nonce = copyBytes(nonce)));\n\n let k32 = u32(k);\n // hsalsa & hchacha: handle extended nonce\n if (extendNonceFn) {\n if (nonce.length !== 24) throw new Error(`arx: extended nonce must be 24 bytes`);\n const n16 = nonce.subarray(0, 16);\n if (isLE) extendNonceFn(sigma as TRet<Uint32Array>, k32, u32(n16), k32);\n else {\n const sigmaRaw = swap32IfBE(Uint32Array.from(sigma));\n extendNonceFn(sigmaRaw, k32, u32(n16), k32);\n clean(sigmaRaw);\n swap32IfBE(k32);\n }\n nonce = nonce.subarray(16);\n } else if (!isLE) swap32IfBE(k32);\n\n // Handle nonce counter\n const nonceNcLen = 16 - counterLength;\n if (nonceNcLen !== nonce.length)\n throw new Error(`arx: nonce must be ${nonceNcLen} or 16 bytes`);\n\n // Normalize 64-bit-nonce layouts to the 12-byte core input: ChaCha/XChaCha prefix 4 zero\n // counter bytes, while Salsa/XSalsa append them after the nonce words.\n if (nonceNcLen !== 12) {\n const nc = new Uint8Array(12);\n nc.set(nonce, counterRight ? 0 : 12 - nonce.length);\n nonce = nc;\n toClean.push(nonce);\n }\n const n32 = swap32IfBE(u32(nonce));\n // Ensure temporary key/nonce copies are wiped even if the remaining\n // runtime guard in runCipher(...) throws on counter overflow.\n try {\n runCipher(core, sigma, k32, n32, data, output, counter, rounds);\n return output as TRet<Uint8Array>;\n } finally {\n clean(...toClean);\n }\n };\n}\n\n/** Internal class which wraps chacha20 or chacha8 to create CSPRNG. */\nexport class _XorStreamPRG implements PRG {\n readonly blockLen: number;\n readonly keyLen: number;\n readonly nonceLen: number;\n private state: TRet<Uint8Array>;\n private buf: TRet<Uint8Array>;\n private key: TRet<Uint8Array>;\n private nonce: TRet<Uint8Array>;\n private pos: number;\n private ctr: number;\n private cipher: TArg<XorStream>;\n constructor(\n cipher: TArg<XorStream>,\n blockLen: number,\n keyLen: number,\n nonceLen: number,\n seed: TArg<Uint8Array>\n ) {\n this.cipher = cipher;\n this.blockLen = blockLen;\n this.keyLen = keyLen;\n this.nonceLen = nonceLen;\n this.state = new Uint8Array(this.keyLen + this.nonceLen) as TRet<Uint8Array>;\n this.reseed(seed);\n this.ctr = 0;\n this.pos = this.blockLen;\n this.buf = new Uint8Array(this.blockLen) as TRet<Uint8Array>;\n // Keep a single key||nonce backing buffer so reseed/addEntropy/clean update the live cipher\n // inputs in place through these subarray views.\n this.key = this.state.subarray(0, this.keyLen) as TRet<Uint8Array>;\n this.nonce = this.state.subarray(this.keyLen) as TRet<Uint8Array>;\n }\n private reseed(seed: TArg<Uint8Array>) {\n abytes(seed);\n if (!seed || seed.length === 0) throw new Error('entropy required');\n // Mix variable-length entropy cyclically across the whole key||nonce state, then restart the\n // keystream so buffered leftovers from the previous state are never reused.\n for (let i = 0; i < seed.length; i++) this.state[i % this.state.length] ^= seed[i];\n this.ctr = 0;\n this.pos = this.blockLen;\n }\n addEntropy(seed: TArg<Uint8Array>): void {\n // Reject empty entropy before re-keying, otherwise a throwing call would still advance state.\n abytes(seed);\n if (seed.length === 0) throw new Error('entropy required');\n // Re-key from the current stream first, then mix external entropy into the fresh key||nonce\n // state through reseed() so stale buffered bytes are discarded.\n this.state.set(this.randomBytes(this.state.length));\n this.reseed(seed);\n }\n randomBytes(len: number): TRet<Uint8Array> {\n anumber(len);\n if (len === 0) return new Uint8Array(0) as TRet<Uint8Array>;\n const avail = this.pos < this.blockLen ? this.blockLen - this.pos : 0;\n const blocks = Math.ceil(Math.max(0, len - avail) / this.blockLen);\n // Preflight overflow so failed reads don't partially consume keystream\n // and leave the PRG repeating blocks.\n if (blocks > 0 && this.ctr > MAX_COUNTER - blocks) throw new Error('arx: counter overflow');\n const out = new Uint8Array(len);\n let outPos = 0;\n // `out` starts zero-filled, and `buf.fill(0)` below does the same for leftovers: XOR-stream\n // ciphers then emit raw keystream bytes directly into those buffers.\n // Serve buffered leftovers first so split reads stay identical to one larger read.\n if (this.pos < this.blockLen) {\n const take = Math.min(len, this.blockLen - this.pos);\n out.set(this.buf.subarray(this.pos, this.pos + take), 0);\n this.pos += take;\n outPos += take;\n if (outPos === len) return out as TRet<Uint8Array>; // fast path\n }\n // Full blocks directly to out\n const full = Math.floor((len - outPos) / this.blockLen);\n if (full > 0) {\n const blockBytes = full * this.blockLen;\n const b = out.subarray(outPos, outPos + blockBytes);\n this.cipher(this.key, this.nonce, b as TRet<Uint8Array>, b as TRet<Uint8Array>, this.ctr);\n this.ctr += full;\n outPos += blockBytes;\n }\n // Save leftovers\n const left = len - outPos;\n if (left > 0) {\n this.buf.fill(0);\n // NOTE: cipher will handle overflow\n this.cipher(\n this.key,\n this.nonce,\n this.buf as TRet<Uint8Array>,\n this.buf as TRet<Uint8Array>,\n this.ctr++\n );\n out.set(this.buf.subarray(0, left), outPos);\n this.pos = left;\n }\n return out as TRet<Uint8Array>;\n }\n // Clone seeds the new instance from this stream, so the source PRG advances too.\n clone(): _XorStreamPRG {\n return new _XorStreamPRG(\n this.cipher,\n this.blockLen,\n this.keyLen,\n this.nonceLen,\n this.randomBytes(this.state.length)\n );\n }\n // Zeroes the current state and leftover buffer, but does not make the instance unusable:\n // Later reads first drain zeros from the cleared buffer and then continue\n // from zero key||nonce state.\n clean(): void {\n this.pos = 0;\n this.ctr = 0;\n this.buf.fill(0);\n this.state.fill(0);\n }\n}\n\n/**\n * PRG constructor backed by an ARX stream cipher.\n * @param seed - Optional seed bytes mixed into the initial state. When omitted, exactly 32\n * random bytes are mixed in by default: larger states keep a zero tail, while smaller states\n * wrap those bytes through `reseed()`'s XOR schedule.\n * @returns Seeded concrete `_XorStreamPRG` instance, including `clone()`.\n */\nexport type XorPRG = (seed?: TArg<Uint8Array>) => TRet<_XorStreamPRG>;\n\n/**\n * Creates a PRG constructor from a stream cipher.\n * @param cipher - Stream cipher used to fill output blocks.\n * @param blockLen - Keystream block length in bytes.\n * @param keyLen - Internal key length in bytes.\n * @param nonceLen - Internal nonce length in bytes.\n * @returns PRG factory for seeded concrete `_XorStreamPRG` instances.\n * @example\n * Builds a PRG from XChaCha20 and reads bytes from a randomly seeded instance.\n * ```ts\n * import { xchacha20 } from '@noble/ciphers/chacha.js';\n * import { createPRG } from '@noble/ciphers/_arx.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const seed = randomBytes(32);\n * const init = createPRG(xchacha20, 64, 32, 24);\n * const prg = init(seed);\n * prg.randomBytes(8);\n * ```\n */\nexport const createPRG = (\n cipher: TArg<XorStream>,\n blockLen: number,\n keyLen: number,\n nonceLen: number\n): TRet<XorPRG> => {\n return ((seed: TArg<Uint8Array> = randomBytes(32)): TRet<_XorStreamPRG> =>\n new _XorStreamPRG(\n cipher,\n blockLen,\n keyLen,\n nonceLen,\n seed\n ) as TRet<_XorStreamPRG>) as TRet<XorPRG>;\n};\n","/**\n * Poly1305 ({@link https://cr.yp.to/mac/poly1305-20050329.pdf | PDF},\n * {@link https://en.wikipedia.org/wiki/Poly1305 | wiki})\n * is a fast and parallel secret-key message-authentication code suitable for\n * a wide variety of applications. It was standardized in\n * {@link https://www.rfc-editor.org/rfc/rfc8439 | RFC 8439} and is now used in TLS 1.3.\n *\n * Polynomial MACs are not perfect for every situation:\n * they lack Random Key Robustness: the MAC can be forged, and can't be used in PAKE schemes.\n * See {@link https://keymaterial.net/2020/09/07/invisible-salamanders-in-aes-gcm-siv/ | the invisible salamanders attack writeup}.\n * To combat invisible salamanders, `hash(key)` can be included in ciphertext,\n * however, this would violate ciphertext indistinguishability:\n * an attacker would know which key was used - so `HKDF(key, i)`\n * could be used instead.\n *\n * Check out the {@link https://cr.yp.to/mac.html | original website}.\n * Based on public-domain {@link https://github.com/floodyberry/poly1305-donna | poly1305-donna}.\n * @module\n */\n// prettier-ignore\nimport {\n abytes, aexists, aoutput, bytesToHex,\n clean, concatBytes, copyBytes, hexToNumber, numberToBytesBE,\n wrapMacConstructor, type CMac, type IHash2, type TArg, type TRet\n} from './utils.ts';\n\n// Little-endian 2-byte load used by the Poly1305 limb decomposition.\nfunction u8to16(a: TArg<Uint8Array>, i: number) {\n return (a[i++] & 0xff) | ((a[i++] & 0xff) << 8);\n}\n\nfunction bytesToNumberLE(bytes: TArg<Uint8Array>): bigint {\n return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));\n}\n\n/** Small version of `poly1305` without loop unrolling. Unused, provided for auditability. */\nfunction poly1305_small(msg: TArg<Uint8Array>, key: TArg<Uint8Array>): TRet<Uint8Array> {\n abytes(msg);\n abytes(key, 32, 'key');\n const POW_2_130_5 = BigInt(2) ** BigInt(130) - BigInt(5); // 2^130-5\n const POW_2_128_1 = BigInt(2) ** BigInt(128) - BigInt(1); // 2^128-1\n const CLAMP_R = BigInt('0x0ffffffc0ffffffc0ffffffc0fffffff');\n const r = bytesToNumberLE(key.subarray(0, 16)) & CLAMP_R;\n const s = bytesToNumberLE(key.subarray(16));\n // Process by 16 byte chunks\n let acc = BigInt(0);\n for (let i = 0; i < msg.length; i += 16) {\n const m = msg.subarray(i, i + 16);\n // RFC 8439 §2.5.1 / RFC 7539 §2.5.1 append [0x01] to each chunk before multiplying by r.\n const n = bytesToNumberLE(m) | (BigInt(1) << BigInt(8 * m.length));\n acc = ((acc + n) * r) % POW_2_130_5;\n }\n const res = (acc + s) & POW_2_128_1;\n // RFC 8439 §2.5 / RFC 7539 §2.5 serialize the low 128 bits in little-endian order.\n return numberToBytesBE(res, 16).reverse() as TRet<Uint8Array>; // LE\n}\n\n// Can be used to replace `computeTag` in chacha.ts. Unused, provided for auditability.\n// @ts-expect-error\nfunction poly1305_computeTag_small(\n authKey: TArg<Uint8Array>,\n // AEAD trailer must already be the 16-byte length block:\n // 8-byte little-endian AAD length || 8-byte little-endian ciphertext length.\n lengths: TArg<Uint8Array>,\n ciphertext: TArg<Uint8Array>,\n AAD?: TArg<Uint8Array>\n): TRet<Uint8Array> {\n // RFC 8439 §2.8.1 / RFC 7539 §2.8.1 MAC input is\n // AAD || pad16(AAD) || ciphertext || pad16(ciphertext) || lengths.\n const res = [];\n const updatePadded2 = (msg: TArg<Uint8Array>) => {\n res.push(msg);\n const leftover = msg.length % 16;\n // RFC 8439 §2.8.1 / RFC 7539 §2.8.1: pad16(x) is empty for aligned\n // inputs, else 16-(len%16) zero bytes.\n if (leftover) res.push(new Uint8Array(16).slice(leftover));\n };\n if (AAD) updatePadded2(AAD);\n updatePadded2(ciphertext);\n res.push(lengths);\n return poly1305_small(concatBytes(...res), authKey);\n}\n\n/**\n * Incremental Poly1305 MAC state.\n * Prefer `poly1305()` for one-shot use.\n * @param key - 32-byte Poly1305 one-time key.\n * @example\n * Feeds one chunk into an incremental Poly1305 state with a fresh one-time key.\n *\n * ```ts\n * import { Poly1305 } from '@noble/ciphers/_poly1305.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const mac = new Poly1305(key);\n * mac.update(new Uint8Array([1, 2, 3]));\n * mac.digest();\n * ```\n */\nexport class Poly1305 implements IHash2 {\n readonly blockLen = 16;\n readonly outputLen = 16;\n private buffer = new Uint8Array(16);\n private r = new Uint16Array(10); // Allocating 1 array with .subarray() here is slower than 3\n private h = new Uint16Array(10);\n private pad = new Uint16Array(8);\n private pos = 0;\n protected finished = false;\n protected destroyed = false;\n\n // Can be speed-up using BigUint64Array, at the cost of complexity\n constructor(key: TArg<Uint8Array>) {\n key = copyBytes(abytes(key, 32, 'key'));\n const t0 = u8to16(key, 0);\n const t1 = u8to16(key, 2);\n const t2 = u8to16(key, 4);\n const t3 = u8to16(key, 6);\n const t4 = u8to16(key, 8);\n const t5 = u8to16(key, 10);\n const t6 = u8to16(key, 12);\n const t7 = u8to16(key, 14);\n\n // RFC 8439 §2.5.1 / RFC 7539 §2.5.1 clamp r before multiplication.\n // These masks unpack that clamped value into 13-bit limbs, while pad\n // keeps the raw s half for finalize().\n // {@link https://github.com/floodyberry/poly1305-donna/blob/e6ad6e091d30d7f4ec2d4f978be1fcfcbce72781/poly1305-donna-16.h#L47 | poly1305-donna reference}\n this.r[0] = t0 & 0x1fff;\n this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff;\n this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03;\n this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff;\n this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff;\n this.r[5] = (t4 >>> 1) & 0x1ffe;\n this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff;\n this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81;\n this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff;\n this.r[9] = (t7 >>> 5) & 0x007f;\n for (let i = 0; i < 8; i++) this.pad[i] = u8to16(key, 16 + 2 * i);\n }\n\n private process(data: TArg<Uint8Array>, offset: number, isLast = false) {\n // RFC 8439 §2.5 / §2.5.1 and RFC 7539 §2.5 / §2.5.1 add an extra high\n // bit to every full 16-byte block. The final partial block gets its\n // explicit `1` byte during digestInto(), so `hibit` stays zero there.\n const hibit = isLast ? 0 : 1 << 11;\n const { h, r } = this;\n const r0 = r[0];\n const r1 = r[1];\n const r2 = r[2];\n const r3 = r[3];\n const r4 = r[4];\n const r5 = r[5];\n const r6 = r[6];\n const r7 = r[7];\n const r8 = r[8];\n const r9 = r[9];\n\n const t0 = u8to16(data, offset + 0);\n const t1 = u8to16(data, offset + 2);\n const t2 = u8to16(data, offset + 4);\n const t3 = u8to16(data, offset + 6);\n const t4 = u8to16(data, offset + 8);\n const t5 = u8to16(data, offset + 10);\n const t6 = u8to16(data, offset + 12);\n const t7 = u8to16(data, offset + 14);\n\n let h0 = h[0] + (t0 & 0x1fff);\n let h1 = h[1] + (((t0 >>> 13) | (t1 << 3)) & 0x1fff);\n let h2 = h[2] + (((t1 >>> 10) | (t2 << 6)) & 0x1fff);\n let h3 = h[3] + (((t2 >>> 7) | (t3 << 9)) & 0x1fff);\n let h4 = h[4] + (((t3 >>> 4) | (t4 << 12)) & 0x1fff);\n let h5 = h[5] + ((t4 >>> 1) & 0x1fff);\n let h6 = h[6] + (((t4 >>> 14) | (t5 << 2)) & 0x1fff);\n let h7 = h[7] + (((t5 >>> 11) | (t6 << 5)) & 0x1fff);\n let h8 = h[8] + (((t6 >>> 8) | (t7 << 8)) & 0x1fff);\n let h9 = h[9] + ((t7 >>> 5) | hibit);\n\n let c = 0;\n\n let d0 = c + h0 * r0 + h1 * (5 * r9) + h2 * (5 * r8) + h3 * (5 * r7) + h4 * (5 * r6);\n c = d0 >>> 13;\n d0 &= 0x1fff;\n d0 += h5 * (5 * r5) + h6 * (5 * r4) + h7 * (5 * r3) + h8 * (5 * r2) + h9 * (5 * r1);\n c += d0 >>> 13;\n d0 &= 0x1fff;\n\n let d1 = c + h0 * r1 + h1 * r0 + h2 * (5 * r9) + h3 * (5 * r8) + h4 * (5 * r7);\n c = d1 >>> 13;\n d1 &= 0x1fff;\n d1 += h5 * (5 * r6) + h6 * (5 * r5) + h7 * (5 * r4) + h8 * (5 * r3) + h9 * (5 * r2);\n c += d1 >>> 13;\n d1 &= 0x1fff;\n\n let d2 = c + h0 * r2 + h1 * r1 + h2 * r0 + h3 * (5 * r9) + h4 * (5 * r8);\n c = d2 >>> 13;\n d2 &= 0x1fff;\n d2 += h5 * (5 * r7) + h6 * (5 * r6) + h7 * (5 * r5) + h8 * (5 * r4) + h9 * (5 * r3);\n c += d2 >>> 13;\n d2 &= 0x1fff;\n\n let d3 = c + h0 * r3 + h1 * r2 + h2 * r1 + h3 * r0 + h4 * (5 * r9);\n c = d3 >>> 13;\n d3 &= 0x1fff;\n d3 += h5 * (5 * r8) + h6 * (5 * r7) + h7 * (5 * r6) + h8 * (5 * r5) + h9 * (5 * r4);\n c += d3 >>> 13;\n d3 &= 0x1fff;\n\n let d4 = c + h0 * r4 + h1 * r3 + h2 * r2 + h3 * r1 + h4 * r0;\n c = d4 >>> 13;\n d4 &= 0x1fff;\n d4 += h5 * (5 * r9) + h6 * (5 * r8) + h7 * (5 * r7) + h8 * (5 * r6) + h9 * (5 * r5);\n c += d4 >>> 13;\n d4 &= 0x1fff;\n\n let d5 = c + h0 * r5 + h1 * r4 + h2 * r3 + h3 * r2 + h4 * r1;\n c = d5 >>> 13;\n d5 &= 0x1fff;\n d5 += h5 * r0 + h6 * (5 * r9) + h7 * (5 * r8) + h8 * (5 * r7) + h9 * (5 * r6);\n c += d5 >>> 13;\n d5 &= 0x1fff;\n\n let d6 = c + h0 * r6 + h1 * r5 + h2 * r4 + h3 * r3 + h4 * r2;\n c = d6 >>> 13;\n d6 &= 0x1fff;\n d6 += h5 * r1 + h6 * r0 + h7 * (5 * r9) + h8 * (5 * r8) + h9 * (5 * r7);\n c += d6 >>> 13;\n d6 &= 0x1fff;\n\n let d7 = c + h0 * r7 + h1 * r6 + h2 * r5 + h3 * r4 + h4 * r3;\n c = d7 >>> 13;\n d7 &= 0x1fff;\n d7 += h5 * r2 + h6 * r1 + h7 * r0 + h8 * (5 * r9) + h9 * (5 * r8);\n c += d7 >>> 13;\n d7 &= 0x1fff;\n\n let d8 = c + h0 * r8 + h1 * r7 + h2 * r6 + h3 * r5 + h4 * r4;\n c = d8 >>> 13;\n d8 &= 0x1fff;\n d8 += h5 * r3 + h6 * r2 + h7 * r1 + h8 * r0 + h9 * (5 * r9);\n c += d8 >>> 13;\n d8 &= 0x1fff;\n\n let d9 = c + h0 * r9 + h1 * r8 + h2 * r7 + h3 * r6 + h4 * r5;\n c = d9 >>> 13;\n d9 &= 0x1fff;\n d9 += h5 * r4 + h6 * r3 + h7 * r2 + h8 * r1 + h9 * r0;\n c += d9 >>> 13;\n d9 &= 0x1fff;\n\n c = ((c << 2) + c) | 0;\n c = (c + d0) | 0;\n d0 = c & 0x1fff;\n c = c >>> 13;\n d1 += c;\n\n h[0] = d0;\n h[1] = d1;\n h[2] = d2;\n h[3] = d3;\n h[4] = d4;\n h[5] = d5;\n h[6] = d6;\n h[7] = d7;\n h[8] = d8;\n h[9] = d9;\n }\n\n private finalize() {\n const { h, pad } = this;\n const g = new Uint16Array(10);\n let c = h[1] >>> 13;\n h[1] &= 0x1fff;\n for (let i = 2; i < 10; i++) {\n h[i] += c;\n c = h[i] >>> 13;\n h[i] &= 0x1fff;\n }\n h[0] += c * 5;\n c = h[0] >>> 13;\n h[0] &= 0x1fff;\n h[1] += c;\n c = h[1] >>> 13;\n h[1] &= 0x1fff;\n h[2] += c;\n\n // RFC 8439 §2.5 / RFC 7539 §2.5 reduce modulo 2^130-5 before repacking\n // to 16-bit words and adding the raw s half.\n g[0] = h[0] + 5;\n c = g[0] >>> 13;\n g[0] &= 0x1fff;\n for (let i = 1; i < 10; i++) {\n g[i] = h[i] + c;\n c = g[i] >>> 13;\n g[i] &= 0x1fff;\n }\n g[9] -= 1 << 13;\n\n let mask = (c ^ 1) - 1;\n for (let i = 0; i < 10; i++) g[i] &= mask;\n mask = ~mask;\n for (let i = 0; i < 10; i++) h[i] = (h[i] & mask) | g[i];\n h[0] = (h[0] | (h[1] << 13)) & 0xffff;\n h[1] = ((h[1] >>> 3) | (h[2] << 10)) & 0xffff;\n h[2] = ((h[2] >>> 6) | (h[3] << 7)) & 0xffff;\n h[3] = ((h[3] >>> 9) | (h[4] << 4)) & 0xffff;\n h[4] = ((h[4] >>> 12) | (h[5] << 1) | (h[6] << 14)) & 0xffff;\n h[5] = ((h[6] >>> 2) | (h[7] << 11)) & 0xffff;\n h[6] = ((h[7] >>> 5) | (h[8] << 8)) & 0xffff;\n h[7] = ((h[8] >>> 8) | (h[9] << 5)) & 0xffff;\n\n let f = h[0] + pad[0];\n h[0] = f & 0xffff;\n for (let i = 1; i < 8; i++) {\n f = (((h[i] + pad[i]) | 0) + (f >>> 16)) | 0;\n h[i] = f & 0xffff;\n }\n clean(g);\n }\n update(data: TArg<Uint8Array>): this {\n aexists(this);\n abytes(data);\n data = copyBytes(data);\n const { buffer, blockLen } = this;\n const len = data.length;\n\n for (let pos = 0; pos < len; ) {\n const take = Math.min(blockLen - this.pos, len - pos);\n // Fast path: we have at least one block in input\n if (take === blockLen) {\n for (; blockLen <= len - pos; pos += blockLen) this.process(data, pos);\n continue;\n }\n buffer.set(data.subarray(pos, pos + take), this.pos);\n this.pos += take;\n pos += take;\n if (this.pos === blockLen) {\n this.process(buffer, 0, false);\n this.pos = 0;\n }\n }\n return this;\n }\n destroy(): void {\n // `aexists(this)` guards update/digest paths, so destroy must mark the instance unusable too.\n this.destroyed = true;\n clean(this.h, this.r, this.buffer, this.pad);\n }\n digestInto(out: TArg<Uint8Array>): void {\n aexists(this);\n aoutput(out, this);\n this.finished = true;\n const { buffer, h } = this;\n let { pos } = this;\n if (pos) {\n // RFC 8439 §2.5 / RFC 7539 §2.5: the final short block appends a\n // single `0x01` byte and zero-fills the remaining bytes before the\n // last multiplication step.\n buffer[pos++] = 1;\n for (; pos < 16; pos++) buffer[pos] = 0;\n this.process(buffer, 0, true);\n }\n this.finalize();\n let opos = 0;\n for (let i = 0; i < 8; i++) {\n out[opos++] = h[i] >>> 0;\n out[opos++] = h[i] >>> 8;\n }\n }\n digest(): TRet<Uint8Array> {\n const { buffer, outputLen } = this;\n this.digestInto(buffer);\n // Copy out before destroy() zeroes the internal buffer.\n const res = buffer.slice(0, outputLen);\n this.destroy();\n return res as TRet<Uint8Array>;\n }\n}\n\n/** One-shot keyed hash helper with `.create()`. */\nexport type CHash = CMac<Poly1305>;\n\n/**\n * Poly1305 MAC from RFC 8439.\n * @param msg - Message bytes to authenticate.\n * @param key - 32-byte Poly1305 one-time key.\n * @returns 16-byte authentication tag.\n * @example\n * Authenticates one message with a one-shot Poly1305 call and a fresh key.\n *\n * ```ts\n * import { poly1305 } from '@noble/ciphers/_poly1305.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * poly1305(new Uint8Array(), key);\n * ```\n */\nexport const poly1305: TRet<CHash> = /* @__PURE__ */ wrapMacConstructor(\n 32,\n (key: TArg<Uint8Array>) => new Poly1305(key)\n);\n","/**\n * ChaCha stream cipher, released\n * in 2008. Developed after Salsa20, ChaCha aims to increase diffusion per round.\n * It was standardized in\n * {@link https://www.rfc-editor.org/rfc/rfc8439 | RFC 8439} and\n * is now used in TLS 1.3.\n *\n * {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha | XChaCha20}\n * extended-nonce variant is also provided. Similar to XSalsa, it's safe to use with\n * randomly-generated nonces.\n *\n * Check out\n * {@link http://cr.yp.to/chacha/chacha-20080128.pdf | PDF},\n * {@link https://en.wikipedia.org/wiki/Salsa20 | wiki}, and\n * {@link https://cr.yp.to/chacha.html | website}.\n *\n * @module\n */\nimport { type XorPRG, createCipher, createPRG, rotl } from './_arx.ts';\nimport { poly1305 } from './_poly1305.ts';\nimport {\n type ARXCipher,\n type CipherWithOutput,\n type TArg,\n type TRet,\n type XorStream,\n abytes,\n clean,\n equalBytes,\n getOutput,\n swap8IfBE,\n swap32IfBE,\n u64Lengths,\n wrapCipher,\n} from './utils.ts';\n\n/**\n * ChaCha core function. It is implemented twice:\n * 1. Simple loop (chachaCore_small, hchacha_small)\n * 2. Unrolled loop (chachaCore, hchacha) - 4x faster, but larger & harder to read\n * The specific implementation is selected in `createCipher` below.\n */\n\n/** RFC 8439 §2.1 quarter round on words a, b, c, d. */\n// prettier-ignore\nfunction chachaQR(x: TArg<Uint32Array>, a: number, b: number, c: number, d: number) {\n x[a] = (x[a] + x[b]) | 0; x[d] = rotl(x[d] ^ x[a], 16);\n x[c] = (x[c] + x[d]) | 0; x[b] = rotl(x[b] ^ x[c], 12);\n x[a] = (x[a] + x[b]) | 0; x[d] = rotl(x[d] ^ x[a], 8);\n x[c] = (x[c] + x[d]) | 0; x[b] = rotl(x[b] ^ x[c], 7);\n}\n\n/** Repeated ChaCha double rounds; callers are expected to pass an even round count. */\nfunction chachaRound(x: TArg<Uint32Array>, rounds = 20) {\n for (let r = 0; r < rounds; r += 2) {\n // RFC 8439 §2.3 / §2.3.1 inner_block: four column rounds, then four diagonal rounds.\n chachaQR(x, 0, 4, 8, 12);\n chachaQR(x, 1, 5, 9, 13);\n chachaQR(x, 2, 6, 10, 14);\n chachaQR(x, 3, 7, 11, 15);\n chachaQR(x, 0, 5, 10, 15);\n chachaQR(x, 1, 6, 11, 12);\n chachaQR(x, 2, 7, 8, 13);\n chachaQR(x, 3, 4, 9, 14);\n }\n}\n\n// Shared scratch for the auditability-only helper below; only the test-only\n// __TESTS.chachaCore_small hook reaches it, so production exports stay reentrant.\nconst ctmp = /* @__PURE__ */ new Uint32Array(16);\n\n/** Small version of chacha without loop unrolling. Unused, provided for auditability. */\n// prettier-ignore\nfunction chacha(\n s: TArg<Uint32Array>, k: TArg<Uint32Array>, i: TArg<Uint32Array>, out: TArg<Uint32Array>,\n isHChacha: boolean = true, rounds: number = 20\n): void {\n // `i` is either `[counter, nonce0, nonce1, nonce2]` for the ChaCha block\n // function or the full 128-bit nonce prefix for the HChaCha subkey path.\n // Create initial array using common pattern\n const y = Uint32Array.from([\n s[0], s[1], s[2], s[3], // \"expa\" \"nd 3\" \"2-by\" \"te k\"\n k[0], k[1], k[2], k[3], // Key Key Key Key\n k[4], k[5], k[6], k[7], // Key Key Key Key\n i[0], i[1], i[2], i[3], // Counter Counter Nonce Nonce\n ]);\n const x = ctmp;\n x.set(y);\n chachaRound(x, rounds);\n\n // HChaCha writes words 0..3 and 12..15 after the rounds; the ChaCha\n // block path adds the original state word-by-word.\n if (isHChacha) {\n const xindexes = [0, 1, 2, 3, 12, 13, 14, 15];\n for (let i = 0; i < 8; i++) out[i] = x[xindexes[i]];\n } else {\n for (let i = 0; i < 16; i++) out[i] = (y[i] + x[i]) | 0;\n }\n}\n\n/** Identical to `chachaCore`. Reached only through the test-only `__TESTS` export. */\n// @ts-ignore\nconst chachaCore_small: typeof chachaCore = (s, k, n, out, cnt, rounds) =>\n // Keep the reference wrapper on the same [counter, nonce0, nonce1, nonce2] layout as chacha().\n chacha(s, k, Uint32Array.from([cnt, n[0], n[1], n[2]]), out, false, rounds);\n/** Identical to `hchacha`. Unused. */\n// @ts-ignore\nconst hchacha_small: typeof hchacha = chacha;\n\n/** RFC 8439 §2.3 block core for `state = constants | key | counter | nonce`. */\n// prettier-ignore\nfunction chachaCore(\n s: TArg<Uint32Array>, k: TArg<Uint32Array>, n: TArg<Uint32Array>, out: TArg<Uint32Array>, cnt: number, rounds = 20\n): void {\n let y00 = s[0], y01 = s[1], y02 = s[2], y03 = s[3], // \"expa\" \"nd 3\" \"2-by\" \"te k\"\n y04 = k[0], y05 = k[1], y06 = k[2], y07 = k[3], // Key Key Key Key\n y08 = k[4], y09 = k[5], y10 = k[6], y11 = k[7], // Key Key Key Key\n y12 = cnt, y13 = n[0], y14 = n[1], y15 = n[2]; // Counter Nonce Nonce Nonce\n // Save state to temporary variables\n let x00 = y00, x01 = y01, x02 = y02, x03 = y03,\n x04 = y04, x05 = y05, x06 = y06, x07 = y07,\n x08 = y08, x09 = y09, x10 = y10, x11 = y11,\n x12 = y12, x13 = y13, x14 = y14, x15 = y15;\n for (let r = 0; r < rounds; r += 2) {\n x00 = (x00 + x04) | 0; x12 = rotl(x12 ^ x00, 16);\n x08 = (x08 + x12) | 0; x04 = rotl(x04 ^ x08, 12);\n x00 = (x00 + x04) | 0; x12 = rotl(x12 ^ x00, 8);\n x08 = (x08 + x12) | 0; x04 = rotl(x04 ^ x08, 7);\n\n x01 = (x01 + x05) | 0; x13 = rotl(x13 ^ x01, 16);\n x09 = (x09 + x13) | 0; x05 = rotl(x05 ^ x09, 12);\n x01 = (x01 + x05) | 0; x13 = rotl(x13 ^ x01, 8);\n x09 = (x09 + x13) | 0; x05 = rotl(x05 ^ x09, 7);\n\n x02 = (x02 + x06) | 0; x14 = rotl(x14 ^ x02, 16);\n x10 = (x10 + x14) | 0; x06 = rotl(x06 ^ x10, 12);\n x02 = (x02 + x06) | 0; x14 = rotl(x14 ^ x02, 8);\n x10 = (x10 + x14) | 0; x06 = rotl(x06 ^ x10, 7);\n\n x03 = (x03 + x07) | 0; x15 = rotl(x15 ^ x03, 16);\n x11 = (x11 + x15) | 0; x07 = rotl(x07 ^ x11, 12);\n x03 = (x03 + x07) | 0; x15 = rotl(x15 ^ x03, 8)\n x11 = (x11 + x15) | 0; x07 = rotl(x07 ^ x11, 7);\n\n x00 = (x00 + x05) | 0; x15 = rotl(x15 ^ x00, 16);\n x10 = (x10 + x15) | 0; x05 = rotl(x05 ^ x10, 12);\n x00 = (x00 + x05) | 0; x15 = rotl(x15 ^ x00, 8);\n x10 = (x10 + x15) | 0; x05 = rotl(x05 ^ x10, 7);\n\n x01 = (x01 + x06) | 0; x12 = rotl(x12 ^ x01, 16);\n x11 = (x11 + x12) | 0; x06 = rotl(x06 ^ x11, 12);\n x01 = (x01 + x06) | 0; x12 = rotl(x12 ^ x01, 8);\n x11 = (x11 + x12) | 0; x06 = rotl(x06 ^ x11, 7);\n\n x02 = (x02 + x07) | 0; x13 = rotl(x13 ^ x02, 16);\n x08 = (x08 + x13) | 0; x07 = rotl(x07 ^ x08, 12);\n x02 = (x02 + x07) | 0; x13 = rotl(x13 ^ x02, 8);\n x08 = (x08 + x13) | 0; x07 = rotl(x07 ^ x08, 7);\n\n x03 = (x03 + x04) | 0; x14 = rotl(x14 ^ x03, 16)\n x09 = (x09 + x14) | 0; x04 = rotl(x04 ^ x09, 12);\n x03 = (x03 + x04) | 0; x14 = rotl(x14 ^ x03, 8);\n x09 = (x09 + x14) | 0; x04 = rotl(x04 ^ x09, 7);\n }\n // RFC 8439 §2.3 / §2.3.1: add the original state words back in state order.\n let oi = 0;\n out[oi++] = (y00 + x00) | 0; out[oi++] = (y01 + x01) | 0;\n out[oi++] = (y02 + x02) | 0; out[oi++] = (y03 + x03) | 0;\n out[oi++] = (y04 + x04) | 0; out[oi++] = (y05 + x05) | 0;\n out[oi++] = (y06 + x06) | 0; out[oi++] = (y07 + x07) | 0;\n out[oi++] = (y08 + x08) | 0; out[oi++] = (y09 + x09) | 0;\n out[oi++] = (y10 + x10) | 0; out[oi++] = (y11 + x11) | 0;\n out[oi++] = (y12 + x12) | 0; out[oi++] = (y13 + x13) | 0;\n out[oi++] = (y14 + x14) | 0; out[oi++] = (y15 + x15) | 0;\n}\n/**\n * hchacha hashes key and nonce into key' and nonce' for xchacha20.\n * Algorithmically identical to `hchacha_small`, but this exported path\n * normalizes word order on big-endian hosts.\n * Need to find a way to merge it with `chachaCore` without 25% performance hit.\n * @param s - Sigma constants as 32-bit words.\n * @param k - Key words.\n * @param i - Nonce-prefix words.\n * @param out - Output buffer for the derived subkey.\n * @example\n * Derives the XChaCha subkey from sigma, key, and nonce-prefix words.\n *\n * ```ts\n * const sigma = new Uint32Array(4);\n * const key = new Uint32Array(8);\n * const nonce = new Uint32Array(4);\n * const out = new Uint32Array(8);\n * hchacha(sigma, key, nonce, out);\n * ```\n */\n// prettier-ignore\nexport function hchacha(\n s: TArg<Uint32Array>, k: TArg<Uint32Array>, i: TArg<Uint32Array>, out: TArg<Uint32Array>\n): void {\n let x00 = swap8IfBE(s[0]), x01 = swap8IfBE(s[1]), x02 = swap8IfBE(s[2]), x03 = swap8IfBE(s[3]),\n x04 = swap8IfBE(k[0]), x05 = swap8IfBE(k[1]), x06 = swap8IfBE(k[2]), x07 = swap8IfBE(k[3]),\n x08 = swap8IfBE(k[4]), x09 = swap8IfBE(k[5]), x10 = swap8IfBE(k[6]), x11 = swap8IfBE(k[7]),\n x12 = swap8IfBE(i[0]), x13 = swap8IfBE(i[1]), x14 = swap8IfBE(i[2]), x15 = swap8IfBE(i[3]);\n for (let r = 0; r < 20; r += 2) {\n x00 = (x00 + x04) | 0; x12 = rotl(x12 ^ x00, 16);\n x08 = (x08 + x12) | 0; x04 = rotl(x04 ^ x08, 12);\n x00 = (x00 + x04) | 0; x12 = rotl(x12 ^ x00, 8);\n x08 = (x08 + x12) | 0; x04 = rotl(x04 ^ x08, 7);\n\n x01 = (x01 + x05) | 0; x13 = rotl(x13 ^ x01, 16);\n x09 = (x09 + x13) | 0; x05 = rotl(x05 ^ x09, 12);\n x01 = (x01 + x05) | 0; x13 = rotl(x13 ^ x01, 8);\n x09 = (x09 + x13) | 0; x05 = rotl(x05 ^ x09, 7);\n\n x02 = (x02 + x06) | 0; x14 = rotl(x14 ^ x02, 16);\n x10 = (x10 + x14) | 0; x06 = rotl(x06 ^ x10, 12);\n x02 = (x02 + x06) | 0; x14 = rotl(x14 ^ x02, 8);\n x10 = (x10 + x14) | 0; x06 = rotl(x06 ^ x10, 7);\n\n x03 = (x03 + x07) | 0; x15 = rotl(x15 ^ x03, 16);\n x11 = (x11 + x15) | 0; x07 = rotl(x07 ^ x11, 12);\n x03 = (x03 + x07) | 0; x15 = rotl(x15 ^ x03, 8)\n x11 = (x11 + x15) | 0; x07 = rotl(x07 ^ x11, 7);\n\n x00 = (x00 + x05) | 0; x15 = rotl(x15 ^ x00, 16);\n x10 = (x10 + x15) | 0; x05 = rotl(x05 ^ x10, 12);\n x00 = (x00 + x05) | 0; x15 = rotl(x15 ^ x00, 8);\n x10 = (x10 + x15) | 0; x05 = rotl(x05 ^ x10, 7);\n\n x01 = (x01 + x06) | 0; x12 = rotl(x12 ^ x01, 16);\n x11 = (x11 + x12) | 0; x06 = rotl(x06 ^ x11, 12);\n x01 = (x01 + x06) | 0; x12 = rotl(x12 ^ x01, 8);\n x11 = (x11 + x12) | 0; x06 = rotl(x06 ^ x11, 7);\n\n x02 = (x02 + x07) | 0; x13 = rotl(x13 ^ x02, 16);\n x08 = (x08 + x13) | 0; x07 = rotl(x07 ^ x08, 12);\n x02 = (x02 + x07) | 0; x13 = rotl(x13 ^ x02, 8);\n x08 = (x08 + x13) | 0; x07 = rotl(x07 ^ x08, 7);\n\n x03 = (x03 + x04) | 0; x14 = rotl(x14 ^ x03, 16)\n x09 = (x09 + x14) | 0; x04 = rotl(x04 ^ x09, 12);\n x03 = (x03 + x04) | 0; x14 = rotl(x14 ^ x03, 8);\n x09 = (x09 + x14) | 0; x04 = rotl(x04 ^ x09, 7);\n }\n // HChaCha derives the subkey from state words 0..3 and 12..15 after 20 rounds.\n let oi = 0;\n out[oi++] = x00; out[oi++] = x01;\n out[oi++] = x02; out[oi++] = x03;\n out[oi++] = x12; out[oi++] = x13;\n out[oi++] = x14; out[oi++] = x15;\n swap32IfBE(out);\n}\n\n/**\n * Original, non-RFC chacha20 from DJB. 8-byte nonce, 8-byte counter.\n * The nonce/counter layout still reserves 8 counter bytes internally, but the shared public\n * `counter` argument follows noble's strict non-wrapping 32-bit policy. See `src/_arx.ts`\n * near `MAX_COUNTER` for the full counter-policy rationale.\n * @param key - 16-byte or 32-byte key.\n * @param nonce - 8-byte nonce.\n * @param data - Input bytes to xor with the keystream.\n * @param output - Optional destination buffer.\n * @param counter - Initial block counter.\n * @returns Encrypted or decrypted bytes.\n * @example\n * Encrypts bytes with the original 8-byte-nonce ChaCha variant and a fresh key/nonce.\n *\n * ```ts\n * import { chacha20orig } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const nonce = randomBytes(8);\n * chacha20orig(key, nonce, new Uint8Array(4));\n * ```\n */\nexport const chacha20orig: TRet<XorStream> = /* @__PURE__ */ createCipher(chachaCore, {\n counterRight: false,\n counterLength: 8,\n allowShortKeys: true,\n});\n/**\n * ChaCha stream cipher. Conforms to RFC 8439 (IETF, TLS). 12-byte nonce, 4-byte counter.\n * With smaller nonce, it's not safe to make it random (CSPRNG), due to collision chance.\n * @param key - 32-byte key.\n * @param nonce - 12-byte nonce.\n * @param data - Input bytes to xor with the keystream.\n * @param output - Optional destination buffer.\n * @param counter - Initial block counter.\n * @returns Encrypted or decrypted bytes.\n * @example\n * Encrypts bytes with the RFC 8439 ChaCha20 stream cipher and a fresh key/nonce.\n *\n * ```ts\n * import { chacha20 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const nonce = randomBytes(12);\n * chacha20(key, nonce, new Uint8Array(4));\n * ```\n */\nexport const chacha20: TRet<XorStream> = /* @__PURE__ */ createCipher(chachaCore, {\n counterRight: false,\n counterLength: 4,\n allowShortKeys: false,\n});\n\n/**\n * XChaCha eXtended-nonce ChaCha. With 24-byte nonce, it's safe to make it random (CSPRNG).\n * See {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha | the IRTF draft}.\n * The nonce/counter layout still reserves 8 counter bytes internally, but the shared public\n * `counter` argument follows noble's strict non-wrapping 32-bit policy. See `src/_arx.ts`\n * near `MAX_COUNTER` for the full counter-policy rationale.\n * @param key - 32-byte key.\n * @param nonce - 24-byte extended nonce.\n * @param data - Input bytes to xor with the keystream.\n * @param output - Optional destination buffer.\n * @param counter - Initial block counter.\n * @returns Encrypted or decrypted bytes.\n * @example\n * Encrypts bytes with XChaCha20 using a fresh key and random 24-byte nonce.\n *\n * ```ts\n * import { xchacha20 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const nonce = randomBytes(24);\n * xchacha20(key, nonce, new Uint8Array(4));\n * ```\n */\nexport const xchacha20: TRet<XorStream> = /* @__PURE__ */ createCipher(chachaCore, {\n counterRight: false,\n counterLength: 8,\n extendNonceFn: hchacha,\n allowShortKeys: false,\n});\n\n/**\n * Reduced 8-round chacha, described in original paper.\n * @param key - 32-byte key.\n * @param nonce - 12-byte nonce.\n * @param data - Input bytes to xor with the keystream.\n * @param output - Optional destination buffer.\n * @param counter - Initial block counter.\n * @returns Encrypted or decrypted bytes.\n * @example\n * Uses the reduced 8-round variant for non-critical workloads with a fresh key/nonce.\n *\n * ```ts\n * import { chacha8 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const nonce = randomBytes(12);\n * chacha8(key, nonce, new Uint8Array(4));\n * ```\n */\nexport const chacha8: TRet<XorStream> = /* @__PURE__ */ createCipher(chachaCore, {\n counterRight: false,\n counterLength: 4,\n rounds: 8,\n});\n\n/**\n * Reduced 12-round chacha, described in original paper.\n * @param key - 32-byte key.\n * @param nonce - 12-byte nonce.\n * @param data - Input bytes to xor with the keystream.\n * @param output - Optional destination buffer.\n * @param counter - Initial block counter.\n * @returns Encrypted or decrypted bytes.\n * @example\n * Uses the reduced 12-round variant for non-critical workloads with a fresh key/nonce.\n *\n * ```ts\n * import { chacha12 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const nonce = randomBytes(12);\n * chacha12(key, nonce, new Uint8Array(4));\n * ```\n */\nexport const chacha12: TRet<XorStream> = /* @__PURE__ */ createCipher(chachaCore, {\n counterRight: false,\n counterLength: 4,\n rounds: 12,\n});\n\n// Test-only hooks for keeping the simple/reference core aligned with the unrolled production core.\nexport const __TESTS: {\n chachaCore_small: typeof chachaCore_small;\n chachaCore: typeof chachaCore;\n} = /* @__PURE__ */ Object.freeze({ chachaCore_small, chachaCore });\n\n// RFC 8439 §2.8.1 pad16(x): shared zero block for AAD/ciphertext padding.\nconst ZEROS16 = /* @__PURE__ */ new Uint8Array(16);\n// RFC 8439 §2.8 / §2.8.1: aligned inputs add nothing, otherwise append 16-(len%16) zero bytes.\nconst updatePadded = (h: ReturnType<typeof poly1305.create>, msg: TArg<Uint8Array>) => {\n h.update(msg);\n const leftover = msg.length % 16;\n if (leftover) h.update(ZEROS16.subarray(leftover));\n};\n\n// RFC 8439 §2.6.1 poly1305_key_gen returns `block[0..31]`, so AEAD key\n// generation only needs 32 zero bytes.\nconst ZEROS32 = /* @__PURE__ */ new Uint8Array(32);\nfunction computeTag(\n fn: TArg<XorStream>,\n key: TArg<Uint8Array>,\n nonce: TArg<Uint8Array>,\n ciphertext: TArg<Uint8Array>,\n AAD?: TArg<Uint8Array>\n): TRet<Uint8Array> {\n if (AAD !== undefined) abytes(AAD, undefined, 'AAD');\n // RFC 8439 §2.6 / §2.8: derive the Poly1305 one-time key from counter 0,\n // then MAC AAD || pad16(AAD) || ciphertext || pad16(ciphertext) || len(AAD) || len(ciphertext).\n const authKey = fn(\n key as TRet<Uint8Array>,\n nonce as TRet<Uint8Array>,\n ZEROS32 as TRet<Uint8Array>\n );\n const lengths = u64Lengths(ciphertext.length, AAD ? AAD.length : 0, true);\n\n // Methods below can be replaced with\n // return poly1305_computeTag_small(authKey, lengths, ciphertext, AAD)\n const h = poly1305.create(authKey);\n if (AAD) updatePadded(h, AAD);\n updatePadded(h, ciphertext);\n h.update(lengths);\n const res = h.digest();\n clean(authKey, lengths);\n return res;\n}\n\n/**\n * AEAD algorithm from RFC 8439.\n * Salsa20 and chacha (RFC 8439) use poly1305 differently.\n * We could have composed them, but it's hard because of authKey:\n * In salsa20, authKey changes position in salsa stream.\n * In chacha, authKey can't be computed inside computeTag, it modifies the counter.\n */\nexport const _poly1305_aead =\n (xorStream: TArg<XorStream>) =>\n (key: TArg<Uint8Array>, nonce: TArg<Uint8Array>, AAD?: TArg<Uint8Array>): CipherWithOutput => {\n // This borrows caller key/nonce/AAD buffers by reference; mutating them after construction\n // changes future encrypt/decrypt results.\n const tagLength = 16;\n return {\n encrypt(plaintext: TArg<Uint8Array>, output?: TArg<Uint8Array>): TRet<Uint8Array> {\n const plength = plaintext.length;\n output = getOutput(plength + tagLength, output, false);\n output.set(plaintext);\n const oPlain = output.subarray(0, -tagLength);\n // RFC 8439 §2.8: payload encryption starts at counter 1 because counter 0 produced the OTK.\n xorStream(\n key as TRet<Uint8Array>,\n nonce as TRet<Uint8Array>,\n oPlain as TRet<Uint8Array>,\n oPlain as TRet<Uint8Array>,\n 1\n );\n const tag = computeTag(xorStream, key, nonce, oPlain, AAD);\n output.set(tag, plength); // append tag\n clean(tag);\n return output as TRet<Uint8Array>;\n },\n decrypt(ciphertext: TArg<Uint8Array>, output?: TArg<Uint8Array>): TRet<Uint8Array> {\n output = getOutput(ciphertext.length - tagLength, output, false);\n const data = ciphertext.subarray(0, -tagLength);\n const passedTag = ciphertext.subarray(-tagLength);\n const tag = computeTag(xorStream, key, nonce, data, AAD);\n // RFC 8439 §2.8 / §4: authenticate ciphertext before decrypting it, and compare tags with\n // the constant-time equalBytes() helper rather than decrypting speculative plaintext first.\n if (!equalBytes(passedTag, tag)) {\n clean(tag);\n throw new Error('invalid tag');\n }\n output.set(ciphertext.subarray(0, -tagLength));\n // Actual decryption\n xorStream(\n key as TRet<Uint8Array>,\n nonce as TRet<Uint8Array>,\n output as TRet<Uint8Array>,\n output as TRet<Uint8Array>,\n 1\n ); // start stream with i=1\n clean(tag);\n return output as TRet<Uint8Array>;\n },\n };\n };\n\n/**\n * ChaCha20-Poly1305 from RFC 8439.\n *\n * Unsafe to use random nonces under the same key, due to collision chance.\n * Prefer XChaCha instead.\n * @param key - 32-byte key.\n * @param nonce - 12-byte nonce.\n * @param AAD - Additional authenticated data.\n * @returns AEAD cipher instance.\n * @example\n * Encrypts and authenticates plaintext with a fresh key and nonce.\n *\n * ```ts\n * import { chacha20poly1305 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const nonce = randomBytes(12);\n * const cipher = chacha20poly1305(key, nonce);\n * cipher.encrypt(new Uint8Array([1, 2, 3]));\n * ```\n */\nexport const chacha20poly1305: TRet<ARXCipher> = /* @__PURE__ */ wrapCipher(\n { blockSize: 64, nonceLength: 12, tagLength: 16 },\n /* @__PURE__ */ _poly1305_aead(chacha20)\n);\n/**\n * XChaCha20-Poly1305 extended-nonce chacha.\n *\n * Can be safely used with random nonces (CSPRNG).\n * See {@link https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha | the IRTF draft}.\n * @param key - 32-byte key.\n * @param nonce - 24-byte nonce.\n * @param AAD - Additional authenticated data.\n * @returns AEAD cipher instance.\n * @example\n * Encrypts and authenticates plaintext with a fresh key and random 24-byte nonce.\n *\n * ```ts\n * import { xchacha20poly1305 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const key = randomBytes(32);\n * const nonce = randomBytes(24);\n * const cipher = xchacha20poly1305(key, nonce);\n * cipher.encrypt(new Uint8Array([1, 2, 3]));\n * ```\n */\nexport const xchacha20poly1305: TRet<ARXCipher> = /* @__PURE__ */ wrapCipher(\n { blockSize: 64, nonceLength: 24, tagLength: 16 },\n /* @__PURE__ */ _poly1305_aead(xchacha20)\n);\n\n/**\n * Chacha20 CSPRNG (cryptographically secure pseudorandom number generator).\n * It's best to limit usage to non-production, non-critical cases: for example, test-only.\n * Compatible with libtomcrypt. It does not have a specification, so unclear how secure it is.\n * @param seed - Optional seed bytes mixed into the internal `key || nonce` state. When omitted,\n * only 32 random bytes are mixed into the 40-byte state.\n * @returns Seeded concrete `_XorStreamPRG` instance, including `clone()`.\n * @example\n * Seeds the test-only ChaCha20 DRBG from fresh entropy.\n *\n * ```ts\n * import { rngChacha20 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const seed = randomBytes(32);\n * const prg = rngChacha20(seed);\n * prg.randomBytes(8);\n * ```\n */\nexport const rngChacha20: TRet<XorPRG> = /* @__PURE__ */ createPRG(chacha20orig, 64, 32, 8);\n/**\n * Chacha20/8 CSPRNG (cryptographically secure pseudorandom number generator).\n * It's best to limit usage to non-production, non-critical cases: for example, test-only.\n * Faster than `rngChacha20`.\n * @param seed - Optional seed bytes mixed into the internal `key || nonce` state. When omitted,\n * only 32 random bytes are mixed into the 44-byte state.\n * @returns Seeded concrete `_XorStreamPRG` instance, including `clone()`.\n * @example\n * Seeds the faster test-only ChaCha8 DRBG from fresh entropy.\n *\n * ```ts\n * import { rngChacha8 } from '@noble/ciphers/chacha.js';\n * import { randomBytes } from '@noble/ciphers/utils.js';\n * const seed = randomBytes(32);\n * const prg = rngChacha8(seed);\n * prg.randomBytes(8);\n * ```\n */\nexport const rngChacha8: TRet<XorPRG> = /* @__PURE__ */ createPRG(chacha8, 64, 32, 12);\n","/**\n * core/field-encryption.ts — client-side field encryption (sdk-changes S6,\n * ARCHITECTURE §8.3).\n *\n * Fields the backend stores but never needs to read (mailbox `memo`, history\n * `memo` + `counterparty_nametag`, payment-request `memo`, and the intent\n * payload — E.3) are encrypted client-side so any of the owner's devices can\n * decrypt but the operator cannot.\n *\n * - **Key**: `HKDF-SHA256(ikm = walletPrivKey bytes, info = \"sphere-fieldenc-v1\")`\n * → 32-byte symmetric key. Deterministic per wallet → multi-device by\n * construction (mirrors token-engine/realization.ts — same @noble/hashes\n * HKDF, no salt).\n * - **Cipher/envelope**: XChaCha20-Poly1305 with a random 24-byte nonce; wire\n * form is EXACTLY `\"enc1.\" + base64(nonce ‖ ciphertext)`.\n * - **One mapping rule everywhere** (ARCHITECTURE §8.3): JSON bodies and\n * responses carry the `enc1.` string verbatim; the server validates only\n * prefix + base64 + size cap, stores the exact UTF-8 bytes, and returns them\n * unchanged. {@link assertFieldEnvelopeShape} is that server-side check.\n */\n\nimport { hkdf } from '@noble/hashes/hkdf.js';\nimport { sha256 } from '@noble/hashes/sha2.js';\nimport { xchacha20poly1305 } from '@noble/ciphers/chacha.js';\nimport { randomBytes } from '@noble/ciphers/utils.js';\nimport { SphereError } from './errors';\n\n/** HKDF info label — versioned; the same label appears in sdk-changes S6. */\nexport const FIELD_ENCRYPTION_HKDF_INFO = 'sphere-fieldenc-v1';\n\n/** Envelope wire prefix. The version lives in the prefix (`enc1`). */\nexport const FIELD_ENVELOPE_PREFIX = 'enc1.';\n\n/** XChaCha20-Poly1305 nonce length (24 bytes). */\nexport const FIELD_ENVELOPE_NONCE_BYTES = 24;\n\n/** Poly1305 authentication tag length appended to the ciphertext. */\nconst POLY1305_TAG_BYTES = 16;\n\n/**\n * Default envelope size cap in bytes (UTF-8 length of the full `enc1.…`\n * string). Matches the intent-payload cap (≤ 4 KiB — ARCHITECTURE §7/§11).\n */\nexport const FIELD_ENVELOPE_MAX_BYTES = 4096;\n\n// =============================================================================\n// base64 (RFC 4648, with padding) — hand-rolled so the codec is identical in\n// Node and browsers (no Buffer / btoa dependency) and decode is strict.\n// =============================================================================\n\nconst B64_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\nconst B64_LOOKUP: Record<string, number> = {};\nfor (let i = 0; i < B64_ALPHABET.length; i++) B64_LOOKUP[B64_ALPHABET[i]] = i;\n\nfunction base64Encode(bytes: Uint8Array): string {\n let out = '';\n for (let i = 0; i < bytes.length; i += 3) {\n const b0 = bytes[i];\n const b1 = i + 1 < bytes.length ? bytes[i + 1] : 0;\n const b2 = i + 2 < bytes.length ? bytes[i + 2] : 0;\n out += B64_ALPHABET[b0 >> 2];\n out += B64_ALPHABET[((b0 & 0x03) << 4) | (b1 >> 4)];\n out += i + 1 < bytes.length ? B64_ALPHABET[((b1 & 0x0f) << 2) | (b2 >> 6)] : '=';\n out += i + 2 < bytes.length ? B64_ALPHABET[b2 & 0x3f] : '=';\n }\n return out;\n}\n\n/** Strict decode: throws on non-alphabet chars, bad length, or bad padding. */\nfunction base64Decode(s: string): Uint8Array {\n if (s.length % 4 !== 0) {\n throw new SphereError('Invalid field envelope: base64 length not a multiple of 4', 'DECRYPTION_ERROR');\n }\n let padding = 0;\n if (s.endsWith('==')) padding = 2;\n else if (s.endsWith('=')) padding = 1;\n const body = s.slice(0, s.length - padding);\n if (body.includes('=')) {\n throw new SphereError('Invalid field envelope: misplaced base64 padding', 'DECRYPTION_ERROR');\n }\n const out = new Uint8Array((s.length / 4) * 3 - padding);\n let o = 0;\n for (let i = 0; i < body.length; i += 4) {\n const n0 = B64_LOOKUP[body[i]];\n const n1 = B64_LOOKUP[body[i + 1]];\n const n2 = body[i + 2] !== undefined ? B64_LOOKUP[body[i + 2]] : 0;\n const n3 = body[i + 3] !== undefined ? B64_LOOKUP[body[i + 3]] : 0;\n if (n0 === undefined || n1 === undefined || n2 === undefined || n3 === undefined) {\n throw new SphereError('Invalid field envelope: non-base64 character', 'DECRYPTION_ERROR');\n }\n const triple = (n0 << 18) | (n1 << 12) | (n2 << 6) | n3;\n if (o < out.length) out[o++] = (triple >> 16) & 0xff;\n if (o < out.length) out[o++] = (triple >> 8) & 0xff;\n if (o < out.length) out[o++] = triple & 0xff;\n }\n return out;\n}\n\n// =============================================================================\n// Key derivation\n// =============================================================================\n\nfunction hexToBytesStrict(hex: string): Uint8Array {\n if (hex.length === 0 || hex.length % 2 !== 0 || !/^[0-9a-fA-F]+$/.test(hex)) {\n throw new SphereError('Invalid private key hex for field-encryption key derivation', 'INVALID_CONFIG');\n }\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < out.length; i++) {\n out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return out;\n}\n\n/**\n * Derive the wallet's 32-byte field-encryption key (sdk-changes S6):\n * `HKDF-SHA256(ikm = wallet privkey bytes, info = \"sphere-fieldenc-v1\")`.\n *\n * Deterministic per wallet key — every device holding the seed derives the\n * same key, so envelopes round-trip across devices with no key exchange.\n *\n * @param privKeyHex - wallet secp256k1 private key, hex (the HKDF ikm is its raw bytes)\n */\nexport function deriveFieldEncryptionKey(privKeyHex: string): Uint8Array {\n const ikm = hexToBytesStrict(privKeyHex);\n const info = new TextEncoder().encode(FIELD_ENCRYPTION_HKDF_INFO);\n return hkdf(sha256, ikm, undefined, info, 32);\n}\n\n// =============================================================================\n// Envelope encrypt / decrypt\n// =============================================================================\n\n/**\n * Encrypt a plaintext field into the S6 wire envelope:\n * `\"enc1.\" + base64(nonce ‖ ciphertext)` (XChaCha20-Poly1305, random 24-byte nonce).\n */\nexport function encryptField(key: Uint8Array, plaintext: string): string {\n const nonce = randomBytes(FIELD_ENVELOPE_NONCE_BYTES);\n const ciphertext = xchacha20poly1305(key, nonce).encrypt(new TextEncoder().encode(plaintext));\n const packed = new Uint8Array(nonce.length + ciphertext.length);\n packed.set(nonce, 0);\n packed.set(ciphertext, nonce.length);\n return FIELD_ENVELOPE_PREFIX + base64Encode(packed);\n}\n\n/**\n * Decrypt an S6 wire envelope. Validates the prefix and shape, then opens the\n * XChaCha20-Poly1305 box; any tampering (nonce, ciphertext, or tag) throws a\n * `SphereError('DECRYPTION_ERROR')`.\n */\nexport function decryptField(key: Uint8Array, envelope: string): string {\n if (typeof envelope !== 'string' || !envelope.startsWith(FIELD_ENVELOPE_PREFIX)) {\n throw new SphereError('Invalid field envelope: missing \"enc1.\" prefix', 'DECRYPTION_ERROR');\n }\n const packed = base64Decode(envelope.slice(FIELD_ENVELOPE_PREFIX.length));\n if (packed.length < FIELD_ENVELOPE_NONCE_BYTES + POLY1305_TAG_BYTES) {\n throw new SphereError('Invalid field envelope: too short for nonce + tag', 'DECRYPTION_ERROR');\n }\n const nonce = packed.slice(0, FIELD_ENVELOPE_NONCE_BYTES);\n const ciphertext = packed.slice(FIELD_ENVELOPE_NONCE_BYTES);\n try {\n const plain = xchacha20poly1305(key, nonce).decrypt(ciphertext);\n return new TextDecoder().decode(plain);\n } catch (err) {\n throw new SphereError('Field envelope authentication failed (tampered or wrong key)', 'DECRYPTION_ERROR', err);\n }\n}\n\n/**\n * The server-side shape check (ARCHITECTURE §8.3): the value must be a string,\n * carry the `enc1.` prefix, decode as base64, be long enough to hold a nonce +\n * tag, and fit the size cap. The server never sees plaintext — this is the\n * ONLY validation it performs before storing the exact UTF-8 bytes verbatim.\n *\n * Throws `SphereError('VALIDATION_ERROR')` on any violation.\n */\nexport function assertFieldEnvelopeShape(value: unknown, maxBytes: number = FIELD_ENVELOPE_MAX_BYTES): void {\n if (typeof value !== 'string') {\n throw new SphereError('Field envelope must be a string', 'VALIDATION_ERROR');\n }\n if (!value.startsWith(FIELD_ENVELOPE_PREFIX)) {\n throw new SphereError('Field envelope must start with \"enc1.\"', 'VALIDATION_ERROR');\n }\n if (new TextEncoder().encode(value).length > maxBytes) {\n throw new SphereError(`Field envelope exceeds size cap of ${maxBytes} bytes`, 'VALIDATION_ERROR');\n }\n let packed: Uint8Array;\n try {\n packed = base64Decode(value.slice(FIELD_ENVELOPE_PREFIX.length));\n } catch (err) {\n throw new SphereError('Field envelope payload is not valid base64', 'VALIDATION_ERROR', err);\n }\n if (packed.length < FIELD_ENVELOPE_NONCE_BYTES + POLY1305_TAG_BYTES) {\n throw new SphereError('Field envelope payload too short for nonce + tag', 'VALIDATION_ERROR');\n }\n}\n","/**\n * Centralized SDK Logger\n *\n * A lightweight singleton logger that works across all tsup bundles\n * by storing state on globalThis. Supports three log levels:\n * - debug: detailed messages (only shown when debug=true)\n * - warn: important warnings (ALWAYS shown regardless of debug flag)\n * - error: critical errors (ALWAYS shown regardless of debug flag)\n *\n * Global debug flag enables all logging. Per-tag overrides allow\n * granular control (e.g., only transport debug).\n *\n * @example\n * ```ts\n * import { logger } from '@unicitylabs/sphere-sdk';\n *\n * // Enable all debug logging\n * logger.configure({ debug: true });\n *\n * // Enable only specific tags\n * logger.setTagDebug('Nostr', true);\n *\n * // Usage in SDK classes\n * logger.debug('Payments', 'Transfer started', { amount, recipient });\n * logger.warn('Nostr', 'queryEvents timed out after 5s');\n * logger.error('Sphere', 'Critical failure', error);\n * ```\n */\n\nexport type LogLevel = 'debug' | 'warn' | 'error';\n\nexport type LogHandler = (level: LogLevel, tag: string, message: string, ...args: unknown[]) => void;\n\nexport interface LoggerConfig {\n /** Enable debug logging globally (default: false). When false, only warn and error messages are shown. */\n debug?: boolean;\n /** Custom log handler. If provided, replaces console output. Useful for tests or custom log sinks. */\n handler?: LogHandler | null;\n}\n\n// Use a unique symbol-like key on globalThis to share logger state across tsup bundles\nconst LOGGER_KEY = '__sphere_sdk_logger__';\n\ninterface LoggerState {\n debug: boolean;\n tags: Record<string, boolean>;\n handler: LogHandler | null;\n}\n\nfunction getState(): LoggerState {\n const g = globalThis as unknown as Record<string, unknown>;\n if (!g[LOGGER_KEY]) {\n g[LOGGER_KEY] = { debug: false, tags: {}, handler: null } satisfies LoggerState;\n }\n return g[LOGGER_KEY] as LoggerState;\n}\n\nfunction isEnabled(tag: string): boolean {\n const state = getState();\n // Per-tag override takes priority\n if (tag in state.tags) return state.tags[tag];\n // Fall back to global flag\n return state.debug;\n}\n\nexport const logger = {\n /**\n * Configure the logger. Can be called multiple times (last write wins).\n * Typically called by createBrowserProviders(), createNodeProviders(), or Sphere.init().\n */\n configure(config: LoggerConfig): void {\n const state = getState();\n if (config.debug !== undefined) state.debug = config.debug;\n if (config.handler !== undefined) state.handler = config.handler;\n },\n\n /**\n * Enable/disable debug logging for a specific tag.\n * Per-tag setting overrides the global debug flag.\n *\n * @example\n * ```ts\n * logger.setTagDebug('Nostr', true); // enable only Nostr logs\n * logger.setTagDebug('Nostr', false); // disable Nostr logs even if global debug=true\n * ```\n */\n setTagDebug(tag: string, enabled: boolean): void {\n getState().tags[tag] = enabled;\n },\n\n /**\n * Clear per-tag override, falling back to global debug flag.\n */\n clearTagDebug(tag: string): void {\n delete getState().tags[tag];\n },\n\n /** Returns true if debug mode is enabled for the given tag (or globally). */\n isDebugEnabled(tag?: string): boolean {\n if (tag) return isEnabled(tag);\n return getState().debug;\n },\n\n /**\n * Debug-level log. Only shown when debug is enabled (globally or for this tag).\n * Use for detailed operational information.\n */\n debug(tag: string, message: string, ...args: unknown[]): void {\n if (!isEnabled(tag)) return;\n const state = getState();\n if (state.handler) {\n state.handler('debug', tag, message, ...args);\n } else {\n console.log(`[${tag}]`, message, ...args);\n }\n },\n\n /**\n * Warning-level log. ALWAYS shown regardless of debug flag.\n * Use for important but non-critical issues (timeouts, retries, degraded state).\n */\n warn(tag: string, message: string, ...args: unknown[]): void {\n const state = getState();\n if (state.handler) {\n state.handler('warn', tag, message, ...args);\n } else {\n console.warn(`[${tag}]`, message, ...args);\n }\n },\n\n /**\n * Error-level log. ALWAYS shown regardless of debug flag.\n * Use for critical failures that should never be silenced.\n */\n error(tag: string, message: string, ...args: unknown[]): void {\n const state = getState();\n if (state.handler) {\n state.handler('error', tag, message, ...args);\n } else {\n console.error(`[${tag}]`, message, ...args);\n }\n },\n\n /** Reset all logger state (debug flag, tags, handler). Primarily for tests. */\n reset(): void {\n const g = globalThis as unknown as Record<string, unknown>;\n delete g[LOGGER_KEY];\n },\n};\n","/**\n * WalletApiMailboxProvider — the reference `DeliveryProvider` implementation\n * over the wallet-api mailbox (sdk-changes S3/S7; ARCHITECTURE §6/§16).\n *\n * Platform-neutral over the injected {@link WalletApiClient}. Key behaviors:\n *\n * - **deliver** = sha256 + upload via upload-urls (a `412` from the\n * content-addressed store means the blob is already present = success,\n * §5.2) → `POST /v1/mailbox` (idempotent by content-derived `entry_id`,\n * §6). The memo is encrypted client-side with the S6 field key before it\n * leaves the device; the deposit's `entryId` is verified to equal the\n * locally computed content-derived id — a backend substituting row ids is a\n * protocol violation (covenant §3.1-4).\n * - **incoming** = `GET /v1/mailbox?since=` paging (`more` loops), yielding\n * claimable entries (pending; claimed/rejected entries are recorded as seen\n * and skipped — they were resolved here or on another of the owner's\n * devices). `fetchBlob` uses the entry's `getUrl` and re-derives\n * (tokenId, stateHash, deliveryId) from the actual bytes — the recipient\n * never trusts the backend (§8.2). `blobCollected` entries throw a typed\n * error.\n * - **ack** → claim with the provider's **composition-time custody**\n * (`'inventory'` → `intoInventory: true` handoff; `'external'` →\n * `intoInventory: false`, ZERO inventory writes — §6 delivery-only claim),\n * or reject (terminal for discovery only — §6).\n * - **Persistent seen-set**: every acked delivery's content-derived id — the\n * canonical hash of its `(tokenId, stateHash)` pair — is persisted via the\n * injected {@link KeyValueStore}; a replayed delivery (server replay, cursor\n * reset, restore) is never yielded again (S7 port contract).\n */\n\nimport { sha256 } from '@noble/hashes/sha2.js';\nimport type {\n DeliverOptions,\n DeliveryCustody,\n DeliveryDisposition,\n DeliveryProvider,\n DeliveryReceipt,\n IncomingDelivery,\n} from '../../../transport/delivery-provider';\nimport { composeDeliveryKeys, computeDeliveryId } from '../../../transport/delivery-provider';\nimport { unwrapTokenBlobBytes } from '../../../token-engine/token-blob';\nimport { deriveFieldEncryptionKey, decryptField, encryptField } from '../../../core/field-encryption';\nimport { WalletApiClient, WalletApiError } from '../../../wallet-api';\nimport type { KeyValueStore, MailboxEntry } from '../../../wallet-api';\nimport { logger } from '../../../core/logger';\n\nexport interface WalletApiMailboxProviderConfig {\n /** The authenticated wallet-api client (S1). DI — never a singleton. */\n client: WalletApiClient;\n /**\n * Composition-time custody (S7 — NEVER a per-call flag): `'inventory'` for\n * the full wallet-api preset (acks hand tokens into the server inventory),\n * `'external'` for the own-storage preset (acks perform zero inventory\n * writes; the app's storage keeps custody).\n */\n custody: DeliveryCustody;\n /** Persists the per-identity seen-set + mailbox cursor. */\n stateStore: KeyValueStore;\n /**\n * The backend-true (tokenId, stateHash) derivation (`ITokenEngine.deliveryKeys`).\n * Optional at construction — compositions are engine-less; `PaymentsModule`\n * late-binds it via `bindDeliveryKeys` at init. The provider never derives\n * these locally (§8.2 / sdk-changes S7) and fails loudly if unbound.\n */\n deliveryKeys?: (blobBytes: Uint8Array) => Promise<{ tokenId: string; stateHash: string }>;\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');\n}\n\nconst TAG = 'WalletApiMailbox';\n\nexport class WalletApiMailboxProvider implements DeliveryProvider {\n readonly custody: DeliveryCustody;\n\n private readonly client: WalletApiClient;\n private readonly stateStore: KeyValueStore;\n private deriveKeysFn: ((blobBytes: Uint8Array) => Promise<{ tokenId: string; stateHash: string }>) | null = null;\n\n private identity: { privateKey: string; chainPubkey: string } | null = null;\n private fieldKey: Uint8Array | null = null;\n\n constructor(config: WalletApiMailboxProviderConfig) {\n this.client = config.client;\n this.custody = config.custody;\n this.stateStore = config.stateStore;\n this.deriveKeysFn = config.deliveryKeys ?? null;\n }\n\n /** @inheritDoc — wired by PaymentsModule at init (engine-owning seam). */\n bindDeliveryKeys(derive: (blobBytes: Uint8Array) => Promise<{ tokenId: string; stateHash: string }>): void {\n this.deriveKeysFn = derive;\n }\n\n private deriveKeys(blobBytes: Uint8Array): Promise<{ tokenId: string; stateHash: string }> {\n if (this.deriveKeysFn === null) {\n throw new WalletApiError(\n 'deliveryKeys derivation not bound — PaymentsModule binds ITokenEngine.deliveryKeys at init (S7)',\n 'PROTOCOL'\n );\n }\n return this.deriveKeysFn(blobBytes);\n }\n\n /** Bind the wallet identity (derives the S6 field key; binds the client). */\n setIdentity(identity: { privateKey: string; chainPubkey: string }): void {\n this.identity = identity;\n this.fieldKey = deriveFieldEncryptionKey(identity.privateKey);\n this.client.setIdentity(identity);\n }\n\n // ── persisted state (per network + identity) ────────────────────────────────\n\n private stateKey(kind: string): string {\n if (!this.identity) {\n throw new WalletApiError('No identity set — call setIdentity() first', 'CONFIG');\n }\n return `wallet-api-mailbox:${kind}:${this.client.network}:${this.identity.chainPubkey}`;\n }\n\n /**\n * The persistent seen-set (S7): content-derived delivery ids — i.e. the\n * canonical `SHA-256(tokenId ‖ stateHash)` encoding of the (tokenId,\n * stateHash) pairs this wallet has already resolved.\n */\n private async readSeen(): Promise<Set<string>> {\n const raw = await this.stateStore.get(this.stateKey('seen'));\n if (!raw) return new Set();\n try {\n return new Set(JSON.parse(raw) as string[]);\n } catch {\n return new Set();\n }\n }\n\n private async addSeen(deliveryIds: string[]): Promise<void> {\n if (deliveryIds.length === 0) return;\n const seen = await this.readSeen();\n for (const id of deliveryIds) seen.add(id);\n await this.stateStore.set(this.stateKey('seen'), JSON.stringify([...seen]));\n }\n\n private async readCursorState(): Promise<{ cursor: bigint; syncEpoch: bigint } | null> {\n const raw = await this.stateStore.get(this.stateKey('cursor'));\n if (!raw) return null;\n try {\n const parsed = JSON.parse(raw) as { cursor?: string; syncEpoch?: string };\n if (typeof parsed.cursor !== 'string' || typeof parsed.syncEpoch !== 'string') return null;\n return { cursor: BigInt(parsed.cursor), syncEpoch: BigInt(parsed.syncEpoch) };\n } catch {\n return null;\n }\n }\n\n private async persistCursorState(cursor: bigint, syncEpoch: bigint): Promise<void> {\n await this.stateStore.set(\n this.stateKey('cursor'),\n JSON.stringify({ cursor: cursor.toString(), syncEpoch: syncEpoch.toString() })\n );\n }\n\n // ── deliver (S3: upload → deposit) ──────────────────────────────────────────\n\n /**\n * Idempotent per (token, state): the upload is content-addressed (412 =\n * already present = success — §5.2) and the deposit is idempotent by the\n * content-derived entry_id — it succeeds even after the recipient claimed\n * (§6), which is what makes the sender's journal replay safe.\n */\n async deliver(recipientPubkey: string, blob: Uint8Array, options: DeliverOptions): Promise<DeliveryReceipt> {\n if (!this.fieldKey) {\n throw new WalletApiError('No identity set — call setIdentity() first', 'CONFIG');\n }\n const keys = composeDeliveryKeys(await this.deriveKeys(blob));\n\n // §5.2/§8.2: the wallet-api wire carries the RAW token bytes — the\n // cross-port blob argument is the sphere envelope; unwrap at the boundary\n // (the real backend content-addresses and Token.fromCBOR's exactly these\n // bytes; the 39051 envelope never crosses the §16 API).\n const wire = unwrapTokenBlobBytes(blob);\n\n // Upload the finished blob (checksum-bound presigned PUT — §5.2).\n const sha = bytesToHex(sha256(wire));\n const urls = await this.client.getUploadUrls([{ sha256: sha, size: wire.length }]);\n const upload = urls.find((u) => u.sha256 === sha);\n if (!upload) {\n throw new WalletApiError(`upload-urls response missing sha256 ${sha}`, 'PROTOCOL');\n }\n await this.client.uploadBlob(upload.putUrl, wire); // 412 = already present = success (§5.2)\n\n // Deposit (idempotent by entry_id — §6). The memo is S6-encrypted BEFORE\n // it leaves the device (§8.3): the operator never sees plaintext.\n let entryId: string;\n try {\n entryId = await this.client.depositMailbox({\n recipientPubkey,\n key: upload.key,\n transferId: options.transferId,\n stateHash: keys.stateHash,\n tokenId: keys.tokenId,\n ...(options.memo !== undefined ? { memo: encryptField(this.fieldKey, options.memo) } : {}),\n });\n } catch (err) {\n // §6 CONFLICT = the backend already holds a record of EXACTLY this\n // (tokenId, stateHash) with different bytes. Reachable honestly in one\n // way: a resume re-derives the byte-identical TRANSACTION (E.1), but\n // the aggregator RECOMPUTES inclusion proofs per request (st-sdk#126),\n // so once the tree has advanced the rebuilt token blob's proof bytes —\n // and its content-addressed key — differ from the originally-deposited\n // blob's. The state itself is identical and bound to this recipient by\n // its own predicate (§8.2), so the existing entry IS this delivery:\n // succeed idempotently with the content-derived id (the port contract —\n // deliver is idempotent per (token, state), S7). A foreign-spend\n // conflict can never reach here: the engine's E.2 match-verify raises\n // TransferConflictError before anything is delivered.\n if (err instanceof WalletApiError && err.status === 409) {\n return { deliveryId: keys.deliveryId };\n }\n throw err;\n }\n\n // covenant §3.1-4: the id is CONTENT-DERIVED — computed client-side; a\n // backend returning anything else (e.g. a row id) is a protocol violation.\n if (entryId !== keys.deliveryId) {\n throw new WalletApiError(\n `mailbox deposit returned a non-content-derived entryId (got ${entryId}, expected ${keys.deliveryId})`,\n 'PROTOCOL'\n );\n }\n return { deliveryId: keys.deliveryId };\n }\n\n // ── incoming (S3: mailbox pull) ─────────────────────────────────────────────\n\n /**\n * Pull entries since the given cursor (or the persisted one), loop while\n * `more`, and yield claimable deliveries not yet in the seen-set. The\n * persisted cursor advances to the server's read pointer (§6) — entries at\n * or below it are all resolved; the seen-set (not the cursor) is the replay\n * guard, so a cursor reset is safe.\n */\n async *incoming(sinceCursor?: string): AsyncIterable<IncomingDelivery> {\n const persisted = await this.readCursorState();\n let since: bigint;\n if (sinceCursor !== undefined) {\n since = BigInt(sinceCursor);\n } else {\n since = persisted?.cursor ?? 0n;\n }\n\n const seen = await this.readSeen();\n let page = await this.client.listMailbox(since);\n // §5.4: a syncEpoch change (server restore) invalidates cursor continuity —\n // discard the persisted cursor and re-pull from the start; the seen-set\n // absorbs the replays.\n if (persisted !== null && page.syncEpoch !== persisted.syncEpoch && sinceCursor === undefined) {\n page = await this.client.listMailbox(0n);\n }\n\n for (;;) {\n for (const entry of page.entries) {\n if (seen.has(entry.entryId)) continue; // persistent replay guard (S7)\n if (entry.status !== 'unclaimed') {\n // Resolved here earlier or on another of the owner's devices —\n // record and skip (claimed/rejected filtering for the consumer).\n seen.add(entry.entryId);\n await this.addSeen([entry.entryId]);\n continue;\n }\n yield this.toIncomingDelivery(entry);\n }\n await this.persistCursorState(page.readPointer, page.syncEpoch);\n if (!page.more) break;\n const lastSeq = page.entries.length > 0 ? page.entries[page.entries.length - 1].seq : since;\n page = await this.client.listMailbox(lastSeq);\n }\n }\n\n private toIncomingDelivery(entry: MailboxEntry): IncomingDelivery {\n const client = this.client;\n const fieldKey = this.fieldKey;\n const deriveKeys = (bytes: Uint8Array): Promise<{ tokenId: string; stateHash: string }> => this.deriveKeys(bytes);\n\n // S6: decrypt the memo envelope. NOTE: the S6 key is wallet-scoped (HKDF\n // from the wallet key), so only memos written by THIS wallet's key\n // decrypt (self-sends / multi-device). A counterparty's memo fails\n // authentication and is surfaced as absent rather than as ciphertext.\n let memo: string | undefined;\n if (entry.memo !== undefined && fieldKey) {\n try {\n memo = decryptField(fieldKey, entry.memo);\n } catch {\n logger.debug(TAG, `memo for entry ${entry.entryId.slice(0, 12)}… not decryptable with this wallet's key`);\n }\n }\n\n return {\n deliveryId: entry.entryId,\n transferId: entry.transferId,\n senderPubkey: entry.senderPubkey,\n ...(memo !== undefined ? { memo } : {}),\n cursor: entry.seq.toString(),\n async fetchBlob(): Promise<Uint8Array> {\n if (entry.blobCollected || !entry.getUrl) {\n // §6: only RESOLVED entries lose their blob after retention; a\n // pending entry's blob is always retained — treat this as a server\n // contract violation rather than silently skipping value.\n throw new WalletApiError(\n `mailbox entry ${entry.entryId} has no fetchable blob (blobCollected)`,\n 'PROTOCOL'\n );\n }\n const bytes = await client.fetchBlob(entry.getUrl);\n // §8.2: the recipient never trusts the backend — re-derive the\n // content-derived id from the ACTUAL bytes and match it.\n const keys = composeDeliveryKeys(await deriveKeys(bytes));\n if (keys.deliveryId !== entry.entryId) {\n throw new WalletApiError(\n `mailbox blob does not match its entry id (expected ${entry.entryId}, bytes derive ${keys.deliveryId})`,\n 'PROTOCOL'\n );\n }\n return bytes;\n },\n };\n }\n\n // ── ack (claim / reject) ────────────────────────────────────────────────────\n\n async ack(deliveryId: string, disposition: DeliveryDisposition): Promise<void> {\n if (disposition === 'claimed') {\n // Custody is the provider's COMPOSITION-TIME property (S7): the\n // own-storage preset bakes 'external' in, so every claim here sends\n // intoInventory:false — zero inventory writes (§6 delivery-only claim) —\n // even when ack is called with no thought given to options.\n const intoInventory = this.custody === 'inventory';\n const result = await this.client.claimMailbox([deliveryId], intoInventory);\n const failed = result.failed.find((f) => f.entryId === deliveryId);\n if (failed) {\n // §16: the defensive lineage bucket — unreachable in normal flows.\n throw new WalletApiError(\n `mailbox claim failed for ${deliveryId}: ${failed.code}`,\n 'CONFLICT'\n );\n }\n // claimed / alreadyClaimed (idempotent — possibly via another device).\n } else {\n // §6: terminal for discovery only — the entry stays claimable and its\n // blob retained (retryable after e.g. a trustbase fix).\n await this.client.rejectMailbox([deliveryId]);\n }\n await this.addSeen([deliveryId]); // the persistent (tokenId, stateHash) seen-set (S7)\n }\n\n // ── wake (optional hook — §9: a nudge, never a correctness dependency) ──────\n\n onWake(callback: () => void): () => void {\n let closed = false;\n let close: (() => void) | null = null;\n void this.client\n .connectWakeSocket((wake) => {\n if (wake.stream === 'mailbox') callback();\n })\n .then((handle) => {\n if (closed) handle.close();\n else close = () => handle.close();\n })\n .catch((err) => {\n // Wakes are best-effort; polling remains the correctness path (§9).\n logger.debug(TAG, 'wake socket unavailable (polling continues):', err);\n });\n return () => {\n closed = true;\n close?.();\n };\n }\n}\n\nexport function createWalletApiMailboxProvider(\n config: WalletApiMailboxProviderConfig\n): WalletApiMailboxProvider {\n return new WalletApiMailboxProvider(config);\n}\n","/**\n * impl/shared/wallet-api/composition.ts — port composition (sdk-changes S4/S7,\n * covenant §3.1-6).\n *\n * The Sphere frontend is a VIEW: all I/O sits behind three independently\n * swappable ports — storage (`TokenStorageProvider`), delivery\n * (`DeliveryProvider`) and the engine/aggregator config (`OracleProvider`) —\n * selected at composition time. wallet-api ships as ONE implementation of each\n * port, not as the port:\n *\n * - {@link createSphereProviders} — the composition root: take any platform\n * base bundle (`createBrowserProviders` / `createNodeProviders`) and select\n * each port independently.\n * - {@link createWalletApiProviders} — the FULL wallet-api preset: thin\n * storage (server inventory custody) + mailbox delivery with custody\n * `'inventory'`.\n * - {@link createOwnStorageWalletApiProviders} — the delivery-only preset:\n * the app's own (local) storage keeps custody; the mailbox provider is\n * constructed with custody `'external'`, so every ack sends\n * `intoInventory: false` — zero server inventory writes by construction\n * (ARCHITECTURE §6 delivery-only claim; never a per-call flag).\n *\n * Asset-transport routing (S4): composing a delivery port moves ASSETS to it;\n * messaging, group chat and nametag bindings stay on the Nostr transport in\n * the base bundle. Payment requests ride wallet-api whenever the `walletApi`\n * client these presets return is passed to `Sphere.init` — `PaymentsModule`\n * detects the §16 payment-request capability on it and does not install the\n * Nostr payment-request channel (sdk-changes S4).\n */\n\nimport type { StorageProvider, TokenStorageProvider, TxfStorageDataBase } from '../../../storage';\nimport type { TransportProvider } from '../../../transport';\nimport type { DeliveryProvider } from '../../../transport/delivery-provider';\nimport type { OracleProvider } from '../../../oracle';\nimport type { TokenBlob } from '../../../token-engine/types';\nimport { WalletApiClient } from '../../../wallet-api';\nimport type { FetchLike, KeyValueStore, WebSocketFactoryLike } from '../../../wallet-api';\nimport { WalletApiTokenStorageProvider } from './WalletApiTokenStorageProvider';\nimport { WalletApiMailboxProvider } from './WalletApiMailboxProvider';\n\n// =============================================================================\n// Composition root\n// =============================================================================\n\n/** The minimum any platform base bundle provides (browser/node factories do). */\nexport interface SphereBaseProviders {\n storage: StorageProvider;\n transport: TransportProvider;\n oracle: OracleProvider;\n tokenStorage: TokenStorageProvider<TxfStorageDataBase>;\n}\n\n/** Independent port selection (sdk-changes S7): any combination is legal. */\nexport interface SphereProviderPorts {\n /** Storage port override (token inventory + blob custody). */\n storage?: TokenStorageProvider<TxfStorageDataBase>;\n /** Delivery port (assets move to it; messaging stays on the base transport). */\n delivery?: DeliveryProvider;\n /** Engine/aggregator config port override. */\n engine?: OracleProvider;\n}\n\n/**\n * Compose a Sphere provider bundle with each port selected independently\n * (covenant §3.1-6). Unselected ports keep the base bundle's implementation.\n */\nexport function createSphereProviders<B extends SphereBaseProviders>(\n base: B,\n ports: SphereProviderPorts = {}\n): B & { delivery?: DeliveryProvider } {\n return {\n ...base,\n ...(ports.storage ? { tokenStorage: ports.storage } : {}),\n ...(ports.engine ? { oracle: ports.engine } : {}),\n ...(ports.delivery ? { delivery: ports.delivery } : {}),\n };\n}\n\n// =============================================================================\n// wallet-api presets (S4)\n// =============================================================================\n\nexport interface WalletApiCompositionConfig {\n /** Backend base URL — https off-loopback (ARCHITECTURE §4, client-enforced). */\n baseUrl: string;\n /** Network name (e.g. 'testnet2') — required end-to-end (ARCHITECTURE §14). */\n network: string;\n /**\n * Stable per-device label (ARCHITECTURE §4 — one session row per (owner,\n * device); the refresh token is stored under it). Pass a persisted value;\n * when omitted a fresh random label is generated per construction, which\n * still works but starts every run with a challenge sign-in.\n */\n deviceId?: string;\n /** Reuse an existing client (tests / advanced wiring). */\n client?: WalletApiClient;\n /** Refresh-token / cursor / seen-set persistence; defaults to `base.storage`. */\n stateStore?: KeyValueStore;\n /** Injectable fetch (defaults to `globalThis.fetch`). */\n fetchFn?: FetchLike;\n /** Injectable WebSocket factory (defaults to `globalThis.WebSocket`). */\n webSocketFactory?: WebSocketFactoryLike;\n /** Local token verification for `recoverRemoved()` (wire the engine here). */\n verifyToken?: (blob: TokenBlob) => Promise<boolean>;\n}\n\n/** What the wallet-api presets add to the base bundle. */\nexport interface WalletApiProviderExtras {\n delivery: DeliveryProvider;\n /** The S1 client — pass to `Sphere.init({ walletApi })` for the S4 auth lifecycle. */\n walletApi: WalletApiClient;\n}\n\nfunction buildClient(base: SphereBaseProviders, config: WalletApiCompositionConfig): {\n client: WalletApiClient;\n stateStore: KeyValueStore;\n} {\n // StorageProvider satisfies KeyValueStore structurally (get/set/remove);\n // all client/provider keys are self-namespaced per network + pubkey.\n const stateStore: KeyValueStore = config.stateStore ?? base.storage;\n const client =\n config.client ??\n new WalletApiClient({\n baseUrl: config.baseUrl,\n network: config.network,\n deviceId: config.deviceId ?? `sphere-${crypto.randomUUID()}`,\n storage: stateStore,\n fetchFn: config.fetchFn,\n webSocketFactory: config.webSocketFactory,\n });\n return { client, stateStore };\n}\n\n/**\n * The FULL wallet-api preset (S4): wallet-api keeps inventory custody —\n * thin/lazy storage over the server's value index + mailbox delivery with\n * custody `'inventory'` (claims perform the §6 ownership handoff).\n */\nexport function createWalletApiProviders<B extends SphereBaseProviders>(\n base: B,\n config: WalletApiCompositionConfig\n): B & WalletApiProviderExtras {\n const { client, stateStore } = buildClient(base, config);\n const tokenStorage = new WalletApiTokenStorageProvider({\n client,\n stateStore,\n verifyToken: config.verifyToken,\n });\n const delivery = new WalletApiMailboxProvider({ client, custody: 'inventory', stateStore });\n return { ...base, tokenStorage, delivery, walletApi: client };\n}\n\n/**\n * The OWN-STORAGE preset (S7: own storage + wallet-api delivery — a\n * supported, tested composition): the base bundle's local storage keeps\n * custody; wallet-api is purely the delivery rail. Custody `'external'` is\n * baked in at construction — every ack sends `intoInventory: false`, so a\n * recipient's claim performs ZERO inventory writes even when `ack` is called\n * with no thought given to options (sdk-changes S7). Senders never call\n * apply; their sends close via `intents/{id}/complete` alone (ARCHITECTURE\n * §6 storage-opt-out senders), which the wallet-api client (passed as\n * `walletApi`) provides.\n */\nexport function createOwnStorageWalletApiProviders<B extends SphereBaseProviders>(\n base: B,\n config: WalletApiCompositionConfig\n): B & WalletApiProviderExtras {\n const { client, stateStore } = buildClient(base, config);\n const delivery = new WalletApiMailboxProvider({ client, custody: 'external', stateStore });\n return { ...base, delivery, walletApi: client };\n}\n"],"mappings":"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","names":["isLE","hexToBytes","bytesToHex","isBytes","anumber","abytes","aexists","aoutput","clean","createView","abytes","isLE","anumber","createView","anumber","abytes","clean","abytes","clean","aexists","aoutput","abytes","clean","bytesToHex"]}