@unicitylabs/sphere-sdk 0.17.2-dev.3 → 0.17.3
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.
- package/README.md +1 -0
- package/dist/connect/index.cjs +1 -1
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.js +1 -1
- package/dist/connect/index.js.map +1 -1
- package/dist/core/index.cjs +53 -2
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +25 -9
- package/dist/core/index.d.ts +25 -9
- package/dist/core/index.js +52 -2
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/connect/index.cjs +1 -1
- package/dist/impl/browser/connect/index.cjs.map +1 -1
- package/dist/impl/browser/connect/index.js +1 -1
- package/dist/impl/browser/connect/index.js.map +1 -1
- package/dist/impl/browser/index.cjs.map +1 -1
- package/dist/impl/browser/index.js.map +1 -1
- package/dist/impl/nodejs/index.cjs.map +1 -1
- package/dist/impl/nodejs/index.js.map +1 -1
- package/dist/impl/wallet-api-v2/index.cjs.map +1 -1
- package/dist/impl/wallet-api-v2/index.js.map +1 -1
- package/dist/index.cjs +53 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -9
- package/dist/index.d.ts +25 -9
- package/dist/index.js +52 -2
- package/dist/index.js.map +1 -1
- package/dist/modules/payments-v2/index.cjs.map +1 -1
- package/dist/modules/payments-v2/index.js.map +1 -1
- package/dist/token-engine/index.cjs.map +1 -1
- package/dist/token-engine/index.d.cts +1 -1
- package/dist/token-engine/index.d.ts +1 -1
- package/dist/token-engine/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../modules/payments-v2/index.ts","../../../node_modules/@noble/hashes/src/utils.ts","../../../node_modules/@noble/hashes/src/_md.ts","../../../node_modules/@noble/hashes/src/sha2.ts","../../../core/errors.ts","../../../token-engine/sdk.ts","../../../token-engine/nft-payload.ts","../../../core/crypto.ts","../../../modules/payments-v2/machine/payload.ts","../../../modules/payments-v2/async.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","../../../modules/payments-v2/machine/payload-view.ts","../../../core/uuid.ts","../../../modules/payments-v2/history/History.ts","../../../core/logger.ts","../../../modules/payments-v2/stores.ts","../../../modules/payments-v2/inventory/presentation.ts","../../../modules/payments-v2/inventory/InventoryView.ts","../../../token-engine/value-envelope.ts","../../../modules/payments-v2/ports.ts","../../../modules/payments-v2/receive/Receive.ts","../../../modules/payments-v2/requests/Requests.ts","../../../modules/payments-v2/machine/journal.ts","../../../token-engine/errors.ts","../../../modules/payments-v2/machine/TransferMachine.ts","../../../modules/payments-v2/machine/resume.ts","../../../modules/payments-v2/convergence.ts","../../../modules/payments-v2/select/ledger.ts","../../../modules/payments-v2/select/pins.ts","../../../modules/payments-v2/select/selector.ts","../../../modules/payments-v2/select/queue.ts","../../../modules/payments-v2/compose.ts","../../../modules/payments-v2/mint-params.ts","../../../modules/payments-v2/mint.ts","../../../modules/payments-v2/mint-nft.ts","../../../modules/payments-v2/inventory/nft-read.ts","../../../modules/payments-v2/inventory/token-data.ts","../../../modules/payments-v2/send-whole.ts","../../../modules/payments-v2/send-errors.ts","../../../modules/payments-v2/recipient.ts","../../../modules/payments-v2/restore.ts","../../../modules/payments-v2/prewarm-cache.ts","../../../modules/payments-v2/PaymentsFacade.ts"],"sourcesContent":["export type { PaymentsV2, PaymentsV2Events, ConnectionStatus, SendRequest, SendWholeTokenRequest, SendCoinlessRequest, MintResult, HistoryEntry, HistoryPage, PaymentRequestView, PaymentRequestStatus, PaymentsRequestsApi, PendingTransfer } from './api';\n// NFT metadata (#785; normative spec docs/NFT-METADATA.md).\nexport type {\n MintNftRequest,\n NftView,\n NftAttribute,\n NftContent,\n NftLink,\n NftMedia,\n NftMediaRef,\n NftMetadata,\n NftSignatureStatus,\n} from './api';\nexport type { NftSignatureContext } from '../../token-engine/nft-payload';\nexport {\n NFT_DOCUMENT_MEDIA_TYPE,\n NFT_LINK_TAG,\n NFT_MEDIA_TAG,\n NFT_METADATA_TAG,\n NFT_SIGNED_TAG,\n encodeNftContent,\n isNftDocumentLink,\n parseNftDocument,\n parseNftPayload,\n verifyNftLinkContent,\n} from '../../token-engine/nft-payload';\nexport { NFT_MAX_PAYLOAD_BYTES } from './mint-nft';\nexport type {\n StoragePort,\n DeliveryPort,\n InventoryItem,\n InventoryPage,\n InventoryAsset,\n ApplyDeltaResult,\n DeliveryReceipt,\n IncomingDelivery,\n DeliverOptions,\n AckRequest,\n AckOutcome,\n RetryableAckError,\n} from './ports';\n// A port implementing the optional ackBatch cannot express the contract without\n// these: the request/outcome shapes, and the retryable signal that stops the\n// caller falling back to one ack per entry against a wall that rejected a batch.\nexport { isRetryableAckError } from './ports';\nexport type { IntentPayload, PlannedOp, OpOutcome, OutcomeClass } from './machine/types';\nexport * from './stores';\nexport {\n PaymentsFacade,\n MAX_RESELECT,\n ATTENTION_MINT_UNRESOLVED,\n ATTENTION_RECIPIENT_NETWORK_UNVERIFIED,\n ATTENTION_RESEED_REJECTED,\n supportsDeterministicMint,\n} from './PaymentsFacade';\nexport { HEARTBEAT_SEED_MS, HEARTBEAT_CAP_MS } from './convergence';\nexport type {\n PaymentsFacadeDeps,\n FacadeSession,\n FacadeClient,\n CheckpointReseeder,\n RecipientInfo,\n DeterministicMintCapable,\n} from './PaymentsFacade';\n","/**\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 * 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 // The op's certification is INDETERMINATE (submit accepted / proof fetch\n // inconclusive) — raised as ProofUnconfirmedError; keep the intent OPEN (#631).\n | 'CERTIFICATION_UNCONFIRMED'\n // Split burn checkpoint (sdk-changes E.4, sphere-sdk#501) — all keep-open (token-engine/errors.ts):\n // burn certified but the checkpoint could not be persisted (no mint submitted);\n | 'CHECKPOINT_PERSIST_FAILED'\n // a certified mint leaf has no reproducing stored bytes, or a stored checkpoint fails byte-binding;\n | 'SPLIT_CHECKPOINT_LOST'\n // a byte-bound checkpoint proof no longer verifies against the current trust base (validator rotation).\n | 'CHECKPOINT_TRUSTBASE_MISMATCH'\n | 'STORAGE_ERROR'\n // #665: the on-chain spend committed but the post-commit wallet-api mirror\n // sync (inventory apply / blob upload / save) failed. NOT a lost payment —\n // the intent is kept open and resume converges the mirror (idempotent apply,\n // #664). Surfaced distinctly so a UI can reassure (\"sent — wallet catching\n // up\") instead of showing a hard send failure.\n | 'SEND_SYNC_PENDING'\n // #677: a multi-leg send lost a source to a concurrent transfer AFTER ≥1\n // earlier leg had already certified on-chain AND been journaled/delivered.\n // The delivered value has irreversibly left the wallet, so this is NOT a\n // plain, re-sendable failure: surfacing a bare TransferConflictError makes\n // the caller re-send the FULL amount and pay the delivered leg twice. Raised\n // as PartialSendConflictError; the caller MUST re-plan ONLY the remainder\n // under a NEW transferId, never the whole amount.\n | 'SEND_PARTIALLY_COMPLETED'\n | 'TRANSPORT_ERROR'\n | 'AGGREGATOR_ERROR'\n | 'VALIDATION_ERROR'\n | 'INVALID_AMOUNT'\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 * #441 deferred-paid linkage: the transferId of the possibly-committed send,\n * stamped by `sendOnce` before the error leaves so a payment-request consumer\n * can durably journal request→transfer and resolve 'paid' only when that\n * transfer actually completes (never optimistically). Present ONLY on\n * possibly-committed outcomes ({@link isPossiblyCommittedSendOutcome}).\n */\n transferId?: string;\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 * #677: a send that PARTIALLY completed before losing a source to a concurrent\n * transfer. At least one earlier leg certified on-chain and was journaled for\n * delivery (its {@link committedTokenIds}) — that value has irreversibly left\n * the wallet — but a LATER leg raised `TransferConflictError` (a lost race), and\n * `send()` could NOT COMPLETE the {@link remainingAmount} from the remaining live\n * sources. This is the fallback after the internal remainder re-plan gave up —\n * either insufficient funds OR a transient/transport error during the re-plan\n * (the underlying reason is on `cause`), not necessarily an \"out of funds\" state.\n *\n * Distinct from `TransferConflictError` on purpose: a bare conflict makes the\n * caller re-send the FULL amount, paying the already-delivered leg a second\n * time. Catching THIS type (or `code === 'SEND_PARTIALLY_COMPLETED'`) tells the\n * caller/UI: the delivered legs are final, the conflicted intent stays OPEN\n * (resume converges its certified legs), and only the REMAINDER\n * ({@link remainingAmount}) may be re-planned — under a NEW transferId, never\n * re-sending the whole amount.\n *\n * NOT a subclass of `TransferConflictError` by design: existing conflict\n * handlers that re-send in full must NOT treat this as an ordinary conflict.\n */\nexport class PartialSendConflictError extends SphereError {\n /**\n * The FIRST partial attempt's transferId — its intent stays open for resume,\n * and it is the §6 handoff anchor. NOTE: `send()` may re-plan the remainder across\n * SEVERAL internal attempts before giving up, so {@link committedTokenIds} can\n * span MULTIPLE transferIds — they do NOT all map to this single id.\n */\n readonly transferId: string;\n /**\n * Source token ids whose spend already certified on-chain (and whose finished\n * output blob is journaled for delivery). Their value has already been\n * delivered; NEVER re-send these. May accumulate across several internal\n * remainder-re-plan attempts (so not all are journaled under {@link transferId}).\n */\n readonly committedTokenIds: readonly string[];\n /**\n * The still-undelivered portion (base units, decimal string) — `send()` could\n * not COMPLETE it from the remaining live sources (insufficient funds or a\n * transient error; see `cause`). Re-plan ONLY this amount, under a new\n * transferId; the delivered legs converge via the recipient's §6 claim.\n */\n readonly remainingAmount: string;\n\n constructor(\n message: string,\n transferId: string,\n committedTokenIds: readonly string[],\n remainingAmount: string,\n cause?: unknown,\n ) {\n super(message, 'SEND_PARTIALLY_COMPLETED', cause);\n this.name = 'PartialSendConflictError';\n this.transferId = transferId;\n this.committedTokenIds = [...committedTokenIds];\n this.remainingAmount = remainingAmount;\n }\n}\n\n/**\n * Error codes for a send outcome where money has (or may have) already left the\n * wallet on-chain, so the send is NOT a clean, re-sendable failure. A consumer\n * that persists a \"paid\" flag (e.g. a payment request) must keep the request\n * NON-payable on any of these — reverting to a re-payable state would double-pay\n * (#441). Covers the post-commit mirror-sync-pending / keep-open certification\n * states AND the partial-conflict outcome.\n */\nconst POSSIBLY_COMMITTED_SEND_CODES: ReadonlySet<SphereErrorCode> = new Set([\n 'SEND_SYNC_PENDING',\n 'CERTIFICATION_UNCONFIRMED',\n 'CHECKPOINT_PERSIST_FAILED',\n 'SPLIT_CHECKPOINT_LOST',\n 'CHECKPOINT_TRUSTBASE_MISMATCH',\n 'SEND_PARTIALLY_COMPLETED',\n]);\n\n/**\n * #441: true when a send failed with an outcome where the payment has (or may\n * have) irreversibly left the wallet — a post-commit sync-pending / keep-open\n * certification state, or a `PartialSendConflictError`. Such a send completes (or\n * has already partially completed) via resume/claim and MUST NOT be re-sent, so\n * a persisted \"paid\" state must stay non-payable. A `false` result is a clean\n * pre-commit failure — nothing left the wallet, safe to re-pay.\n */\nexport function isPossiblyCommittedSendOutcome(err: unknown): boolean {\n return isSphereError(err) && POSSIBLY_COMMITTED_SEND_CODES.has(err.code);\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 * 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';\n// #739: the 'not yet certified' answer the proof loop tolerates; tests model the\n// pre-finalization window with it, which is how the deadline path is reachable.\nexport { JsonRpcNetworkError } from '@unicitylabs/state-transition-sdk/lib/api/json-rpc/JsonRpcNetworkError.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 { StateMask } from '@unicitylabs/state-transition-sdk/lib/transaction/StateMask.js';\nexport { MintJustificationVerifierService } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/MintJustificationVerifierService.js';\nexport { TokenIssuanceVerifierService } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/TokenIssuanceVerifierService.js';\nexport { VerificationContext } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/VerificationContext.js';\nexport { UnicityCertificateVerifier } from '@unicitylabs/state-transition-sdk/lib/api/bft/verification/UnicityCertificateVerifier.js';\nexport { UnicitySealQuorumSignaturesVerificationRule } from '@unicitylabs/state-transition-sdk/lib/api/bft/verification/rule/UnicitySealQuorumSignaturesVerificationRule.js';\nexport { VerifiedSealCache } from '@unicitylabs/state-transition-sdk/lib/api/bft/verification/VerifiedSealCache.js';\nexport { Secp256k1SignatureVerifier } from '@unicitylabs/state-transition-sdk/lib/crypto/secp256k1/Secp256k1SignatureVerifier.js';\nexport type { ITokenVerifier } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/ITokenVerifier.js';\nexport { WorkerTokenVerifier } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/worker/WorkerTokenVerifier.js';\nexport type { IWorker } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/worker/IWorker.js';\nexport type { IVerificationContext } from '@unicitylabs/state-transition-sdk/lib/verification/IVerificationContext.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// Head-only CBOR reads, for classifying a value envelope WITHOUT parsing its body\n// (`value-envelope.ts`): `CborDeserializer.decodeTag` asserts exhaustion, so it\n// cannot tell a corrupt envelope from a payload that carries no envelope at all.\nexport { CborReader } from '@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborReader.js';\nexport { MajorType } from '@unicitylabs/state-transition-sdk/lib/serialization/cbor/MajorType.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 { SplitAllocationProof } from '@unicitylabs/state-transition-sdk/lib/payment/SplitAllocationProof.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// ── 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 * NFT payload codec (#785, normative spec: docs/NFT-METADATA.md). Recognition is\n * display-only and never throws, so no path that can refuse a token may depend on\n * it. One validator set serves the encoder and the decoder alike.\n */\nimport { sha256 } from '@noble/hashes/sha2.js';\n\nimport { SphereError } from '../core/errors';\n\nimport {\n CborDeserializer,\n CborReader,\n CborSerializer,\n type DataHash,\n DataHasher,\n HashAlgorithm,\n HexConverter,\n MajorType,\n NetworkId,\n Signature,\n SigningService,\n} from './sdk';\n\nexport const NFT_METADATA_TAG = 39052n;\nexport const NFT_MEDIA_TAG = 39053n;\nexport const NFT_LINK_TAG = 39054n;\nexport const NFT_SIGNED_TAG = 39055n;\nexport const NFT_FORMAT_VERSION = 1n;\n/** The media type of an NftLink that points at a metadata document instead of a media file. */\nexport const NFT_DOCUMENT_MEDIA_TYPE = 'application/vnd.unicity.nft+cbor';\n\n/** An inline file. */\nexport interface NftMedia {\n readonly kind: 'media';\n readonly media_type: string;\n readonly bytes: Uint8Array;\n}\n\n/** A hosted file, pinned by the SHA-256 of its bytes (64 hex; decoded lowercase). */\nexport interface NftLink {\n readonly kind: 'link';\n readonly media_type: string;\n readonly uri: string;\n readonly sha256: string;\n}\n\nexport type NftMediaRef = NftMedia | NftLink;\n\nexport interface NftAttribute {\n readonly trait_type: string;\n /** Text, or an integer within ±(2^53 − 1). Decimals and larger numbers are text. */\n readonly value: string | number;\n}\n\n/** ERC-721 field names; an absent optional field is `null`, never `''`. */\nexport interface NftMetadata {\n readonly kind: 'metadata';\n readonly name: string;\n readonly description: string | null;\n readonly image: NftMediaRef | null;\n readonly animation_url: NftMediaRef | null;\n readonly external_url: string | null;\n readonly attributes: readonly NftAttribute[];\n readonly collection: string | null;\n /** The collection the item claims: 1–64 bytes as even-length hex (decoded lowercase). Never verified here. */\n readonly collection_id: string | null;\n}\n\nexport type NftContent = NftMetadata | NftMedia | NftLink;\nexport type NftSignatureStatus = 'unsigned' | 'valid' | 'invalid';\ntype NftDocument = NftMetadata | NftMedia;\n\nexport interface ParsedNft {\n readonly content: NftContent;\n /** Present iff the top level is NftSigned. */\n readonly signed: {\n readonly creator: Uint8Array;\n readonly payload: Uint8Array;\n readonly signature: Uint8Array;\n } | null;\n}\n\n/** What an NftSigned signature binds besides its payload, exactly as the token's mint records it. */\nexport interface NftSignatureContext {\n /** The network identifier α (`NetworkId.id`). */\n readonly networkId: number | bigint;\n /** The genesis recipient predicate, as `EncodedPredicate.toCBOR()` bytes. */\n readonly recipientPredicate: Uint8Array;\n /** The 32 raw token id bytes. */\n readonly tokenId: Uint8Array;\n readonly tokenType: Uint8Array;\n}\n\nconst METADATA_ARITY = 9;\nconst MEDIA_ARITY = 3;\nconst LINK_ARITY = 4;\nconst SIGNED_ARITY = 4;\nconst CREATOR_BYTES = 33;\nconst SIGNATURE_BYTES = 65;\nconst MAX_URI_LENGTH = 2048;\nconst LINK_SCHEMES = ['https://', 'ipfs://', 'ar://'];\nconst SIGNED_DOMAIN = new TextEncoder().encode('UNICITY_NFT_SIGNED');\nconst MEDIA_TYPE_PATTERN = /^[a-z0-9][a-z0-9!#$&^_.+-]{0,126}\\/[a-z0-9][a-z0-9!#$&^_.+-]{0,126}$/;\nconst SHA256_HEX_PATTERN = /^[0-9a-f]{64}$/i;\nconst COLLECTION_ID_PATTERN = /^(?:[0-9a-f]{2}){1,64}$/i;\nconst LONE_SURROGATE = /\\p{Cs}/u;\nconst CBOR_MAJOR_TYPE_MASK = 0b1110_0000;\nconst ATTRIBUTE_VALUE_RULE =\n 'must be non-empty text or an integer within ±(2^53 − 1) — write decimals and larger numbers as text';\nconst COLLECTION_ID_RULE = 'must be null or 1–64 bytes as even-length hex (2–128 characters)';\nconst DOCUMENT_AS_MEDIA_RULE = `must not be ${NFT_DOCUMENT_MEDIA_TYPE}: a document link is a token's content, never media`;\n// The SDK's text decoder substitutes U+FFFD, which would recognise invalid UTF-8;\n// ignoreBOM keeps a leading U+FEFF so a decoded string re-encodes byte-identically.\nconst UTF8 = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true });\n\n// ── shared field rules (encoder and decoder) ────────────────────────────────\n\nfunction refuse(field: string, rule: string, cause?: unknown): SphereError {\n return new SphereError(`Invalid NFT ${field}: ${rule}`, 'VALIDATION_ERROR', cause);\n}\n\nfunction ensure(ok: boolean, field: string, rule: string): void {\n if (!ok) throw refuse(field, rule);\n}\n\nconst fieldName = (prefix: string, name: string): string => (prefix === '' ? name : `${prefix}.${name}`);\n\n/** Non-empty and representable as UTF-8 exactly (a lone surrogate is not). */\nconst isText = (value: unknown): value is string =>\n typeof value === 'string' && value.length > 0 && !LONE_SURROGATE.test(value);\n\nconst isBytes = (value: unknown, length?: number): value is Uint8Array =>\n value instanceof Uint8Array && (length === undefined ? value.length > 0 : value.length === length);\n\nconst isMediaType = (value: unknown): boolean => typeof value === 'string' && MEDIA_TYPE_PATTERN.test(value);\n\nconst isCollectionId = (value: unknown): boolean => typeof value === 'string' && COLLECTION_ID_PATTERN.test(value);\n\nconst isAttributeValue = (value: unknown): boolean =>\n typeof value === 'number' ? Number.isSafeInteger(value) : isText(value);\n\nfunction hasSpaceOrControl(value: string): boolean {\n for (let i = 0; i < value.length; i++) {\n const code = value.charCodeAt(i);\n if (code <= 0x20 || code === 0x7f) return true;\n }\n return false;\n}\n\nfunction isLinkUri(value: unknown): boolean {\n if (!isText(value) || value.length > MAX_URI_LENGTH || hasSpaceOrControl(value)) return false;\n const scheme = LINK_SCHEMES.find((prefix) => value.startsWith(prefix));\n return scheme !== undefined && value.length > scheme.length;\n}\n\nfunction checkText(field: string, value: unknown): void {\n ensure(isText(value), field, 'must be non-empty, well-formed text');\n}\n\nfunction checkOptionalText(field: string, value: unknown): void {\n ensure(value === null || isText(value), field, 'must be null or non-empty, well-formed text');\n}\n\nfunction checkMediaType(field: string, value: unknown): void {\n ensure(isMediaType(value), field, 'must be a lowercase type/subtype media type without parameters');\n}\n\nfunction checkMedia(prefix: string, media: NftMedia): void {\n checkMediaType(fieldName(prefix, 'media_type'), media.media_type);\n ensure(isBytes(media.bytes), fieldName(prefix, 'bytes'), 'must be non-empty bytes');\n}\n\nfunction checkLink(prefix: string, link: NftLink): void {\n checkMediaType(fieldName(prefix, 'media_type'), link.media_type);\n ensure(\n isLinkUri(link.uri),\n fieldName(prefix, 'uri'),\n `must be an https://, ipfs:// or ar:// URI of at most ${MAX_URI_LENGTH} characters with no whitespace or control characters`,\n );\n ensure(\n typeof link.sha256 === 'string' && SHA256_HEX_PATTERN.test(link.sha256),\n fieldName(prefix, 'sha256'),\n 'must be the 64-hex SHA-256 of the linked file',\n );\n}\n\nfunction checkMediaRef(field: string, ref: NftMediaRef | null): void {\n if (ref === null) return;\n if (ref?.kind === 'media') return checkMedia(field, ref);\n if (ref?.kind !== 'link') throw refuse(field, 'must be an NftMedia, an NftLink or null');\n checkLink(field, ref);\n ensure(!isNftDocumentLink(ref), fieldName(field, 'media_type'), DOCUMENT_AS_MEDIA_RULE);\n}\n\nfunction checkAttributes(attributes: readonly NftAttribute[]): void {\n ensure(Array.isArray(attributes), 'attributes', 'must be an array — [] when there are none');\n // entries(), not forEach: a sparse array's holes must be refused, not skipped.\n for (const [index, attribute] of attributes.entries()) {\n checkText(`attributes[${index}].trait_type`, attribute?.trait_type);\n ensure(isAttributeValue(attribute?.value), `attributes[${index}].value`, ATTRIBUTE_VALUE_RULE);\n }\n}\n\nfunction checkMetadata(metadata: NftMetadata): void {\n checkText('name', metadata.name);\n checkOptionalText('description', metadata.description);\n checkMediaRef('image', metadata.image);\n checkMediaRef('animation_url', metadata.animation_url);\n checkOptionalText('external_url', metadata.external_url);\n checkAttributes(metadata.attributes);\n checkOptionalText('collection', metadata.collection);\n ensure(metadata.collection_id === null || isCollectionId(metadata.collection_id), 'collection_id', COLLECTION_ID_RULE);\n}\n\nfunction checkContent(content: NftContent): void {\n switch (content?.kind) {\n case 'metadata':\n return checkMetadata(content);\n case 'media':\n return checkMedia('', content);\n case 'link':\n return checkLink('', content);\n default:\n throw refuse('content', \"kind must be 'metadata', 'media' or 'link'\");\n }\n}\n\nfunction checkSignedParts(creator: unknown, signature: unknown): void {\n ensure(isBytes(creator, CREATOR_BYTES), 'creator', 'must be a 33-byte compressed secp256k1 public key');\n ensure(isBytes(signature, SIGNATURE_BYTES), 'signature', 'must be 65 bytes: r(32) ‖ s(32) ‖ recovery(1)');\n}\n\n// ── encoder ─────────────────────────────────────────────────────────────────\n\nconst text = (value: string): Uint8Array => CborSerializer.encodeTextString(value);\n\nconst optionalText = (value: string | null): Uint8Array =>\n CborSerializer.encodeNullable(value, CborSerializer.encodeTextString);\n\nfunction versioned(tag: bigint, ...fields: Uint8Array[]): Uint8Array {\n return CborSerializer.encodeTag(\n tag,\n CborSerializer.encodeArray(CborSerializer.encodeUnsignedInteger(NFT_FORMAT_VERSION), ...fields),\n );\n}\n\n/** Major type 1 shares the unsigned head layout; the SDK serializer has no encoder for it. */\nfunction integerCbor(value: number): Uint8Array {\n if (value >= 0) return CborSerializer.encodeUnsignedInteger(value);\n const head = CborSerializer.encodeUnsignedInteger(-1 - value);\n head[0] |= MajorType.NEGATIVE_INTEGER;\n return head;\n}\n\nfunction mediaCbor(media: NftMedia): Uint8Array {\n return versioned(NFT_MEDIA_TAG, text(media.media_type), CborSerializer.encodeByteString(media.bytes));\n}\n\nfunction linkCbor(link: NftLink): Uint8Array {\n const digest = HexConverter.decode(link.sha256.toLowerCase());\n return versioned(NFT_LINK_TAG, text(link.media_type), text(link.uri), CborSerializer.encodeByteString(digest));\n}\n\nfunction mediaRefCbor(ref: NftMediaRef | null): Uint8Array {\n if (ref === null) return CborSerializer.encodeNull();\n return ref.kind === 'media' ? mediaCbor(ref) : linkCbor(ref);\n}\n\nfunction attributeCbor({ trait_type, value }: NftAttribute): Uint8Array {\n return CborSerializer.encodeArray(text(trait_type), typeof value === 'string' ? text(value) : integerCbor(value));\n}\n\n/**\n * The SDK's array head over a list of any length. Spreading the list into\n * `encodeArray` arguments overflows the call stack past ~125k items (fewer in JSC).\n */\nfunction arrayCbor(items: readonly Uint8Array[]): Uint8Array {\n const head = CborSerializer.encodeUnsignedInteger(items.length);\n head[0] |= MajorType.ARRAY;\n const out = new Uint8Array(items.reduce((length, item) => length + item.length, head.length));\n out.set(head);\n let offset = head.length;\n for (const item of items) {\n out.set(item, offset);\n offset += item.length;\n }\n return out;\n}\n\nconst optionalHexBytes = (value: string | null): Uint8Array =>\n CborSerializer.encodeNullable(value, (hex) => CborSerializer.encodeByteString(HexConverter.decode(hex.toLowerCase())));\n\nfunction metadataCbor(metadata: NftMetadata): Uint8Array {\n return versioned(\n NFT_METADATA_TAG,\n text(metadata.name),\n optionalText(metadata.description),\n mediaRefCbor(metadata.image),\n mediaRefCbor(metadata.animation_url),\n optionalText(metadata.external_url),\n arrayCbor(metadata.attributes.map(attributeCbor)),\n optionalText(metadata.collection),\n optionalHexBytes(metadata.collection_id),\n );\n}\n\n/** Encode one unsigned item. Throws SphereError('…', 'VALIDATION_ERROR') naming the offending field. */\nexport function encodeNftContent(content: NftContent): Uint8Array {\n checkContent(content);\n if (content.kind === 'metadata') return metadataCbor(content);\n return content.kind === 'media' ? mediaCbor(content) : linkCbor(content);\n}\n\n/** Wrap an encoded unsigned item; `signature` is `Signature.encode()` over {@link nftSignedDigest}. */\nexport function encodeNftSigned(creator: Uint8Array, payload: Uint8Array, signature: Uint8Array): Uint8Array {\n checkSignedParts(creator, signature);\n checkContent(signablePayload(payload));\n return versioned(\n NFT_SIGNED_TAG,\n CborSerializer.encodeByteString(creator),\n payload,\n CborSerializer.encodeByteString(signature),\n );\n}\n\nfunction signablePayload(payload: Uint8Array): NftContent {\n try {\n return decodeItem(UNSIGNED_DECODERS, 'payload', payload);\n } catch (error) {\n throw refuse('payload', 'must be exactly one encoded NftMetadata, NftMedia or NftLink item', error);\n }\n}\n\n// ── decoder (structure only; value rules are the shared checks above) ──────\n\ntype BodyDecoder<T> = (body: Uint8Array) => T;\n\nconst majorTypeOf = (item: Uint8Array): MajorType => (item.at(0) ?? 0) & CBOR_MAJOR_TYPE_MASK;\n\nfunction decodeText(item: Uint8Array): string {\n const reader = new CborReader(item);\n const bytes = reader.read(Number(reader.readLength(MajorType.TEXT_STRING)));\n reader.assertExhausted();\n return UTF8.decode(bytes);\n}\n\nconst decodeOptionalText = (item: Uint8Array): string | null => CborDeserializer.decodeNullable(item, decodeText);\n\nfunction decodeAttributeValue(item: Uint8Array): string | number {\n const major = majorTypeOf(item);\n if (major === MajorType.TEXT_STRING) return decodeText(item);\n const isInteger = major === MajorType.UNSIGNED_INTEGER || major === MajorType.NEGATIVE_INTEGER;\n ensure(isInteger, 'attribute value', ATTRIBUTE_VALUE_RULE);\n const reader = new CborReader(item);\n const magnitude = reader.readLength(major);\n reader.assertExhausted();\n return Number(major === MajorType.UNSIGNED_INTEGER ? magnitude : -1n - magnitude);\n}\n\nfunction decodeAttributes(item: Uint8Array): NftAttribute[] {\n return CborDeserializer.decodeArray(item).map((entry) => {\n const [traitType, value] = CborDeserializer.decodeArray(entry, 2);\n return { trait_type: decodeText(traitType), value: decodeAttributeValue(value) };\n });\n}\n\nfunction versionedFields(body: Uint8Array, arity: number): Uint8Array[] {\n const fields = CborDeserializer.decodeArray(body, arity);\n ensure(CborDeserializer.decodeUnsignedInteger(fields[0]) === NFT_FORMAT_VERSION, 'version', 'must be 1');\n return fields;\n}\n\nfunction decodeMedia(body: Uint8Array): NftMedia {\n const [, mediaType, bytes] = versionedFields(body, MEDIA_ARITY);\n return { kind: 'media', media_type: decodeText(mediaType), bytes: CborDeserializer.decodeByteString(bytes) };\n}\n\nconst decodeHex = (item: Uint8Array): string => HexConverter.encode(CborDeserializer.decodeByteString(item));\n\nfunction decodeLink(body: Uint8Array): NftLink {\n const [, mediaType, uri, digest] = versionedFields(body, LINK_ARITY);\n return {\n kind: 'link',\n media_type: decodeText(mediaType),\n uri: decodeText(uri),\n sha256: decodeHex(digest),\n };\n}\n\nfunction decodeMetadata(body: Uint8Array): NftMetadata {\n const fields = versionedFields(body, METADATA_ARITY);\n return {\n kind: 'metadata',\n name: decodeText(fields[1]),\n description: decodeOptionalText(fields[2]),\n image: decodeMediaRef('image', fields[3]),\n animation_url: decodeMediaRef('animation_url', fields[4]),\n external_url: decodeOptionalText(fields[5]),\n attributes: decodeAttributes(fields[6]),\n collection: decodeOptionalText(fields[7]),\n collection_id: CborDeserializer.decodeNullable(fields[8], decodeHex),\n };\n}\n\n// The nesting rules: a media slot holds NftMedia or NftLink (never a document link,\n// which checkMediaRef refuses); NftSigned wraps any unsigned item and itself appears\n// only at the top level; a linked document is NftMetadata or NftMedia.\nconst MEDIA_REF_DECODERS: ReadonlyMap<bigint, BodyDecoder<NftMediaRef>> = new Map<bigint, BodyDecoder<NftMediaRef>>([\n [NFT_MEDIA_TAG, decodeMedia],\n [NFT_LINK_TAG, decodeLink],\n]);\nconst UNSIGNED_DECODERS: ReadonlyMap<bigint, BodyDecoder<NftContent>> = new Map<bigint, BodyDecoder<NftContent>>([\n [NFT_METADATA_TAG, decodeMetadata],\n [NFT_MEDIA_TAG, decodeMedia],\n [NFT_LINK_TAG, decodeLink],\n]);\nconst DOCUMENT_DECODERS: ReadonlyMap<bigint, BodyDecoder<NftDocument>> = new Map<bigint, BodyDecoder<NftDocument>>([\n [NFT_METADATA_TAG, decodeMetadata],\n [NFT_MEDIA_TAG, decodeMedia],\n]);\n\nfunction decodeBody<T>(decoders: ReadonlyMap<bigint, BodyDecoder<T>>, field: string, tag: bigint, body: Uint8Array): T {\n const decode = decoders.get(tag);\n if (decode === undefined) throw refuse(field, `tag ${tag} is not allowed here`);\n return decode(body);\n}\n\nfunction decodeItem<T>(decoders: ReadonlyMap<bigint, BodyDecoder<T>>, field: string, item: Uint8Array): T {\n const { tag, data } = CborDeserializer.decodeTag(item);\n return decodeBody(decoders, field, tag, data);\n}\n\nfunction decodeMediaRef(field: string, item: Uint8Array): NftMediaRef | null {\n return CborDeserializer.decodeNullable(item, (ref) => decodeItem(MEDIA_REF_DECODERS, field, ref));\n}\n\nfunction decodeSigned(body: Uint8Array): ParsedNft {\n const [, creatorItem, payload, signatureItem] = versionedFields(body, SIGNED_ARITY);\n const creator = CborDeserializer.decodeByteString(creatorItem);\n const signature = CborDeserializer.decodeByteString(signatureItem);\n checkSignedParts(creator, signature);\n return { content: decodeItem(UNSIGNED_DECODERS, 'payload', payload), signed: { creator, payload, signature } };\n}\n\nfunction decodePayload(data: Uint8Array): ParsedNft {\n const { tag, data: body } = CborDeserializer.decodeTag(data);\n if (tag === NFT_SIGNED_TAG) return decodeSigned(body);\n return { content: decodeBody(UNSIGNED_DECODERS, 'payload', tag, body), signed: null };\n}\n\n/** Structural parse of a genesis payload. NEVER throws; null = not a recognised NFT. */\nexport function parseNftPayload(data: Uint8Array | null): ParsedNft | null {\n if (data === null) return null;\n try {\n const parsed = decodePayload(data);\n checkContent(parsed.content);\n return parsed;\n } catch {\n return null;\n }\n}\n\n/**\n * Parse the file a document link points at: exactly one NftMetadata or NftMedia item.\n * NEVER throws; null = not a document. Check the bytes with verifyNftLinkContent first.\n */\nexport function parseNftDocument(bytes: Uint8Array): NftMetadata | NftMedia | null {\n try {\n const document = decodeItem(DOCUMENT_DECODERS, 'document', bytes);\n checkContent(document);\n return document;\n } catch {\n return null;\n }\n}\n\n/** Is this an NftLink to a metadata document ({@link NFT_DOCUMENT_MEDIA_TYPE}), resolved with parseNftDocument? */\nexport function isNftDocumentLink(content: NftContent): boolean {\n return content?.kind === 'link' && content.media_type === NFT_DOCUMENT_MEDIA_TYPE;\n}\n\n// ── signature ───────────────────────────────────────────────────────────────\n\n/**\n * SHA-256 of CBOR `[h'UNICITY_NFT_SIGNED', 1, α, h(recipient predicate), h(token id), h(token type), h(payload)]`:\n * every term a byte string except the version and α, as in the yellowpaper genesis commitment.\n */\nexport function nftSignedDigest(context: NftSignatureContext, payload: Uint8Array): Promise<DataHash> {\n const preimage = CborSerializer.encodeArray(\n CborSerializer.encodeByteString(SIGNED_DOMAIN),\n CborSerializer.encodeUnsignedInteger(NFT_FORMAT_VERSION),\n CborSerializer.encodeUnsignedInteger(NetworkId.fromId(context.networkId).id),\n CborSerializer.encodeByteString(context.recipientPredicate),\n CborSerializer.encodeByteString(context.tokenId),\n CborSerializer.encodeByteString(context.tokenType),\n CborSerializer.encodeByteString(payload),\n );\n return new DataHasher(HashAlgorithm.SHA256).update(preimage).digest();\n}\n\n/** Recovering verification: binds the recovery byte and refuses high-s. Never throws. */\nexport async function verifyNftSignature(\n signed: NonNullable<ParsedNft['signed']>,\n context: NftSignatureContext,\n): Promise<Exclude<NftSignatureStatus, 'unsigned'>> {\n try {\n if (!SigningService.isPublicKeyValid(signed.creator)) return 'invalid';\n const signature = Signature.decode(signed.signature);\n const digest = await nftSignedDigest(context, signed.payload);\n return (await SigningService.verifyWithPublicKey(digest, signature, signed.creator)) ? 'valid' : 'invalid';\n } catch {\n return 'invalid';\n }\n}\n\n/** Does `bytes` match the link's sha256? Pure, sync. */\nexport function verifyNftLinkContent(link: NftLink, bytes: Uint8Array): boolean {\n return HexConverter.encode(sha256(bytes)) === link.sha256.toLowerCase();\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 { secp256k1 } from '@noble/curves/secp256k1.js';\nimport * as bip39 from 'bip39';\nimport CryptoJS from 'crypto-js';\nimport { SphereError } from './errors';\n\n// =============================================================================\n// Constants\n// =============================================================================\n\n/** secp256k1 curve order */\nconst CURVE_ORDER = BigInt(\n '0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141'\n);\n\n/** A secp256k1 private key is exactly 32 bytes — 64 hex chars. */\nconst PRIVKEY_HEX_RE = /^[0-9a-fA-F]{64}$/;\n\n/**\n * Reject a malformed private key BEFORE it reaches the curve (#674 review).\n * `hexToBytes` coerces any non-hex character to a zero byte\n * (`parseInt('gg', 16)` → NaN → 0), so a right-length string with a stray\n * non-hex char would otherwise derive/sign with a DIFFERENT valid key and no\n * error — silently signing with an unintended key. secp256k1 already rejects\n * wrong-*length* input; this closes the same-length-wrong-chars hole.\n */\nfunction assertPrivKeyHex(privateKeyHex: string): void {\n if (!PRIVKEY_HEX_RE.test(privateKeyHex)) {\n throw new SphereError(\n `Invalid private key: expected 64 hex chars, got ${privateKeyHex.length}`,\n 'VALIDATION_ERROR',\n );\n }\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 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 compressedPubKey = getPublicKey(parentPrivKey, true);\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 assertPrivKeyHex(privateKey);\n // SEC1 encoding: compressed = 02/03 prefix + x (33 bytes),\n // uncompressed = 04 prefix + x + y (65 bytes) — identical to elliptic's output.\n return bytesToHex(secp256k1.getPublicKey(hexToBytes(privateKey), compressed));\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// 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 key 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 */\nexport function deriveAddressInfo(\n masterKey: MasterKey,\n basePath: string,\n index: number,\n isChange: boolean = false\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\n return {\n privateKey: derived.privateKey,\n publicKey,\n path: fullPath,\n index,\n };\n}\n\n/**\n * Generate full key info from private key with index and path\n */\nexport function generateAddressInfo(\n privateKey: string,\n index: number,\n path: string\n): AddressInfo {\n const publicKey = getPublicKey(privateKey);\n return {\n privateKey,\n publicKey,\n path,\n index,\n };\n}\n\n/**\n * Generate key info from master private key using HMAC-SHA512 derivation\n * This matches exactly the original index.html implementation\n * NOTE: This is NON-STANDARD derivation for legacy wallet compatibility.\n *\n * Dual-use: in `wif_hmac` derivation mode (legacy wallet import) this derives\n * the wallet's chainPubkey (used for L3 identity).\n *\n * @param masterPrivateKey - 32-byte hex private key (64 chars)\n * @param index - Address index\n */\nexport function generateAddressFromMasterKey(\n masterPrivateKey: string,\n index: number\n): AddressInfo {\n const derivationPath = `m/44'/0'/${index}'`;\n\n // HMAC-SHA512 with path as key (matching index.html exactly)\n const hmacInput = CryptoJS.enc.Hex.parse(masterPrivateKey);\n const hmacKey = CryptoJS.enc.Utf8.parse(derivationPath);\n const hmacOutput = CryptoJS.HmacSHA512(hmacInput, hmacKey).toString();\n\n // Use left 32 bytes for private key\n const childPrivateKey = hmacOutput.substring(0, 64);\n\n return generateAddressInfo(childPrivateKey, index, derivationPath);\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 assertPrivKeyHex(privateKeyHex);\n const hashHex = hashSignMessage(message);\n // prehash:false — the message is already hashed (double-SHA256 above);\n // lowS:true — canonical low-S signatures (same as elliptic's {canonical:true});\n // format:'recovered' — recoveryId(1) || r(32) || s(32), RFC6979-deterministic.\n const sigBytes = secp256k1.sign(hexToBytes(hashHex), hexToBytes(privateKeyHex), {\n prehash: false,\n lowS: true,\n format: 'recovered',\n });\n\n const recoveryParam = sigBytes[0];\n const v = (31 + recoveryParam).toString(16).padStart(2, '0');\n // r and s are fixed-width 32-byte big-endian — already left-padded.\n return v + bytesToHex(sigBytes.subarray(1));\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\n try {\n const recovered = secp256k1.Signature\n .fromHex(r + s, 'compact')\n .addRecoveryBit(v)\n .recoverPublicKey(hexToBytes(hashHex));\n return recovered.toHex(true) === expectedPubkey; // compressed\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\n const recovered = secp256k1.Signature\n .fromHex(r + s, 'compact')\n .addRecoveryBit(v)\n .recoverPublicKey(hexToBytes(hashHex));\n return recovered.toHex(true); // compressed\n}\n","// The plan → intent-payload codec (§5.5): what a send attempt PUTs as its\n// durable server intent. Extracted from PaymentsFacade (pure, no state).\n\nimport type { SendRequest } from '../api';\nimport type { PlannedSpend } from '../select/queue';\nimport type { CoinIntentPayload, WholeIntentPayload } from './types';\n\nexport function buildPayload(\n recipientPubkey: string,\n request: SendRequest,\n spend: PlannedSpend,\n spentStates: Record<string, { local: string; protocol: string }>\n): CoinIntentPayload {\n return {\n v: 2,\n kind: 'coin',\n recipient: recipientPubkey,\n coinId: request.coinId,\n amount: request.amount,\n ...(request.memo !== undefined ? { memo: request.memo } : {}),\n direct: [...spend.plan.direct],\n ...(spend.plan.split !== undefined\n ? {\n split: {\n tokenId: spend.plan.split.tokenId,\n splitAmount: spend.plan.split.splitAmount.toString(),\n remainderAmount: spend.plan.split.remainderAmount.toString(),\n },\n }\n : {}),\n spentStates,\n };\n}\n\nexport function messageOf(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\n/**\n * A token-addressed spend (#777). Takes no PlannedSpend because nothing was\n * selected: the source is named, so there is no amount, no split and no change.\n */\nexport function buildWholePayload(\n recipientPubkey: string,\n request: { tokenId: string; memo?: string },\n spentStates: Record<string, { local: string; protocol: string }>\n): WholeIntentPayload {\n return {\n v: 2,\n kind: 'whole',\n recipient: recipientPubkey,\n ...(request.memo !== undefined ? { memo: request.memo } : {}),\n direct: [request.tokenId],\n spentStates,\n };\n}\n","// Shared concurrency primitives. Both advance on SETTLED, never fulfilled —\n// a rejection never bricks the next run (async.test.ts pins the recovery).\n\nexport class SingleFlight<T> {\n private flight: Promise<T> | null = null;\n\n run(fn: () => Promise<T>): Promise<T> {\n if (this.flight !== null) return this.flight;\n const current = fn().finally(() => {\n this.flight = null;\n });\n this.flight = current;\n return current;\n }\n}\n\nexport class SerialChain {\n private tail: Promise<unknown> = Promise.resolve();\n\n /** FIFO; starts after every prior fn settled; returns this fn's own outcome. */\n enqueue<T>(fn: () => Promise<T>): Promise<T> {\n const run = this.tail.then(fn, fn);\n this.tail = run.then(\n () => undefined,\n () => undefined\n );\n return run;\n }\n}\n\n/** Fire-and-forget sibling of {@link SingleFlight}: one in flight, one queued behind it. */\nexport function coalesced(\n run: () => Promise<unknown>,\n observe?: (op: Promise<unknown>) => void\n): () => void {\n let inFlight = false;\n let queued = false;\n const start = (): void => {\n inFlight = true;\n // A synchronous throw would escape before .catch attaches and strand\n // inFlight, wedging every later trigger. Started eagerly, not on a\n // microtask, so a caller can rely on the first run having begun.\n let running: Promise<unknown>;\n try {\n running = run();\n } catch {\n running = Promise.resolve();\n }\n observe?.(running);\n void running\n .catch(() => undefined)\n .finally(() => {\n inFlight = false;\n if (!queued) return;\n queued = false;\n start();\n });\n };\n return () => {\n if (inFlight) {\n queued = true;\n return;\n }\n start();\n };\n}\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 * NOTE: the server-side INTENT cap is being raised (wallet-api#102); the SDK\n * deliberately does NOT pre-flight-enforce it on sends (#670) — the server\n * decides, and a deterministic 422 is handled as terminal by the send path.\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 BINARY plaintext into the S6 wire envelope, optionally bound to associated data (AAD):\n * `\"enc1.\" + base64(nonce ‖ ciphertext)` (XChaCha20-Poly1305, random 24-byte nonce). The AAD is\n * authenticated but NOT stored in the envelope — the reader re-derives it from context, so a\n * record decrypted against a different AAD fails the poly1305 tag (E.4: AAD = `transferId:opIndex`\n * binds a checkpoint to its slot, defeating a mis-served / cross-intent replay at the crypto layer).\n */\nexport function encryptFieldBytes(key: Uint8Array, plaintext: Uint8Array, aad?: Uint8Array): string {\n const nonce = randomBytes(FIELD_ENVELOPE_NONCE_BYTES);\n const ciphertext = xchacha20poly1305(key, nonce, aad).encrypt(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 to BINARY bytes, requiring the same `aad` used at encrypt time.\n * Any tampering, wrong key, OR wrong AAD throws `SphereError('DECRYPTION_ERROR')`.\n */\nexport function decryptFieldBytes(key: Uint8Array, envelope: string, aad?: Uint8Array): Uint8Array {\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 return xchacha20poly1305(key, nonce, aad).decrypt(ciphertext);\n } catch (err) {\n throw new SphereError('Field envelope authentication failed (tampered, wrong key, or wrong AAD)', 'DECRYPTION_ERROR', err);\n }\n}\n\n/**\n * Encrypt a UTF-8 string field into the S6 wire envelope (AAD-less). Thin wrapper over\n * {@link encryptFieldBytes} — the memo/nametag/intent-payload path.\n */\nexport function encryptField(key: Uint8Array, plaintext: string): string {\n return encryptFieldBytes(key, new TextEncoder().encode(plaintext));\n}\n\n/**\n * Decrypt an AAD-less S6 wire envelope to a UTF-8 string (memo/nametag/intent payload). Any\n * tampering throws `SphereError('DECRYPTION_ERROR')`.\n */\nexport function decryptField(key: Uint8Array, envelope: string): string {\n return new TextDecoder().decode(decryptFieldBytes(key, envelope));\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","import type { CoinIntentPayload, IntentPayload, WholeIntentPayload } from './types';\n\nexport function isWholeIntent(p: IntentPayload): p is WholeIntentPayload {\n return p.kind === 'whole' || p.kind === 'coinless';\n}\n\nexport function isCoinIntent(p: IntentPayload): p is CoinIntentPayload {\n return p.kind === 'coin';\n}\n\nexport function splitOf(p: IntentPayload): CoinIntentPayload['split'] {\n return p.kind === 'coin' ? p.split : undefined;\n}\n\n/** The coin spent, or undefined when token-addressed. Handle absence, never ''. */\nexport function coinIdOf(p: IntentPayload): string | undefined {\n return p.kind === 'coin' ? p.coinId : undefined;\n}\n\n","/**\n * Browser-safe UUID v4 generation.\n *\n * Kept dependency-free (no node:crypto require, unlike core/utils.ts) so it is\n * safe to import from the platform:'browser' bundles and the token-engine\n * subpath without dragging a Node builtin into them.\n */\n\n/**\n * Generate a v4 UUID.\n *\n * Prefers `crypto.randomUUID()` (secure context; Safari 15.4+, Chrome 92+,\n * Node 19+). Falls back to deriving one from `crypto.getRandomValues()`, which\n * is available in every browser — including insecure / non-HTTPS contexts and\n * older WebViews — and in Node 20+. This avoids\n * `crypto.randomUUID is not a function` on sub-15.4 / insecure-context runtimes\n * (sphere-sdk#619), with no node:crypto fallback that would break browser bundles.\n */\nexport function randomUUID(): string {\n const c = globalThis.crypto;\n if (typeof c !== 'undefined' && typeof c.randomUUID === 'function') {\n return c.randomUUID();\n }\n // RFC 4122 v4 from CSPRNG bytes.\n const b = c.getRandomValues(new Uint8Array(16));\n b[6] = (b[6] & 0x0f) | 0x40; // version 4\n b[8] = (b[8] & 0x3f) | 0x80; // variant 10xx\n const h = Array.from(b, (x) => x.toString(16).padStart(2, '0'));\n return `${h[0]}${h[1]}${h[2]}${h[3]}-${h[4]}${h[5]}-${h[6]}${h[7]}-${h[8]}${h[9]}-${h[10]}${h[11]}${h[12]}${h[13]}${h[14]}${h[15]}`;\n}\n","// §5.9 of docs/PAYMENTS-V2-DESIGN.md — history is a server read-through plus\n// client POSTs. No local ledger; the server log is the store of record.\n\nimport { encryptField, decryptField } from '../../../core/field-encryption';\nimport { randomUUID } from '../../../core/uuid';\n\nimport type { HistoryEntry, HistoryPage } from '../api';\n\nexport interface HistoryWireAsset {\n coinId: string;\n amount: string;\n}\n\n// §16 wire record (structural slice of impl/wallet-api-v2 HistoryRecordWire).\nexport interface HistoryWireRecord {\n dedupKey: string;\n id: string;\n type: 'SENT' | 'RECEIVED' | 'MINT';\n assets: HistoryWireAsset[];\n ts: string;\n transferId?: string;\n tokenId?: string;\n counterpartyPubkey?: string;\n counterpartyNametag?: string;\n memo?: string;\n}\n\n// WalletApiV2Client satisfies this structurally; tests drive FakeWalletApi\n// through a thin adapter of the same shape.\nexport interface HistoryClient {\n listHistory(options?: { before?: string; limit?: number }): Promise<{\n records: readonly HistoryWireRecord[];\n more: boolean;\n cursor: string | null;\n }>;\n postHistory(records: HistoryWireRecord[]): Promise<unknown>;\n}\n\nexport interface HistoryRegistryReader {\n getSymbol(coinId: string): string;\n}\n\nexport interface HistoryDeps {\n readonly client: HistoryClient;\n /** S6 self-scoped field-encryption key (core/field-encryption, `enc1.`). */\n readonly fieldKey: Uint8Array;\n readonly registry: HistoryRegistryReader;\n /** §4: the event carries the recorded entry, client-shaped (never `{}`). */\n readonly emit: (event: 'history:updated', entry: HistoryEntry) => void;\n readonly log?: (message: string, error?: unknown) => void;\n readonly now?: () => number;\n readonly newId?: () => string;\n}\n\nexport interface RecordSentInput {\n transferId: string;\n /** EMPTY when nothing with a coin moved (#780). Every type accepts an empty list. */\n assets: readonly { coinId: string; amount: string }[];\n recipientPubkey?: string;\n recipientNametag?: string;\n memo?: string;\n tokenId?: string;\n timestamp?: number;\n}\n\nexport interface RecordReceivedInput {\n tokenId: string;\n stateHash: string;\n /**\n * What arrived. EMPTY for a coinless token (#777) — wallet-api#151 accepts an\n * empty list and keeps refusing `coinId: ''`, so a synthetic empty-coin entry\n * 422s and the row is lost. §10 forbids a record naming neither assets nor a\n * tokenId; `tokenId` is always set here, so an empty list is legal.\n */\n assets: readonly { coinId: string; amount: string }[];\n transferId?: string;\n senderPubkey?: string;\n senderNametag?: string;\n memo?: string;\n timestamp?: number;\n}\n\nexport interface RecordMintInput {\n tokenId: string;\n assets: readonly { coinId: string; amount: string }[];\n timestamp?: number;\n}\n\n/** Copied, never aliased: the wire record must not share the caller's array. */\nfunction wireAssets(\n assets: readonly { coinId: string; amount: string }[]\n): { coinId: string; amount: string }[] {\n return assets.map((a) => ({ coinId: a.coinId, amount: a.amount }));\n}\n\n/**\n * A 4xx other than 408/429 is the server refusing this record's SHAPE — permanent,\n * so no retry can fix it. Duck-typed on `status` so the module keeps no dependency\n * on a transport implementation.\n */\nfunction isPermanentReject(err: unknown): boolean {\n const status = (err as { status?: unknown } | null)?.status;\n if (typeof status !== 'number') return false;\n return status >= 400 && status < 500 && status !== 408 && status !== 429;\n}\n\nconst WIRE_TOKEN_ID = /^(?:[0-9a-f]{2}){1,64}$/;\nconst WIRE_PUBKEY = /^0[23][0-9a-f]{64}$/;\n\nexport class History {\n constructor(private readonly deps: HistoryDeps) {}\n\n // ── read-through ───────────────────────────────────────────────────────────\n\n async page(opts: { before?: string; limit?: number } = {}): Promise<HistoryPage> {\n const result = await this.deps.client.listHistory({\n ...(opts.before !== undefined ? { before: opts.before } : {}),\n ...(opts.limit !== undefined ? { limit: opts.limit } : {}),\n });\n return {\n entries: result.records.map((record) => this.toEntry(record)),\n more: result.more,\n cursor: result.cursor,\n };\n }\n\n // ── client POSTs (best-effort — NEVER throw into the money path) ────────────\n\n async recordSent(input: RecordSentInput): Promise<void> {\n await this.post(() => ({\n dedupKey: input.transferId,\n id: (this.deps.newId ?? randomUUID)(),\n type: 'SENT' as const,\n assets: wireAssets(input.assets),\n ts: this.ts(input.timestamp),\n transferId: input.transferId,\n ...this.wireTokenId(input.tokenId),\n ...this.wireCounterparty(input.recipientPubkey, input.recipientNametag),\n ...this.wireMemo(input.memo),\n }));\n }\n\n async recordReceived(input: RecordReceivedInput): Promise<void> {\n await this.post(() => ({\n dedupKey: `RECEIVED:${input.tokenId.toLowerCase()}:${input.stateHash.toLowerCase()}`,\n id: (this.deps.newId ?? randomUUID)(),\n type: 'RECEIVED' as const,\n assets: wireAssets(input.assets),\n ts: this.ts(input.timestamp),\n ...(input.transferId !== undefined ? { transferId: input.transferId } : {}),\n ...this.wireTokenId(input.tokenId),\n ...this.wireCounterparty(input.senderPubkey, input.senderNametag),\n ...this.wireMemo(input.memo),\n }));\n }\n\n async recordMint(input: RecordMintInput): Promise<void> {\n await this.post(() => ({\n dedupKey: `MINT:${input.tokenId.toLowerCase()}`,\n id: (this.deps.newId ?? randomUUID)(),\n type: 'MINT' as const,\n assets: wireAssets(input.assets),\n ts: this.ts(input.timestamp),\n ...this.wireTokenId(input.tokenId),\n }));\n }\n\n // ── internals ────────────────────────────────────────────────────────────────\n\n private async post(build: () => HistoryWireRecord): Promise<void> {\n const record = build();\n try {\n await this.deps.client.postHistory([record]);\n } catch (err) {\n // §5.9 keeps this off the money path, but a 4xx is PERMANENT: no retry can\n // fix a shape the server refuses, and logging it as retry-safe is what let a\n // coinless receipt vanish silently (#780). Name the two apart.\n this.deps.log?.(\n isPermanentReject(err)\n ? 'history POST REJECTED — the record shape is refused; no retry can fix it'\n : 'history POST failed (dedupKey makes retry safe)',\n err\n );\n return;\n }\n // The recorded entry is in hand — emit it through the SAME read-through\n // mapping page() serves (decrypted memo/nametag, `timestamp` name).\n this.deps.emit('history:updated', this.toEntry(record));\n }\n\n private ts(timestamp?: number): string {\n return new Date(timestamp ?? (this.deps.now ?? Date.now)()).toISOString();\n }\n\n private wireTokenId(tokenId?: string): { tokenId?: string } {\n const lower = tokenId?.toLowerCase();\n return lower !== undefined && WIRE_TOKEN_ID.test(lower) ? { tokenId: lower } : {};\n }\n\n // Server zod is strict — a non-pubkey counterparty stays off the wire; the\n // nametag rides regardless (S6-encrypted, operator-blind).\n private wireCounterparty(\n pubkey?: string,\n nametag?: string\n ): { counterpartyPubkey?: string; counterpartyNametag?: string } {\n const lower = pubkey?.toLowerCase();\n return {\n ...(lower !== undefined && WIRE_PUBKEY.test(lower) ? { counterpartyPubkey: lower } : {}),\n ...(nametag !== undefined ? { counterpartyNametag: encryptField(this.deps.fieldKey, nametag) } : {}),\n };\n }\n\n private wireMemo(memo?: string): { memo?: string } {\n return memo !== undefined ? { memo: encryptField(this.deps.fieldKey, memo) } : {};\n }\n\n // Consumed mapping: wire `ts` (ISO 8601, any offset) → epoch-ms `timestamp`;\n // coinId/amount from the FIRST asset (multi-asset remainder surfaces via\n // tokenIds[]); counterparty lands on the role-appropriate side by type.\n private toEntry(wire: HistoryWireRecord): HistoryEntry {\n const first = wire.assets[0];\n const coinId = first?.coinId ?? '';\n const received = wire.type === 'RECEIVED';\n const memo = this.tryDecrypt(wire.memo);\n const nametag = this.tryDecrypt(wire.counterpartyNametag);\n return {\n id: wire.id,\n type: wire.type,\n coinId,\n amount: first?.amount ?? '0',\n symbol: this.deps.registry.getSymbol(coinId),\n timestamp: Date.parse(wire.ts),\n ...(wire.transferId !== undefined ? { transferId: wire.transferId } : {}),\n ...(wire.tokenId !== undefined ? { tokenId: wire.tokenId } : {}),\n ...(wire.assets.length > 1\n ? { tokenIds: wire.assets.map((asset) => ({ id: asset.coinId, amount: asset.amount })) }\n : {}),\n ...(wire.counterpartyPubkey !== undefined\n ? received\n ? { senderPubkey: wire.counterpartyPubkey }\n : { recipientPubkey: wire.counterpartyPubkey }\n : {}),\n ...(nametag !== undefined\n ? received\n ? { senderNametag: nametag }\n : { recipientNametag: nametag }\n : {}),\n ...(memo !== undefined ? { memo } : {}),\n };\n }\n\n // Self-scoped decrypt: a foreign/undecryptable/plaintext value is absent,\n // never ciphertext and never a throw.\n private tryDecrypt(envelope?: string): string | undefined {\n if (envelope === undefined) return undefined;\n try {\n return decryptField(this.deps.fieldKey, envelope);\n } catch {\n return undefined;\n }\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","// The complete §6 durable-state inventory. One writer per store.\n\nimport { logger } from '../../core/logger';\nimport type { StorageProvider } from '../../storage';\n\n/** Generation 2 of the durable client state; renaming IS the 3.x migration\n * (kv-generation.test.ts). Must not START with a superseded prefix — the sweep\n * below matches by `startsWith`. */\nconst KV_PREFIX = 'pv2g2:';\n\nconst SUPERSEDED_KV_PREFIXES = ['pv2:'] as const;\n\n/** Never `storage.clear()` — that takes the keys too. */\nexport async function sweepSupersededState(storage: StorageProvider): Promise<void> {\n for (const prefix of SUPERSEDED_KV_PREFIXES) {\n try {\n await storage.clear(prefix);\n } catch (err) {\n logger.warn('PaymentsV2', `could not clear superseded state under \"${prefix}\": ${String(err)}`);\n }\n }\n}\n\nexport interface ScopedKV {\n get<T>(key: string): Promise<T | null>;\n set<T>(key: string, value: T): Promise<void>;\n remove(key: string): Promise<void>;\n}\n\nexport function createScopedKV(\n storage: StorageProvider,\n network: string,\n chainPubkey: string\n): ScopedKV {\n const prefix = `${KV_PREFIX}${network}:${chainPubkey}:`;\n return {\n async get<T>(key: string): Promise<T | null> {\n const raw = await storage.get(prefix + key);\n if (raw === null || raw === undefined) return null;\n return typeof raw === 'string' ? (JSON.parse(raw) as T) : (raw as T);\n },\n async set<T>(key: string, value: T): Promise<void> {\n await storage.set(prefix + key, JSON.stringify(value));\n },\n async remove(key: string): Promise<void> {\n await storage.remove(prefix + key);\n },\n };\n}\n\n\nexport interface IntentBackstopEntry {\n transferId: string;\n payloadEnvelope: string;\n requiresSeedClose: boolean;\n // #676: a locally-aborted intent is NEVER resumed.\n disposition: 'open' | 'abortPending' | 'aborted';\n createdAt: number;\n}\n\n\n// #621 delivery journal.\nexport interface DeliveryJournalEntry {\n transferId: string;\n opIndex: number;\n recipientPubkey: string;\n blobHex: string;\n memo?: string;\n // Poison budget (#517); 429 deferrals do NOT count.\n attempts: number;\n deferredUntil?: number;\n undeliverable?: boolean;\n}\n\n// §5.9 mint journal.\nexport interface MintJournalEntry {\n mintId: string;\n coinId: string;\n amount: string;\n tokenId: string;\n createdAt: number;\n}\n\n// §5.9 NFT mint journal (#785). Its own store: an older client reading a coin\n// journal entry without coinId/amount would retry it every pass, forever.\n// Every field a byte-identical re-mint needs is journaled, so resume never re-signs.\nexport interface NftMintJournalEntry {\n mintId: string;\n tokenId: string;\n dataHex: string;\n saltHex: string;\n tokenTypeHex: string;\n createdAt: number;\n}\n\n// #690 shortfall record.\nexport interface ShortfallEntry {\n transferId: string;\n remainingAmount: string;\n coinId: string;\n recipient: string;\n // Already delivered — NEVER re-send these sources.\n committedTokenIds: string[];\n createdAt: number;\n}\n\n// #441 settling link.\nexport interface SettlingLink {\n requestId: string;\n transferId: string;\n committed: boolean;\n createdAt: number;\n}\n\nexport type StreamName = 'inventory' | 'mailbox' | 'payment_requests' | 'history';\n\n// Cursor+epoch persist as ONE record — never two keys (#692 F10).\nexport interface StreamCursor {\n cursor: number | string;\n syncEpoch: string;\n}\n\nexport const STORE_KEYS = {\n intentBackstop: 'intents',\n checkpointCache: 'checkpoints',\n deliveryJournal: 'delivery-journal',\n mintJournal: 'mint-journal',\n nftMintJournal: 'nft-mint-journal',\n shortfalls: 'shortfalls',\n settlingLinks: 'settling',\n streamCursor: (s: StreamName) => `cursor:${s}`,\n epochLatch: 'epoch-latch',\n // §5.2 InventoryView durable overlays (#625/#679).\n suspectedSpent: 'suspected-spent',\n knownSpends: 'known-spends',\n} as const;\n","// §5.2 presentation half (split out per PR #727 review): pure registry/fiat\n// display mapping over mirror snapshots. No mirror mutation, no concurrency —\n// InventoryView owns the money mirror; this file only formats it.\n\nimport type { Asset, Token } from '../../../types';\nimport type { InventoryAsset } from '../ports';\n\nexport interface RegistryReader {\n getSymbol(coinId: string): string;\n getName(coinId: string): string;\n getDecimals(coinId: string): number;\n getIconUrl(coinId: string): string | null;\n /** Coinless token CLASS metadata, keyed by token type — a separate namespace. */\n getTypeMeta?(tokenType: string): { name: string; iconUrl: string | null } | null;\n}\n\nexport interface PriceQuote {\n readonly priceUsd: number;\n readonly priceEur?: number;\n readonly change24h?: number;\n}\n\nexport interface PriceReader {\n getPrices(tokenNames: string[]): Promise<Map<string, PriceQuote>>;\n}\n\nexport interface TokenSnapshot {\n readonly assets: readonly InventoryAsset[];\n readonly createdAt: number;\n readonly updatedAt: number;\n}\n\nexport interface TokenFlags {\n readonly transferring: boolean;\n readonly suspectedSpent: boolean;\n}\n\nexport function toToken(\n tokenId: string,\n snapshot: TokenSnapshot,\n asset: InventoryAsset,\n registry: RegistryReader,\n flags: TokenFlags\n): Token {\n const iconUrl = registry.getIconUrl(asset.coinId);\n return {\n id: tokenId,\n coinId: asset.coinId,\n symbol: registry.getSymbol(asset.coinId),\n name: registry.getName(asset.coinId),\n decimals: registry.getDecimals(asset.coinId),\n ...(iconUrl !== null ? { iconUrl } : {}),\n amount: asset.amount,\n status: flags.transferring ? 'transferring' : 'confirmed',\n createdAt: snapshot.createdAt,\n updatedAt: snapshot.updatedAt,\n lazy: true,\n ...(flags.suspectedSpent ? { suspectedSpent: true } : {}),\n };\n}\n\ninterface CoinTotals {\n total: bigint;\n count: number;\n transferring: bigint;\n transferringCount: number;\n}\n\nexport function aggregateAssets(\n entries: Iterable<[string, TokenSnapshot]>,\n isTransferring: (tokenId: string) => boolean,\n registry: RegistryReader\n): Asset[] {\n const groups = new Map<string, CoinTotals>();\n for (const [tokenId, entry] of entries) {\n const moving = isTransferring(tokenId);\n for (const asset of entry.assets) {\n let group = groups.get(asset.coinId);\n if (!group) {\n group = { total: 0n, count: 0, transferring: 0n, transferringCount: 0 };\n groups.set(asset.coinId, group);\n }\n if (moving) {\n group.transferring += BigInt(asset.amount);\n group.transferringCount += 1;\n } else {\n group.total += BigInt(asset.amount);\n group.count += 1;\n }\n }\n }\n return [...groups].map(([coinId, totals]) => toAsset(coinId, totals, registry));\n}\n\nfunction toAsset(coinId: string, totals: CoinTotals, registry: RegistryReader): Asset {\n const iconUrl = registry.getIconUrl(coinId);\n return {\n coinId,\n symbol: registry.getSymbol(coinId),\n name: registry.getName(coinId),\n decimals: registry.getDecimals(coinId),\n ...(iconUrl !== null ? { iconUrl } : {}),\n totalAmount: totals.total.toString(),\n tokenCount: totals.count,\n confirmedAmount: totals.total.toString(),\n unconfirmedAmount: '0',\n confirmedTokenCount: totals.count,\n unconfirmedTokenCount: 0,\n transferringTokenCount: totals.transferringCount,\n transferringAmount: totals.transferring.toString(),\n priceUsd: null,\n priceEur: null,\n change24h: null,\n fiatValueUsd: null,\n fiatValueEur: null,\n };\n}\n\n/**\n * The price-platform id for a coin.\n *\n * `RegistryReader.getName()` returns the DISPLAY name — the registry's raw name\n * with its first letter capitalized (\"Bitcoin\", \"Unicity\"). Price platform ids\n * (CoinGecko) are the raw lowercase names, and CoinGecko answers under the\n * canonical lowercase id even when asked with a capitalized one — so a\n * capitalized key MISSES on the way back and every asset silently prices at 0.\n * Lowercasing recovers the raw registry name exactly (a coinId fallback is hex,\n * already lowercase). Display keeps using getName(); only the price key differs.\n */\nfunction priceIdOf(registry: RegistryReader, coinId: string): string {\n return registry.getName(coinId).toLowerCase();\n}\n\nexport async function withPrices(\n raw: Asset[],\n registry: RegistryReader,\n price: PriceReader\n): Promise<Asset[]> {\n try {\n const ids = [...new Set(raw.map((a) => priceIdOf(registry, a.coinId)))];\n const quotes = await price.getPrices(ids);\n return raw.map((a) => priceOne(a, quotes.get(priceIdOf(registry, a.coinId))));\n } catch {\n return raw;\n }\n}\n\n// Fiat display conversion is the one sanctioned Number use (display only).\nfunction priceOne(asset: Asset, quote: PriceQuote | undefined): Asset {\n if (!quote) return asset;\n const human = Number(asset.totalAmount) / Math.pow(10, asset.decimals);\n return {\n ...asset,\n priceUsd: quote.priceUsd,\n priceEur: quote.priceEur ?? null,\n change24h: quote.change24h ?? null,\n fiatValueUsd: human * quote.priceUsd,\n fiatValueEur: quote.priceEur != null ? human * quote.priceEur : null,\n };\n}\n\n/** A source token as it appears mid-send: no snapshot yet, flagged transferring. */\nexport function transferringToken(\n tokenId: string,\n coinId: string,\n amount: bigint,\n registry: RegistryReader,\n now: number\n): Token {\n const snapshot = { assets: [], createdAt: now, updatedAt: now };\n return toToken(tokenId, snapshot, { coinId, amount: amount.toString() }, registry, {\n transferring: true,\n suspectedSpent: false,\n });\n}\n","// §5.2 of docs/PAYMENTS-V2-DESIGN.md — in-memory mirror of the server\n// inventory (a view, never a store of record). Single writer of the mirror,\n// the suspectedSpent overlay, the knownSpends set, the in-flight registry and\n// the §6 inventory StreamCursor record. Display mapping lives in presentation.ts.\n\nimport type { Asset, Token } from '../../../types';\nimport { SerialChain, SingleFlight } from '../async';\nimport type { CoinlessToken } from '../api';\nimport type { InventoryAsset, InventoryItem, InventoryPage, StoragePort } from '../ports';\nimport { STORE_KEYS, type ScopedKV, type StreamCursor } from '../stores';\nimport {\n aggregateAssets,\n toToken,\n withPrices,\n type PriceReader,\n type RegistryReader,\n} from './presentation';\n\nexport type { PriceQuote, PriceReader, RegistryReader } from './presentation';\n\n// F6: state-scoped by schema — a bare-tokenId spend record is unrepresentable.\nexport interface KnownSpend {\n readonly tokenId: string;\n readonly stateHash: string;\n}\n\nexport interface PoolEntry {\n readonly tokenId: string;\n readonly amount: bigint;\n}\n\nexport type ReAddResult = 'added' | 'evidenced-tombstone';\n\nexport interface RecoverOutcome {\n readonly recovered: readonly string[];\n readonly confirmedSpent: readonly KnownSpend[];\n}\n\nexport interface InventoryViewDeps {\n readonly port: StoragePort;\n readonly kv: ScopedKV;\n readonly emit: (event: 'inventory:updated') => void;\n readonly now?: () => number;\n /**\n * #737: tokens pinned by a §5.4 reservation — an open intent keeps its sources\n * reserved, and a token the selector cannot pick is NOT spendable balance. The\n * reporting side reads the pin instead of guessing from `inFlight` alone, which\n * only knows about the attempt still running in THIS session.\n */\n readonly isPinned?: (tokenId: string) => boolean;\n}\n\ninterface MirrorEntry {\n stateHash: string;\n seq: number;\n status: 'active' | 'removed';\n assets: readonly InventoryAsset[];\n /**\n * Positive statement that this ACTIVE row names no coin (wallet-api#140).\n * Computed here, where `status` is in hand, because absent `assets` means two\n * different things: a tombstone omits them for an unrelated reason, and\n * `assets` is INHERITED from the previous entry on a delta that omits them.\n */\n coinless: boolean;\n tokenType?: string;\n createdAt: number;\n updatedAt: number;\n}\n\nconst SUSPECTED_KEY = STORE_KEYS.suspectedSpent;\nconst KNOWN_SPENDS_KEY = STORE_KEYS.knownSpends;\nconst CURSOR_KEY = STORE_KEYS.streamCursor('inventory');\n\nfunction stateKey(tokenId: string, stateHash: string): string {\n return `${tokenId}:${stateHash}`;\n}\n\n/**\n * Only an ACTIVE row's absent `assets` positively states coinlessness. A tombstone\n * omits them for an unrelated reason, so it inherits rather than being reclassified\n * (wallet-api sdk-changes S2: discriminate on `status`, never on assets-absent).\n */\n/**\n * A type is a function of tokenId so it never CHANGES, but it can appear late\n * (wallet-api writes it on insert and reactivate; migration 0015 does not\n * backfill). The RESOLVED value is compared: comparing `item.tokenType` would\n * rewrite the entry on every delta that merely omits it.\n */\nfunction unchanged(prev: MirrorEntry, item: InventoryItem, tokenType: string | undefined): boolean {\n return (\n prev.seq === item.seq &&\n prev.status === item.status &&\n prev.stateHash === item.stateHash &&\n tokenType === prev.tokenType\n );\n}\n\nfunction isCoinless(item: InventoryItem, prev: MirrorEntry | undefined): boolean {\n if (item.status !== 'active') return prev?.coinless ?? false;\n return (item.assets?.length ?? 0) === 0;\n}\n\nexport class InventoryView {\n private readonly mirror = new Map<string, MirrorEntry>();\n private readonly suspected = new Set<string>();\n private readonly knownSpends = new Set<string>();\n private readonly inFlight = new Set<string>();\n private firstPullOk = false;\n private hydrated: Promise<void> | null = null;\n private readonly chain = new SerialChain();\n private readonly overlayChain = new SerialChain();\n private readonly pullFlight = new SingleFlight<void>();\n\n constructor(private readonly deps: InventoryViewDeps) {}\n\n fullPull(): Promise<void> {\n return this.pullFlight.run(() => this.chain.enqueue(() => this.doFullPull(false)));\n }\n\n // §5.2/§6: incremental pull from the persisted (cursor, epoch) record; a\n // stale epoch (server restore) voids cursor continuity → full re-pull.\n delta(): Promise<void> {\n return this.chain.enqueue(async () => {\n await this.hydrate();\n const record = this.firstPullOk ? await this.deps.kv.get<StreamCursor>(CURSOR_KEY) : null;\n if (record === null) return this.doFullPull(false);\n const first = await this.deps.port.listInventory(Number(record.cursor));\n if (first.syncEpoch !== record.syncEpoch) return this.doFullPull(true);\n const flags = { changed: false };\n try {\n await this.consumePages(first, undefined, flags);\n } finally {\n if (flags.changed) this.deps.emit('inventory:updated');\n }\n });\n }\n\n // Epoch reset (§5.1): full re-pull with per-key replace; entries absent from\n // the restored server drop only AFTER the new snapshot is fully applied.\n onEpochReset(): Promise<void> {\n return this.chain.enqueue(() => this.doFullPull(true));\n }\n\n async demote(tokenId: string, stateHash: string): Promise<void> {\n if (tokenId === '' || stateHash === '') {\n throw new Error('demote requires both tokenId and stateHash');\n }\n const key = stateKey(tokenId, stateHash);\n if (this.suspected.has(key)) return;\n const added = await this.overlayChain.enqueue(async () => {\n await this.hydrate();\n if (this.suspected.has(key)) return false;\n await this.deps.kv.set(SUSPECTED_KEY, [...this.suspected, key]);\n this.suspected.add(key);\n return true;\n });\n if (added) this.deps.emit('inventory:updated');\n }\n\n recoverRemoved(\n getBlobs: (tokenIds: string[]) => Promise<Map<string, Uint8Array>>,\n isSpent: (tokenId: string, blob: Uint8Array) => Promise<boolean>,\n reAdd: (tokenId: string, blob: Uint8Array) => Promise<ReAddResult>\n ): Promise<RecoverOutcome> {\n return this.chain.enqueue(() => this.doRecover(getBlobs, isSpent, reAdd));\n }\n\n markInFlight(tokenId: string): void {\n if (this.inFlight.has(tokenId)) return;\n this.inFlight.add(tokenId);\n this.deps.emit('inventory:updated');\n }\n\n /** Reserve a whole plan as ONE change — per token emitted 54 events per send. */\n markInFlightMany(tokenIds: Iterable<string>): void {\n let changed = false;\n for (const tokenId of tokenIds) {\n if (this.inFlight.has(tokenId)) continue;\n this.inFlight.add(tokenId);\n changed = true;\n }\n if (changed) this.deps.emit('inventory:updated');\n }\n\n release(tokenId: string): void {\n if (this.inFlight.delete(tokenId)) this.deps.emit('inventory:updated');\n }\n\n /** Release a whole set as ONE change (per-token emitted 54 events per send). */\n releaseMany(tokenIds: Iterable<string>): void {\n let changed = false;\n for (const tokenId of tokenIds) if (this.inFlight.delete(tokenId)) changed = true;\n if (changed) this.deps.emit('inventory:updated');\n }\n\n private pinned(tokenId: string): boolean {\n return this.deps.isPinned?.(tokenId) ?? false;\n }\n\n /** In flight here OR pinned by a reservation: either way not spendable (#737). */\n private held(tokenId: string): boolean {\n return this.inFlight.has(tokenId) || this.pinned(tokenId);\n }\n\n // A PINNED token stays in the pool: the queue applies the ledger filter itself\n // and needs the entry to say how much is pinned when it refuses (#737). In\n // flight without a pin (spent, awaiting the mirror refresh) stays out.\n pool(coinId: string): PoolEntry[] {\n const out: PoolEntry[] = [];\n for (const [tokenId, entry] of this.mirror) {\n if (!this.isSpendable(tokenId, entry)) continue;\n const asset = entry.assets.find((a) => a.coinId === coinId);\n if (asset) out.push({ tokenId, amount: BigInt(asset.amount) });\n }\n return out;\n }\n\n /**\n * The eligibility gates every spend shares, coin or token — ONE definition, so a\n * single probe covers both verbs and neither can drift from the other.\n */\n private isSpendable(tokenId: string, entry: MirrorEntry): boolean {\n if (entry.status !== 'active') return false;\n if (this.inFlight.has(tokenId) && !this.pinned(tokenId)) return false;\n return !this.suspected.has(stateKey(tokenId, entry.stateHash));\n }\n\n /** Is this NAMED token spendable whole — coinless or valued (#777)? */\n spendableToken(tokenId: string): boolean {\n const entry = this.mirror.get(tokenId);\n return entry !== undefined && this.isSpendable(tokenId, entry);\n }\n\n /**\n * Current mirrored state of an ACTIVE token, or undefined when it is unknown\n * or tombstoned. Exists so a cached blob can be state-scoped (F6): a blob is\n * only reusable while the token still sits at the state it was fetched at.\n */\n stateHashOf(tokenId: string): string | undefined {\n const entry = this.mirror.get(tokenId);\n return entry !== undefined && entry.status === 'active' ? entry.stateHash : undefined;\n }\n\n tokens(registry: RegistryReader, filter?: { coinId?: string }): Token[] {\n const out: Token[] = [];\n for (const [tokenId, entry] of this.mirror) {\n if (entry.status !== 'active') continue;\n const asset = entry.assets[0];\n if (!asset) continue;\n if (filter?.coinId !== undefined && asset.coinId !== filter.coinId) continue;\n out.push(\n toToken(tokenId, entry, asset, registry, {\n transferring: this.held(tokenId),\n suspectedSpent: this.suspected.has(stateKey(tokenId, entry.stateHash)),\n })\n );\n }\n return out;\n }\n\n /**\n * Coinless holdings (#777) — DISJOINT from tokens(): an entry is coinless\n * exactly when it is not, so no mirror row can appear in both reads.\n */\n coinless(registry: RegistryReader): CoinlessToken[] {\n const out: CoinlessToken[] = [];\n for (const [tokenId, entry] of this.mirror) {\n if (entry.status !== 'active' || !entry.coinless) continue;\n const meta = entry.tokenType !== undefined ? registry.getTypeMeta?.(entry.tokenType) : null;\n out.push({\n tokenId,\n ...(entry.tokenType !== undefined ? { tokenType: entry.tokenType } : {}),\n ...(meta ? { name: meta.name } : {}),\n ...(meta?.iconUrl != null ? { iconUrl: meta.iconUrl } : {}),\n stateHash: entry.stateHash,\n transferring: this.held(tokenId),\n ...(this.suspected.has(stateKey(tokenId, entry.stateHash))\n ? { suspectedSpent: true }\n : {}),\n createdAt: entry.createdAt,\n updatedAt: entry.updatedAt,\n });\n }\n return out;\n }\n\n async assets(registry: RegistryReader, price?: PriceReader): Promise<Asset[]> {\n const raw = aggregateAssets(this.activeEntries(), (tokenId) => this.held(tokenId), registry);\n if (!price || raw.length === 0) return raw;\n return withPrices(raw, registry, price);\n }\n\n private *activeEntries(): Iterable<[string, MirrorEntry]> {\n for (const [tokenId, entry] of this.mirror) {\n if (entry.status === 'active') yield [tokenId, entry];\n }\n }\n\n private hydrate(): Promise<void> {\n this.hydrated ??= this.loadDurable().catch((error: unknown) => {\n this.hydrated = null;\n throw error;\n });\n return this.hydrated;\n }\n\n private async loadDurable(): Promise<void> {\n const suspected = await this.deps.kv.get<string[]>(SUSPECTED_KEY);\n for (const key of suspected ?? []) this.suspected.add(key);\n const known = await this.deps.kv.get<string[]>(KNOWN_SPENDS_KEY);\n for (const key of known ?? []) this.knownSpends.add(key);\n }\n\n private now(): number {\n return (this.deps.now ?? Date.now)();\n }\n\n private async doFullPull(reconcileAbsent: boolean): Promise<void> {\n await this.hydrate();\n const seen = reconcileAbsent ? new Set<string>() : undefined;\n const flags = { changed: false };\n try {\n let page = await this.deps.port.listInventory();\n const firstCursor = page.cursor;\n if (this.applyItems(page.items, seen)) flags.changed = true;\n while (page.more) {\n page = await this.deps.port.listInventory(page.cursor);\n if (this.applyItems(page.items, seen)) flags.changed = true;\n }\n // One immediate since-delta from the page-1 cursor: pulls span snapshots,\n // its tombstones/upserts repair any inter-page flips.\n await this.consumePages(await this.deps.port.listInventory(firstCursor), seen, flags);\n if (seen && this.dropAbsent(seen)) flags.changed = true;\n this.firstPullOk = true;\n } finally {\n // A partially applied pull still emits — the view DID change.\n if (flags.changed) this.deps.emit('inventory:updated');\n }\n }\n\n /** Applies a since-page and its more-loop, then persists the ONE (cursor, epoch) record. */\n private async consumePages(\n first: InventoryPage,\n seen: Set<string> | undefined,\n flags: { changed: boolean }\n ): Promise<void> {\n let page = first;\n if (this.applyItems(page.items, seen)) flags.changed = true;\n while (page.more) {\n page = await this.deps.port.listInventory(page.cursor);\n if (this.applyItems(page.items, seen)) flags.changed = true;\n }\n const record: StreamCursor = { cursor: page.cursor, syncEpoch: page.syncEpoch };\n await this.deps.kv.set(CURSOR_KEY, record);\n }\n\n // Synchronous per-key application; the overlay prune runs in this same\n // synchronous step (F7) — never against a cleared or half-filled view.\n private applyItems(items: readonly InventoryItem[], seen?: Set<string>): boolean {\n const now = this.now();\n let changed = false;\n for (const item of items) {\n seen?.add(item.tokenId);\n if (this.applyOne(item, now)) changed = true;\n }\n const pruned = this.pruneOverlaySync(false);\n return changed || pruned;\n }\n\n private applyOne(item: InventoryItem, now: number): boolean {\n const prev = this.mirror.get(item.tokenId);\n if (prev && item.seq < prev.seq) return false;\n const tokenType = item.tokenType ?? prev?.tokenType;\n if (prev && unchanged(prev, item, tokenType)) return false;\n this.mirror.set(item.tokenId, {\n stateHash: item.stateHash,\n seq: item.seq,\n status: item.status,\n // ONLY a tombstone inherits: it omits assets for an unrelated reason and\n // recoverRemoved must know the amount it restores. An ACTIVE row that omits\n // them is stating coinlessness, and inheriting there would keep stale assets\n // in tokens() while `coinless` is true — the row in BOTH reads (§16).\n assets: item.assets ?? (item.status === 'removed' ? (prev?.assets ?? []) : []),\n coinless: isCoinless(item, prev),\n ...(tokenType !== undefined ? { tokenType } : {}),\n createdAt: prev?.createdAt ?? now,\n updatedAt: now,\n });\n return true;\n }\n\n // Prunes only on positive evidence (state advance or tombstone). Absence is\n // evidence only when the caller holds a complete post-reset snapshot.\n private pruneOverlaySync(allowAbsent: boolean): boolean {\n let pruned = false;\n for (const key of this.suspected) {\n const cut = key.lastIndexOf(':');\n const entry = this.mirror.get(key.slice(0, cut));\n const live = entry !== undefined\n ? entry.status === 'active' && entry.stateHash === key.slice(cut + 1)\n : !allowAbsent;\n if (!live) {\n this.suspected.delete(key);\n pruned = true;\n }\n }\n if (pruned) this.schedulePersistSuspected();\n return pruned;\n }\n\n private schedulePersistSuspected(): void {\n void this.overlayChain\n .enqueue(() => this.deps.kv.set(SUSPECTED_KEY, [...this.suspected]))\n .catch(() => undefined);\n }\n\n private dropAbsent(seen: Set<string>): boolean {\n let changed = false;\n for (const tokenId of [...this.mirror.keys()]) {\n if (!seen.has(tokenId)) {\n this.mirror.delete(tokenId);\n changed = true;\n }\n }\n if (changed) this.pruneOverlaySync(true);\n return changed;\n }\n\n private async doRecover(\n getBlobs: (tokenIds: string[]) => Promise<Map<string, Uint8Array>>,\n isSpent: (tokenId: string, blob: Uint8Array) => Promise<boolean>,\n reAdd: (tokenId: string, blob: Uint8Array) => Promise<ReAddResult>\n ): Promise<RecoverOutcome> {\n await this.hydrate();\n const candidates = this.firstPullOk ? this.recoveryCandidates() : [];\n if (candidates.length === 0) return { recovered: [], confirmedSpent: [] };\n const blobs = await getBlobs(candidates.map((c) => c.tokenId));\n const recovered: string[] = [];\n const confirmedSpent: KnownSpend[] = [];\n try {\n for (const candidate of candidates) {\n const blob = blobs.get(candidate.tokenId);\n if (!blob) continue;\n const outcome = await this.recoverOne(candidate, blob, isSpent, reAdd);\n if (outcome === 'recovered') recovered.push(candidate.tokenId);\n if (outcome === 'spent') confirmedSpent.push(candidate);\n }\n } finally {\n if (recovered.length > 0) this.deps.emit('inventory:updated');\n }\n return { recovered, confirmedSpent };\n }\n\n private recoveryCandidates(): KnownSpend[] {\n const out: KnownSpend[] = [];\n for (const [tokenId, entry] of this.mirror) {\n if (entry.status !== 'removed') continue;\n if (this.knownSpends.has(stateKey(tokenId, entry.stateHash))) continue;\n out.push({ tokenId, stateHash: entry.stateHash });\n }\n return out;\n }\n\n private async recoverOne(\n candidate: KnownSpend,\n blob: Uint8Array,\n isSpent: (tokenId: string, blob: Uint8Array) => Promise<boolean>,\n reAdd: (tokenId: string, blob: Uint8Array) => Promise<ReAddResult>\n ): Promise<'recovered' | 'spent' | 'skipped'> {\n if (await isSpent(candidate.tokenId, blob)) {\n await this.recordKnownSpend(candidate);\n return 'spent';\n }\n if ((await reAdd(candidate.tokenId, blob)) === 'evidenced-tombstone') {\n await this.recordKnownSpend(candidate);\n return 'spent';\n }\n const current = this.mirror.get(candidate.tokenId);\n if (!current || current.status !== 'removed' || current.stateHash !== candidate.stateHash) {\n return 'skipped';\n }\n current.status = 'active';\n current.updatedAt = this.now();\n return 'recovered';\n }\n\n private async recordKnownSpend(spend: KnownSpend): Promise<void> {\n if (spend.tokenId === '' || spend.stateHash === '') {\n throw new Error('knownSpend requires both tokenId and stateHash');\n }\n this.knownSpends.add(stateKey(spend.tokenId, spend.stateHash));\n await this.deps.kv.set(KNOWN_SPENDS_KEY, [...this.knownSpends]);\n }\n}\n","/**\n * Genesis value-envelope classification: the client half of wallet-api's §8.2\n * step 6. This throw set stays a SUBSET of wallet-api's 422 set — throwing where\n * it accepts loses a token (`Receive.screen()` acks a decode throw as invalid).\n */\nimport { SphereError } from '../core/errors';\n\nimport {\n CborDeserializer,\n CborReader,\n HexConverter,\n MajorType,\n type Token,\n} from './sdk';\nimport { SpherePaymentData } from './SpherePaymentData';\nimport type { SphereToken, SphereValue, TokenBlob } from './types';\n\n/** `none_*` = coinless; `bare_collection` = a dialect this SDK cannot read. */\nexport type ValueEnvelope =\n | 'sphere'\n | 'bare_collection'\n | 'none_tag'\n | 'none_other'\n | 'none_absent';\n\n/**\n * Does the token genuinely name NO coin? NOT the same question as `value === null`:\n * `bare_collection` is null too while carrying coins this SDK cannot read.\n */\nexport function isCoinlessEnvelope(envelope: ValueEnvelope): boolean {\n return envelope.startsWith('none_');\n}\n\nexport interface ClassifiedValue {\n readonly envelope: ValueEnvelope;\n /** Populated only for `'sphere'`; null for every other envelope. */\n readonly value: SphereValue | null;\n}\n\nconst SELF_DESCRIBED_CBOR_TAG = 55799n;\nconst CBOR_MAJOR_TYPE_MASK = 0b1110_0000;\n\nconst describe = (error: unknown): string =>\n error instanceof Error ? error.message : String(error);\n\nconst invalid = (message: string): SphereError => new SphereError(message, 'VALIDATION_ERROR');\n\nfunction majorTypeOf(bytes: Uint8Array): MajorType | null {\n const first = bytes.at(0);\n return first === undefined ? null : first & CBOR_MAJOR_TYPE_MASK;\n}\n\n/** Tag number from the HEAD ALONE; `null` = truncated or non-canonical head. */\nfunction headTagNumber(bytes: Uint8Array): bigint | null {\n try {\n return new CborReader(bytes).readLength(MajorType.TAG);\n } catch {\n return null;\n }\n}\n\n/** `Asset.toCBOR()`'s signature: a 2-array of byte strings. Arity and types only. */\nfunction isAssetShaped(item: Uint8Array): boolean {\n try {\n return CborDeserializer.decodeArray(item, 2).every(\n (field) => majorTypeOf(field) === MajorType.BYTE_STRING,\n );\n } catch {\n return false;\n }\n}\n\nfunction arrayItemsOrNull(bytes: Uint8Array): readonly Uint8Array[] | null {\n try {\n return CborDeserializer.decodeArray(bytes);\n } catch {\n return null;\n }\n}\n\nfunction decodeSphere(genesisData: Uint8Array): SphereValue {\n try {\n return SpherePaymentData.fromCBOR(genesisData).toValue();\n } catch (error) {\n throw invalid(`Failed to decode token payment data: ${describe(error)}`);\n }\n}\n\n/** Tagged items must frame cleanly, so raw binary in the tag range is refused. */\nfunction taggedItemBody(genesisData: Uint8Array): Uint8Array {\n try {\n return CborDeserializer.decodeTag(genesisData).data;\n } catch (error) {\n throw invalid(\n `Token value payload is a CBOR tag whose item is malformed or carries trailing bytes: ${describe(error)}`,\n );\n }\n}\n\n/** Does a 55799 wrapper hide a value envelope? Nested wrappers are refused, not walked. */\nfunction selfDescribedBodyCarriesValue(body: Uint8Array): boolean {\n const major = majorTypeOf(body);\n if (major === MajorType.TAG) {\n const inner = headTagNumber(body);\n return inner === SpherePaymentData.CBOR_TAG || inner === SELF_DESCRIBED_CBOR_TAG;\n }\n if (major === MajorType.ARRAY) {\n const items = arrayItemsOrNull(body);\n return items !== null && items.some(isAssetShaped);\n }\n return false;\n}\n\n/** Tag 39050 decodes; 55799-over-value is refused; any other tag is coinless. */\nfunction classifyTagged(genesisData: Uint8Array): ClassifiedValue {\n const tag = headTagNumber(genesisData);\n if (tag === null) {\n throw invalid(\n 'Token value payload has an unreadable or non-canonically encoded CBOR tag head — it could be a malformed SpherePaymentData envelope',\n );\n }\n if (tag === SpherePaymentData.CBOR_TAG) {\n return { envelope: 'sphere', value: decodeSphere(genesisData) };\n }\n const body = taggedItemBody(genesisData);\n if (tag === SELF_DESCRIBED_CBOR_TAG && selfDescribedBodyCarriesValue(body)) {\n throw invalid(\n 'Token value payload is a value envelope wrapped in the self-described CBOR tag 55799 (RFC 8949 §3.4.6), which no codec here unwraps — its coins would be invisible. Emit the envelope without the self-describe prefix',\n );\n }\n return { envelope: 'none_tag', value: null };\n}\n\n/** Must frame cleanly (a truncation may be a corrupt collection). `.some`, never `.every`. */\nfunction classifyArray(genesisData: Uint8Array): ClassifiedValue {\n const items = arrayItemsOrNull(genesisData);\n if (items === null) {\n throw invalid('Token value payload is not PaymentAssetCollection: malformed CBOR array');\n }\n return items.some(isAssetShaped)\n ? { envelope: 'bare_collection', value: null }\n : { envelope: 'none_other', value: null };\n}\n\n/** Not a value envelope ⇒ null value (coinless); claims one and fails to decode ⇒ throws. */\nexport function classifyValueEnvelope(genesisData: Uint8Array | null): ClassifiedValue {\n if (genesisData === null) return { envelope: 'none_absent', value: null };\n const major = majorTypeOf(genesisData);\n if (major === null) return { envelope: 'none_absent', value: null };\n if (major === MajorType.TAG) return classifyTagged(genesisData);\n if (major === MajorType.ARRAY) return classifyArray(genesisData);\n return { envelope: 'none_other', value: null };\n}\n\n/** Wrap an SDK token: blob (incl. stable tokenId), classified envelope, decoded value. */\nexport function wrapToken(sdkToken: Token): SphereToken {\n const { envelope, value } = classifyValueEnvelope(sdkToken.genesis.data);\n const blob: TokenBlob = {\n tokenId: HexConverter.encode(sdkToken.id.bytes),\n token: sdkToken.toCBOR(),\n };\n return {\n sdkToken,\n blob,\n value,\n valueEnvelope: envelope,\n tokenType: HexConverter.encode(sdkToken.type.bytes),\n };\n}\n\n/**\n * Pre-flight for `mintDataToken`'s opaque payload, BEFORE any chain op — otherwise\n * the refusal surfaces from `wrapToken` after the mint certified, stranding a token\n * this SDK can no longer decode and wallet-api would refuse at deposit anyway.\n */\nexport function assertMintableData(data: Uint8Array): void {\n try {\n classifyValueEnvelope(data);\n } catch (error) {\n throw invalid(\n `Cannot mint a data token with this payload: ${describe(error)}. Raw bytes starting in the CBOR array (0x80-0x9f) or tag (0xc0-0xdf) range must be well-formed canonical CBOR; wrap them in a CBOR byte string, map, text string, or a tag other than 39050/55799.`,\n );\n }\n}\n","// S2/S7 interfaces (amended 2026-07-31). Blob bytes = RAW v2 Token.toCBOR().\n\nexport interface InventoryAsset {\n coinId: string;\n amount: string;\n}\n\nexport interface InventoryItem {\n tokenId: string;\n status: 'active' | 'removed';\n seq: number;\n stateHash: string;\n /** Absent for a tombstone AND for an active COINLESS token — read `status`, not this. */\n assets?: InventoryAsset[];\n tokenType?: string;\n}\n\nexport interface InventoryPage {\n cursor: number;\n syncEpoch: string;\n more: boolean;\n items: InventoryItem[];\n}\n\nexport interface ApplyDeltaResult {\n cursor: number;\n syncEpoch: string;\n}\n\nexport interface StoragePort {\n listInventory(since?: number): Promise<InventoryPage>;\n getBlobs(tokenIds: string[]): Promise<Map<string, Uint8Array>>;\n uploadBlobs(blobs: { sha256: string; bytes: Uint8Array }[]): Promise<Map<string, string>>;\n // The one authoritative spend write, after the deposit ATTEMPT (§5.5). Rejects DeltaConflictError('DELTA_CONFLICT',409) / DeltaValidationError('DELTA_VALIDATION',422) — impl/wallet-api-v2/storage.ts; match on `code`.\n applyDelta(delta: {\n transferId: string;\n spent: string[];\n added: { tokenId: string; key: string }[];\n }): Promise<ApplyDeltaResult>;\n}\n\nexport interface DeliveryReceipt {\n // hex(SHA-256(tokenId ‖ stateHash)) — content-derived, never a row id/seq.\n deliveryId: string;\n}\n\nexport interface IncomingDelivery {\n deliveryId: string;\n transferId?: string;\n senderPubkey?: string;\n senderNametag?: string;\n memo?: string;\n fetchBlob(): Promise<Uint8Array>;\n cursor: string;\n}\n\nexport interface DeliverOptions {\n transferId: string;\n memo?: string;\n senderNametag?: string;\n}\n\nexport interface DeliveryPort {\n bindDeliveryKeys(\n derive: (blob: Uint8Array) => Promise<{ tokenId: string; stateHash: string }>\n ): void;\n // Idempotent per (token, state), bytes MAY differ — absorb the key-variant 409.\n deliver(\n recipientPubkey: string,\n blob: Uint8Array,\n options: DeliverOptions\n ): Promise<DeliveryReceipt>;\n deliverBatch?(\n recipientPubkey: string,\n blobs: Uint8Array[],\n options: DeliverOptions\n ): Promise<DeliveryReceipt[]>;\n // At-least-once; the impl owns the persistent seen-set (S7).\n incoming(sinceCursor?: string): AsyncIterable<IncomingDelivery>;\n /**\n * The syncEpoch of the most recent incoming() page — updated per page, null\n * before the first. §5.7 restore self-detection: the mailbox page is the\n * honest epoch source, so Receive voids its (cursor, epoch) continuity on a\n * mismatch even when the wake socket missed a server restore. (Pinned by the\n * S7 contract suite; wallet-api#119's S7 text carries the same sentence.)\n */\n incomingEpoch(): string | null;\n ack(\n deliveryId: string,\n disposition: 'claimed' | 'rejected',\n reason?: 'invalid' | 'not-owned' | 'storage-rejected' | 'other'\n ): Promise<void>;\n /** Settle many acks at once (#757). Contract pinned by the delivery-port contract suite. */\n ackBatch?(acks: readonly AckRequest[]): Promise<readonly AckOutcome[]>;\n onWake?(cb: () => void): () => void;\n}\n\nexport interface AckRequest {\n readonly deliveryId: string;\n readonly disposition: 'claimed' | 'rejected';\n readonly reason?: 'invalid' | 'not-owned' | 'storage-rejected' | 'other';\n}\n\nexport type AckOutcome =\n | { readonly deliveryId: string; readonly status: 'settled' }\n | { readonly deliveryId: string; readonly status: 'conflict' };\n\n/** ackBatch failed in a way a per-entry retry would hit too — do not fall back. */\nexport interface RetryableAckError extends Error {\n readonly retryable: true;\n}\n\nexport function isRetryableAckError(err: unknown): err is RetryableAckError {\n return err !== null && typeof err === 'object' && (err as { retryable?: unknown }).retryable === true;\n}\n","// §5.7 of docs/PAYMENTS-V2-DESIGN.md — the single-flighted receive drain.\n// Entry order is money-load-bearing: the view store precedes the claimed ack (#724).\n\nimport { logger } from '../../../core/logger';\nimport type { ITokenEngine, SphereToken } from '../../../token-engine';\nimport { isCoinlessEnvelope } from '../../../token-engine/value-envelope';\nimport type { IncomingTransfer, Token } from '../../../types';\nimport { SingleFlight } from '../async';\nimport type { RegistryReader } from '../inventory/InventoryView';\nimport type { AttentionEmitter } from '../machine/journal';\nimport { isRetryableAckError } from '../ports';\nimport type { AckOutcome, AckRequest, DeliveryPort, IncomingDelivery } from '../ports';\nimport { STORE_KEYS, type ScopedKV, type StreamCursor } from '../stores';\n\nexport type ReceiveEngine = Pick<\n ITokenEngine,\n 'getIdentity' | 'decodeToken' | 'verify' | 'isOwnedBy' | 'isSpent' | 'tokenId' | 'deliveryKeys'\n>;\n\nexport interface IncomingAssetAmount {\n readonly coinId: string;\n readonly amount: string;\n}\n\nexport interface StoredIncoming {\n readonly tokenId: string;\n readonly stateHash: string;\n readonly assets: readonly IncomingAssetAmount[];\n /** Genesis type of an arrival that names no coin (#777) — its only display handle. */\n readonly tokenType?: string;\n}\n\n// Per-key seam over the inventory view (adapted by the facade in P9).\nexport interface ReceiveView {\n heldState(tokenId: string): string | null;\n store(entry: StoredIncoming): Promise<void>;\n}\n\nexport interface ReceivedRecord {\n readonly dedupKey: string;\n readonly tokenId: string;\n readonly stateHash: string;\n readonly assets: readonly IncomingAssetAmount[];\n readonly tokenType?: string;\n readonly senderPubkey?: string;\n readonly senderNametag?: string;\n readonly memo?: string;\n readonly receivedAt: number;\n}\n\nexport interface ReceiveDeps {\n readonly delivery: DeliveryPort;\n /** Snapshot taken once per drain (§7 collaborator-snapshot rule). */\n readonly engine: () => ReceiveEngine;\n readonly view: ReceiveView;\n readonly kv: ScopedKV;\n readonly registry: RegistryReader;\n readonly recordReceived: (record: ReceivedRecord) => Promise<void>;\n readonly emit: (event: 'transfer:incoming', transfer: IncomingTransfer) => void;\n /** Refresh the inventory mirror mid-drain; fire-and-forget. Receive throttles the calls. */\n readonly refreshView?: () => void;\n readonly attention: AttentionEmitter;\n readonly syncEpoch: () => string;\n readonly track?: (op: Promise<unknown>) => void;\n readonly now?: () => number;\n}\n\nexport const ACK_BATCH_SIZE = 200;\n/**\n * Mid-drain mirror refresh cadence. Coarse because a refresh flushes acks and\n * costs an inventory round trip, both on the drain's critical path. It shipped\n * at 750 ms first, which is SHORTER than the ~1 s a token takes, so the throttle\n * never throttled: every token paid for one and a 54-token receive stretched to\n * ~58 s. Any value below the per-token cost has that effect.\n */\nexport const REFRESH_INTERVAL_MS = 2500;\nexport const POLL_INTERVAL_MS = 30_000;\nexport const ATTENTION_CLAIM_CONFLICT = 'claim:conflict';\n\nexport function receivedDedupKey(tokenId: string, stateHash: string): string {\n // Lowercased like History's keys — a case-variant would defeat server dedup.\n return `RECEIVED:${tokenId.toLowerCase()}:${stateHash.toLowerCase()}`;\n}\n\ninterface PendingAck {\n readonly deliveryId: string;\n readonly disposition: 'claimed' | 'rejected';\n readonly reason?: 'invalid' | 'not-owned' | 'other';\n readonly cursor: string;\n readonly transferId?: string;\n}\n\ntype Screened = { kind: 'ack'; ack: PendingAck } | { kind: 'accept'; record: StoredIncoming };\n\n/** The mutable state one listing pass threads through (max-params ≤ 5). */\ninterface DrainPass {\n readonly deps: ReceiveDeps;\n readonly engine: ReceiveEngine;\n readonly pending: PendingAck[];\n readonly stored: IncomingTransfer[];\n readonly pageEpoch: () => string;\n /** Entries this drain made claimable — stored, or a held-state claim retry. */\n readonly claimable: { n: number };\n}\n\nfunction isClaimConflict(err: unknown): boolean {\n const e = err !== null && typeof err === 'object' ? (err as { code?: unknown; failureCode?: unknown }) : null;\n return e !== null && e.code === 'MAILBOX_CLAIM_FAILED' && e.failureCode === 'CONFLICT';\n}\n\nexport class Receive {\n private readonly drainFlight = new SingleFlight<IncomingTransfer[]>();\n private pollTimer: ReturnType<typeof setInterval> | null = null;\n private unsubscribeWake: (() => void) | null = null;\n private lastRefreshAt = 0;\n\n constructor(private readonly deps: ReceiveDeps) {}\n\n drainOnce(): Promise<IncomingTransfer[]> {\n return this.drainFlight.run(() => this.doDrain());\n }\n\n start(pollIntervalMs: number = POLL_INTERVAL_MS): void {\n this.unsubscribeWake ??= this.deps.delivery.onWake?.(() => this.spawnDrain()) ?? null;\n this.pollTimer ??= setInterval(() => this.spawnDrain(), pollIntervalMs);\n }\n\n private spawnDrain(): void {\n const op = this.drainOnce();\n if (this.deps.track !== undefined) this.deps.track(op);\n else void op;\n }\n\n stop(): void {\n if (this.pollTimer !== null) clearInterval(this.pollTimer);\n this.pollTimer = null;\n this.unsubscribeWake?.();\n this.unsubscribeWake = null;\n }\n\n /**\n * Flush what has been accepted, then ask for a mirror refresh — at most once\n * per REFRESH_INTERVAL_MS.\n *\n * The flush is not incidental. A `claimed` ack is what materializes a token\n * into SERVER inventory, and acks otherwise sit queued until ACK_BATCH_SIZE\n * (200) — so for any ordinary drain, including the 54-token case this exists\n * for, refreshing before the flush would query an inventory holding none of\n * the tokens just accepted, and the balance would still only move at the end.\n * Ordering is preserved: store() still precedes the ack (§5.7).\n */\n private async maybeRefresh(ctx: DrainPass): Promise<void> {\n const { deps, pending, pageEpoch } = ctx;\n if (deps.refreshView === undefined) return;\n const now = deps.now?.() ?? Date.now();\n if (now - this.lastRefreshAt < REFRESH_INTERVAL_MS) return;\n this.lastRefreshAt = now;\n // A blocked flush materialized nothing, so the delta would show today's balance.\n if ((await flushAcks(deps, pending, pageEpoch)).progressed) deps.refreshView();\n }\n\n /** One listing pass: process each entry, flushing and refreshing as it goes. */\n private async drainPages(ctx: DrainPass, basis: StreamCursor | null): Promise<void> {\n const { deps, pending, pageEpoch, claimable } = ctx;\n for await (const entry of deps.delivery.incoming(basis === null ? undefined : String(basis.cursor))) {\n const claimableBefore = claimable.n;\n await this.processEntry(ctx, entry);\n if (pending.length >= ACK_BATCH_SIZE) {\n // Nothing settled = the head is blocked; continuing re-flushes it once per\n // remaining entry, amplifying one failure into hundreds.\n if (!(await flushAcks(deps, pending, pageEpoch)).progressed) return;\n }\n // Only when THIS entry entered the balance: a rejected one changes nothing.\n // Keyed on claimable, not stored — a held-state RETRY claims without storing,\n // and a long retry drain is the frozen balance this PR exists to fix.\n if (claimable.n > claimableBefore) await this.maybeRefresh(ctx);\n }\n await flushAcks(deps, pending, pageEpoch);\n }\n\n private async doDrain(): Promise<IncomingTransfer[]> {\n const deps = this.deps;\n // Clock starts at the drain: one finishing inside an interval refreshes once,\n // at the end, exactly as before. Only a slow drain pays for mid-flight ones.\n this.lastRefreshAt = deps.now?.() ?? Date.now();\n const engine = deps.engine();\n const stored: IncomingTransfer[] = [];\n const pending: PendingAck[] = [];\n // The port's page epoch is the honest source for the persisted record.\n const pageEpoch = (): string => deps.delivery.incomingEpoch() ?? deps.syncEpoch();\n // Every exit refreshes (automatic drains never call receive(), and the §5.7\n // wake is best-effort), counted where the entry becomes claimable — every\n // downstream proxy had a path that destroyed it.\n const claimable = { n: 0 };\n const finish = (): IncomingTransfer[] => {\n if (claimable.n > 0) deps.refreshView?.();\n return stored;\n };\n try {\n const record = await deps.kv.get<StreamCursor>(STORE_KEYS.streamCursor('mailbox'));\n // Cursor continuity holds only within one syncEpoch (§6); the session\n // latch gates the resume decision.\n let basis = record !== null && record.syncEpoch === deps.syncEpoch() ? record : null;\n for (let pass = 0; pass < 2; pass++) {\n await this.drainPages({ deps, engine, pending, stored, pageEpoch, claimable }, basis);\n const served = deps.delivery.incomingEpoch();\n if (basis === null || served === null || served === basis.syncEpoch) break;\n // §5.7 restore self-detection: the page reports a different epoch than\n // the cursor record's — post-restore seqs restart, so the resumed\n // listing may have SKIPPED entries. Void the continuity record and\n // re-list from the start (dedup: seen-set + (tokenId, stateHash)).\n await deps.kv.remove(STORE_KEYS.streamCursor('mailbox'));\n basis = null;\n }\n } catch (err) {\n // Infra failure (engine/blob/view/ack): the failed entry stays UNACKED and\n // re-lists next drain; the fully-processed prefix still flushes below.\n logger.warn('PaymentsV2', 'receive drain interrupted — unacked entries retry next drain:', err);\n // Retryable = the wall is still up; re-flushing spends another slot. Exits\n // via finish() because ackBatch kept its committed chunks, which never re-list.\n if (isRetryableAckError(err)) return finish();\n await flushAcks(deps, pending, pageEpoch).catch((flushErr: unknown) => {\n logger.warn('PaymentsV2', 'receive ack flush failed — cursor holds at the acked prefix:', flushErr);\n return { progressed: false };\n });\n }\n return finish();\n }\n\n private async processEntry(ctx: DrainPass, entry: IncomingDelivery): Promise<void> {\n const { deps, engine, pending, stored, claimable } = ctx;\n const screened = await screen(deps, engine, entry);\n if (screened.kind === 'ack') {\n pending.push(screened.ack);\n // A held-state re-list is the retry after a failed ack: nothing to store,\n // but it still materializes server-side.\n if (screened.ack.disposition === 'claimed') claimable.n += 1;\n return;\n }\n await deps.view.store(screened.record);\n pending.push(claimAck(entry));\n claimable.n += 1;\n const transfer = await announce(deps, entry, screened.record);\n stored.push(transfer);\n deps.emit('transfer:incoming', transfer);\n }\n}\n\nasync function screen(deps: ReceiveDeps, engine: ReceiveEngine, entry: IncomingDelivery): Promise<Screened> {\n const blobBytes = await entry.fetchBlob();\n let token: SphereToken;\n try {\n token = await engine.decodeToken({ tokenId: '', token: blobBytes });\n } catch (err) {\n logger.warn('PaymentsV2', `receive: undecodable blob rejected — ${String(err)}`);\n return { kind: 'ack', ack: rejectAck(entry, 'invalid') };\n }\n const verdict = await engine.verify(token);\n if (!verdict.ok) return { kind: 'ack', ack: rejectAck(entry, 'invalid') };\n if (!engine.isOwnedBy(token, engine.getIdentity().chainPubkey)) {\n return { kind: 'ack', ack: rejectAck(entry, 'not-owned') };\n }\n const keys = await engine.deliveryKeys(blobBytes);\n const held = deps.view.heldState(keys.tokenId);\n if (held === keys.stateHash) return { kind: 'ack', ack: claimAck(entry) };\n if (held !== null && (await engine.isSpent(token))) {\n // #687 gate: a replayed OLDER, already-spent state never displaces the live one.\n return { kind: 'ack', ack: rejectAck(entry, 'invalid') };\n }\n return {\n kind: 'accept',\n record: {\n tokenId: keys.tokenId,\n stateHash: keys.stateHash,\n assets: toAssetAmounts(token),\n ...(isCoinlessEnvelope(token.valueEnvelope) ? { tokenType: token.tokenType } : {}),\n },\n };\n}\n\nasync function announce(\n deps: ReceiveDeps,\n entry: IncomingDelivery,\n record: StoredIncoming\n): Promise<IncomingTransfer> {\n const receivedAt = (deps.now ?? Date.now)();\n try {\n await deps.recordReceived({\n dedupKey: receivedDedupKey(record.tokenId, record.stateHash),\n tokenId: record.tokenId,\n stateHash: record.stateHash,\n assets: record.assets,\n ...(record.tokenType !== undefined ? { tokenType: record.tokenType } : {}),\n ...(entry.senderPubkey !== undefined ? { senderPubkey: entry.senderPubkey } : {}),\n ...(entry.senderNametag !== undefined ? { senderNametag: entry.senderNametag } : {}),\n ...(entry.memo !== undefined ? { memo: entry.memo } : {}),\n receivedAt,\n });\n } catch (err) {\n // §5.9: the history hook never fails the money path.\n logger.debug('PaymentsV2', 'RECEIVED history hook failed (money path unaffected):', err);\n }\n return {\n id: record.tokenId,\n senderPubkey: entry.senderPubkey ?? '',\n ...(entry.senderNametag !== undefined ? { senderNametag: entry.senderNametag } : {}),\n tokens: record.assets.map((asset) => toUiToken(record.tokenId, asset, deps.registry, receivedAt)),\n // #777: named here rather than mapped from assets, which announced an EMPTY list.\n ...(record.tokenType !== undefined\n ? {\n coinless: [\n {\n tokenId: record.tokenId,\n tokenType: record.tokenType,\n stateHash: record.stateHash,\n transferring: false,\n createdAt: receivedAt,\n updatedAt: receivedAt,\n },\n ],\n }\n : {}),\n ...(entry.memo !== undefined ? { memo: entry.memo } : {}),\n receivedAt,\n };\n}\n\n/** Cursor reaches only the last CONSECUTIVE success. progressed=false means nothing settled. */\nasync function flushAcks(\n deps: ReceiveDeps,\n pending: PendingAck[],\n epochOf: () => string\n): Promise<{ progressed: boolean }> {\n if (pending.length === 0) return { progressed: true };\n const before = pending.length;\n let lastAcked: string | null = null;\n try {\n const settled = await settleAcks(deps, pending);\n let i = 0;\n while (i < pending.length && settled.has(pending[i].deliveryId)) {\n lastAcked = pending[i].cursor;\n i += 1;\n }\n // Drop every settled entry, not just the prefix: a later flush must never\n // re-ack one that already settled.\n const stuck = pending.filter((p) => !settled.has(p.deliveryId));\n pending.length = 0;\n pending.push(...stuck);\n } finally {\n if (lastAcked !== null) {\n const record: StreamCursor = { cursor: lastAcked, syncEpoch: epochOf() };\n await deps.kv.set(STORE_KEYS.streamCursor('mailbox'), record);\n }\n }\n return { progressed: pending.length < before };\n}\n\n/** Batched when the port offers it, one at a time otherwise; never reorders `pending`. */\nasync function settleAcks(deps: ReceiveDeps, pending: readonly PendingAck[]): Promise<Set<string>> {\n const batch = deps.delivery.ackBatch?.bind(deps.delivery);\n if (batch === undefined) return settleOneByOne(deps, pending);\n let outcomes: readonly AckOutcome[];\n try {\n outcomes = await batch(pending.map(toAckRequest));\n } catch (err) {\n // A wall a per-entry retry would hit too (429, outage): falling back turns\n // one transient failure into N of them.\n if (isRetryableAckError(err)) throw err;\n logger.warn('PaymentsV2', 'batched mailbox ack failed — settling one at a time:', err);\n return settleOneByOne(deps, pending);\n }\n const settled = new Set(outcomes.filter((o) => o.status === 'settled').map((o) => o.deliveryId));\n const conflicts = outcomes.filter((o) => o.status === 'conflict').map((o) => o.deliveryId);\n if (conflicts.length > 0) await resolveConflicts(deps, pending, conflicts, settled);\n return settled;\n}\n\n/** Settled only once its reject succeeded, so a failed reject holds the cursor. */\nasync function resolveConflicts(\n deps: ReceiveDeps,\n pending: readonly PendingAck[],\n conflicts: readonly string[],\n settled: Set<string>\n): Promise<void> {\n for (const deliveryId of conflicts) {\n const entry = pending.find((p) => p.deliveryId === deliveryId);\n try {\n await rejectStaleClaim(deps, deliveryId, entry?.transferId);\n } catch (err) {\n logger.warn('PaymentsV2', `stale-reject failed for ${deliveryId} — cursor holds here:`, err);\n continue;\n }\n settled.add(deliveryId);\n }\n}\n\n/** §5.7: a stale claim is terminal for discovery, or the entry re-processes forever. */\nasync function rejectStaleClaim(deps: ReceiveDeps, deliveryId: string, transferId?: string): Promise<void> {\n logger.warn('PaymentsV2', `mailbox claim CONFLICT for ${deliveryId} — rejected('other') as stale`);\n await deps.delivery.ack(deliveryId, 'rejected', 'other');\n deps.attention(transferId ?? '', ATTENTION_CLAIM_CONFLICT, deliveryId);\n}\n\n/** Today's loop, in seq order, stopping at the first failure. */\nasync function settleOneByOne(deps: ReceiveDeps, pending: readonly PendingAck[]): Promise<Set<string>> {\n const settled = new Set<string>();\n for (const ack of pending) {\n try {\n await ackOne(deps, ack);\n } catch (err) {\n logger.warn('PaymentsV2', `mailbox ack failed for ${ack.deliveryId} — cursor holds here:`, err);\n break;\n }\n settled.add(ack.deliveryId);\n }\n return settled;\n}\n\nfunction toAckRequest(ack: PendingAck): AckRequest {\n return {\n deliveryId: ack.deliveryId,\n disposition: ack.disposition,\n ...(ack.reason !== undefined ? { reason: ack.reason } : {}),\n };\n}\n\nasync function ackOne(deps: ReceiveDeps, ack: PendingAck): Promise<void> {\n try {\n await deps.delivery.ack(ack.deliveryId, ack.disposition, ack.reason);\n } catch (err) {\n if (ack.disposition !== 'claimed' || !isClaimConflict(err)) throw err;\n await rejectStaleClaim(deps, ack.deliveryId, ack.transferId);\n }\n}\n\nfunction claimAck(entry: IncomingDelivery): PendingAck {\n return {\n deliveryId: entry.deliveryId,\n disposition: 'claimed',\n cursor: entry.cursor,\n ...(entry.transferId !== undefined ? { transferId: entry.transferId } : {}),\n };\n}\n\nfunction rejectAck(entry: IncomingDelivery, reason: 'invalid' | 'not-owned'): PendingAck {\n return { deliveryId: entry.deliveryId, disposition: 'rejected', reason, cursor: entry.cursor };\n}\n\n\nfunction toAssetAmounts(token: SphereToken): IncomingAssetAmount[] {\n return (token.value?.assets ?? []).map((asset) => ({\n coinId: asset.coinId,\n amount: asset.amount.toString(),\n }));\n}\n\nfunction toUiToken(\n tokenId: string,\n asset: IncomingAssetAmount,\n registry: RegistryReader,\n receivedAt: number\n): Token {\n const iconUrl = registry.getIconUrl(asset.coinId);\n return {\n id: tokenId,\n coinId: asset.coinId,\n symbol: registry.getSymbol(asset.coinId),\n name: registry.getName(asset.coinId),\n decimals: registry.getDecimals(asset.coinId),\n ...(iconUrl !== null ? { iconUrl } : {}),\n amount: asset.amount,\n status: 'confirmed',\n createdAt: receivedAt,\n updatedAt: receivedAt,\n lazy: true,\n };\n}\n","// §5.8 of docs/PAYMENTS-V2-DESIGN.md — the incoming payment-request mirror\n// over the wallet-api `?since=` stream, plus the #441 settling journal\n// (verbatim semantics: durable link BEFORE any possibly-committed throw\n// surfaces; direction of error is always PAID-NEVER-RE-PAYABLE).\n\nimport { logger } from '../../../core/logger';\nimport {\n SphereError,\n PartialSendConflictError,\n isPossiblyCommittedSendOutcome,\n} from '../../../core/errors';\nimport type { TransferResult } from '../../../types';\nimport type {\n PaymentRequestStatus,\n PaymentRequestView,\n PaymentsRequestsApi,\n PaymentsV2Events,\n SendRequest,\n} from '../api';\nimport { SerialChain, SingleFlight } from '../async';\nimport { STORE_KEYS, type ScopedKV, type SettlingLink, type StreamCursor } from '../stores';\n\nexport type RequestWireStatus = 'open' | 'paid' | 'declined' | 'expired';\n\nexport interface RequestWire {\n readonly id: string;\n readonly seq: number;\n readonly fromPubkey: string;\n readonly toPubkey: string;\n readonly assets: readonly { readonly coinId: string; readonly amount: string }[];\n readonly memo?: string;\n readonly status: RequestWireStatus;\n readonly transferId: string | null;\n readonly createdAt: string;\n readonly expiresAt?: string;\n}\n\nexport interface RequestsPageWire {\n readonly requests: readonly RequestWire[];\n readonly more: boolean;\n readonly cursor: number | string | null;\n readonly syncEpoch: number;\n}\n\n// Structural subset of WalletApiV2Client — the real client is assignable.\nexport interface RequestsWireClient {\n createPaymentRequest(input: {\n toPubkey: string;\n assets: { coinId: string; amount: string }[];\n memo?: string;\n expiresAt?: string;\n }): Promise<RequestWire>;\n listPaymentRequests(params: { role: 'incoming'; since?: number }): Promise<RequestsPageWire>;\n respondPaymentRequest(\n id: string,\n response: { action: 'paid'; transferId: string } | { action: 'declined' }\n ): Promise<RequestWire>;\n}\n\n// Recipient-ECDH bundle codec (core/delivery-envelope.ts, shared with Delivery).\nexport interface RequestMemoCodec {\n encrypt(peerPubkey: string, bundle: { memo?: string; senderNametag?: string }): string | undefined;\n decrypt(peerPubkey: string, envelope: string): { memo?: string; senderNametag?: string };\n}\n\nexport type RequestsEmit = <K extends 'payment_request:incoming' | 'payment_request:updated'>(\n event: K,\n payload: PaymentsV2Events[K]\n) => void;\n\nexport interface RequestsDeps {\n readonly client: RequestsWireClient;\n readonly kv: ScopedKV;\n readonly ownPubkey: string;\n readonly send: (request: SendRequest) => Promise<TransferResult>;\n readonly resolvePubkey: (identifier: string) => Promise<string | null>;\n // Server `listIntents('aborted')` authority for unaccounted settling links.\n readonly listAbortedTransferIds: () => Promise<string[]>;\n readonly emit: RequestsEmit;\n readonly memo: RequestMemoCodec;\n readonly ownNametag?: () => string | undefined;\n readonly now?: () => number;\n}\n\n// Resume outcomes keyed by transferId (§5.8 reconcile).\nexport interface ResumeOutcomes {\n readonly resumed: readonly string[];\n readonly conflicted: readonly string[];\n readonly open: readonly string[];\n}\n\nconst WIRE_STATUS: Record<RequestWireStatus, PaymentRequestStatus> = {\n open: 'pending',\n paid: 'paid',\n declined: 'rejected',\n expired: 'expired',\n};\n\nconst TERMINAL: ReadonlySet<PaymentRequestStatus> = new Set(['paid', 'rejected', 'expired']);\n\nconst MAX_HYDRATION_PAGES = 100;\nconst CHAIN_PUBKEY_RE = /^0[23][0-9a-fA-F]{64}$/;\nconst CURSOR_KEY = STORE_KEYS.streamCursor('payment_requests');\n\nfunction isConflict409(err: unknown): boolean {\n if (typeof err !== 'object' || err === null) return false;\n const e = err as { status?: unknown; statusCode?: unknown; code?: unknown };\n return e.status === 409 || e.statusCode === 409 || e.code === 'CONFLICT';\n}\n\nexport class Requests implements PaymentsRequestsApi {\n private readonly mirror = new Map<string, PaymentRequestView>();\n private hydrated = false;\n private readonly drainFlight = new SingleFlight<void>();\n\n private journal: Map<string, SettlingLink> | null = null;\n private journalLoad: Promise<void> | null = null;\n private readonly journalChain = new SerialChain();\n\n private readonly payInFlight = new Map<string, Promise<TransferResult>>();\n private readonly reconcileFlight = new SingleFlight<void>();\n\n constructor(private readonly deps: RequestsDeps) {}\n\n private now(): number {\n return this.deps.now?.() ?? Date.now();\n }\n\n // ── settling journal (#441; single-flight load, serialized RMW) ──────────\n\n private ensureJournalLoaded(): Promise<void> {\n return (this.journalLoad ??= (async () => {\n let entries: [string, SettlingLink][] = [];\n try {\n const raw = await this.deps.kv.get<Record<string, SettlingLink>>(STORE_KEYS.settlingLinks);\n if (raw !== null && typeof raw === 'object') entries = Object.entries(raw);\n } catch (err) {\n // Corrupt blob: fail OPEN to empty (never wedge the pump/resume).\n logger.error('PaymentsV2', 'Settling journal unreadable — failing open to empty:', err);\n }\n this.journal = new Map(entries);\n })());\n }\n\n private mutateJournal(fn: (m: Map<string, SettlingLink>) => boolean): Promise<void> {\n return this.journalChain.enqueue(async () => {\n await this.ensureJournalLoaded();\n if (fn(this.journal!)) {\n await this.deps.kv.set(STORE_KEYS.settlingLinks, Object.fromEntries(this.journal!));\n }\n });\n }\n\n /** Idempotent for a same-transferId re-write: committed only ratchets up, createdAt kept. */\n private writeLink(requestId: string, transferId: string, committed: boolean): Promise<void> {\n return this.mutateJournal((m) => {\n const prev = m.get(requestId);\n const same = prev !== undefined && prev.transferId === transferId;\n const next: SettlingLink = {\n requestId,\n transferId,\n committed: committed || (same && prev.committed),\n createdAt: same ? prev.createdAt : this.now(),\n };\n if (same && prev.committed === next.committed) return false;\n m.set(requestId, next);\n return true;\n });\n }\n\n private clearLink(requestId: string): Promise<void> {\n return this.mutateJournal((m) => m.delete(requestId));\n }\n\n // ── incoming stream (gap-free ?since= upsert-by-id) ──────────────────────\n\n drainIncoming(): Promise<void> {\n return this.drainFlight.run(() => this.doDrain());\n }\n\n private async doDrain(): Promise<void> {\n // Journal must be in memory BEFORE any wire surfaces (settling hold).\n await this.ensureJournalLoaded();\n const persisted = await this.deps.kv.get<StreamCursor>(CURSOR_KEY);\n\n if (!this.hydrated) {\n // Fresh instance: the mirror is memory-only, rebuild ALL current state\n // from since=0 (open AND resolved), bounded pages; id-dedup absorbs replays.\n let page = await this.deps.client.listPaymentRequests({ role: 'incoming', since: 0 });\n for (let i = 0; i < MAX_HYDRATION_PAGES; i++) {\n for (const wire of page.requests) this.surface(wire);\n if (!page.more || typeof page.cursor !== 'number') break;\n page = await this.deps.client.listPaymentRequests({ role: 'incoming', since: page.cursor });\n }\n this.hydrated = true;\n }\n\n let since = typeof persisted?.cursor === 'number' ? persisted.cursor : 0;\n let page = await this.deps.client.listPaymentRequests({ role: 'incoming', since });\n if (persisted !== null && String(page.syncEpoch) !== persisted.syncEpoch) {\n since = 0; // epoch changed (server restore) — cursor continuity is void\n page = await this.deps.client.listPaymentRequests({ role: 'incoming', since: 0 });\n }\n for (;;) {\n for (const wire of page.requests) this.surface(wire);\n const record: StreamCursor = {\n cursor: typeof page.cursor === 'number' ? page.cursor : since,\n syncEpoch: String(page.syncEpoch),\n };\n await this.deps.kv.set(CURSOR_KEY, record);\n if (!page.more || typeof page.cursor !== 'number') break;\n since = page.cursor;\n page = await this.deps.client.listPaymentRequests({ role: 'incoming', since });\n }\n }\n\n private surface(wire: RequestWire): void {\n if (wire.toPubkey !== this.deps.ownPubkey) {\n logger.warn('PaymentsV2', `payment request ${wire.id.slice(0, 12)}… addressed to a different owner — dropped`);\n return;\n }\n\n let status = WIRE_STATUS[wire.status];\n const link = this.journal?.get(wire.id);\n if (link !== undefined) {\n if (wire.status === 'open') {\n status = 'settling'; // live link holds the request non-payable\n } else {\n // Server already resolved — the deferred tell landed elsewhere; drop the stale link.\n void this.clearLink(wire.id).catch((err) =>\n logger.warn('PaymentsV2', `failed to clear stale settling link for ${wire.id}:`, err)\n );\n }\n }\n\n const existing = this.mirror.get(wire.id);\n if (existing !== undefined) {\n // Upsert: advance INTO a terminal state, never out of one; never re-notify.\n if (TERMINAL.has(status) && !TERMINAL.has(existing.status)) this.setStatus(wire.id, status);\n return;\n }\n\n const bundle = this.decryptMemo(wire);\n const view: PaymentRequestView = {\n id: wire.id,\n requestId: wire.id,\n senderPubkey: wire.fromPubkey,\n ...(bundle.senderNametag !== undefined ? { senderNametag: bundle.senderNametag } : {}),\n amount: wire.assets[0]?.amount ?? '0',\n coinId: wire.assets[0]?.coinId ?? '',\n ...(bundle.memo !== undefined ? { message: bundle.memo } : {}),\n timestamp: Date.parse(wire.createdAt),\n status,\n };\n this.mirror.set(wire.id, view);\n if (status === 'pending') this.deps.emit('payment_request:incoming', { ...view });\n }\n\n private decryptMemo(wire: RequestWire): { memo?: string; senderNametag?: string } {\n if (wire.memo === undefined) return {};\n try {\n return this.deps.memo.decrypt(wire.fromPubkey, wire.memo);\n } catch {\n logger.debug('PaymentsV2', `payment request ${wire.id.slice(0, 12)}… memo not decryptable here`);\n return {};\n }\n }\n\n private setStatus(id: string, status: PaymentRequestStatus): void {\n const entry = this.mirror.get(id);\n if (entry === undefined || entry.status === status) return;\n entry.status = status;\n this.deps.emit('payment_request:updated', { id, status });\n }\n\n // ── public surface (PaymentsRequestsApi) ─────────────────────────────────\n\n list(): PaymentRequestView[] {\n const views = [...this.mirror.values()].map((entry) => ({\n ...entry,\n // A live settling link is NEVER payable, whatever the mirror says.\n status:\n entry.status === 'pending' && this.journal?.has(entry.id) ? ('settling' as const) : entry.status,\n }));\n return views.sort((a, b) => b.timestamp - a.timestamp || (a.id < b.id ? -1 : 1));\n }\n\n async create(\n to: string,\n terms: { coinId: string; amount: string; memo?: string }\n ): Promise<{ success: boolean; requestId?: string; error?: string }> {\n try {\n const toPubkey = CHAIN_PUBKEY_RE.test(to) ? to.toLowerCase() : await this.deps.resolvePubkey(to);\n if (toPubkey === null || toPubkey === undefined) {\n return { success: false, error: `Recipient ${to} has no published chain pubkey` };\n }\n const amount = BigInt(terms.amount);\n if (amount <= 0n) return { success: false, error: 'Amount must be a positive base-unit decimal string' };\n const senderNametag = this.deps.ownNametag?.();\n const envelope = this.deps.memo.encrypt(toPubkey, {\n ...(terms.memo !== undefined ? { memo: terms.memo } : {}),\n ...(senderNametag !== undefined ? { senderNametag } : {}),\n });\n const wire = await this.deps.client.createPaymentRequest({\n toPubkey,\n assets: [{ coinId: terms.coinId, amount: amount.toString() }],\n ...(envelope !== undefined ? { memo: envelope } : {}),\n });\n return { success: true, requestId: wire.id };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n }\n\n pay(id: string): Promise<TransferResult> {\n // Per-request single-flight: a double-tap coalesces onto ONE send.\n const inFlight = this.payInFlight.get(id);\n if (inFlight !== undefined) return inFlight;\n const run = this.payInner(id).finally(() => {\n this.payInFlight.delete(id);\n });\n this.payInFlight.set(id, run);\n return run;\n }\n\n private async payInner(id: string): Promise<TransferResult> {\n await this.ensureJournalLoaded();\n const entry = this.mirror.get(id);\n if (entry === undefined) throw new SphereError(`Payment request not found: ${id}`, 'VALIDATION_ERROR');\n if (entry.status !== 'pending' || this.journal!.has(id)) {\n throw new SphereError(`Payment request is not payable: ${entry.status}`, 'VALIDATION_ERROR');\n }\n\n let result: TransferResult;\n try {\n result = await this.deps.send({\n recipient: entry.senderPubkey,\n amount: entry.amount,\n coinId: entry.coinId,\n ...(entry.message !== undefined ? { memo: entry.message } : {}),\n });\n } catch (error) {\n if (isPossiblyCommittedSendOutcome(error)) {\n const transferId =\n error instanceof SphereError && error.transferId !== undefined ? error.transferId : undefined;\n if (transferId !== undefined) {\n // Outcome unknown — link + 'settling', respond deferred to reconcile.\n const committed = error instanceof PartialSendConflictError;\n await this.settle(id, transferId, { committed, respond: false });\n } else {\n logger.error('PaymentsV2', `possibly-committed send for ${id} carried no transferId — paid (fail-closed)`);\n this.setStatus(id, 'paid');\n }\n } else {\n // Proven clean pre-commit failure — removal cause (b): payable, no link.\n await this.revertPayable(id);\n }\n throw error;\n }\n\n await this.settle(id, result.id, { committed: true, respond: true });\n return result;\n }\n\n /**\n * THE settlement invariant (#441 + the failed-respond P1): a settling link is\n * removed ONLY by (a) a CONFIRMED paid respond — a 2xx, or the 409\n * already-resolved absorb — or (b) a proven clean pre-commit failure\n * (revertPayable). Nothing else removes one: not a network error, not a 5xx,\n * not a reload. Every path that binds a request to a transfer outcome funnels\n * through here — pay()'s clean success (respond now), pay()'s\n * possibly-committed throw (respond deferred), and reconcile's deferred arms\n * — so a failed respond always leaves the link + 'settling' and the next\n * reconcile pass (the committed-link override) retries the respond.\n */\n private async settle(\n requestId: string,\n transferId: string,\n opts: { committed: boolean; respond: boolean }\n ): Promise<void> {\n // #441 — order is load-bearing: durable link BEFORE any flip, respond, or\n // rethrow. A crash in between leaves the link, so reload re-applies\n // 'settling', never re-payable.\n let journalDown = false;\n try {\n await this.writeLink(requestId, transferId, opts.committed);\n } catch (err) {\n if (!opts.respond) throw err; // deferred-respond arm: the link IS the outcome\n // Respond-now arm fails CLOSED on a dead journal: the server record\n // becomes the anchor — never leave a completed send re-payable silently.\n journalDown = true;\n logger.error('PaymentsV2', `settling link write failed for ${requestId} — responding fail-closed:`, err);\n }\n if (!(opts.respond && (await this.respondPaid(requestId, transferId)))) {\n this.setStatus(requestId, journalDown ? 'paid' : 'settling');\n return;\n }\n // A failed removal is safe (paid-never-re-payable holds); surface() drops\n // the stale link once the wire shows the terminal state.\n if (!journalDown) await this.clearLink(requestId).catch(() => undefined);\n this.setStatus(requestId, 'paid');\n }\n\n /** 'paid' respond leg: 409 = already resolved = idempotent success; other errors defer. */\n private async respondPaid(id: string, transferId: string): Promise<boolean> {\n try {\n await this.deps.client.respondPaymentRequest(id, { action: 'paid', transferId });\n return true;\n } catch (err) {\n if (isConflict409(err)) return true;\n logger.warn('PaymentsV2', `paid respond failed for ${id} (deferred):`, err);\n return false;\n }\n }\n\n async decline(id: string): Promise<void> {\n const entry = this.mirror.get(id);\n if (entry === undefined) throw new SphereError(`Payment request not found: ${id}`, 'VALIDATION_ERROR');\n // A refused decline must never look like success — server 403/409 PROPAGATE.\n await this.deps.client.respondPaymentRequest(id, { action: 'declined' });\n this.setStatus(id, 'rejected');\n }\n\n dismissProcessed(): void {\n for (const [id, entry] of this.mirror) {\n if (TERMINAL.has(entry.status)) this.mirror.delete(id);\n }\n }\n\n // ── reconcile (#441, fed by resume outcomes) ─────────────────────────────\n\n reconcile(outcomes: ResumeOutcomes): Promise<void> {\n // Single-flight (§7: no sampled *InFlight booleans) — a concurrent call\n // coalesces onto the running pass instead of racing the journal.\n return this.reconcileFlight.run(() => this.doReconcile(outcomes));\n }\n\n private async doReconcile(outcomes: ResumeOutcomes): Promise<void> {\n await this.ensureJournalLoaded();\n if (this.journal!.size === 0) return;\n const resumed = new Set(outcomes.resumed);\n const conflicted = new Set(outcomes.conflicted);\n const open = new Set(outcomes.open);\n let aborted: Set<string> | null = null;\n\n for (const [requestId, link] of [...this.journal!]) {\n if (link.committed || resumed.has(link.transferId)) {\n // Value left the wallet (or the transfer completed) → deferred paid.\n await this.resolvePaid(requestId, link);\n } else if (conflicted.has(link.transferId)) {\n await this.revertPayable(requestId);\n } else if (open.has(link.transferId)) {\n // Still settling — keep the link, retry next session.\n } else {\n aborted = await this.reconcileUnaccounted(requestId, link, aborted);\n }\n }\n }\n\n // Unaccounted link: consult the server aborted authority (lazy, memoized);\n // a probe failure defers the link to the next session.\n private async reconcileUnaccounted(\n requestId: string,\n link: SettlingLink,\n aborted: Set<string> | null\n ): Promise<Set<string> | null> {\n try {\n aborted ??= new Set(await this.deps.listAbortedTransferIds());\n if (aborted.has(link.transferId)) await this.revertPayable(requestId);\n else await this.resolvePaid(requestId, link); // PAID-NEVER-RE-PAYABLE\n } catch (err) {\n logger.warn('PaymentsV2', `aborted-intent probe failed — ${requestId} deferred:`, err);\n }\n return aborted;\n }\n\n /** Deferred paid: the ONE settlement path again — a failed respond keeps the link. */\n private resolvePaid(requestId: string, link: SettlingLink): Promise<void> {\n return this.settle(requestId, link.transferId, { committed: link.committed, respond: true });\n }\n\n /** Removal cause (b): a PROVEN clean outcome (pre-commit failure / server-aborted). */\n private async revertPayable(requestId: string): Promise<void> {\n await this.clearLink(requestId);\n this.setStatus(requestId, 'pending');\n }\n}\n","// §5.6/§6 durable machine stores over ScopedKV: content-idempotent saves keyed\n// by (transferId, opIndex), one serialized RMW tail-chain per (kv, store key),\n// and the bounded delivery replay (#621) with 429 deferrals outside the poison\n// budget (#517).\n\nimport { hexToBytes } from '../../../core/crypto';\nimport { SerialChain, SingleFlight } from '../async';\nimport type { DeliveryPort } from '../ports';\nimport {\n STORE_KEYS,\n type DeliveryJournalEntry,\n type IntentBackstopEntry,\n type MintJournalEntry,\n type NftMintJournalEntry,\n type ScopedKV,\n type ShortfallEntry,\n} from '../stores';\n\nexport const MAX_DELIVERY_ATTEMPTS = 6;\nexport const RATE_LIMIT_DEFER_MS = 30_000;\n\nexport const ATTENTION_DELIVERY_DEFERRED = 'delivery:deferred';\nexport const ATTENTION_DELIVERY_UNDELIVERABLE = 'delivery:undeliverable';\nexport const ATTENTION_CHECKPOINT_STUCK = 'split:checkpoint-stuck';\nexport const ATTENTION_SYNC_PENDING = 'sync:pending';\n\nexport type AttentionEmitter = (transferId: string, code: string, detail?: string) => void;\n\ninterface WireErrorShape {\n status?: unknown;\n statusCode?: unknown;\n code?: unknown;\n}\n\nfunction wireShape(err: unknown): WireErrorShape | null {\n return err !== null && typeof err === 'object' ? (err as WireErrorShape) : null;\n}\n\nexport function isRateLimited(err: unknown): boolean {\n const e = wireShape(err);\n if (e === null) return false;\n return e.status === 429 || e.statusCode === 429 || e.code === 'QUOTA_EXCEEDED' || e.code === 'RATE_LIMITED';\n}\n\nexport function isValidationReject(err: unknown): boolean {\n const e = wireShape(err);\n if (e === null) return false;\n return e.status === 422 || e.statusCode === 422 || e.code === 'VALIDATION' || e.code === 'VALIDATION_FAILED';\n}\n\n/**\n * Duck-typed `WalletApiHttpError.retryAfter` (milliseconds) — modules never\n * import from impl/, so the heartbeat honors the header structurally.\n */\nexport function retryAfterMsOf(err: unknown): number | null {\n const retryAfter =\n err !== null && typeof err === 'object' ? (err as { retryAfter?: unknown }).retryAfter : undefined;\n return typeof retryAfter === 'number' && Number.isFinite(retryAfter) && retryAfter >= 0 ? retryAfter : null;\n}\n\n// Registered per (kv, store key) so EVERY store instance over the same\n// ScopedKV serializes its read-modify-writes with every other instance.\nconst chainRegistry = new WeakMap<ScopedKV, Map<string, SerialChain>>();\nconst replayRegistry = new WeakMap<ScopedKV, Map<string, SingleFlight<ReplayStats>>>();\n\nfunction registryFor<T>(\n registry: WeakMap<ScopedKV, Map<string, T>>,\n kv: ScopedKV,\n storeKey: string,\n make: () => T\n): T {\n let perKv = registry.get(kv);\n if (perKv === undefined) {\n perKv = new Map();\n registry.set(kv, perKv);\n }\n let entry = perKv.get(storeKey);\n if (entry === undefined) {\n entry = make();\n perKv.set(storeKey, entry);\n }\n return entry;\n}\n\nexport class ListStore<T> {\n constructor(\n protected readonly kv: ScopedKV,\n protected readonly storeKey: string,\n protected readonly keyOf: (entry: T) => string\n ) {}\n\n list(): Promise<T[]> {\n return this.chained(() => this.read());\n }\n\n getByKey(key: string): Promise<T | undefined> {\n return this.chained(async () => (await this.read()).find((e) => this.keyOf(e) === key));\n }\n\n /** Upsert; a byte-identical re-save is a no-op (content-idempotent). */\n upsert(entry: T): Promise<void> {\n return this.mutate((list) => {\n const key = this.keyOf(entry);\n const at = list.findIndex((e) => this.keyOf(e) === key);\n if (at >= 0 && JSON.stringify(list[at]) === JSON.stringify(entry)) return { result: undefined };\n const next = [...list];\n if (at >= 0) next[at] = entry;\n else next.push(entry);\n return { list: next, result: undefined };\n });\n }\n\n removeByKey(key: string): Promise<void> {\n return this.mutate((list) => {\n const next = list.filter((e) => this.keyOf(e) !== key);\n return next.length === list.length ? { result: undefined } : { list: next, result: undefined };\n });\n }\n\n patch(key: string, fn: (entry: T) => T): Promise<T | undefined> {\n return this.mutate((list) => {\n const at = list.findIndex((e) => this.keyOf(e) === key);\n if (at < 0) return { result: undefined };\n const next = [...list];\n next[at] = fn(next[at]);\n return { list: next, result: next[at] };\n });\n }\n\n protected mutate<R>(fn: (list: T[]) => { list?: T[]; result: R }): Promise<R> {\n return this.chained(async () => {\n const { list, result } = fn(await this.read());\n if (list !== undefined) await this.kv.set(this.storeKey, list);\n return result;\n });\n }\n\n protected chained<R>(run: () => Promise<R>): Promise<R> {\n return registryFor(chainRegistry, this.kv, this.storeKey, () => new SerialChain()).enqueue(run);\n }\n\n private async read(): Promise<T[]> {\n return (await this.kv.get<T[]>(this.storeKey)) ?? [];\n }\n}\n\nexport interface ReplayStats {\n delivered: number;\n deferred: number;\n failed: number;\n poisoned: number;\n}\n\nexport interface ReplayDeps {\n readonly delivery: DeliveryPort;\n readonly now: () => number;\n readonly attention: AttentionEmitter;\n /** sphere#487 — see {@link senderNametagOption}. */\n readonly ownNametag?: () => string | undefined;\n}\n\n/**\n * sphere#487: the recipient learns the sender's Unicity ID from the delivery\n * envelope and NOWHERE else (no lookup, no second rail) — so every deliver\n * carries it, or the recipient renders \"Someone\".\n *\n * Read LIVE at deliver time, never snapshotted into the plan or the journal:\n * registration (or an address switch) can land between a send and the replay\n * of one of its deferred legs, and the wallet's name today is the honest one.\n * A wallet with no Unicity ID omits the field — `''` is not a name.\n *\n * A throwing getter degrades to no name: by the time a leg is delivered its\n * token is already CERTIFIED, so raising here would replay the journaled blob\n * into the poison budget and end at `delivery:undeliverable`. A display name\n * must never cost a settled transfer its delivery.\n */\nexport function senderNametagOption(\n ownNametag?: () => string | undefined\n): { senderNametag?: string } {\n let nametag: string | undefined;\n try {\n nametag = ownNametag?.();\n } catch {\n return {};\n }\n return nametag === undefined || nametag === '' ? {} : { senderNametag: nametag };\n}\n\nexport class DeliveryJournal extends ListStore<DeliveryJournalEntry> {\n constructor(kv: ScopedKV) {\n super(kv, STORE_KEYS.deliveryJournal, (e) => `${e.transferId}:${String(e.opIndex)}`);\n }\n\n async byTransfer(transferId: string): Promise<Map<number, DeliveryJournalEntry>> {\n const mine = (await this.list()).filter((e) => e.transferId === transferId);\n return new Map(mine.map((e) => [e.opIndex, e]));\n }\n\n remove(transferId: string, opIndex: number): Promise<void> {\n return this.removeByKey(`${transferId}:${String(opIndex)}`);\n }\n\n /** 429 deferral: pushes deferredUntil out WITHOUT touching the poison budget. */\n async defer(transferId: string, opIndex: number, until: number): Promise<void> {\n await this.patch(`${transferId}:${String(opIndex)}`, (e) => ({ ...e, deferredUntil: until }));\n }\n\n /** Genuine failure: attempts++, poisoning (undeliverable) at the budget. */\n async recordFailure(transferId: string, opIndex: number, attention: AttentionEmitter): Promise<boolean> {\n const updated = await this.patch(`${transferId}:${String(opIndex)}`, (e) => {\n if (e.undeliverable === true) return e;\n const attempts = e.attempts + 1;\n return attempts >= MAX_DELIVERY_ATTEMPTS ? { ...e, attempts, undeliverable: true } : { ...e, attempts };\n });\n const poisoned = updated?.undeliverable === true;\n if (poisoned && updated.attempts === MAX_DELIVERY_ATTEMPTS) {\n attention(transferId, ATTENTION_DELIVERY_UNDELIVERABLE, `op ${String(opIndex)} after ${String(updated.attempts)} attempts`);\n }\n return poisoned;\n }\n\n /** Single-flight per (kv, store); concurrent calls coalesce onto one pass. */\n replay(deps: ReplayDeps): Promise<ReplayStats> {\n return registryFor(replayRegistry, this.kv, this.storeKey, () => new SingleFlight<ReplayStats>()).run(\n () => this.replayOnce(deps)\n );\n }\n\n private async replayOnce(deps: ReplayDeps): Promise<ReplayStats> {\n const stats: ReplayStats = { delivered: 0, deferred: 0, failed: 0, poisoned: 0 };\n for (const entry of await this.list()) {\n if (entry.undeliverable === true) continue;\n if (entry.deferredUntil !== undefined && entry.deferredUntil > deps.now()) {\n stats.deferred += 1;\n continue;\n }\n await this.replayEntry(entry, deps, stats);\n }\n return stats;\n }\n\n private async replayEntry(entry: DeliveryJournalEntry, deps: ReplayDeps, stats: ReplayStats): Promise<void> {\n try {\n await deps.delivery.deliver(entry.recipientPubkey, hexToBytes(entry.blobHex), {\n transferId: entry.transferId,\n ...(entry.memo !== undefined ? { memo: entry.memo } : {}),\n ...senderNametagOption(deps.ownNametag),\n });\n await this.remove(entry.transferId, entry.opIndex);\n stats.delivered += 1;\n } catch (err) {\n if (isRateLimited(err)) {\n await this.defer(entry.transferId, entry.opIndex, deps.now() + RATE_LIMIT_DEFER_MS);\n deps.attention(entry.transferId, ATTENTION_DELIVERY_DEFERRED);\n stats.deferred += 1;\n } else if (await this.recordFailure(entry.transferId, entry.opIndex, deps.attention)) {\n stats.poisoned += 1;\n } else {\n stats.failed += 1;\n }\n }\n }\n}\n\nexport interface MachineStores {\n readonly backstop: ListStore<IntentBackstopEntry>;\n readonly deliveryJournal: DeliveryJournal;\n readonly mintJournal: ListStore<MintJournalEntry>;\n readonly nftMintJournal: ListStore<NftMintJournalEntry>;\n readonly shortfalls: ListStore<ShortfallEntry>;\n}\n\nexport function createMachineStores(kv: ScopedKV): MachineStores {\n return {\n backstop: new ListStore<IntentBackstopEntry>(kv, STORE_KEYS.intentBackstop, (e) => e.transferId),\n deliveryJournal: new DeliveryJournal(kv),\n mintJournal: new ListStore<MintJournalEntry>(kv, STORE_KEYS.mintJournal, (e) => e.mintId),\n nftMintJournal: new ListStore<NftMintJournalEntry>(kv, STORE_KEYS.nftMintJournal, (e) => e.mintId),\n shortfalls: new ListStore<ShortfallEntry>(kv, STORE_KEYS.shortfalls, (e) => e.transferId),\n };\n}\n","/**\n * token-engine/errors.ts — the engine's typed error surface (Part E.2).\n */\n\nimport { SphereError } from '../core/errors';\n\n/**\n * The source state was already consumed by a *different* transaction — the\n * fetched inclusion proof does not match the rebuilt transaction\n * (`TRANSACTION_HASH_MISMATCH`). Typically the owner's other device raced the\n * same source under a different `transferId` (ARCHITECTURE §7).\n *\n * This is a lost race, **not** an interrupted resume: the engine never applies\n * the foreign proof and never retries. The caller's recovery is to abort the\n * intent, drop the lost source from its plan, and re-plan the remainder under\n * a NEW `transferId` (never reusing the old realization) — sdk-changes E.2.\n */\nexport class TransferConflictError extends SphereError {\n /**\n * #625: the source token id (the caller's id, e.g. `v2_<genesis>`) whose state was already spent.\n * Set by PaymentsModule at the engine call site so the self-healing retry can demote it and re-plan.\n */\n conflictedSourceId?: string;\n\n constructor(message: string, cause?: unknown) {\n super(message, 'TRANSFER_CONFLICT', cause);\n this.name = 'TransferConflictError';\n }\n}\n\n/**\n * The op's certification is INDETERMINATE: the submit was accepted (`SUCCESS`)\n * or failed ambiguously (a thrown submit POST that may have been processed\n * server-side), and the inclusion-proof fetch/verify returned NO verdict — a\n * transient network/timeout error, NOT a matching proof and NOT\n * `TRANSACTION_HASH_MISMATCH`. The source's spend MAY already be on-chain under\n * THIS `transferId`.\n *\n * Unlike {@link TransferConflictError} (a foreign tx won — abort + re-plan under\n * a NEW id), the caller MUST keep the intent OPEN: resume re-derives the\n * byte-identical transaction from `(seed, transferId, opIndex)` and recovers the\n * certified proof + recipient blob, or records the spend if a foreign tx won the\n * race — never a second on-chain spend (sdk-changes E.2/E.3, #631).\n */\nexport class ProofUnconfirmedError extends SphereError {\n readonly mayHaveCertified = true as const;\n\n constructor(message: string, cause?: unknown) {\n super(message, 'CERTIFICATION_UNCONFIRMED', cause);\n this.name = 'ProofUnconfirmedError';\n }\n}\n\n/**\n * A split's burn certified but its checkpoint (sdk-changes E.4, sphere-sdk#501) could NOT be\n * durably persisted — the `SplitCheckpointStore.put` rejected (network / 5xx / timeout / quota) —\n * so NO mint leg was submitted. The burn is on-chain (funds in-flight, not lost); the outputs are\n * fully recoverable on resume.\n *\n * Keep-open family (like {@link ProofUnconfirmedError}): the caller MUST keep the intent OPEN and\n * resume under the SAME `transferId` — the next attempt re-derives the byte-identical burn,\n * re-persists the checkpoint (content-idempotent), and mints. NEVER abort.\n */\nexport class CheckpointPersistFailedError extends SphereError {\n readonly mayHaveCertified = true as const;\n\n constructor(message: string, cause?: unknown) {\n super(message, 'CHECKPOINT_PERSIST_FAILED', cause);\n this.name = 'CheckpointPersistFailedError';\n }\n}\n\n/**\n * A split cannot be rebuilt from its checkpoint, in a way that is NOT a lost race: either a mint\n * leaf is already certified on-chain but no stored bytes reproduce its certified transactionHash\n * (server data loss / withholding, or a pre-E.4 legacy intent), or a stored checkpoint fails its\n * byte-binding checks (the re-derived burn tx ≠ the stored bytes — cross-version derivation drift\n * — or a corrupt stored proof, or a burnt-token re-encode mismatch).\n *\n * Distinct from {@link TransferConflictError}: a split-mint stateId is HKDF-derived from\n * `(seed, transferId)`, so only a seed-holder under THIS `transferId` can have certified it — this\n * is never a foreign spend. Keep-open, alert loudly: the caller MUST NOT abort, NOT complete, and\n * NOT record the source as foreign-spent (sdk-changes E.4).\n */\nexport class SplitCheckpointLostError extends SphereError {\n constructor(message: string, cause?: unknown) {\n super(message, 'SPLIT_CHECKPOINT_LOST', cause);\n this.name = 'SplitCheckpointLostError';\n }\n}\n\n/**\n * A stored split checkpoint (sdk-changes E.4) is authentic and byte-bound to the re-derived burn\n * transaction, but its inclusion proof no longer verifies against the CURRENT trust base\n * (`INVALID_TRUSTBASE`) — a validator-set / quorum rotation while the intent was open. The bytes\n * are NOT wrong; re-burning would strand the certified split, so the engine never falls through to\n * a re-burn.\n *\n * Keep-open, distinct signal: the operational remedy is to drain open split intents BEFORE a\n * validator rotation (the SDK has no epoch map — single-epoch trust base, ARCHITECTURE §8.2/§19).\n */\nexport class CheckpointTrustbaseMismatchError extends SphereError {\n constructor(message: string, cause?: unknown) {\n super(message, 'CHECKPOINT_TRUSTBASE_MISMATCH', cause);\n this.name = 'CheckpointTrustbaseMismatchError';\n }\n}\n","// §5.5/§5.6 of docs/PAYMENTS-V2-DESIGN.md — ONE machine for send AND resume.\n// Persisted state is the server intent + the E.4 checkpoint + the delivery\n// journal; every transition is pinned by tests/unit/payments-v2/machine*.test.ts.\n\nimport { sha256 } from '@noble/hashes/sha2.js';\n\nimport { bytesToHex, hexToBytes } from '../../../core/crypto';\nimport { SphereError } from '../../../core/errors';\nimport type { TransferResult } from '../../../types';\nimport type { ITokenEngine, SplitCheckpointStore } from '../../../token-engine/engine';\nimport type { SphereToken } from '../../../token-engine/types';\nimport {\n CheckpointPersistFailedError,\n CheckpointTrustbaseMismatchError,\n ProofUnconfirmedError,\n SplitCheckpointLostError,\n TransferConflictError,\n} from '../../../token-engine/errors';\nimport type { DeliverOptions, DeliveryPort, StoragePort } from '../ports';\nimport { coinIdOf, splitOf } from './payload-view';\nimport type { DeliveryJournalEntry, ScopedKV, ShortfallEntry } from '../stores';\nimport type { IntentPayload, OpOutcome, OutcomeClass, PlannedOp } from './types';\nimport {\n ATTENTION_DELIVERY_DEFERRED,\n ATTENTION_SYNC_PENDING,\n RATE_LIMIT_DEFER_MS,\n createMachineStores,\n isRateLimited,\n isValidationReject,\n senderNametagOption,\n type AttentionEmitter,\n type MachineStores,\n} from './journal';\n\n// #746: measured live, a 4-op wave cost the same as an 8-op wave — at 8 we were\n// latency-bound, so each wave paid a proof round-trip and the barrier multiplied\n// it. Safe to widen only because a rate-limited submit now retries instead of\n// burning a full deadline per op (proof-wait.retryTransient).\nconst CERTIFY_WIDTH = 20;\n\nconst KEEP_OPEN_CODES = new Set([\n 'CERTIFICATION_UNCONFIRMED',\n 'CHECKPOINT_PERSIST_FAILED',\n 'SPLIT_CHECKPOINT_LOST',\n 'CHECKPOINT_TRUSTBASE_MISMATCH',\n]);\n\nexport interface IntentApi {\n put(transferId: string, envelope: string, requiresSeedClose: boolean): Promise<void>;\n listOpen(): Promise<{ transferId: string; payload: string; createdAt: string }[]>;\n abort(transferId: string): Promise<void>;\n complete(transferId: string, signature?: string): Promise<void>;\n}\n\nexport interface MachineDeps {\n /** Snapshot taken once per operation entry (the setEngine hot-swap seam). */\n engine: () => ITokenEngine;\n storage: StoragePort;\n delivery: DeliveryPort;\n intents: IntentApi;\n checkpointStore: SplitCheckpointStore;\n kv: ScopedKV;\n encryptPayload: (p: IntentPayload) => Promise<string>;\n decryptPayload: (envelope: string) => Promise<unknown>;\n signComplete: (transferId: string) => Promise<string>;\n ownPubkey: Uint8Array;\n /** sphere#487: the wallet's own Unicity ID — see {@link senderNametagOption}. */\n ownNametag?: () => string | undefined;\n emit: (event: string, payload: unknown) => void;\n now: () => number;\n /** `committedAmount` = what SETTLED (the certified recipient blobs' value), never the plan. */\n recordHistory?: (info: {\n transferId: string;\n payload: IntentPayload;\n phase: 'sent' | 'resumed';\n committedAmount: string;\n /** A WHOLE-token spend moves the token, not an amount: its real assets, [] when coinless. */\n committedAssets?: readonly { coinId: string; amount: string }[];\n }) => Promise<void>;\n}\n\nexport interface MachinePlan {\n transferId: string;\n recipientPubkey: string;\n payload: IntentPayload;\n ops: PlannedOp[];\n /** Source SphereTokens keyed by tokenId — materialized (blob-fetched) pre-run. */\n sources: Map<string, SphereToken>;\n memo?: string;\n}\n\nexport interface RehydratedIntent {\n transferId: string;\n payload: IntentPayload;\n sources: Map<string, SphereToken>;\n journaled: Map<number, DeliveryJournalEntry>;\n}\n\nexport interface ResumeIntentOutcome {\n deliveryPending: boolean;\n /** Non-null when ≥1 leg delivered but a later leg conflicted (#677/#690). */\n partial: ShortfallEntry | null;\n}\n\ninterface CertifyCtx {\n transferId: string;\n recipientPubkey: string;\n payload: IntentPayload;\n memo?: string;\n}\n\ninterface ResumeConflict {\n op: PlannedOp;\n error: unknown;\n amount: bigint;\n}\n\n/** opIndex is plan-derived: the op's position in direct[], split at direct.length (E.1). */\nexport function buildOps(payload: IntentPayload): PlannedOp[] {\n const ops: PlannedOp[] = payload.direct.map((sourceTokenId, opIndex) => ({\n kind: 'direct',\n opIndex,\n sourceTokenId,\n deliveredAmount: 0n,\n }));\n if (payload.split !== undefined) {\n ops.push({\n kind: 'split',\n opIndex: payload.direct.length,\n sourceTokenId: payload.split.tokenId,\n deliveredAmount: BigInt(payload.split.splitAmount),\n });\n }\n return ops;\n}\n\nexport function classifyError(e: unknown): OutcomeClass {\n if (\n e instanceof ProofUnconfirmedError ||\n e instanceof SplitCheckpointLostError ||\n e instanceof CheckpointPersistFailedError ||\n e instanceof CheckpointTrustbaseMismatchError\n ) {\n return 'keep-open';\n }\n if (e instanceof TransferConflictError) return 'conflict';\n const coded = e !== null && typeof e === 'object' ? (e as { code?: unknown; mayHaveCertified?: unknown }) : null;\n if (coded !== null) {\n if (coded.mayHaveCertified === true) return 'keep-open';\n if (typeof coded.code === 'string' && KEEP_OPEN_CODES.has(coded.code)) return 'keep-open';\n if (coded.code === 'TRANSFER_CONFLICT') return 'conflict';\n }\n return 'other';\n}\n\n/** Precedence keep-open > conflict > other; committed = certified regardless of error (#441). */\n/** Settlement tolerates conflicts and nothing else; `cls` cannot say that, because\n * it ranks conflict ABOVE 'other' and so hides an ordinary failure (#745 review). */\nexport function firstNonConflictError(outcomes: OpOutcome[]): OpOutcome | undefined {\n return outcomes.find((o) => o.error !== undefined && classifyError(o.error) !== 'conflict');\n}\n\nexport function summarize(outcomes: OpOutcome[]): {\n committed: OpOutcome[];\n cls: OutcomeClass | null;\n firstError: unknown;\n} {\n const committed = outcomes.filter((o) => o.certified);\n const rank: Record<OutcomeClass, number> = { 'keep-open': 3, conflict: 2, other: 1 };\n let cls: OutcomeClass | null = null;\n let firstError: unknown;\n for (const o of outcomes) {\n if (o.error === undefined) continue;\n const c = classifyError(o.error);\n if (cls === null || rank[c] > rank[cls]) {\n cls = c;\n firstError = o.error;\n }\n }\n return { committed, cls, firstError };\n}\n\nexport class TransferMachine {\n private readonly stores: MachineStores;\n\n constructor(private readonly deps: MachineDeps) {\n this.stores = createMachineStores(deps.kv);\n }\n\n // ── send path ─────────────────────────────────────────────────────────────\n async run(plan: MachinePlan): Promise<{ committed: OpOutcome[]; deliveryPending: boolean }> {\n const engine = this.deps.engine();\n const envelope = await this.deps.encryptPayload(plan.payload);\n await this.stores.backstop.upsert({\n transferId: plan.transferId,\n payloadEnvelope: envelope,\n requiresSeedClose: plan.payload.split !== undefined,\n disposition: 'open',\n createdAt: this.deps.now(),\n });\n await this.putIntentGate(plan, envelope);\n\n const outcomes = await this.certifyAll(plan, engine);\n const { committed, cls, firstError } = summarize(outcomes);\n\n let deliveryPending = false;\n if (committed.length > 0) {\n deliveryPending = await this.deliverSet(plan.transferId, plan.recipientPubkey, plan.memo, committed);\n }\n if (cls === null) {\n await this.applyCommitted(engine, plan.transferId, committed);\n this.closeTail(engine, plan.transferId, plan.payload, committed);\n return { committed, deliveryPending };\n }\n if (cls === 'conflict' && committed.length > 0) {\n await this.applyBestEffort(engine, plan.transferId, committed);\n }\n await this.disposeOnFailure(plan.transferId, committed, cls);\n throw firstError;\n }\n\n // ── resume path: the SAME machine, rehydrated from an open intent ─────────\n async resumeIntent(r: RehydratedIntent): Promise<ResumeIntentOutcome> {\n const engine = this.deps.engine();\n const ctx: CertifyCtx = {\n transferId: r.transferId,\n recipientPubkey: r.payload.recipient,\n payload: r.payload,\n ...(r.payload.memo !== undefined ? { memo: r.payload.memo } : {}),\n };\n const outcomes = await this.resumeOps(ctx, engine, r);\n const { committed } = summarize(outcomes);\n const conflicts = this.toConflicts(engine, r, outcomes);\n if (committed.length === 0 && conflicts.length > 0) throw conflicts[0].error;\n\n let deliveryPending = false;\n if (committed.length > 0) {\n deliveryPending = await this.deliverSet(r.transferId, r.payload.recipient, r.payload.memo, committed);\n }\n // An intent closes only when every op settled cleanly (#744) — judged per\n // outcome, since a conflict outranks and would hide an ordinary failure whose\n // amount is in neither committed[] nor conflicts[] (#745 review).\n const blocking = firstNonConflictError(outcomes);\n if (blocking !== undefined) throw blocking.error;\n\n await this.applyCommitted(engine, r.transferId, committed);\n if (conflicts.length > 0) {\n return { deliveryPending, partial: await this.settlePartial(engine, r, committed, conflicts) };\n }\n await this.completeIntent(r.transferId, r.payload);\n await this.finishBookkeeping(engine, r.transferId, r.payload, 'resumed', committed);\n return { deliveryPending, partial: null };\n }\n\n // ── shared transitions ─────────────────────────────────────────────────────\n\n private async putIntentGate(plan: MachinePlan, envelope: string): Promise<void> {\n try {\n await this.deps.intents.put(plan.transferId, envelope, plan.payload.split !== undefined);\n } catch (err) {\n // #670: only the deterministic pre-submit 422 proves no server row exists.\n if (isValidationReject(err)) await this.stores.backstop.removeByKey(plan.transferId);\n throw err;\n }\n }\n\n private async certifyAll(plan: MachinePlan, engine: ITokenEngine): Promise<OpOutcome[]> {\n const ctx: CertifyCtx = {\n transferId: plan.transferId,\n recipientPubkey: plan.recipientPubkey,\n payload: plan.payload,\n ...(plan.memo !== undefined ? { memo: plan.memo } : {}),\n };\n const outcomes: OpOutcome[] = [];\n const certified: OpOutcome[] = [];\n for (let at = 0; at < plan.ops.length; at += CERTIFY_WIDTH) {\n const batch = plan.ops.slice(at, at + CERTIFY_WIDTH);\n const settled = await Promise.all(\n batch.map((op) =>\n this.certifyOne(ctx, engine, op, plan.sources.get(op.sourceTokenId)).then((o) => {\n // Report each leg as it lands, not each wave: a <=CERTIFY_WIDTH send is\n // one wave, so per-wave reporting would jump 0% -> 100%. Rides the\n // existing transfer:updated / tokenTransfers surface — nothing new.\n if (o.certified) {\n certified.push(o);\n this.emitProgress(plan, certified);\n }\n return o;\n })\n )\n );\n outcomes.push(...settled);\n if (settled.some((o) => o.error !== undefined && !o.certified)) break;\n }\n return outcomes;\n }\n\n /** In-flight snapshot: `tokenTransfers` holds the legs certified SO FAR. */\n private emitProgress(plan: MachinePlan, certified: readonly OpOutcome[]): void {\n this.deps.emit('transfer:updated', {\n id: plan.transferId,\n status: 'submitted',\n tokens: [],\n tokenTransfers: certified.map((o) => ({\n sourceTokenId: o.op.sourceTokenId,\n method: o.op.kind,\n })),\n } satisfies TransferResult);\n }\n\n private async certifyOne(\n ctx: CertifyCtx,\n engine: ITokenEngine,\n op: PlannedOp,\n source: SphereToken | undefined\n ): Promise<OpOutcome> {\n if (source === undefined) {\n return {\n op,\n certified: false,\n error: new SphereError(`source ${op.sourceTokenId} is not materialized`, 'VALIDATION_ERROR'),\n };\n }\n let produced: { recipientBlob: Uint8Array; changeBlob?: Uint8Array };\n try {\n produced = await this.certifyOnChain(ctx, engine, op, source);\n } catch (error) {\n return { op, certified: false, error };\n }\n const outcome: OpOutcome = { op, certified: true, ...produced };\n try {\n // #621: journal the instant the op certifies, BEFORE any delivery attempt.\n await this.stores.deliveryJournal.upsert({\n transferId: ctx.transferId,\n opIndex: op.opIndex,\n recipientPubkey: ctx.recipientPubkey,\n blobHex: bytesToHex(produced.recipientBlob),\n ...(ctx.memo !== undefined ? { memo: ctx.memo } : {}),\n attempts: 0,\n });\n return outcome;\n } catch (error) {\n return { ...outcome, error };\n }\n }\n\n private async certifyOnChain(\n ctx: CertifyCtx,\n engine: ITokenEngine,\n op: PlannedOp,\n source: SphereToken\n ): Promise<{ recipientBlob: Uint8Array; changeBlob?: Uint8Array }> {\n const recipientPubkey = hexToBytes(ctx.recipientPubkey);\n const opts = { transferId: ctx.transferId, opIndex: op.opIndex, checkpointStore: this.deps.checkpointStore };\n if (op.kind === 'direct') {\n const finished = await engine.transfer({ token: source, recipientPubkey }, opts);\n return { recipientBlob: finished.blob.token };\n }\n const split = splitOf(ctx.payload)!;\n // A split is planned only for a coin spend, so the coin id is present by\n // construction; a token-addressed intent never reaches this branch.\n const splitCoinId = coinIdOf(ctx.payload)!;\n const { outputs } = await engine.split(\n {\n token: source,\n outputs: [\n { recipientPubkey, coinId: splitCoinId, amount: BigInt(split.splitAmount) },\n { recipientPubkey: this.deps.ownPubkey, coinId: splitCoinId, amount: BigInt(split.remainderAmount) },\n ],\n },\n opts\n );\n return { recipientBlob: outputs[0].blob.token, changeBlob: outputs[1].blob.token };\n }\n\n /** Raw outcomes; `summarize` alone decides what they mean — same as the send path. */\n private async resumeOps(\n ctx: CertifyCtx,\n engine: ITokenEngine,\n r: RehydratedIntent\n ): Promise<OpOutcome[]> {\n const outcomes: OpOutcome[] = [];\n for (const op of buildOps(r.payload)) {\n // #621 direct legs re-deliver from the journal, never re-certify; a split\n // ALWAYS re-runs through its E.4 checkpoint to recover the change (#634).\n const journaled = op.kind === 'direct' ? r.journaled.get(op.opIndex) : undefined;\n if (journaled !== undefined) {\n outcomes.push({ op, certified: true, recipientBlob: hexToBytes(journaled.blobHex) });\n continue;\n }\n outcomes.push(await this.certifyOne(ctx, engine, op, r.sources.get(op.sourceTokenId)));\n // Fail-fast on anything but a conflict, as before — but the outcome is\n // RECORDED, so the shared decision below sees it (#744).\n const last = outcomes[outcomes.length - 1];\n if (last.error !== undefined && classifyError(last.error) !== 'conflict') break;\n }\n return outcomes;\n }\n\n /** Conflicted ops with the amount each leaves undelivered (#690 shortfall math). */\n private toConflicts(engine: ITokenEngine, r: RehydratedIntent, outcomes: OpOutcome[]): ResumeConflict[] {\n return outcomes\n .filter((o) => !o.certified && classifyError(o.error) === 'conflict')\n .map((o) => ({\n op: o.op,\n error: o.error,\n amount: conflictAmount(engine, r.payload, o.op, r.sources.get(o.op.sourceTokenId)),\n }));\n }\n\n private async deliverSet(\n transferId: string,\n recipientPubkey: string,\n memo: string | undefined,\n committed: OpOutcome[]\n ): Promise<boolean> {\n const journaled = committed.filter((o) => o.error === undefined && o.recipientBlob !== undefined);\n let pending = journaled.length < committed.length;\n if (journaled.length === 0) return pending;\n const options = {\n transferId,\n ...(memo !== undefined ? { memo } : {}),\n ...senderNametagOption(this.deps.ownNametag),\n };\n if (await this.tryBatchDeposit(recipientPubkey, journaled, options)) return pending;\n for (const outcome of journaled) {\n const stillPending = await this.deliverOne(recipientPubkey, outcome, options);\n pending = pending || stillPending;\n }\n return pending;\n }\n\n private async tryBatchDeposit(\n recipientPubkey: string,\n journaled: OpOutcome[],\n options: DeliverOptions\n ): Promise<boolean> {\n const batch = this.deps.delivery.deliverBatch?.bind(this.deps.delivery);\n if (batch === undefined) return false;\n try {\n await batch(recipientPubkey, journaled.map((o) => o.recipientBlob!), options);\n } catch {\n return false; // §5.6: batch failure falls back to the per-entry loop\n }\n for (const o of journaled) await this.removeJournaled(options.transferId, o.op.opIndex);\n return true;\n }\n\n private async deliverOne(\n recipientPubkey: string,\n outcome: OpOutcome,\n options: DeliverOptions\n ): Promise<boolean> {\n try {\n await this.deps.delivery.deliver(recipientPubkey, outcome.recipientBlob!, options);\n await this.removeJournaled(options.transferId, outcome.op.opIndex);\n return false;\n } catch (err) {\n if (isRateLimited(err)) {\n await this.stores.deliveryJournal.defer(options.transferId, outcome.op.opIndex, this.deps.now() + RATE_LIMIT_DEFER_MS);\n this.attention()(options.transferId, ATTENTION_DELIVERY_DEFERRED);\n } else {\n await this.stores.deliveryJournal.recordFailure(options.transferId, outcome.op.opIndex, this.attention());\n }\n return true;\n }\n }\n\n private async removeJournaled(transferId: string, opIndex: number): Promise<void> {\n try {\n await this.stores.deliveryJournal.remove(transferId, opIndex);\n } catch {\n /* deposit is idempotent — the replay converges a lingering entry */\n }\n }\n\n private async applyCommitted(engine: ITokenEngine, transferId: string, committed: OpOutcome[]): Promise<void> {\n try {\n const added = await this.uploadChangeBlobs(engine, committed);\n await this.deps.storage.applyDelta({\n transferId,\n spent: committed.map((o) => o.op.sourceTokenId),\n added,\n });\n } catch (cause) {\n // #665: post-commit mirror lag — never transfer:failed; resume converges.\n const pending = new SphereError(\n 'The spend committed on-chain; the wallet-api mirror is catching up.',\n 'SEND_SYNC_PENDING',\n cause\n );\n pending.transferId = transferId;\n throw pending;\n }\n }\n\n private async applyBestEffort(engine: ITokenEngine, transferId: string, committed: OpOutcome[]): Promise<void> {\n if (committed.some((o) => o.error !== undefined)) return; // unjournaled leg: resume owns it\n try {\n await this.applyCommitted(engine, transferId, committed);\n } catch {\n this.attention()(transferId, ATTENTION_SYNC_PENDING);\n }\n }\n\n private async uploadChangeBlobs(\n engine: ITokenEngine,\n committed: OpOutcome[]\n ): Promise<{ tokenId: string; key: string }[]> {\n const added: { tokenId: string; key: string }[] = [];\n for (const o of committed) {\n if (o.changeBlob === undefined) continue;\n const digest = bytesToHex(sha256(o.changeBlob));\n const keys = await this.deps.storage.uploadBlobs([{ sha256: digest, bytes: o.changeBlob }]);\n const key = keys.get(digest);\n if (key === undefined) throw new SphereError(`no upload key returned for ${digest}`, 'STORAGE_ERROR');\n const { tokenId } = await engine.deliveryKeys(o.changeBlob);\n added.push({ tokenId, key });\n }\n return added;\n }\n\n private async settlePartial(\n engine: ITokenEngine,\n r: RehydratedIntent,\n committed: OpOutcome[],\n conflicts: ResumeConflict[]\n ): Promise<ShortfallEntry> {\n const undelivered = conflicts.reduce((sum, c) => sum + c.amount, 0n);\n const entry: ShortfallEntry = {\n transferId: r.transferId,\n remainingAmount: undelivered.toString(),\n // '' only on a token-addressed intent, which is one leg: it either lands or\n // conflicts, so a shortfall row is unreachable there (settlePartial needs >1).\n coinId: coinIdOf(r.payload) ?? '',\n recipient: r.payload.recipient,\n committedTokenIds: committed.map((o) => o.op.sourceTokenId),\n createdAt: this.deps.now(),\n };\n // #690: durable BEFORE complete — after complete the intent is unlistable\n // and no resume could ever rebuild the remainder the app never saw.\n await this.stores.shortfalls.upsert(entry);\n await this.completeIntent(r.transferId, r.payload);\n await this.finishBookkeeping(engine, r.transferId, r.payload, 'resumed', committed);\n return entry;\n }\n\n private closeTail(engine: ITokenEngine, transferId: string, payload: IntentPayload, committed: OpOutcome[]): void {\n void (async () => {\n try {\n await this.completeIntent(transferId, payload);\n } catch {\n return; // idempotent backstop — resume converges the unevidenced edge\n }\n await this.finishBookkeeping(engine, transferId, payload, 'sent', committed);\n })();\n }\n\n private async completeIntent(transferId: string, payload: IntentPayload): Promise<void> {\n const signature = payload.split !== undefined ? await this.deps.signComplete(transferId) : undefined;\n await this.deps.intents.complete(transferId, signature);\n }\n\n private async finishBookkeeping(\n engine: ITokenEngine,\n transferId: string,\n payload: IntentPayload,\n phase: 'sent' | 'resumed',\n committed: OpOutcome[]\n ): Promise<void> {\n try {\n // A token-addressed spend has no coin to sum: what settled is the token itself.\n const coinId = coinIdOf(payload);\n const committedAmount =\n coinId === undefined ? '0' : await this.settledAmount(engine, coinId, committed);\n // A whole-token spend has no coin to sum — record what the moved token ACTUALLY\n // carried, so a valued one is not logged as `assets: []`.\n const committedAssets =\n coinId === undefined ? await this.settledAssets(engine, committed) : undefined;\n await this.deps.recordHistory?.({\n transferId,\n payload,\n phase,\n committedAmount,\n ...(committedAssets !== undefined ? { committedAssets } : {}),\n });\n } catch {\n /* a history failure never fails the money path */\n }\n try {\n await this.stores.backstop.removeByKey(transferId);\n } catch {\n /* stale 'open' backstops are inert — resume lists server-open only */\n }\n }\n\n /**\n * §5.9: SENT history records what SETTLED, never the plan — the value of the\n * certified recipient blobs (summarize()'s committed set is the only source;\n * a journal-rehydrated resume leg has no source token, but every committed\n * leg carries its recipient blob, so the outcome-derived rule is uniform).\n */\n /** Every asset across the certified recipient blobs — the whole-spend twin of settledAmount. */\n private async settledAssets(\n engine: ITokenEngine,\n committed: OpOutcome[]\n ): Promise<{ coinId: string; amount: string }[]> {\n const total = new Map<string, bigint>();\n for (const outcome of committed) {\n if (outcome.recipientBlob === undefined) continue;\n const token = await engine.decodeToken({ tokenId: '', token: outcome.recipientBlob });\n for (const asset of engine.readValue(token)?.assets ?? []) {\n total.set(asset.coinId, (total.get(asset.coinId) ?? 0n) + asset.amount);\n }\n }\n return [...total].map(([coinId, amount]) => ({ coinId, amount: amount.toString() }));\n }\n\n private async settledAmount(engine: ITokenEngine, coinId: string, committed: OpOutcome[]): Promise<string> {\n let total = 0n;\n for (const outcome of committed) {\n if (outcome.recipientBlob === undefined) continue;\n const token = await engine.decodeToken({ tokenId: '', token: outcome.recipientBlob });\n total += engine.balanceOf(token, coinId);\n }\n return total.toString();\n }\n\n private async disposeOnFailure(transferId: string, committed: OpOutcome[], cls: OutcomeClass): Promise<void> {\n // Abort ONLY when nothing certified AND the class is clean; the keep-open\n // family and any partially-certified send leave the intent open (E.2/E.3).\n if (committed.length > 0 || cls === 'keep-open') return;\n try {\n await this.stores.backstop.patch(transferId, (e) => ({ ...e, disposition: 'abortPending' }));\n } catch {\n /* server abort below still converges; #676 gate covers the gap */\n }\n try {\n await this.deps.intents.abort(transferId);\n await this.stores.backstop.removeByKey(transferId);\n } catch {\n /* stays abortPending — the #676 resume gate converges, never re-executes */\n }\n }\n\n private attention(): AttentionEmitter {\n return (transferId, code, detail) => {\n this.deps.emit('transfer:attention', detail === undefined ? { transferId, code } : { transferId, code, detail });\n };\n }\n}\n\nfunction conflictAmount(\n engine: ITokenEngine,\n payload: IntentPayload,\n op: PlannedOp,\n source: SphereToken | undefined\n): bigint {\n const split = splitOf(payload);\n if (op.kind === 'split') return BigInt(split!.splitAmount);\n const coinId = coinIdOf(payload);\n if (coinId === undefined) return 0n; // token-addressed: the unit is the token\n return source !== undefined ? engine.balanceOf(source, coinId) : 0n;\n}\n","// §5.5 P6 — resume = the SAME TransferMachine, rehydrated from server-open\n// intents: the #676 local-disposition gate, v:2 payload validation, batched\n// cross-intent source reads, and {resumed, conflicted, failed} classification.\n\nimport { SphereError } from '../../../core/errors';\nimport { logger } from '../../../core/logger';\nimport type { SphereToken } from '../../../token-engine/types';\nimport type { DeliveryJournalEntry, IntentBackstopEntry } from '../stores';\nimport { isWholeIntent } from './payload-view';\nimport type { CoinIntentPayload, IntentPayload, WholeIntentPayload } from './types';\nimport { ATTENTION_CHECKPOINT_STUCK, createMachineStores, type MachineStores } from './journal';\nimport { TransferMachine, buildOps, classifyError, type MachineDeps } from './TransferMachine';\n\nexport interface ResumeReport {\n resumed: string[];\n conflicted: string[];\n failed: string[];\n}\n\ninterface ResumeJob {\n transferId: string;\n payload: IntentPayload;\n journaled: Map<number, DeliveryJournalEntry>;\n}\n\nexport interface ResumeAllOptions {\n /** Ids with an in-process machine attempt — their backstop entries are never GC'd. */\n isLocallyActive?: (transferId: string) => boolean;\n}\n\nexport async function resumeAll(deps: MachineDeps, options: ResumeAllOptions = {}): Promise<ResumeReport> {\n const report: ResumeReport = { resumed: [], conflicted: [], failed: [] };\n const stores = createMachineStores(deps.kv);\n const open = await deps.intents.listOpen();\n\n let locals: Map<string, IntentBackstopEntry>;\n try {\n locals = new Map((await stores.backstop.list()).map((e) => [e.transferId, e]));\n } catch {\n // #676: local dispositions unknowable — a server-open intent could be\n // locally aborted, so resuming ANY would risk re-executing one. Defer all.\n return report;\n }\n await dropStaleBackstops(\n stores,\n locals,\n new Set(open.map((i) => i.transferId)),\n options.isLocallyActive ?? (() => false)\n );\n\n const jobs = await gateAndDecode(deps, stores, open, locals, report);\n const ctx: RunCtx = {\n deps,\n stores,\n machine: new TransferMachine(deps),\n sources: await fetchSources(deps, jobs),\n };\n for (const job of jobs) {\n await runOne(ctx, job, report);\n }\n return report;\n}\n\ninterface RunCtx {\n deps: MachineDeps;\n stores: MachineStores;\n machine: TransferMachine;\n sources: Map<string, SphereToken>;\n}\n\n/**\n * Reconciliation GC (never money logic — when in doubt, KEEP the entry).\n * Non-'open' entries not server-open: stale local aborts, dropped as before.\n * S1: an 'open' entry that is NOT server-open (= completed-or-never: tail\n * crash after complete, or crash before the intent PUT was acked) with NO\n * journal legs owed and no in-process attempt is pure residue — without this\n * sweep it is a permanent phantom pendingTransfers() row and the heartbeat\n * re-arms forever. Any journal leg or active op keeps the entry.\n */\nasync function dropStaleBackstops(\n stores: MachineStores,\n locals: Map<string, IntentBackstopEntry>,\n openIds: Set<string>,\n isLocallyActive: (transferId: string) => boolean\n): Promise<void> {\n for (const entry of locals.values()) {\n if (openIds.has(entry.transferId)) continue;\n if (entry.disposition !== 'open') {\n await stores.backstop.removeByKey(entry.transferId);\n continue;\n }\n if (isLocallyActive(entry.transferId)) continue;\n if ((await stores.deliveryJournal.byTransfer(entry.transferId)).size > 0) continue;\n await stores.backstop.removeByKey(entry.transferId);\n }\n}\n\nasync function gateAndDecode(\n deps: MachineDeps,\n stores: MachineStores,\n open: { transferId: string; payload: string }[],\n locals: Map<string, IntentBackstopEntry>,\n report: ResumeReport\n): Promise<ResumeJob[]> {\n const jobs: ResumeJob[] = [];\n for (const intent of open) {\n const local = locals.get(intent.transferId);\n if (local !== undefined && local.disposition !== 'open') {\n // #676: a locally-aborted intent is NEVER resumed — converge the server.\n try {\n await deps.intents.abort(intent.transferId);\n await stores.backstop.removeByKey(intent.transferId);\n } catch {\n /* stays locally aborted; converged at the next resume */\n }\n report.conflicted.push(intent.transferId);\n continue;\n }\n let payload: IntentPayload;\n try {\n payload = validatePayload(await deps.decryptPayload(intent.payload));\n } catch {\n report.failed.push(intent.transferId);\n continue;\n }\n jobs.push({\n transferId: intent.transferId,\n payload,\n journaled: await stores.deliveryJournal.byTransfer(intent.transferId),\n });\n }\n return jobs;\n}\n\n/** One batched blob read across every intent (§7 start() posture). */\nasync function fetchSources(deps: MachineDeps, jobs: ResumeJob[]): Promise<Map<string, SphereToken>> {\n const needed = new Set<string>();\n for (const job of jobs) {\n for (const op of buildOps(job.payload)) {\n if (op.kind === 'direct' && job.journaled.has(op.opIndex)) continue;\n needed.add(op.sourceTokenId);\n }\n }\n const decoded = new Map<string, SphereToken>();\n if (needed.size === 0) return decoded;\n let blobs: Map<string, Uint8Array>;\n try {\n blobs = await deps.storage.getBlobs([...needed]);\n } catch {\n return decoded; // jobs that needed a source fail closed below\n }\n const engine = deps.engine();\n for (const [tokenId, bytes] of blobs) {\n try {\n decoded.set(tokenId, await engine.decodeToken({ tokenId, token: bytes }));\n } catch (err) {\n logger.warn('PaymentsV2', `resume: source ${tokenId} did not decode — ${String(err)}`);\n }\n }\n return decoded;\n}\n\nasync function runOne(ctx: RunCtx, job: ResumeJob, report: ResumeReport): Promise<void> {\n const mine = new Map<string, SphereToken>();\n for (const op of buildOps(job.payload)) {\n if (op.kind === 'direct' && job.journaled.has(op.opIndex)) continue;\n const token = ctx.sources.get(op.sourceTokenId);\n if (token === undefined) {\n report.failed.push(job.transferId); // fail closed: intent stays open, untouched\n return;\n }\n // The blob is the authority on what a source carries — the same rule the send\n // path applies at materialize. A durable intent labelled whole whose named\n // source actually holds coins would move them while history records assets: [].\n if (isWholeIntent(job.payload) && token.valueEnvelope === 'bare_collection') {\n logger.warn(\n 'PaymentsV2',\n `resume: token intent ${job.transferId} names a source carrying coin value — refusing`\n );\n report.failed.push(job.transferId);\n return;\n }\n mine.set(op.sourceTokenId, token);\n }\n try {\n await ctx.machine.resumeIntent({\n transferId: job.transferId,\n payload: job.payload,\n sources: mine,\n journaled: job.journaled,\n });\n report.resumed.push(job.transferId);\n } catch (err) {\n await classifyResumeFailure(ctx.deps, ctx.stores, job.transferId, err, report);\n }\n}\n\nasync function classifyResumeFailure(\n deps: MachineDeps,\n stores: MachineStores,\n transferId: string,\n err: unknown,\n report: ResumeReport\n): Promise<void> {\n if (classifyError(err) === 'conflict') {\n // E.2 pure lost race — nothing was delivered under this intent: soft-abort,\n // never apply the foreign proof; the caller re-plans under a NEW transferId.\n try {\n await deps.intents.abort(transferId);\n await stores.backstop.removeByKey(transferId);\n } catch {\n /* retried at the next resume */\n }\n report.conflicted.push(transferId);\n return;\n }\n const code = err !== null && typeof err === 'object' ? (err as { code?: unknown }).code : undefined;\n if (code === 'SPLIT_CHECKPOINT_LOST' || code === 'CHECKPOINT_TRUSTBASE_MISMATCH') {\n deps.emit('transfer:attention', { transferId, code: ATTENTION_CHECKPOINT_STUCK, detail: String(code) });\n }\n report.failed.push(transferId);\n}\n\n/**\n * A token-addressed intent is EXACTLY one named source and never a split. Both are\n * enforced here rather than trusted: a second leg would make `settlePartial`\n * reachable with every conflict amount 0n, so a remainder of '0' would complete the\n * intent and report success for a leg that never landed.\n */\nfunction validateCoinPayload(c: Partial<CoinIntentPayload>): CoinIntentPayload {\n if (typeof c.coinId !== 'string' || typeof c.amount !== 'string') {\n throw new SphereError('intent payload is missing coinId/amount', 'VALIDATION_ERROR');\n }\n const s = c.split;\n if (\n s !== undefined &&\n (typeof s.tokenId !== 'string' || typeof s.splitAmount !== 'string' || typeof s.remainderAmount !== 'string')\n ) {\n throw new SphereError('intent payload split spec is malformed', 'VALIDATION_ERROR');\n }\n return { ...(c as CoinIntentPayload), kind: 'coin' };\n}\n\nfunction validateWholePayload(p: Partial<WholeIntentPayload>): WholeIntentPayload {\n if (p.direct?.length !== 1 || typeof p.direct[0] !== 'string' || p.direct[0] === '') {\n throw new SphereError(\n 'token intent payload must name exactly one source token',\n 'VALIDATION_ERROR'\n );\n }\n if (p.split !== undefined) {\n throw new SphereError('token intent payload cannot carry a split', 'VALIDATION_ERROR');\n }\n return { ...(p as WholeIntentPayload), kind: 'whole', direct: [p.direct[0]] };\n}\n\nfunction validatePayload(raw: unknown): IntentPayload {\n const p = raw !== null && typeof raw === 'object' ? (raw as Partial<IntentPayload>) : null;\n if (p === null || p.v !== 2 || !Array.isArray(p.direct) || p.direct.some((t) => typeof t !== 'string')) {\n throw new SphereError(\n `unsupported intent payload shape (v=${String((raw as { v?: unknown } | null)?.v)}) — not resumable`,\n 'VALIDATION_ERROR'\n );\n }\n if (typeof p.recipient !== 'string') {\n throw new SphereError('intent payload is missing recipient', 'VALIDATION_ERROR');\n }\n // ABSENT migrates to 'coin' (the only pre-#777 shape); an EXPLICIT unknown one\n // does NOT. 'coinless' is 0.17.0's spelling of 'whole' — durable server state, so\n // a client that wrote one must still resume it.\n const kind = p.kind ?? 'coin';\n if (kind !== 'coin' && kind !== 'whole' && kind !== 'coinless') {\n throw new SphereError(\n `unsupported intent kind '${String(kind)}' — not resumable by this client`,\n 'VALIDATION_ERROR'\n );\n }\n return kind === 'coin'\n ? validateCoinPayload(p as Partial<CoinIntentPayload>)\n : validateWholePayload(p as Partial<WholeIntentPayload>);\n}\n","// §7 in-session convergence: the heartbeat timing cell (in-memory timer +\n// backoff value ONLY), the single convergence pass, and the §4\n// pendingTransfers() on-read derivation. The facade owns lifecycle,\n// the resume single-flight, and the active-op ownership registry.\n\nimport type { PendingTransfer } from './api';\nimport type { DeliveryPort } from './ports';\nimport type { DeliveryJournalEntry, IntentBackstopEntry, ShortfallEntry } from './stores';\nimport type { CoinIntentPayload, IntentPayload } from './machine/types';\nimport { retryAfterMsOf, type MachineStores, type ReplayDeps } from './machine/journal';\nimport { resumeAll } from './machine/resume';\nimport type { MachineDeps } from './machine/TransferMachine';\n\n// Backoff: seed 5 s, ×2 per unproductive pass, cap 120 s; reset on progress\n// and on connection recovery; a surfaced Retry-After floors the next pass.\nexport const HEARTBEAT_SEED_MS = 5_000;\nexport const HEARTBEAT_CAP_MS = 120_000;\n\nexport interface ConvergeOutcome {\n progress: boolean;\n retryAfterMs: number | null;\n}\n\ninterface HeartbeatDeps {\n now: () => number;\n onTick: () => void;\n}\n\nexport class ConvergenceHeartbeat {\n private timer: ReturnType<typeof setTimeout> | null = null;\n private delayMs = HEARTBEAT_SEED_MS;\n private notBefore = 0;\n private running = false;\n\n constructor(private readonly deps: HeartbeatDeps) {}\n\n start(): void {\n this.running = true;\n this.delayMs = HEARTBEAT_SEED_MS;\n this.notBefore = 0;\n }\n\n /** §7 quiescence unchanged: a mid-backoff stop() cancels cleanly. */\n stop(): void {\n this.running = false;\n this.clearTimer();\n }\n\n /** Reset to seed on progress, ×2 to the cap otherwise; idle stops rescheduling. */\n settle(outcome: ConvergeOutcome, pending: boolean): void {\n if (outcome.retryAfterMs !== null) {\n this.notBefore = Math.max(this.notBefore, this.deps.now() + outcome.retryAfterMs);\n }\n if (!pending) {\n // Never clearTimer here: an arm() for work that appeared AFTER this\n // pass read the pending set must survive the pass's idle settle — the\n // armed tick re-reads the stores and idles itself if truly quiescent.\n this.delayMs = HEARTBEAT_SEED_MS;\n return;\n }\n const delay = outcome.progress ? HEARTBEAT_SEED_MS : this.delayMs;\n this.delayMs = Math.min(delay * 2, HEARTBEAT_CAP_MS);\n this.schedule(delay);\n }\n\n /** New pending work (keep-open park / journaled delivery / mint hold): prompt retry. */\n arm(): void {\n if (!this.running) return;\n this.delayMs = Math.min(HEARTBEAT_SEED_MS * 2, HEARTBEAT_CAP_MS);\n this.schedule(HEARTBEAT_SEED_MS);\n }\n\n /** connection:status recovery: the backoff resets; a pending tick re-fires at the seed. */\n recovered(): void {\n this.delayMs = HEARTBEAT_SEED_MS;\n if (this.timer !== null) this.arm();\n }\n\n private schedule(delayMs: number): void {\n this.clearTimer();\n if (!this.running) return;\n const floored = Math.max(delayMs, this.notBefore - this.deps.now());\n this.timer = setTimeout(() => {\n this.timer = null;\n this.deps.onTick();\n }, floored);\n }\n\n private clearTimer(): void {\n if (this.timer !== null) clearTimeout(this.timer);\n this.timer = null;\n }\n}\n\nexport interface ConvergerDeps {\n machineDeps: MachineDeps;\n stores: MachineStores;\n delivery: DeliveryPort;\n reconcile(report: { resumed: string[]; conflicted: string[]; open: string[] }): Promise<void>;\n refreshView(): Promise<void>;\n replayMints(): Promise<number>;\n replayNftMints(): Promise<number>;\n /** §7 ownership: the pass never adopts an op whose machine runs in-process. */\n isActiveOp(id: string): boolean;\n emit(event: string, payload: unknown): void;\n now(): number;\n}\n\nexport class Converger {\n constructor(private readonly deps: ConvergerDeps) {}\n\n /** Resume open intents, then drain the delivery + mint journals (all idempotent). */\n async convergeOnce(): Promise<ConvergeOutcome> {\n let progress = false;\n let retryAfterMs: number | null = null;\n try {\n progress = await this.resumePass();\n } catch (err) {\n retryAfterMs = retryAfterMsOf(err);\n }\n try {\n const stats = await this.deps.stores.deliveryJournal.replay(this.replayDeps());\n progress = progress || stats.delivered > 0;\n } catch (err) {\n retryAfterMs ??= retryAfterMsOf(err);\n }\n // Caught apart: an unreadable coin journal must not starve the NFT one.\n for (const replay of [() => this.deps.replayMints(), () => this.deps.replayNftMints()]) {\n try {\n progress = (await replay()) > 0 || progress;\n } catch (err) {\n retryAfterMs ??= retryAfterMsOf(err);\n }\n }\n return { progress, retryAfterMs };\n }\n\n /** §4 heartbeat predicate — read fresh from the §6 stores, never cached. */\n async pendingWork(): Promise<boolean> {\n const [backstop, journal, mints, nftMints] = await Promise.all([\n this.deps.stores.backstop.list(),\n this.deps.stores.deliveryJournal.list(),\n this.deps.stores.mintJournal.list(),\n this.deps.stores.nftMintJournal.list(),\n ]);\n const mintsOpen = mints.length > 0 || nftMints.length > 0;\n return backstop.length > 0 || journal.some((e) => e.undeliverable !== true) || mintsOpen;\n }\n\n private async resumePass(): Promise<boolean> {\n const report = await resumeAll(this.filteredMachineDeps(), {\n isLocallyActive: (id) => this.deps.isActiveOp(id),\n });\n const progress = report.resumed.length > 0 || report.conflicted.length > 0;\n await this.deps.reconcile({\n resumed: report.resumed,\n conflicted: report.conflicted,\n open: report.failed,\n });\n if (progress) await this.deps.refreshView().catch(() => undefined);\n return progress;\n }\n\n private filteredMachineDeps(): MachineDeps {\n const intents = this.deps.machineDeps.intents;\n return {\n ...this.deps.machineDeps,\n intents: {\n ...intents,\n listOpen: async () =>\n (await intents.listOpen()).filter((intent) => !this.deps.isActiveOp(intent.transferId)),\n },\n };\n }\n\n private replayDeps(): ReplayDeps {\n return {\n delivery: this.deps.delivery,\n now: () => this.deps.now(),\n // sphere#487: a replayed leg carries the sender's name too — the machine\n // deps hold the one live getter, so replay can never drift from a send.\n ...(this.deps.machineDeps.ownNametag !== undefined\n ? { ownNametag: this.deps.machineDeps.ownNametag }\n : {}),\n attention: (transferId, code, detail) => {\n this.deps.emit(\n 'transfer:attention',\n detail === undefined ? { transferId, code } : { transferId, code, detail }\n );\n },\n };\n }\n}\n\n/** §4 pendingTransfers(): derived ON READ from the §6 stores — never cached. */\nexport async function derivePendingTransfers(\n stores: MachineStores,\n decryptPayload: (envelope: string) => Promise<unknown>\n): Promise<PendingTransfer[]> {\n const [backstop, journal, shortfalls] = await Promise.all([\n stores.backstop.list(),\n stores.deliveryJournal.list(),\n stores.shortfalls.list(),\n ]);\n const byTransfer = groupJournal(journal);\n const out: PendingTransfer[] = [];\n const seen = new Set<string>();\n for (const entry of backstop) {\n // abortPending/aborted rows are rollbacks in convergence, not user-visible sends.\n if (entry.disposition !== 'open') continue;\n seen.add(entry.transferId);\n out.push(await openRow(entry, byTransfer.get(entry.transferId) ?? [], decryptPayload));\n }\n for (const [transferId, entries] of byTransfer) {\n if (seen.has(transferId)) continue;\n seen.add(transferId);\n out.push(journalOnlyRow(transferId, entries));\n }\n for (const entry of shortfalls) {\n if (!seen.has(entry.transferId)) out.push(shortfallRow(entry));\n }\n return out;\n}\n\n/**\n * #737: the source tokenIds each still-open intent pins, derived ON READ from the\n * same §6 backstop `derivePendingTransfers` reads — the pin needs no store of its\n * own, so a restart re-derives it instead of re-offering the tokens as spendable.\n */\nexport async function deriveOpenIntentHolds(\n stores: MachineStores,\n decryptPayload: (envelope: string) => Promise<unknown>\n): Promise<{ open: Map<string, string[]>; complete: boolean }> {\n const holds = new Map<string, string[]>();\n let complete = true;\n for (const entry of await stores.backstop.list()) {\n if (entry.disposition !== 'open') continue;\n let payload: Partial<IntentPayload> | null = null;\n try {\n const raw = await decryptPayload(entry.payloadEnvelope);\n if (raw !== null && typeof raw === 'object') payload = raw as Partial<IntentPayload>;\n } catch {\n // Undecodable envelope on a STILL-OPEN intent: its sources are unknown, so\n // they cannot be proven safe. Report incompleteness — the caller fails\n // closed rather than treating \"unknown sources\" as \"no sources\" (#738).\n complete = false;\n continue;\n }\n if (payload === null) {\n complete = false;\n continue;\n }\n const direct = Array.isArray(payload?.direct) ? payload.direct.filter((id) => typeof id === 'string') : [];\n const split = typeof payload?.split?.tokenId === 'string' ? [payload.split.tokenId] : [];\n holds.set(entry.transferId, [...direct, ...split]);\n }\n return { open: holds, complete };\n}\n\nfunction groupJournal(journal: DeliveryJournalEntry[]): Map<string, DeliveryJournalEntry[]> {\n const byTransfer = new Map<string, DeliveryJournalEntry[]>();\n for (const entry of journal) {\n const mine = byTransfer.get(entry.transferId);\n if (mine === undefined) byTransfer.set(entry.transferId, [entry]);\n else mine.push(entry);\n }\n return byTransfer;\n}\n\nasync function openRow(\n entry: IntentBackstopEntry,\n journal: DeliveryJournalEntry[],\n decryptPayload: (envelope: string) => Promise<unknown>\n): Promise<PendingTransfer> {\n let payload: Partial<IntentPayload> | null = null;\n try {\n const raw = await decryptPayload(entry.payloadEnvelope);\n if (raw !== null && typeof raw === 'object') payload = raw as Partial<IntentPayload>;\n } catch {\n payload = null; // undecodable envelope: surface the row, not the fields\n }\n const total = Array.isArray(payload?.direct)\n ? payload.direct.length + (payload.split !== undefined ? 1 : 0)\n : 0;\n const certified = distinctOpCount(journal);\n return {\n transferId: entry.transferId,\n kind: 'open',\n recipient: typeof payload?.recipient === 'string' ? payload.recipient : '',\n ...subject(payload),\n legs: { certified, total: Math.max(total, certified) },\n deliveryPending: journal.length > 0,\n createdAt: entry.createdAt,\n };\n}\n\n/**\n * What the row is FOR: a coin and an amount, or the token being moved. A\n * token-addressed intent names no coin, so it renders as its token rather than\n * as `coinId: ''` / `amount: ''`.\n */\nfunction subject(\n payload: Partial<IntentPayload> | null\n): { coinId: string; amount: string; tokenId?: string } {\n // Both spellings: this reads the RAW decrypted payload, never normalised by\n // validatePayload, so a 0.17-written intent still says 'coinless'.\n const rawKind = (payload as { kind?: string } | null)?.kind;\n if (rawKind === 'whole' || rawKind === 'coinless') {\n const tokenId = payload?.direct?.[0];\n return { coinId: '', amount: '', ...(typeof tokenId === 'string' ? { tokenId } : {}) };\n }\n const coin = payload as Partial<CoinIntentPayload> | null;\n return {\n coinId: typeof coin?.coinId === 'string' ? coin.coinId : '',\n amount: typeof coin?.amount === 'string' ? coin.amount : '',\n };\n}\n\n/** The intent already completed but a deposit is still owed from the journal. */\nfunction journalOnlyRow(transferId: string, entries: DeliveryJournalEntry[]): PendingTransfer {\n const certified = distinctOpCount(entries);\n return {\n transferId,\n kind: 'open',\n recipient: entries[0].recipientPubkey,\n coinId: '',\n amount: '',\n legs: { certified, total: certified },\n deliveryPending: true,\n createdAt: 0,\n };\n}\n\nfunction shortfallRow(entry: ShortfallEntry): PendingTransfer {\n return {\n transferId: entry.transferId,\n kind: 'shortfall',\n recipient: entry.recipient,\n coinId: entry.coinId,\n amount: entry.remainingAmount,\n legs: { certified: entry.committedTokenIds.length, total: entry.committedTokenIds.length },\n deliveryPending: false,\n createdAt: entry.createdAt,\n };\n}\n\nfunction distinctOpCount(entries: readonly DeliveryJournalEntry[]): number {\n return new Set(entries.map((entry) => entry.opIndex)).size;\n}\n","// §5.4 Reservations — whole-token set semantics, fully synchronous. The queue\n// reserves whole tokens only (doc §5.4), so a token is either free or held by\n// exactly one reservation; partial-amount arithmetic was dead surface (#727).\n\nexport interface ReservationRequest {\n readonly tokenId: string;\n}\n\nexport class ReservationLedger {\n private readonly reservations = new Map<string, ReadonlySet<string>>();\n private readonly tokenHolder = new Map<string, string>();\n // #738: the held-set is RECONSTRUCTED from the open intents, so until\n // IntentPins proves every one of them \"no holder\" means unknown, not free.\n private authoritative = false;\n\n /** Sole writer: IntentPins.sync(), true only if it reconstructed every open intent.\n * Returns whether the gate actually moved, so callers signal transitions, not passes. */\n setAuthoritative(value: boolean): boolean {\n const moved = this.authoritative !== value;\n this.authoritative = value;\n return moved;\n }\n\n /** Non-null while the held-set is unproven: nothing plans, nothing reads free. */\n unprovenReason(): string | null {\n return this.authoritative\n ? null\n : 'Cannot yet verify which tokens are held by transfers still converging — spending is paused until that check succeeds';\n }\n\n // All-or-nothing: every entry is validated before any state mutates.\n reserve(reservationId: string, entries: readonly ReservationRequest[]): void {\n if (entries.length === 0) throw new Error('EMPTY_RESERVATION');\n if (this.reservations.has(reservationId)) throw new Error('DUPLICATE_RESERVATION_ID');\n const tokenIds = new Set(entries.map((e) => e.tokenId));\n for (const tokenId of tokenIds) {\n if (this.tokenHolder.has(tokenId)) throw new Error('INSUFFICIENT_FREE_AMOUNT');\n }\n this.reservations.set(reservationId, tokenIds);\n for (const tokenId of tokenIds) this.tokenHolder.set(tokenId, reservationId);\n }\n\n commit(reservationId: string): void {\n this.release(reservationId);\n }\n\n cancel(reservationId: string): void {\n this.release(reservationId);\n }\n\n cancelForToken(tokenId: string, excludeReservationId?: string): string[] {\n const holder = this.tokenHolder.get(tokenId);\n if (holder === undefined || holder === excludeReservationId) return [];\n this.release(holder);\n return [holder];\n }\n\n getFreeAmount(tokenId: string, tokenAmount: bigint): bigint {\n return this.tokenHolder.has(tokenId) ? 0n : tokenAmount;\n }\n\n /** #737: who pins this token — the reporting side reads it so a held token is never called spendable. */\n holderOf(tokenId: string): string | undefined {\n return this.tokenHolder.get(tokenId);\n }\n\n tokensOf(reservationId: string): readonly string[] {\n return [...(this.reservations.get(reservationId) ?? [])];\n }\n\n clear(): void {\n this.reservations.clear();\n this.tokenHolder.clear();\n }\n\n private release(reservationId: string): void {\n const tokenIds = this.reservations.get(reservationId);\n if (!tokenIds) return;\n this.reservations.delete(reservationId);\n for (const tokenId of tokenIds) this.tokenHolder.delete(tokenId);\n }\n}\n","// #737: the ledger holds exactly the sources of the intents the §6 backstop still\n// calls OPEN — adopting what a dead session left open (that spend may be on-chain)\n// and dropping what stopped being open (source spent, or ours again).\n\nimport type { ReservationLedger } from './ledger';\n\nexport interface IntentPinsDeps {\n readonly ledger: ReservationLedger;\n /** Open intents → source tokenIds, re-derived per call; `complete: false` if any could not be. */\n readonly openIntents: () => Promise<{ open: Map<string, string[]>; complete: boolean }>;\n readonly isActive: (transferId: string) => boolean;\n readonly release: (tokenId: string) => void;\n readonly changed: () => void;\n}\n\nexport class IntentPins {\n private readonly pinned = new Set<string>();\n\n constructor(private readonly deps: IntentPinsDeps) {}\n\n /** The keep-open reservation IS this intent's pin from now on. */\n adopt(transferId: string): void {\n this.pinned.add(transferId);\n }\n\n async sync(): Promise<void> {\n // A throw leaves the ledger unproven — never an empty held-set (#738).\n const { open, complete } = await this.deps.openIntents();\n let changed = false;\n for (const transferId of [...this.pinned]) {\n if (open.has(transferId) || this.deps.isActive(transferId)) continue;\n this.pinned.delete(transferId);\n for (const tokenId of this.deps.ledger.tokensOf(transferId)) this.deps.release(tokenId);\n this.deps.ledger.cancel(transferId);\n changed = true;\n }\n for (const [transferId, tokenIds] of open) {\n if (this.deps.isActive(transferId)) continue;\n this.pinned.add(transferId);\n changed = this.pin(transferId, tokenIds) || changed;\n }\n const gateMoved = this.deps.ledger.setAuthoritative(complete);\n if (changed || gateMoved) this.deps.changed();\n }\n\n /** Every pass, not just on adoption; the free subset, since a partial pin beats none. */\n private pin(transferId: string, tokenIds: readonly string[]): boolean {\n if (this.deps.ledger.tokensOf(transferId).length > 0) return false;\n const free = tokenIds.filter((tokenId) => this.deps.ledger.holderOf(tokenId) === undefined);\n if (free.length === 0) return false;\n this.deps.ledger.reserve(transferId, free.map((tokenId) => ({ tokenId })));\n return true;\n }\n}\n","// §5.3 CoinSelector — pure function, no I/O, no engine, no blobs.\n\nexport interface PoolEntry {\n readonly tokenId: string;\n readonly amount: bigint;\n}\n\nexport interface SplitSpec {\n readonly tokenId: string;\n readonly splitAmount: bigint;\n readonly remainderAmount: bigint;\n}\n\nexport interface SelectionPlan {\n readonly direct: readonly string[];\n readonly split?: SplitSpec;\n}\n\nexport interface SelectorStats {\n combinationsExamined: number;\n}\n\nexport interface SelectorOptions {\n readonly workBudget?: number;\n /** Instrumentation out-param: pins the tested work-budget invariant (select.test.ts). */\n readonly stats?: SelectorStats;\n}\n\nexport const DEFAULT_WORK_BUDGET = 20_000;\nexport const MAX_COMBINATION_SIZE = 5;\n\ninterface ComboSearch {\n examined: number;\n readonly budget: number;\n}\n\nexport function selectCoins(\n pool: readonly PoolEntry[],\n target: bigint,\n options: SelectorOptions = {}\n): SelectionPlan | null {\n if (target <= 0n) return null;\n const candidates = pool.filter((e) => e.amount > 0n).sort(byAmountAscending);\n let total = 0n;\n for (const c of candidates) total += c.amount;\n if (total < target) return null;\n\n const single = candidates.find((c) => c.amount === target);\n if (single) return { direct: [single.tokenId] };\n\n const search: ComboSearch = {\n examined: 0,\n budget: options.workBudget ?? DEFAULT_WORK_BUDGET,\n };\n const combo = findExactCombination(candidates, target, search);\n if (options.stats) options.stats.combinationsExamined = search.examined;\n if (combo) return { direct: combo.map((c) => c.tokenId) };\n\n return greedyWithSplit(candidates, target);\n}\n\nfunction byAmountAscending(a: PoolEntry, b: PoolEntry): number {\n if (a.amount !== b.amount) return a.amount < b.amount ? -1 : 1;\n return a.tokenId < b.tokenId ? -1 : a.tokenId > b.tokenId ? 1 : 0;\n}\n\nfunction greedyWithSplit(\n sortedAscending: readonly PoolEntry[],\n target: bigint\n): SelectionPlan | null {\n const direct: string[] = [];\n let sum = 0n;\n for (const candidate of sortedAscending) {\n const next = sum + candidate.amount;\n if (next < target) {\n direct.push(candidate.tokenId);\n sum = next;\n } else if (next === target) {\n direct.push(candidate.tokenId);\n return { direct };\n } else {\n const splitAmount = target - sum;\n return {\n direct,\n split: {\n tokenId: candidate.tokenId,\n splitAmount,\n remainderAmount: candidate.amount - splitAmount,\n },\n };\n }\n }\n return null;\n}\n\nfunction findExactCombination(\n sortedAscending: readonly PoolEntry[],\n target: bigint,\n search: ComboSearch\n): readonly PoolEntry[] | null {\n const maxSize = Math.min(MAX_COMBINATION_SIZE, sortedAscending.length);\n for (let size = 2; size <= maxSize; size++) {\n if (search.examined >= search.budget) return null;\n const window = orderNearestTo(sortedAscending, target / BigInt(size));\n const found = searchCombinationsOfSize(window, size, target, search);\n if (found) return found;\n }\n return null;\n}\n\n// Window ordering: candidates nearest target/size are tried first, so the\n// budget spends its work where exact sums are most likely.\nfunction orderNearestTo(entries: readonly PoolEntry[], pivot: bigint): PoolEntry[] {\n const distance = (e: PoolEntry): bigint =>\n e.amount >= pivot ? e.amount - pivot : pivot - e.amount;\n return [...entries].sort((a, b) => {\n const da = distance(a);\n const db = distance(b);\n if (da !== db) return da < db ? -1 : 1;\n return byAmountAscending(a, b);\n });\n}\n\nfunction searchCombinationsOfSize(\n window: readonly PoolEntry[],\n size: number,\n target: bigint,\n search: ComboSearch\n): readonly PoolEntry[] | null {\n const chosen: PoolEntry[] = [];\n const recurse = (start: number, sum: bigint): readonly PoolEntry[] | null => {\n if (chosen.length === size) {\n search.examined += 1;\n return sum === target ? [...chosen] : null;\n }\n for (let i = start; i < window.length; i++) {\n if (search.examined >= search.budget) return null;\n chosen.push(window[i]);\n const found = recurse(i + 1, sum + window[i].amount);\n chosen.pop();\n if (found) return found;\n }\n return null;\n };\n return recurse(0, 0n);\n}\n","// §5.4 SpendQueue — per-coin FIFO with skip-ahead; plan+reserve is one\n// synchronous critical section (no await between free-view read and reserve).\n\nimport { SphereError } from '../../../core/errors';\nimport { selectCoins, type PoolEntry, type SelectionPlan } from './selector';\nimport type { ReservationLedger } from './ledger';\n\nexport const QUEUE_TIMEOUT_MS = 30_000;\nexport const QUEUE_MAX_SIZE = 100;\n\nexport interface PlannedSpend {\n readonly reservationId: string;\n readonly plan: SelectionPlan;\n}\n\nexport type PlanOutcome =\n | { readonly kind: 'planned'; readonly spend: PlannedSpend }\n | { readonly kind: 'queued'; readonly settled: Promise<PlannedSpend> };\n\nexport interface SpendQueueDeps {\n readonly ledger: ReservationLedger;\n readonly getPool: (coinId: string) => readonly PoolEntry[];\n /** #777: is this NAMED token spendable whole right now? Same gates as pool(). */\n readonly spendableToken?: (tokenId: string) => boolean;\n readonly workBudget?: number;\n}\n\ninterface QueueEntry {\n readonly id: string;\n readonly coinId: string;\n readonly amount: bigint;\n readonly enqueuedAt: number;\n readonly resolve: (spend: PlannedSpend) => void;\n readonly reject: (error: Error) => void;\n readonly timer: ReturnType<typeof setTimeout>;\n}\n\ninterface ExpectedChange {\n readonly coinId: string;\n readonly amount: bigint;\n}\n\ninterface FreeView {\n readonly freeView: PoolEntry[];\n readonly freeTotal: bigint;\n /** Held by a reservation — an open intent's sources stay pinned until it converges. */\n readonly pinnedTotal: bigint;\n readonly pinnedBy: number;\n /** #738: non-null = the held-set is unproven, so NOTHING in this view is free. */\n readonly unproven: string | null;\n}\n\n/**\n * #737: the CODE is load-bearing (dApps key on it) but \"insufficient balance\" sent\n * a user auditing a treasury that was never short — every token was pinned by an\n * intent still converging. When something is pinned, the message says so.\n */\nfunction insufficientBalance(view: FreeView, amount: bigint): SphereError {\n if (view.unproven !== null) return new SphereError(view.unproven, 'SEND_INSUFFICIENT_BALANCE');\n const message =\n view.pinnedTotal > 0n\n ? `Insufficient spendable balance: need ${amount.toString()}, ${view.freeTotal.toString()} free, ` +\n `${view.pinnedTotal.toString()} pinned by ${String(view.pinnedBy)} transfer(s) still converging — ` +\n 'see payments.pendingTransfers(); do not re-send.'\n : 'Insufficient balance for this transaction';\n return new SphereError(message, 'SEND_INSUFFICIENT_BALANCE');\n}\n\nexport class SpendQueue {\n private readonly queues = new Map<string, QueueEntry[]>();\n private readonly expectedChange = new Map<string, ExpectedChange>();\n private destroyed = false;\n\n constructor(private readonly deps: SpendQueueDeps) {}\n\n plan(reservationId: string, request: { coinId: string; amount: string }): PlanOutcome {\n if (this.destroyed) {\n throw new SphereError('Module has been destroyed', 'MODULE_DESTROYED');\n }\n const amount = parseAmount(request.amount);\n const view = this.freeView(request.coinId);\n const { freeView, freeTotal } = view;\n if (freeTotal + this.expectedChangeTotal(request.coinId) < amount) {\n throw insufficientBalance(view, amount);\n }\n const plan = selectCoins(freeView, amount, { workBudget: this.deps.workBudget });\n if (plan !== null) {\n this.reservePlan(reservationId, plan, freeView);\n return { kind: 'planned', spend: { reservationId, plan } };\n }\n return { kind: 'queued', settled: this.enqueue(reservationId, request.coinId, amount) };\n }\n\n /**\n * #777: reserve a NAMED coinless source. Never queues — there is nothing to wait\n * for. A coin plan waits because some OTHER combination may free up; a named\n * token is either free now or held by a reservation that only its own transfer\n * can release, so queueing would block until a timeout on a spend that cannot\n * become possible.\n */\n planWhole(reservationId: string, tokenId: string): PlannedSpend {\n if (this.destroyed) {\n throw new SphereError('Module has been destroyed', 'MODULE_DESTROYED');\n }\n // #738 fail-closed, the same gate freeView() applies: while the held-set is\n // unproven nothing is spendable, or a restart could double-spend a source an\n // open intent already holds.\n const unproven = this.deps.ledger.unprovenReason();\n if (unproven !== null) {\n throw new SphereError(`Cannot spend yet: ${unproven}`, 'SEND_SYNC_PENDING');\n }\n if (this.deps.spendableToken?.(tokenId) !== true) {\n throw new SphereError(`Token ${tokenId} is not a spendable holding`, 'VALIDATION_ERROR');\n }\n const holder = this.deps.ledger.holderOf(tokenId);\n if (holder !== undefined) {\n throw new SphereError(\n `Token ${tokenId} is already reserved by transfer ${holder}`,\n 'VALIDATION_ERROR'\n );\n }\n this.deps.ledger.reserve(reservationId, [{ tokenId }]);\n return { reservationId, plan: { direct: [tokenId] } };\n }\n\n /**\n * The sources `plan()` WOULD pick right now, reserving nothing and queueing\n * nothing — a read-only probe used to warm blobs while the user is still\n * looking at the confirm screen.\n *\n * Deliberately side-effect free: reserving here would pin the user's balance\n * across think-time and strand it if they never press send. The consequence is\n * that the real `plan()` may pick differently (inventory moves, another send\n * reserves first); callers must treat the result as a HINT and tolerate a miss,\n * never as a commitment that these sources will be spent.\n */\n previewSelection(request: { coinId: string; amount: string }): readonly string[] {\n if (this.destroyed) return [];\n let amount: bigint;\n try {\n amount = parseAmount(request.amount);\n } catch {\n return []; // a malformed amount is the caller's problem at plan() time, not here\n }\n const { freeView, freeTotal } = this.freeView(request.coinId);\n if (freeTotal < amount) return []; // would throw or queue — nothing worth warming\n const plan = selectCoins(freeView, amount, { workBudget: this.deps.workBudget });\n if (plan === null) return [];\n return [...plan.direct, ...(plan.split !== undefined ? [plan.split.tokenId] : [])];\n }\n\n // Coverage math: free + Σ declared expected change of in-flight sends —\n // never the full amount of in-flight sources (§5.3).\n declareExpectedChange(transferId: string, coinId: string, amount: bigint): void {\n this.expectedChange.set(transferId, { coinId, amount });\n }\n\n clearExpectedChange(transferId: string): void {\n this.expectedChange.delete(transferId);\n }\n\n notifyChange(coinId: string): void {\n if (this.destroyed) return;\n const entries = this.queues.get(coinId);\n if (!entries) return;\n let i = 0;\n while (i < entries.length) {\n const entry = entries[i];\n if (this.tryServe(entry) === 'blocked') {\n i += 1;\n continue;\n }\n clearTimeout(entry.timer);\n entries.splice(i, 1);\n }\n if (entries.length === 0) this.queues.delete(coinId);\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n for (const entries of this.queues.values()) {\n for (const entry of entries) {\n clearTimeout(entry.timer);\n entry.reject(new SphereError('Module destroyed', 'MODULE_DESTROYED'));\n }\n }\n this.queues.clear();\n this.expectedChange.clear();\n }\n\n private tryServe(entry: QueueEntry): 'served' | 'rejected' | 'blocked' {\n if (Date.now() - entry.enqueuedAt > QUEUE_TIMEOUT_MS) {\n entry.reject(new SphereError('Send queue timeout', 'SEND_QUEUE_TIMEOUT'));\n return 'rejected';\n }\n const view = this.freeView(entry.coinId);\n const { freeView, freeTotal } = view;\n if (freeTotal + this.expectedChangeTotal(entry.coinId) < entry.amount) {\n entry.reject(insufficientBalance(view, entry.amount));\n return 'rejected';\n }\n const plan = selectCoins(freeView, entry.amount, { workBudget: this.deps.workBudget });\n if (plan === null) return 'blocked';\n try {\n this.reservePlan(entry.id, plan, freeView);\n } catch (e) {\n entry.reject(e instanceof Error ? e : new Error(String(e)));\n return 'rejected';\n }\n entry.resolve({ reservationId: entry.id, plan });\n return 'served';\n }\n\n private enqueue(id: string, coinId: string, amount: bigint): Promise<PlannedSpend> {\n if (this.totalQueued() >= QUEUE_MAX_SIZE) {\n throw new SphereError('Send queue is full', 'SEND_QUEUE_FULL');\n }\n let resolve!: (spend: PlannedSpend) => void;\n let reject!: (error: Error) => void;\n const settled = new Promise<PlannedSpend>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n settled.catch(() => {});\n const timer = setTimeout(() => this.expire(id, coinId), QUEUE_TIMEOUT_MS);\n const entry: QueueEntry = { id, coinId, amount, enqueuedAt: Date.now(), resolve, reject, timer };\n let queue = this.queues.get(coinId);\n if (!queue) {\n queue = [];\n this.queues.set(coinId, queue);\n }\n queue.push(entry);\n return settled;\n }\n\n private expire(id: string, coinId: string): void {\n const entries = this.queues.get(coinId);\n if (!entries) return;\n const index = entries.findIndex((e) => e.id === id);\n if (index === -1) return;\n const [entry] = entries.splice(index, 1);\n entry.reject(new SphereError('Send queue timeout', 'SEND_QUEUE_TIMEOUT'));\n if (entries.length === 0) this.queues.delete(coinId);\n }\n\n // Whole-token semantics: only fully-free tokens enter the selector pool. What\n // the reservations hold back is counted too — the refusal has to name it (#737).\n private freeView(coinId: string): FreeView {\n const freeView: PoolEntry[] = [];\n let freeTotal = 0n;\n let pinnedTotal = 0n;\n const holders = new Set<string>();\n // #738: the same rule the reporter applies — while the held-set is unproven\n // nothing is free. Placed here because freeView() is what plan() AND the\n // queued path (tryServe) both go through; gating only plan() left a queued\n // entry servable through a closed gate.\n const unproven = this.deps.ledger.unprovenReason();\n for (const entry of this.deps.getPool(coinId)) {\n if (entry.amount <= 0n) continue;\n const holder = unproven === null ? this.deps.ledger.holderOf(entry.tokenId) : entry.tokenId;\n if (holder === undefined) {\n freeView.push(entry);\n freeTotal += entry.amount;\n } else {\n pinnedTotal += entry.amount;\n holders.add(holder);\n }\n }\n return { freeView, freeTotal, pinnedTotal, pinnedBy: holders.size, unproven };\n }\n\n private expectedChangeTotal(coinId: string): bigint {\n let total = 0n;\n for (const change of this.expectedChange.values()) {\n if (change.coinId === coinId) total += change.amount;\n }\n return total;\n }\n\n private reservePlan(\n reservationId: string,\n plan: SelectionPlan,\n freeView: readonly PoolEntry[]\n ): void {\n const pool = new Set(freeView.map((e) => e.tokenId));\n const tokenIds = [...plan.direct, ...(plan.split ? [plan.split.tokenId] : [])];\n for (const tokenId of tokenIds) {\n if (!pool.has(tokenId)) {\n throw new SphereError('Planned token missing from pool', 'VALIDATION_ERROR');\n }\n }\n this.deps.ledger.reserve(reservationId, tokenIds.map((tokenId) => ({ tokenId })));\n }\n\n private totalQueued(): number {\n let total = 0;\n for (const entries of this.queues.values()) total += entries.length;\n return total;\n }\n}\n\nfunction parseAmount(raw: string): bigint {\n if (!/^\\d+$/.test(raw)) {\n throw new SphereError('Invalid send amount', 'VALIDATION_ERROR');\n }\n const amount = BigInt(raw);\n if (amount <= 0n) {\n throw new SphereError('Send amount must be positive', 'VALIDATION_ERROR');\n }\n return amount;\n}\n","// Composition helper for PaymentsFacade: the injected-deps surface and the\n// wiring of every built component (§5 layout). Policy stays in PaymentsFacade.\n\nimport { coalesced } from './async';\nimport { hexToBytes } from '../../core/crypto';\nimport { decryptField, encryptField } from '../../core/field-encryption';\nimport type { ITokenEngine, SplitCheckpointStore } from '../../token-engine/engine';\nimport type { TransferResult } from '../../types';\n\nimport type { ConnectionStatus, SendRequest } from './api';\nimport { isWholeIntent } from './machine/payload-view';\nimport type { DeliveryPort, StoragePort } from './ports';\nimport type { ScopedKV } from './stores';\nimport { History, type HistoryClient } from './history/History';\nimport { InventoryView, type PriceReader, type RegistryReader } from './inventory/InventoryView';\nimport { Receive, type ReceivedRecord, type StoredIncoming } from './receive/Receive';\nimport { Requests, type RequestMemoCodec, type RequestsWireClient } from './requests/Requests';\nimport { deriveOpenIntentHolds } from './convergence';\nimport type { RestoreDeps } from './restore';\nimport { ReservationLedger } from './select/ledger';\nimport { IntentPins } from './select/pins';\nimport { SpendQueue } from './select/queue';\nimport { createMachineStores, type MachineStores } from './machine/journal';\nimport { TransferMachine, type MachineDeps } from './machine/TransferMachine';\n\n/**\n * F13 makes `mint(params, { transferId, opIndex })` idempotent-recoverable — a\n * same-seed re-CALL recovers the existing certification via the E.2 probe\n * (pinned by tests/unit/token-engine/mint-recovery.test.ts) — so replay needs\n * no pre-derivation, just a safe re-call; a non-advertising engine falls back\n * to the inventory-guard + hold path (never a blind re-mint).\n */\nexport interface DeterministicMintCapable {\n readonly deterministicMint: true;\n}\n\nexport function supportsDeterministicMint(\n engine: ITokenEngine\n): engine is ITokenEngine & DeterministicMintCapable {\n return (engine as Partial<DeterministicMintCapable>).deterministicMint === true;\n}\n\nexport interface RecipientInfo {\n chainPubkey: string;\n /** The recipient's PROVEN network — `null` when nothing proved one (§5.6). */\n network: string | null;\n nametag?: string;\n}\n\nexport interface FacadeSession {\n start(): Promise<void>;\n stop(): Promise<void>;\n subscribeStream(\n stream: 'inventory' | 'mailbox' | 'payment_requests',\n handler: () => void\n ): () => void;\n /** §5.1: the latched server syncEpoch ('' before first server contact). */\n currentEpoch(): string;\n /**\n * §5.1 restore hook — REQUIRED so an unwired restore protocol is a COMPILE\n * ERROR: handlers run and are AWAITED on a syncEpoch change BEFORE any\n * stream nudge resumes. The facade registers handleEpochChange here.\n */\n subscribeEpochChange(handler: (epoch: string) => Promise<void>): () => void;\n /**\n * The session's CURRENT status — REQUIRED, and the ONE source `connectionStatus()`\n * and `connection:status` both come from ('offline' before first contact).\n */\n status(): ConnectionStatus;\n /**\n * Optional connection-status feed (same wiring pattern as the streams; the\n * emission point is the session's existing `connection:status` transition).\n * The facade's heartbeat resets its backoff on a 'connected' recovery.\n */\n subscribeStatus?(handler: (status: ConnectionStatus) => void): () => void;\n}\n\n/**\n * §5.1/§6 restore surface of the checkpoint store: re-POST the slot's cached\n * encrypt-once ciphertext byte-identical after a server restore (insert-once,\n * first-write-wins server-side). Returns false when no ciphertext is cached.\n */\nexport interface CheckpointReseeder {\n reseedCheckpoint(transferId: string, opIndex: number): Promise<boolean>;\n}\n\ninterface IntentWireLike {\n transferId: string;\n payload: string;\n createdAt: string;\n}\n\n/** Structural slice of WalletApiV2Client the facade consumes directly. */\nexport interface FacadeClient extends HistoryClient, RequestsWireClient {\n putIntent(transferId: string, payloadEnvelope: string, requiresSeedClose?: boolean): Promise<void>;\n listIntents(status?: 'open' | 'aborted'): Promise<IntentWireLike[]>;\n abortIntent(transferId: string): Promise<void>;\n completeIntent(transferId: string, signature?: string): Promise<void>;\n}\n\nexport interface PaymentsFacadeDeps {\n session: FacadeSession;\n client: FacadeClient;\n storagePort: StoragePort;\n deliveryPort: DeliveryPort;\n /** Reseeder REQUIRED: the restore protocol re-POSTs cached ciphertexts (§5.1). */\n checkpointStore: SplitCheckpointStore & CheckpointReseeder;\n /** Initial engine source; setEngine() swaps what FUTURE operations snapshot. */\n engineRef: () => ITokenEngine;\n kv: ScopedKV;\n registry: RegistryReader;\n price?: PriceReader;\n emit: (event: string, payload: unknown) => void;\n resolveRecipient: (identifier: string) => Promise<RecipientInfo | null>;\n signComplete: (transferId: string) => Promise<string>;\n /** S6 self-scoped field key: intent payload envelope + history memo/nametag. */\n fieldKey: Uint8Array;\n /** The session's network — a recipient not verifiably on it is refused (§5.6). */\n network: string;\n /** The network's NFT vessel token type (64 hex) every mintNft() mints under (#785). */\n nftTokenType: string;\n ownPubkey: string;\n ownNametag?: () => string | undefined;\n requestMemo: RequestMemoCodec;\n /** REQUIRED (§5.1): reads the session's current epoch — never a default. */\n syncEpoch: () => string;\n now?: () => number;\n newId?: () => string;\n workBudget?: number;\n receivePollMs?: number;\n}\n\n/** Derived (non-authoritative) tokenId→stateHash cache backing the ReceiveView seam. */\nexport type HeldStateCache = Map<string, string>;\n\nexport interface FacadeHooks {\n engine(): ITokenEngine;\n send(request: SendRequest): Promise<TransferResult>;\n /** §7 ownership — an attempt running in-process owns its own reservation (#737). */\n isActiveOp(transferId: string): boolean;\n /** Register a background op so stop() cannot return while it is still writing. */\n track(op: Promise<unknown>): void;\n}\n\nexport interface FacadeParts {\n ownPubkeyBytes: Uint8Array;\n view: InventoryView;\n ledger: ReservationLedger;\n pins: IntentPins;\n queue: SpendQueue;\n historyStore: History;\n machineStores: MachineStores;\n machineDeps: MachineDeps;\n machine: TransferMachine;\n heldStates: HeldStateCache;\n /** ONE coalescer over view.delta(), shared by the §9 wake and the receive drain. */\n refreshView: () => void;\n receiveLoop: Receive;\n requests: Requests;\n restoreDeps: RestoreDeps;\n}\n\nexport function composeFacadeParts(deps: PaymentsFacadeDeps, hooks: FacadeHooks): FacadeParts {\n const ownPubkeyBytes = hexToBytes(deps.ownPubkey);\n const ledger = new ReservationLedger();\n const view = new InventoryView({\n port: deps.storagePort,\n kv: deps.kv,\n emit: (event) => deps.emit(event, {}),\n // #737: a reserved token is unselectable, so it is never confirmed balance.\n // #738: while the held-set is unproven, EVERY token reads pinned — the report\n // must not call a token spendable that the queue is about to refuse to spend.\n isPinned: (tokenId) => ledger.unprovenReason() !== null || ledger.holderOf(tokenId) !== undefined,\n ...(deps.now !== undefined ? { now: deps.now } : {}),\n });\n const queue = new SpendQueue({\n ledger,\n getPool: (coinId) => view.pool(coinId),\n spendableToken: (tokenId) => view.spendableToken(tokenId),\n ...(deps.workBudget !== undefined ? { workBudget: deps.workBudget } : {}),\n });\n const historyStore = new History({\n client: deps.client,\n fieldKey: deps.fieldKey,\n registry: deps.registry,\n emit: (event, entry) => deps.emit(event, entry),\n ...(deps.now !== undefined ? { now: deps.now } : {}),\n ...(deps.newId !== undefined ? { newId: deps.newId } : {}),\n });\n const machineDeps = buildMachineDeps(deps, hooks, historyStore);\n const machineStores = createMachineStores(deps.kv);\n const heldStates: HeldStateCache = new Map();\n\n const refreshView = coalesced(() => view.delta(), hooks.track);\n return {\n ownPubkeyBytes,\n view,\n refreshView,\n ledger,\n pins: buildPins(deps, hooks, { ledger, view, machineStores, machineDeps }),\n queue,\n historyStore,\n machineStores,\n machineDeps,\n machine: new TransferMachine(machineDeps),\n heldStates,\n receiveLoop: buildReceive(deps, hooks, historyStore, heldStates, refreshView),\n requests: buildRequests(deps, hooks),\n restoreDeps: buildRestoreDeps(deps, machineDeps, machineStores, view),\n };\n}\n\n/** #737 pin lifecycle wiring (see select/pins.ts); the facade owns when it runs. */\nfunction buildPins(\n deps: PaymentsFacadeDeps,\n hooks: FacadeHooks,\n parts: {\n ledger: ReservationLedger;\n view: InventoryView;\n machineStores: MachineStores;\n machineDeps: MachineDeps;\n }\n): IntentPins {\n return new IntentPins({\n ledger: parts.ledger,\n openIntents: () => deriveOpenIntentHolds(parts.machineStores, parts.machineDeps.decryptPayload),\n isActive: (transferId) => hooks.isActiveOp(transferId),\n release: (tokenId) => {\n parts.view.release(tokenId);\n },\n changed: () => deps.emit('inventory:updated', {}),\n });\n}\n\n/** §5.1 restore protocol wiring (reseedAndReset's deps) — policy stays in the facade. */\nfunction buildRestoreDeps(\n deps: PaymentsFacadeDeps,\n machineDeps: MachineDeps,\n machineStores: MachineStores,\n view: InventoryView\n): RestoreDeps {\n return {\n stores: machineStores,\n kv: deps.kv,\n reput: (transferId, envelope, requiresSeedClose) =>\n machineDeps.intents.put(transferId, envelope, requiresSeedClose),\n reseedCheckpoint: (transferId, opIndex) => deps.checkpointStore.reseedCheckpoint(transferId, opIndex),\n decryptPayload: machineDeps.decryptPayload,\n fullRePull: () => view.onEpochReset(),\n attention: (transferId, code, detail) => {\n deps.emit(\n 'transfer:attention',\n detail === undefined ? { transferId, code } : { transferId, code, detail }\n );\n },\n };\n}\n\nfunction buildMachineDeps(\n deps: PaymentsFacadeDeps,\n hooks: FacadeHooks,\n historyStore: History\n): MachineDeps {\n return {\n engine: () => hooks.engine(),\n storage: deps.storagePort,\n delivery: deps.deliveryPort,\n intents: {\n put: (transferId, envelope, requiresSeedClose) =>\n deps.client.putIntent(transferId, envelope, requiresSeedClose),\n listOpen: () => deps.client.listIntents('open'),\n abort: (transferId) => deps.client.abortIntent(transferId),\n complete: (transferId, signature) => deps.client.completeIntent(transferId, signature),\n },\n checkpointStore: deps.checkpointStore,\n kv: deps.kv,\n encryptPayload: async (payload) => encryptField(deps.fieldKey, JSON.stringify(payload)),\n decryptPayload: async (envelope) => JSON.parse(decryptField(deps.fieldKey, envelope)) as unknown,\n signComplete: deps.signComplete,\n ownPubkey: hexToBytes(deps.ownPubkey),\n // sphere#487: the same live getter Requests uses — the delivery envelope is\n // the recipient's ONLY source for the sender's Unicity ID.\n ...(deps.ownNametag !== undefined ? { ownNametag: deps.ownNametag } : {}),\n emit: deps.emit,\n now: deps.now ?? Date.now,\n recordHistory: async ({ transferId, payload, committedAmount, committedAssets }) => {\n await historyStore.recordSent({\n transferId,\n // §5.9: the SETTLED amount, never payload.amount — the plan. A token\n // spend moved no coin: `assets: []` + tokenId (wallet-api#151 / §10).\n ...(isWholeIntent(payload)\n ? { assets: committedAssets ?? [], tokenId: payload.direct[0] }\n : { assets: [{ coinId: payload.coinId, amount: committedAmount }] }),\n recipientPubkey: payload.recipient,\n ...(payload.memo !== undefined ? { memo: payload.memo } : {}),\n });\n },\n };\n}\n\nfunction buildReceive(\n deps: PaymentsFacadeDeps,\n hooks: FacadeHooks,\n historyStore: History,\n heldStates: HeldStateCache,\n refreshView: () => void\n): Receive {\n return new Receive({\n delivery: deps.deliveryPort,\n engine: () => hooks.engine(),\n view: {\n heldState: (tokenId) => heldStates.get(tokenId) ?? null,\n store: async (entry: StoredIncoming) => {\n heldStates.set(entry.tokenId, entry.stateHash);\n },\n },\n kv: deps.kv,\n registry: deps.registry,\n recordReceived: (record) => recordReceived(historyStore, record),\n emit: (event, transfer) => deps.emit(event, transfer),\n refreshView,\n attention: (transferId, code, detail) => {\n deps.emit(\n 'transfer:attention',\n detail === undefined ? { transferId, code } : { transferId, code, detail }\n );\n },\n syncEpoch: deps.syncEpoch,\n // #770: the poll/wake drains Receive spawns itself must hold stop() too.\n track: hooks.track,\n ...(deps.now !== undefined ? { now: deps.now } : {}),\n });\n}\n\nasync function recordReceived(historyStore: History, record: ReceivedRecord): Promise<void> {\n await historyStore.recordReceived({\n tokenId: record.tokenId,\n stateHash: record.stateHash,\n assets: record.assets,\n ...(record.senderPubkey !== undefined ? { senderPubkey: record.senderPubkey } : {}),\n ...(record.senderNametag !== undefined ? { senderNametag: record.senderNametag } : {}),\n ...(record.memo !== undefined ? { memo: record.memo } : {}),\n timestamp: record.receivedAt,\n });\n}\n\nfunction buildRequests(deps: PaymentsFacadeDeps, hooks: FacadeHooks): Requests {\n return new Requests({\n client: deps.client,\n kv: deps.kv,\n ownPubkey: deps.ownPubkey,\n send: (request) => hooks.send(request),\n resolvePubkey: async (identifier) =>\n (await deps.resolveRecipient(identifier))?.chainPubkey ?? null,\n listAbortedTransferIds: async () =>\n (await deps.client.listIntents('aborted')).map((intent) => intent.transferId),\n emit: deps.emit,\n memo: deps.requestMemo,\n ...(deps.ownNametag !== undefined ? { ownNametag: deps.ownNametag } : {}),\n ...(deps.now !== undefined ? { now: deps.now } : {}),\n });\n}\n","import type { MintParams } from '../../token-engine';\n\nexport function mintParams(recipientPubkey: Uint8Array, coinId: string, amount: bigint): MintParams {\n return { recipientPubkey, value: { assets: [{ coinId, amount }] } };\n}\n","import { sha256 } from '@noble/hashes/sha2.js';\n\nimport { bytesToHex } from '../../core/crypto';\nimport { SphereError } from '../../core/errors';\nimport type { ITokenEngine } from '../../token-engine/engine';\nimport type { SphereToken } from '../../token-engine/types';\n\nimport type { MintResult } from './api';\nimport { supportsDeterministicMint } from './compose';\nimport type { RecordMintInput } from './history/History';\nimport { messageOf } from './machine/payload';\nimport { mintParams } from './mint-params';\nimport type { ListStore } from './machine/journal';\nimport type { MintJournalEntry } from './stores';\nimport type { StoragePort } from './ports';\n\nexport const ATTENTION_MINT_UNRESOLVED = 'mint:unresolved';\n\n/** What finalising a certified mint needs — shared by the coin and the NFT mint. */\nexport interface FinalizeMintDeps {\n readonly engine: ITokenEngine;\n readonly storagePort: Pick<StoragePort, 'uploadBlobs' | 'applyDelta'>;\n readonly recordMint: (input: RecordMintInput) => Promise<void>;\n readonly noteHeldState: (tokenId: string, stateHash: string) => void;\n readonly refreshView: () => void;\n}\n\n/** Everything the journal-first mint needs, injected so the path stays testable. */\nexport interface MintDeps extends FinalizeMintDeps {\n readonly mintJournal: ListStore<MintJournalEntry>;\n readonly armHeartbeat: () => void;\n readonly ownPubkeyBytes: Uint8Array;\n readonly now: () => number;\n}\n\n/** What replaying a mint journal needs on top of minting. */\nexport interface MintReplayDeps {\n /** §7 ownership: an entry whose live call is still running is never replayed. */\n readonly isActiveOp: (mintId: string) => boolean;\n readonly tokenInServerInventory: (tokenId: string) => Promise<boolean>;\n}\n\nexport interface CoinReplayDeps extends MintDeps, MintReplayDeps {\n readonly emit: (event: string, payload: unknown) => void;\n}\n\nexport interface FinalizeMintInput {\n readonly mintId: string;\n readonly token: SphereToken;\n /** `[]` for an NFT: a mint that names no coin never writes `coinId: ''` (wallet-api#151). */\n readonly assets: RecordMintInput['assets'];\n /** The journal holding `mintId`; its entry goes only after the apply and the record. */\n readonly journal: { removeByKey(key: string): Promise<void> };\n}\n\n/**\n * Journal-first self-mint: the entry is durable BEFORE the chain op, so a crash\n * converges by the F13 same-seed re-call rather than minting twice.\n */\nexport function runMintUnderJournal(\n deps: MintDeps,\n input: { mintId: string; coinId: string; amount: bigint }\n): Promise<MintResult> {\n return mintUnderJournal(deps, input);\n}\n\nasync function mintUnderJournal(\ndeps: MintDeps,\ninput: { mintId: string; coinId: string; amount: bigint }\n): Promise<MintResult> {\nconst { mintId, coinId, amount } = input;\nconst engine = deps.engine;\n // tokenId stays '' until mint returns; replay converges via the F13 same-seed re-call.\n const entry: MintJournalEntry = {\n mintId,\n coinId,\n amount: amount.toString(),\n tokenId: '',\n createdAt: deps.now(),\n };\n await deps.mintJournal.upsert(entry);\n let token: SphereToken;\n try {\n token = await engine.mint(mintParams(deps.ownPubkeyBytes, coinId, amount), { transferId: mintId });\n } catch (err) {\n // Entry retained: the heartbeat / start() replay resolves it (inventory check / F13 seed).\n deps.armHeartbeat();\n return { success: false, error: messageOf(err) };\n }\n if (token.blob.tokenId !== entry.tokenId) {\n await deps.mintJournal.upsert({ ...entry, tokenId: token.blob.tokenId });\n }\n try {\n const assets = [{ coinId, amount: amount.toString() }];\n await finalizeMint(deps, { mintId, token, assets, journal: deps.mintJournal });\n } catch (err) {\n deps.armHeartbeat();\n return { success: false, tokenId: token.blob.tokenId, error: messageOf(err) };\n }\n return { success: true, tokenId: token.blob.tokenId };\n}\n\nexport async function finalizeMint(deps: FinalizeMintDeps, input: FinalizeMintInput): Promise<void> {\n const { mintId, token } = input;\n const bytes = token.blob.token;\n const digest = bytesToHex(sha256(bytes));\n const keys = await deps.storagePort.uploadBlobs([{ sha256: digest, bytes }]);\n const key = keys.get(digest);\n if (key === undefined) {\n throw new SphereError(`no upload key returned for mint blob ${digest}`, 'STORAGE_ERROR');\n }\n await deps.storagePort.applyDelta({\n transferId: mintId,\n spent: [],\n added: [{ tokenId: token.blob.tokenId, key }],\n });\n await deps.recordMint({ tokenId: token.blob.tokenId, assets: input.assets });\n await input.journal.removeByKey(mintId);\n deps.noteHeldState(token.blob.tokenId, (await deps.engine.deliveryKeys(bytes)).stateHash);\n deps.refreshView();\n}\n\n/** @returns how many coin journal entries were RESOLVED (cleared) — heartbeat progress. */\nexport async function replayCoinMints(deps: CoinReplayDeps): Promise<number> {\n let resolved = 0;\n for (const entry of await deps.mintJournal.list()) {\n if (deps.isActiveOp(entry.mintId)) continue; // its live mint still owns it\n try {\n if (await replayCoinMint(deps, entry)) resolved += 1;\n } catch {\n // Entry retained — replayed again at the next pass / start().\n }\n }\n return resolved;\n}\n\nasync function replayCoinMint(deps: CoinReplayDeps, entry: MintJournalEntry): Promise<boolean> {\n if (entry.tokenId !== '' && (await deps.tokenInServerInventory(entry.tokenId))) {\n await deps.mintJournal.removeByKey(entry.mintId);\n return true;\n }\n if (!supportsDeterministicMint(deps.engine)) {\n // Without the F13 seed a re-mint would create a SECOND token: hold + alert.\n deps.emit('transfer:attention', { transferId: entry.mintId, code: ATTENTION_MINT_UNRESOLVED });\n return false; // held, not resolved — never counts as heartbeat progress\n }\n const token = await deps.engine.mint(mintParams(deps.ownPubkeyBytes, entry.coinId, BigInt(entry.amount)), {\n transferId: entry.mintId,\n });\n if (token.blob.tokenId !== entry.tokenId) {\n await deps.mintJournal.upsert({ ...entry, tokenId: token.blob.tokenId });\n }\n const assets = [{ coinId: entry.coinId, amount: entry.amount }];\n await finalizeMint(deps, { mintId: entry.mintId, token, assets, journal: deps.mintJournal });\n return true;\n}\n","// §5.9 NFT mint (#785): journal-first like the coin mint, but the journal holds the\n// planned BYTES — payload, salt and type — so a resume re-submits exactly what the\n// first attempt did, whatever the engine's signing or salt source.\n\nimport { bytesToHex, hexToBytes } from '../../core/crypto';\nimport { SphereError } from '../../core/errors';\nimport type { NftMintPlan } from '../../token-engine/types';\n\nimport type { MintNftRequest, MintResult } from './api';\nimport type { ListStore } from './machine/journal';\nimport { messageOf } from './machine/payload';\nimport { finalizeMint, type FinalizeMintDeps, type MintReplayDeps } from './mint';\nimport type { NftMintJournalEntry } from './stores';\n\nexport interface NftMintDeps extends FinalizeMintDeps {\n readonly nftMintJournal: ListStore<NftMintJournalEntry>;\n readonly armHeartbeat: () => void;\n /** The first owner: an NFT always mints to the wallet itself. */\n readonly ownPubkeyBytes: Uint8Array;\n /** The composed network's NFT vessel token type, 64 hex. */\n readonly nftTokenType: string;\n readonly now: () => number;\n}\n\nexport type NftReplayDeps = NftMintDeps & MintReplayDeps;\n\n/** Genesis payload cap, NftSigned wrapper included: wallet-api refuses an oversize blob only after the mint certified. */\nexport const NFT_MAX_PAYLOAD_BYTES = 1024 * 1024;\n\nfunction assertPayloadSize(data: Uint8Array): void {\n if (data.length <= NFT_MAX_PAYLOAD_BYTES) return;\n throw new SphereError(\n `NFT payload is ${data.length} bytes, over the ${NFT_MAX_PAYLOAD_BYTES}-byte limit: link large files with NftLink`,\n 'VALIDATION_ERROR'\n );\n}\n\n/** Plan, journal, mint, finalise. A refused payload fails with nothing journaled and nothing minted. */\nexport async function runNftMintUnderJournal(\n deps: NftMintDeps,\n input: { mintId: string; request: MintNftRequest }\n): Promise<MintResult> {\n let plan: NftMintPlan;\n try {\n plan = await deps.engine.buildNftMint({\n recipientPubkey: deps.ownPubkeyBytes,\n content: input.request.content,\n sign: input.request.sign ?? true,\n tokenType: hexToBytes(deps.nftTokenType),\n });\n // Before the journal: a blob the server will refuse must never reach the chain.\n assertPayloadSize(plan.data);\n } catch (err) {\n return { success: false, error: messageOf(err) };\n }\n const entry = journalEntryOf(input.mintId, plan, deps.now());\n await deps.nftMintJournal.upsert(entry);\n try {\n await mintJournaled(deps, entry);\n } catch (err) {\n // Entry retained: the heartbeat / start() replay re-submits these same bytes.\n deps.armHeartbeat();\n return { success: false, tokenId: entry.tokenId, error: messageOf(err) };\n }\n return { success: true, tokenId: entry.tokenId };\n}\n\n/** @returns how many NFT journal entries were RESOLVED (cleared) — heartbeat progress. */\nexport async function replayNftMints(deps: NftReplayDeps): Promise<number> {\n let resolved = 0;\n for (const entry of await deps.nftMintJournal.list()) {\n if (deps.isActiveOp(entry.mintId)) continue; // its live mintNft still owns it\n try {\n if (await deps.tokenInServerInventory(entry.tokenId)) {\n await deps.nftMintJournal.removeByKey(entry.mintId);\n } else {\n await mintJournaled(deps, entry);\n }\n resolved += 1;\n } catch {\n // Entry retained — replayed again at the next pass / start().\n }\n }\n return resolved;\n}\n\nfunction journalEntryOf(mintId: string, plan: NftMintPlan, createdAt: number): NftMintJournalEntry {\n return {\n mintId,\n tokenId: plan.tokenId,\n dataHex: bytesToHex(plan.data),\n saltHex: bytesToHex(plan.salt),\n tokenTypeHex: bytesToHex(plan.tokenType),\n createdAt,\n };\n}\n\n/** Mint exactly the journaled bytes, then finalise. A throw leaves the entry journaled. */\nasync function mintJournaled(deps: NftMintDeps, entry: NftMintJournalEntry): Promise<void> {\n const params = {\n recipientPubkey: deps.ownPubkeyBytes,\n data: hexToBytes(entry.dataHex),\n tokenType: hexToBytes(entry.tokenTypeHex),\n salt: hexToBytes(entry.saltHex),\n };\n const token = await deps.engine.mintDataToken(params, { transferId: entry.mintId });\n if (token.blob.tokenId !== entry.tokenId) {\n // Never finalise a token the plan did not name.\n throw new SphereError(`minted token ${token.blob.tokenId}, but the plan names ${entry.tokenId}`, 'VALIDATION_ERROR');\n }\n await finalizeMint(deps, { mintId: entry.mintId, token, assets: [], journal: deps.nftMintJournal });\n}\n","// §5.2 NFT reads (#785): a held token's genesis payload through the engine's\n// never-throwing NFT reader, behind a facade-owned bounded LRU.\n\nimport { SphereError } from '../../../core/errors';\nimport { logger } from '../../../core/logger';\nimport type { ITokenEngine } from '../../../token-engine/engine';\nimport type { NftView } from '../api';\nimport type { StoragePort } from '../ports';\n\nimport type { InventoryView } from './InventoryView';\n\nexport const NFT_CACHE_MAX = 256;\n\n/**\n * Token id → NFT reading, where `null` caches \"not an NFT\" so a list view never\n * refetches it. A genesis payload never changes for a token id, so no entry goes stale.\n */\nexport class NftCache {\n private readonly entries = new Map<string, NftView | null>();\n\n constructor(private readonly max = NFT_CACHE_MAX) {}\n\n /** `undefined` = not cached. A hit becomes the most recently used entry. */\n get(tokenId: string): NftView | null | undefined {\n const view = this.entries.get(tokenId);\n if (view === undefined) return undefined;\n this.entries.delete(tokenId);\n this.entries.set(tokenId, view);\n return view;\n }\n\n set(tokenId: string, view: NftView | null): void {\n this.entries.delete(tokenId);\n this.entries.set(tokenId, view);\n const oldest = this.entries.keys().next().value;\n if (this.entries.size > this.max && oldest !== undefined) this.entries.delete(oldest);\n }\n}\n\nexport interface NftReadDeps {\n readonly engine: ITokenEngine;\n readonly view: Pick<InventoryView, 'stateHashOf'>;\n readonly storagePort: Pick<StoragePort, 'getBlobs'>;\n readonly cache: NftCache;\n}\n\n/** One held token read as an NFT; `null` = not a recognised NFT. */\nexport async function readNft(deps: NftReadDeps, tokenId: string): Promise<NftView | null> {\n if (deps.view.stateHashOf(tokenId) === undefined) {\n throw new SphereError(`Token ${tokenId} is not in inventory`, 'VALIDATION_ERROR');\n }\n const cached = deps.cache.get(tokenId);\n if (cached !== undefined) return cached;\n const bytes = (await deps.storagePort.getBlobs([tokenId])).get(tokenId);\n if (bytes === undefined) {\n throw new SphereError(`Token ${tokenId} has no blob in storage`, 'STORAGE_ERROR');\n }\n return decodeView(deps, tokenId, bytes);\n}\n\n/** Held ids read as NFTs, with ONE blob fetch for all cache misses. Anything unreadable is absent. */\nexport async function readNfts(\n deps: NftReadDeps,\n tokenIds: readonly string[]\n): Promise<ReadonlyMap<string, NftView>> {\n const held = [...new Set(tokenIds)].filter((tokenId) => deps.view.stateHashOf(tokenId) !== undefined);\n const views = new Map<string, NftView | null>();\n const misses: string[] = [];\n for (const tokenId of held) {\n const cached = deps.cache.get(tokenId);\n if (cached === undefined) misses.push(tokenId);\n else views.set(tokenId, cached);\n }\n const blobs = misses.length > 0 ? await deps.storagePort.getBlobs(misses) : new Map<string, Uint8Array>();\n for (const tokenId of misses) {\n const bytes = blobs.get(tokenId);\n if (bytes !== undefined) views.set(tokenId, await decodeView(deps, tokenId, bytes).catch(() => null));\n }\n const out = new Map<string, NftView>();\n for (const tokenId of held) {\n const view = views.get(tokenId);\n if (view) out.set(tokenId, view);\n }\n return out;\n}\n\n/** Cached only once decoded: a blob that failed to decode is re-read next time, not remembered as \"not an NFT\". */\nasync function decodeView(deps: NftReadDeps, tokenId: string, bytes: Uint8Array): Promise<NftView | null> {\n let view: NftView | null;\n try {\n const token = await deps.engine.decodeToken({ tokenId, token: bytes });\n if (token.blob.tokenId !== tokenId) {\n throw new SphereError(`the blob served for ${tokenId} decodes as ${token.blob.tokenId}`, 'STORAGE_ERROR');\n }\n const reading = await deps.engine.readNft(token);\n view = reading === null ? null : { tokenId, ...reading };\n } catch (err) {\n logger.warn('PaymentsV2', `NFT read: token ${tokenId} did not decode — ${String(err)}`);\n throw err;\n }\n deps.cache.set(tokenId, view);\n return view;\n}\n","import { SphereError } from '../../../core/errors';\nimport type { ITokenEngine } from '../../../token-engine/engine';\nimport type { StoragePort } from '../ports';\n\nimport type { InventoryView } from './InventoryView';\n\nexport interface TokenDataDeps {\n readonly engine: ITokenEngine;\n readonly view: Pick<InventoryView, 'stateHashOf'>;\n readonly storagePort: Pick<StoragePort, 'getBlobs'>;\n}\n\n/** A token's genesis payload, or null. Fetched on demand. */\nexport async function readTokenData(\n deps: TokenDataDeps,\n tokenId: string\n): Promise<Uint8Array | null> {\n if (deps.view.stateHashOf(tokenId) === undefined) {\n throw new SphereError(`Token ${tokenId} is not in inventory`, 'VALIDATION_ERROR');\n }\n const bytes = (await deps.storagePort.getBlobs([tokenId])).get(tokenId);\n if (bytes === undefined) {\n throw new SphereError(`Token ${tokenId} has no blob in storage`, 'STORAGE_ERROR');\n }\n return deps.engine.readTokenData(await deps.engine.decodeToken({ tokenId, token: bytes }));\n}\n","import { SphereError } from '../../core/errors';\nimport type { ITokenEngine } from '../../token-engine/engine';\nimport type { Token } from '../../types';\n\nimport { buildWholePayload } from './machine/payload';\nimport { buildOps, type MachinePlan } from './machine/TransferMachine';\nimport type { SendWholeTokenRequest } from './api';\nimport { transferringToken, type RegistryReader } from './inventory/presentation';\nimport type { StoragePort } from './ports';\n\nexport interface WholeSpendDeps {\n readonly engine: ITokenEngine;\n readonly storagePort: Pick<StoragePort, 'getBlobs'>;\n readonly registry: RegistryReader;\n readonly now: number;\n}\n\nexport interface WholeSpendInput {\n readonly transferId: string;\n readonly recipientPubkey: string;\n readonly request: SendWholeTokenRequest;\n readonly sourceIds: readonly string[];\n /** NFT-scoped entry point sets this: `nft:transfer` must not move coins. */\n readonly requireCoinless: boolean;\n}\n\n/**\n * The token-addressed twin of the facade's `materialize`: one named source, never a\n * split. `sourceTokens` become the result's `tokens`, so they list every asset the\n * named token carries — empty only for a coinless one, which moves no amount.\n */\nexport async function materializeWholeSpend(\n deps: WholeSpendDeps,\n input: WholeSpendInput\n): Promise<{\n transferId: string;\n coinId: string;\n plan: MachinePlan;\n sourceIds: readonly string[];\n sourceTokens: Token[];\n}> {\n const { engine } = deps;\n const tokenId = input.request.tokenId;\n const bytes = (await deps.storagePort.getBlobs([tokenId])).get(tokenId);\n if (bytes === undefined) {\n throw new SphereError(`Selected source ${tokenId} has no blob in storage`, 'STORAGE_ERROR');\n }\n const token = await engine.decodeToken({ tokenId, token: bytes });\n // A whole spend moves the token AS IS, so a valued source is fine. `bare_collection`\n // is not: its coins are real but undecodable here, so the move would happen while\n // history could only say `assets: []`. The BLOB decides, never the mirror.\n if (token.valueEnvelope === 'bare_collection') {\n throw new SphereError(\n `Token ${tokenId} carries a value envelope this SDK cannot read, so its coins ` +\n 'cannot be accounted for; it cannot be sent',\n 'VALIDATION_ERROR'\n );\n }\n if (input.requireCoinless && token.value !== null) {\n throw new SphereError(\n `Token ${tokenId} carries coin value and cannot be sent with sendCoinless — use ` +\n 'sendWholeToken, which requires coin-transfer authority',\n 'VALIDATION_ERROR'\n );\n }\n const keys = await engine.deliveryKeys(bytes);\n const payload = buildWholePayload(input.recipientPubkey, input.request, {\n [tokenId]: { local: keys.stateHash, protocol: keys.stateHash },\n });\n const plan: MachinePlan = {\n transferId: input.transferId,\n recipientPubkey: input.recipientPubkey,\n payload,\n ops: buildOps(payload),\n sources: new Map([[tokenId, token]]),\n ...(input.request.memo !== undefined ? { memo: input.request.memo } : {}),\n };\n const sourceTokens = (token.value?.assets ?? []).map((asset) =>\n transferringToken(tokenId, asset.coinId, asset.amount, deps.registry, deps.now)\n );\n return { transferId: input.transferId, coinId: '', plan, sourceIds: input.sourceIds, sourceTokens };\n}\n","import { isPossiblyCommittedSendOutcome, PartialSendConflictError, SphereError } from '../../core/errors';\n\n/** The parts of a send run these shapers read. */\nexport interface PartialRun {\n readonly amount: string;\n readonly delivered: readonly string[];\n readonly firstPartialId: string | undefined;\n}\n\n/** Once anything was delivered, the failure is a SHORTFALL: re-plan the remainder, never the total. */\nexport function partialize(err: unknown, run: PartialRun): unknown {\n if (run.delivered.length === 0) return err;\n return new PartialSendConflictError(\n 'Part of your payment was sent; the remaining amount could not be completed (see cause). The delivered portion is final — re-plan only the shortfall, never the full amount.',\n run.firstPartialId ?? '',\n [...run.delivered],\n run.amount,\n err\n );\n}\n\n/** #441: possibly-committed errors must carry the transferId for the settling journal. */\nexport function stampTransferId(err: unknown, transferId: string): void {\n if (\n err instanceof SphereError &&\n isPossiblyCommittedSendOutcome(err) &&\n err.transferId === undefined\n ) {\n err.transferId = transferId;\n }\n}\n","// §5.6 recipient gate: the cross-network deposit trap — a deposit keys the\n// recipient under the SENDER's network and the server 200s an entry the\n// recipient never queries. TRANSITION (#734) — docs/PAYMENTS-V2-DESIGN.md §5.6.\n\nimport { SphereError } from '../../core/errors';\n\nimport type { RecipientInfo } from './compose';\n\nexport const ATTENTION_RECIPIENT_NETWORK_UNVERIFIED = 'recipient:network-unverified';\n\nexport interface RecipientGateDeps {\n resolveRecipient: (identifier: string) => Promise<RecipientInfo | null>;\n network: string;\n emit: (event: string, payload: unknown) => void;\n}\n\nexport async function requireSameNetworkRecipient(\n deps: RecipientGateDeps,\n identifier: string\n): Promise<RecipientInfo> {\n const recipient = await deps.resolveRecipient(identifier);\n if (recipient === null || recipient.chainPubkey === '') {\n throw new SphereError(`Recipient ${identifier} has no published chain pubkey`, 'INVALID_RECIPIENT');\n }\n if (recipient.network === null) {\n deps.emit('transfer:attention', {\n transferId: '', // the gate precedes plan allocation — no transferId exists yet\n code: ATTENTION_RECIPIENT_NETWORK_UNVERIFIED,\n detail: `could not verify the network of recipient ${identifier} — assuming this session's \"${deps.network}\"`,\n });\n return recipient;\n }\n // #734 owes this compare a canonical name (`testnet` aliases `testnet2`) — §5.6.\n if (recipient.network !== deps.network) {\n throw new SphereError(\n `Recipient ${identifier} is on network \"${recipient.network}\" but this session is on \"${deps.network}\" — a cross-network deposit is unrecoverable`,\n 'INVALID_RECIPIENT'\n );\n }\n return recipient;\n}\n","// §5.1 restore — THE invariant, once: after a syncEpoch change, intents and\n// checkpoint progress re-seed from the §6 backstops BEFORE anything resumes;\n// no stream resumes a pre-restore cursor; a rejected re-seed KEEPS+alerts (E.3).\n\nimport { STORE_KEYS, type ScopedKV, type StreamName } from './stores';\nimport type { AttentionEmitter, MachineStores } from './machine/journal';\nimport type { IntentPayload } from './machine/types';\n\nexport const ATTENTION_RESEED_REJECTED = 'intent:reseed-rejected';\n\nconst ALL_STREAMS: readonly StreamName[] = ['inventory', 'mailbox', 'payment_requests', 'history'];\n\nexport interface RestoreDeps {\n readonly stores: MachineStores;\n readonly kv: ScopedKV;\n readonly reput: (transferId: string, envelope: string, requiresSeedClose: boolean) => Promise<void>;\n readonly reseedCheckpoint: (transferId: string, opIndex: number) => Promise<boolean>;\n readonly decryptPayload: (envelope: string) => Promise<unknown>;\n readonly fullRePull: () => Promise<void>;\n readonly attention: AttentionEmitter;\n}\n\nexport async function reseedAndReset(deps: RestoreDeps): Promise<void> {\n for (const entry of await deps.stores.backstop.list()) {\n if (entry.disposition !== 'open') continue; // #676: a local abort is never resurrected\n try {\n await deps.reput(entry.transferId, entry.payloadEnvelope, entry.requiresSeedClose);\n if (entry.requiresSeedClose) {\n await deps.reseedCheckpoint(entry.transferId, await splitOpIndex(deps, entry.payloadEnvelope));\n }\n } catch (err) {\n deps.attention(entry.transferId, ATTENTION_RESEED_REJECTED, err instanceof Error ? err.message : String(err));\n }\n }\n for (const stream of ALL_STREAMS) await deps.kv.remove(STORE_KEYS.streamCursor(stream));\n await deps.fullRePull();\n}\n\n// E.1: split = direct.length.\nasync function splitOpIndex(deps: RestoreDeps, envelope: string): Promise<number> {\n const payload = (await deps.decryptPayload(envelope)) as Partial<IntentPayload>;\n return Array.isArray(payload.direct) ? payload.direct.length : 0;\n}\n","import type { InventoryView } from './inventory/InventoryView';\nimport type { StoragePort } from './ports';\nimport type { SpendQueue } from './select/queue';\n\n/** Source blobs fetched ahead of a send, scoped to the state each token sat at (F6). */\nexport class PrewarmCache {\n private readonly entries = new Map<string, Uint8Array>();\n private generation = 0;\n\n private static key(tokenId: string, stateHash: string): string {\n return `${tokenId}:${stateHash}`;\n }\n\n /** Claim the cache for a warm about to start; supersedes any warm already running. */\n begin(): number {\n this.entries.clear();\n this.generation += 1;\n return this.generation;\n }\n\n /**\n * Publish a warm's result, unless it was cancelled or superseded while its\n * fetch was in flight — a cancel that only cleared what had landed so far\n * would be undone by the continuation of the very warm it cancelled.\n */\n commit(generation: number, warmed: readonly (readonly [string, string, Uint8Array])[]): void {\n if (generation !== this.generation) return;\n for (const [tokenId, stateHash, bytes] of warmed) {\n this.entries.set(PrewarmCache.key(tokenId, stateHash), bytes);\n }\n }\n\n get(tokenId: string, stateHash: string | undefined): Uint8Array | undefined {\n if (stateHash === undefined) return undefined;\n return this.entries.get(PrewarmCache.key(tokenId, stateHash));\n }\n\n clear(): void {\n this.entries.clear();\n this.generation += 1;\n }\n\n get size(): number {\n return this.entries.size;\n }\n}\n\nexport interface WarmDeps {\n readonly queue: SpendQueue;\n readonly view: Pick<InventoryView, 'stateHashOf' | 'delta'>;\n readonly storagePort: Pick<StoragePort, 'getBlobs'>;\n readonly cache: PrewarmCache;\n}\n\n/** Reserves nothing and throws nothing: the send re-fetches whatever is missing. */\nexport async function warmSendSources(\n deps: WarmDeps,\n request: { coinId: string; amount: string }\n): Promise<void> {\n const ids = deps.queue.previewSelection(request);\n if (ids.length === 0) return;\n const generation = deps.cache.begin();\n const at = new Map(ids.map((id) => [id, deps.view.stateHashOf(id)]));\n let blobs: Map<string, Uint8Array>;\n try {\n blobs = await deps.storagePort.getBlobs([...ids]);\n } catch {\n return;\n }\n const warmed: (readonly [string, string, Uint8Array])[] = [];\n for (const [tokenId, bytes] of blobs) {\n const stateHash = at.get(tokenId);\n if (stateHash !== undefined) warmed.push([tokenId, stateHash, bytes]);\n }\n deps.cache.commit(generation, warmed);\n}\n\n/**\n * Warm where the token still sits at its warmed state; single-use. Refreshes the\n * mirror FIRST — warming and consuming both read `stateHashOf`, so they agree\n * even when the server has moved on, and the uncached path reads the server's\n * current blob. Unverifiable freshness re-fetches instead.\n */\nexport async function takeSourceBlobs(\n deps: Pick<WarmDeps, 'view' | 'storagePort' | 'cache'>,\n sourceIds: readonly string[]\n): Promise<Map<string, Uint8Array>> {\n const blobs = new Map<string, Uint8Array>();\n const missing: string[] = [];\n let trustCache = deps.cache.size > 0;\n if (trustCache) {\n try {\n await deps.view.delta();\n } catch {\n trustCache = false;\n }\n }\n for (const tokenId of sourceIds) {\n const warm = trustCache ? deps.cache.get(tokenId, deps.view.stateHashOf(tokenId)) : undefined;\n if (warm === undefined) missing.push(tokenId);\n else blobs.set(tokenId, warm);\n }\n deps.cache.clear();\n if (missing.length > 0) {\n for (const [tokenId, bytes] of await deps.storagePort.getBlobs(missing)) {\n blobs.set(tokenId, bytes);\n }\n }\n return blobs;\n}\n","// §4 of docs/PAYMENTS-V2-DESIGN.md — the PaymentsV2 facade. The send() POLICY\n// lives here (bounded re-plan, remainder accumulation, keep-open rethrow);\n// the TransferMachine stays policy-free. Wiring lives in compose.ts.\n\n\nimport {\n PartialSendConflictError,\n SphereError,\n isPossiblyCommittedSendOutcome,\n} from '../../core/errors';\nimport { randomUUID } from '../../core/uuid';\nimport type { ITokenEngine } from '../../token-engine/engine';\nimport type { SphereToken } from '../../token-engine/types';\nimport type { Asset, IncomingTransfer, Token, TokenTransferDetail, TransferResult } from '../../types';\n\nimport type { CoinlessToken, ConnectionStatus, HistoryPage, MintNftRequest, MintResult, NftView, PaymentsV2, PendingTransfer, SendRequest, SendWholeTokenRequest } from './api';\nimport { SerialChain, SingleFlight } from './async';\nimport { ConvergenceHeartbeat, Converger, derivePendingTransfers } from './convergence';\nimport { NftCache, readNft, readNfts, type NftReadDeps } from './inventory/nft-read';\nimport { readTokenData } from './inventory/token-data';\nimport { type CoinReplayDeps, replayCoinMints, runMintUnderJournal } from './mint';\nimport { type NftReplayDeps, replayNftMints, runNftMintUnderJournal } from './mint-nft';\nimport { materializeWholeSpend } from './send-whole';\nimport { partialize, stampTransferId } from './send-errors';\nimport { requireSameNetworkRecipient } from './recipient';\nimport { reseedAndReset, type RestoreDeps } from './restore';\nimport { PrewarmCache, takeSourceBlobs, warmSendSources, type WarmDeps } from './prewarm-cache';\nimport type { ShortfallEntry } from './stores';\nimport type { History } from './history/History';\nimport type { InventoryView } from './inventory/InventoryView';\nimport { transferringToken } from './inventory/presentation';\nimport type { Receive } from './receive/Receive';\nimport type { Requests } from './requests/Requests';\nimport type { ReservationLedger } from './select/ledger';\nimport type { IntentPins } from './select/pins';\nimport type { SpendQueue, PlannedSpend } from './select/queue';\nimport type { MachineStores } from './machine/journal';\nimport { buildOps, classifyError, type MachineDeps, type MachinePlan, type TransferMachine } from './machine/TransferMachine';\nimport { buildPayload, messageOf } from './machine/payload';\nimport {\n composeFacadeParts,\n type HeldStateCache,\n type PaymentsFacadeDeps,\n} from './compose';\n\nexport {\n supportsDeterministicMint,\n type CheckpointReseeder,\n type DeterministicMintCapable,\n type FacadeClient,\n type FacadeSession,\n type PaymentsFacadeDeps,\n type RecipientInfo,\n} from './compose';\nexport { ATTENTION_MINT_UNRESOLVED } from './mint';\nexport { ATTENTION_RESEED_REJECTED } from './restore';\nexport { ATTENTION_RECIPIENT_NETWORK_UNVERIFIED } from './recipient';\n\n/** Max re-plans after a conflicted attempt (#625/#677 parity with the old send loop). */\nexport const MAX_RESELECT = 8;\n\nconst INVENTORY_SCAN_PAGE_LIMIT = 50;\n\n/**\n * What this attempt is spending. The policy loop is shared; only planning and the\n * conflict rule differ, so the union is narrowed in exactly those two places.\n */\ntype SendJob =\n | { readonly kind: 'coin'; readonly request: SendRequest }\n | {\n readonly kind: 'whole';\n readonly request: SendWholeTokenRequest;\n readonly requireCoinless: boolean;\n };\n\ninterface AttemptCtx {\n readonly transferId: string;\n /** '' for a token-addressed spend: it names no coin. */\n readonly coinId: string;\n readonly plan: MachinePlan;\n readonly sourceIds: readonly string[];\n readonly sourceTokens: readonly Token[];\n}\n\ntype AttemptDisposition =\n | { kind: 'rethrow'; error: unknown }\n | { kind: 'retry-full'; error: unknown }\n | { kind: 'success'; deliveryPending: boolean }\n | { kind: 'partial'; entry: ShortfallEntry; deliveryPending: boolean };\n\n/** Accumulated state of one send() across its internal attempts. */\ninterface SendRun {\n amount: string;\n delivered: string[];\n sentTokens: Token[];\n tokenTransfers: TokenTransferDetail[];\n settledShortfalls: string[];\n firstPartialId: string | undefined;\n pendingAny: boolean;\n lastTransferId: string; // latest attempt's id ('' pre-plan) — rides a clean-failure emission\n}\n\nexport class PaymentsFacade implements PaymentsV2 {\n private readonly wakeRefresh: () => void;\n private readonly prewarmed = new PrewarmCache();\n private readonly view: InventoryView;\n private readonly ledger: ReservationLedger;\n private readonly queue: SpendQueue;\n private readonly machine: TransferMachine;\n private readonly machineDeps: MachineDeps;\n private readonly machineStores: MachineStores;\n private readonly historyStore: History;\n private readonly receiveLoop: Receive;\n private readonly heldStates: HeldStateCache;\n private readonly ownPubkeyBytes: Uint8Array;\n private readonly restoreDeps: RestoreDeps;\n readonly requests: Requests;\n\n private currentEngine: ITokenEngine | null = null;\n private readonly pendingOps = new Set<Promise<void>>();\n private unsubscribers: (() => void)[] = [];\n private started = false;\n\n // §7 heartbeat: in-memory timing cell + pass runner (see convergence.ts).\n private readonly heartbeat: ConvergenceHeartbeat;\n private readonly converger: Converger;\n /** Resume single-flight (§7): ticks, start() and resumeNow() coalesce onto ONE pass. */\n private readonly resumeFlight = new SingleFlight<void>();\n /** §5.1/§7: restore + convergence passes SERIALIZE here. */\n private readonly passChain = new SerialChain();\n /** §7 ownership: ids with an in-process machine attempt — the pass never adopts one. */\n private readonly activeMoneyOps = new Set<string>();\n /** #737: the ledger holds exactly the sources of the still-open intents. */\n private readonly pins: IntentPins;\n /** Per facade, so per address: an NFT reading is never served to another wallet. */\n private readonly nftCache = new NftCache();\n\n constructor(private readonly deps: PaymentsFacadeDeps) {\n const parts = composeFacadeParts(deps, {\n engine: () => this.engine(),\n send: (request) => this.send(request),\n isActiveOp: (id) => this.activeMoneyOps.has(id),\n track: (op) => this.trackTail(op),\n });\n this.view = parts.view;\n this.wakeRefresh = parts.refreshView;\n this.ledger = parts.ledger;\n this.queue = parts.queue;\n this.machine = parts.machine;\n this.machineDeps = parts.machineDeps;\n this.machineStores = parts.machineStores;\n this.historyStore = parts.historyStore;\n this.receiveLoop = parts.receiveLoop;\n this.heldStates = parts.heldStates;\n this.ownPubkeyBytes = parts.ownPubkeyBytes;\n this.restoreDeps = parts.restoreDeps;\n this.requests = parts.requests;\n this.pins = parts.pins;\n deps.deliveryPort.bindDeliveryKeys((blob) => this.engine().deliveryKeys(blob));\n this.heartbeat = new ConvergenceHeartbeat({\n now: () => this.nowMs(),\n onTick: () => this.trackTail(this.runConvergencePass()),\n });\n this.converger = new Converger({\n machineDeps: this.machineDeps,\n stores: this.machineStores,\n delivery: deps.deliveryPort,\n reconcile: (report) => this.requests.reconcile(report),\n refreshView: () => this.view.delta(),\n replayMints: () => replayCoinMints(this.mintDeps()),\n replayNftMints: () => replayNftMints(this.mintDeps()),\n isActiveOp: (id) => this.activeMoneyOps.has(id),\n emit: deps.emit,\n now: () => this.nowMs(),\n });\n }\n\n // ── lifecycle ──────────────────────────────────────────────────────────────\n\n async start(): Promise<void> {\n if (this.started) return;\n this.started = true;\n this.heartbeat.start();\n // Subscriptions BEFORE session.start(): no frame can beat the restore hook.\n this.unsubscribers.push(\n this.deps.session.subscribeEpochChange((epoch) => this.handleEpochChange(epoch)),\n this.deps.session.subscribeStream('mailbox', () => {\n this.trackTail(this.receiveLoop.drainOnce());\n }),\n this.deps.session.subscribeStream('inventory', this.wakeRefresh),\n this.deps.session.subscribeStream('payment_requests', () => {\n this.trackTail(this.requests.drainIncoming());\n })\n );\n const statusUnsub = this.deps.session.subscribeStatus?.((status) => {\n if (status === 'connected') this.heartbeat.recovered();\n });\n if (statusUnsub !== undefined) this.unsubscribers.push(statusUnsub);\n await this.deps.session.start();\n // BEFORE the first pass and before any send can plan: a source pinned by an\n // intent left open by the previous session must not be re-offered (#737).\n // A rejection leaves the ledger unproven: reads keep working, spending does not (#738).\n await this.pins.sync().catch(() => undefined);\n // §7 start posture: never awaited; the heartbeat re-runs this same pass.\n this.trackTail(this.runConvergencePass());\n this.trackTail(this.seedHeldStates());\n await this.view.fullPull().catch(() => undefined);\n this.receiveLoop.start(this.deps.receivePollMs);\n }\n\n /** §7 same-address restart gate: resolves only after in-flight ops settle. */\n async stop(): Promise<void> {\n this.started = false;\n this.heartbeat.stop(); // §7 quiescence unchanged: a mid-backoff stop cancels cleanly\n this.receiveLoop.stop();\n for (const unsubscribe of this.unsubscribers) unsubscribe();\n this.unsubscribers = [];\n await this.deps.session.stop();\n while (this.pendingOps.size > 0) {\n await Promise.allSettled([...this.pendingOps]);\n }\n }\n\n /** Swaps what FUTURE operations snapshot. Chain ops finish on the old engine, but it is\n * DISPOSED here, so one mid-`verify()` is cancelled — MODULE_DESTROYED, #770(4). */\n setEngine(next: ITokenEngine): void {\n const previous = this.currentEngine ?? this.deps.engineRef();\n this.currentEngine = next;\n if (previous !== next) previous.dispose?.();\n }\n\n // ── reads ──────────────────────────────────────────────────────────────────\n\n async assets(coinId?: string): Promise<Asset[]> {\n const all = await this.view.assets(this.deps.registry, this.deps.price);\n return coinId === undefined ? all : all.filter((asset) => asset.coinId === coinId);\n }\n\n tokens(filter?: { coinId?: string }): Token[] {\n return this.view.tokens(this.deps.registry, filter);\n }\n\n coinless(): CoinlessToken[] {\n return this.view.coinless(this.deps.registry);\n }\n\n tokenData(tokenId: string): Promise<Uint8Array | null> {\n return readTokenData(this.readDeps(), tokenId);\n }\n\n nft(tokenId: string): Promise<NftView | null> {\n return readNft(this.readDeps(), tokenId);\n }\n\n nfts(tokenIds: readonly string[]): Promise<ReadonlyMap<string, NftView>> {\n return readNfts(this.readDeps(), tokenIds);\n }\n\n private readDeps(): NftReadDeps {\n return { engine: this.engine(), view: this.view, storagePort: this.deps.storagePort, cache: this.nftCache };\n }\n\n history(page?: { before?: string; limit?: number }): Promise<HistoryPage> {\n return this.historyStore.page(page ?? {});\n }\n\n /** §4: read through to the session — the same value `connection:status` carries (sphere#473). No session ⇒ 'offline'. */\n connectionStatus(): ConnectionStatus {\n return this.started ? this.deps.session.status() : 'offline';\n }\n\n /** §4 pending-transfers UI surface — derived on read, never cached (convergence.ts). */\n pendingTransfers(): Promise<PendingTransfer[]> {\n return derivePendingTransfers(this.machineStores, this.machineDeps.decryptPayload);\n }\n\n // ── money movement ─────────────────────────────────────────────────────────\n\n async prewarmSend(request: SendRequest): Promise<void> {\n await warmSendSources(this.warmDeps(), request);\n }\n\n discardPrewarm(): void {\n this.prewarmed.clear();\n }\n\n private warmDeps(): WarmDeps {\n return { queue: this.queue, view: this.view, storagePort: this.deps.storagePort, cache: this.prewarmed };\n }\n\n send(request: SendRequest): Promise<TransferResult> {\n return this.track(this.runJob({ kind: 'coin', request }, request.amount));\n }\n\n sendWholeToken(request: SendWholeTokenRequest): Promise<TransferResult> {\n // '0': no amount, keeping the shortfall arithmetic total-free.\n return this.track(this.runJob({ kind: 'whole', request, requireCoinless: false }, '0'));\n }\n\n /** NFT-scoped twin: refuses a valued source. */\n sendCoinless(request: SendWholeTokenRequest): Promise<TransferResult> {\n return this.track(this.runJob({ kind: 'whole', request, requireCoinless: true }, '0'));\n }\n\n async receive(): Promise<{ transfers: IncomingTransfer[] }> {\n const transfers = await this.track(this.receiveLoop.drainOnce());\n return { transfers };\n }\n\n mint(coinId: string, amount: bigint): Promise<MintResult> {\n return this.track(this.mintInner(coinId, amount));\n }\n\n mintNft(request: MintNftRequest): Promise<MintResult> {\n return this.track(this.ownedMint((mintId) => runNftMintUnderJournal(this.mintDeps(), { mintId, request })));\n }\n\n // §4 retry verb: coalesces onto the running pass — NEVER re-issue send() (#631/#676).\n async resumeNow(): Promise<void> {\n if (!this.started) return;\n await this.track(this.runConvergencePass());\n }\n\n /** §5.1 restore — awaited by the session latch BEFORE streams resume; never coalesced onto a pre-restore pass. */\n async handleEpochChange(_newEpoch: string): Promise<void> {\n await this.passChain.enqueue(() => reseedAndReset(this.restoreDeps));\n await this.passChain.enqueue(() => this.convergeBody());\n }\n\n /** One single-flighted pass + its reschedule: concurrent callers coalesce. */\n private runConvergencePass(): Promise<void> {\n return this.resumeFlight.run(() => this.passChain.enqueue(() => this.convergeBody()));\n }\n\n private async convergeBody(): Promise<void> {\n const outcome = await this.converger.convergeOnce();\n // After the pass refreshed the mirror: an intent that stopped being open\n // stops pinning, one still open keeps pinning (#737).\n // A rejection leaves the ledger unproven: reads keep working, spending does not (#738).\n await this.pins.sync().catch(() => undefined);\n const pending = await this.converger.pendingWork().catch(() => true);\n this.heartbeat.settle(outcome, pending);\n }\n\n private nowMs(): number {\n return (this.deps.now ?? Date.now)();\n }\n\n /** One snapshot serves the coin and the NFT mint, live and replayed. */\n private mintDeps(): CoinReplayDeps & NftReplayDeps {\n return {\n engine: this.engine(),\n mintJournal: this.machineStores.mintJournal,\n nftMintJournal: this.machineStores.nftMintJournal,\n storagePort: this.deps.storagePort,\n recordMint: (input) => this.historyStore.recordMint(input),\n armHeartbeat: () => this.heartbeat.arm(),\n noteHeldState: (tokenId, stateHash) => void this.heldStates.set(tokenId, stateHash),\n refreshView: () => this.trackTail(this.view.delta()),\n ownPubkeyBytes: this.ownPubkeyBytes,\n nftTokenType: this.deps.nftTokenType,\n isActiveOp: (mintId) => this.activeMoneyOps.has(mintId),\n tokenInServerInventory: (tokenId) => this.tokenInServerInventory(tokenId),\n emit: this.deps.emit,\n now: () => this.nowMs(),\n };\n }\n\n // ── send policy (§5.5 + old-loop parity; the machine stays policy-free) ────\n\n /** The ONE place a send() outcome is shaped: success emits in finishSend, a\n * CLEAN rejection emits `transfer:updated{status:'failed'}` here (§4). */\n private async runJob(job: SendJob, amount: string): Promise<TransferResult> {\n const run: SendRun = {\n amount,\n delivered: [],\n sentTokens: [],\n tokenTransfers: [],\n settledShortfalls: [],\n firstPartialId: undefined,\n pendingAny: false,\n lastTransferId: '',\n };\n try {\n return await this.sendWithPolicy(job, run);\n } catch (err) {\n this.emitCleanFailure(err, run.lastTransferId);\n throw err;\n }\n }\n\n /** Only a CLEAN failure (nothing certified, classifyError 'other') is 'failed'.\n * Keep-open/partial/conflict outcomes are pending/converging — labelling them\n * 'failed' invites a dApp re-send, i.e. a double-pay (#631/#676). */\n private emitCleanFailure(err: unknown, transferId: string): void {\n if (isPossiblyCommittedSendOutcome(err) || classifyError(err) !== 'other') return;\n const failed: TransferResult = {\n id: transferId,\n status: 'failed',\n tokens: [],\n tokenTransfers: [],\n error: messageOf(err),\n };\n this.deps.emit('transfer:updated', failed);\n }\n\n private async sendWithPolicy(job: SendJob, run: SendRun): Promise<TransferResult> {\n const recipient = await requireSameNetworkRecipient(this.deps, job.request.recipient);\n for (let attempt = 0; ; attempt++) {\n let ctx: AttemptCtx;\n try {\n ctx = await this.planAndMaterialize(recipient.chainPubkey, job, run);\n } catch (err) {\n throw partialize(err, run);\n }\n const disposition = await this.runAttempt(ctx);\n if (disposition.kind === 'rethrow') throw partialize(disposition.error, run);\n if (disposition.kind === 'retry-full') {\n // #625's re-plan searches for a DIFFERENT source. A named token has no\n // alternative — re-planning would pick the same one or nothing — so a\n // proven conflict is TERMINAL here rather than a bounded retry.\n if (job.kind === 'whole' || attempt >= MAX_RESELECT) throw partialize(disposition.error, run);\n continue;\n }\n if (disposition.kind === 'success') {\n run.pendingAny = run.pendingAny || disposition.deliveryPending;\n this.accumulate(ctx, ctx.sourceIds, run);\n return await this.finishSend(ctx.transferId, run);\n }\n const surfaced = await this.consumePartial(ctx, disposition, run, attempt);\n if (surfaced !== null) return surfaced;\n }\n }\n\n private async runAttempt(ctx: AttemptCtx): Promise<AttemptDisposition> {\n this.activeMoneyOps.add(ctx.transferId);\n try {\n const { deliveryPending } = await this.machine.run(ctx.plan);\n this.settleSuccess(ctx, ctx.sourceIds);\n return { kind: 'success', deliveryPending };\n } catch (err) {\n return await this.disposeFailedAttempt(ctx, err);\n } finally {\n this.activeMoneyOps.delete(ctx.transferId);\n }\n }\n\n /** Partial (#677/#690): shortfall already durable (machine wrote it BEFORE\n * complete); accumulate settled, re-plan ONLY the remainder, NEW transferId. */\n private async consumePartial(\n ctx: AttemptCtx,\n disposition: { entry: ShortfallEntry; deliveryPending: boolean },\n run: SendRun,\n attempt: number\n ): Promise<TransferResult | null> {\n if (disposition.deliveryPending) {\n run.pendingAny = true;\n this.heartbeat.arm(); // deposits owed — heartbeat work even if the remainder later throws\n }\n const partial = disposition.entry;\n run.delivered.push(...partial.committedTokenIds);\n run.firstPartialId ??= partial.transferId;\n run.settledShortfalls.push(partial.transferId);\n this.accumulate(ctx, partial.committedTokenIds, run);\n this.settlePartial(ctx, partial);\n if (BigInt(partial.remainingAmount) <= 0n) {\n return this.finishSend(ctx.transferId, run);\n }\n if (attempt >= MAX_RESELECT) {\n throw new PartialSendConflictError(\n 'Part of your payment was sent, but the remainder could not be completed within the re-plan budget. The delivered portion is final — re-plan only the shortfall, never the full amount.',\n run.firstPartialId,\n run.delivered,\n partial.remainingAmount\n );\n }\n run.amount = partial.remainingAmount;\n return null;\n }\n\n /** Failure disposition: possibly-committed → rethrow UNWRAPPED; backstop\n * 'open' → converge via resumeIntent; clean demoted conflict → full re-plan. */\n private async disposeFailedAttempt(ctx: AttemptCtx, err: unknown): Promise<AttemptDisposition> {\n if (isPossiblyCommittedSendOutcome(err)) {\n this.settleKeepOpen(ctx);\n stampTransferId(err, ctx.transferId);\n return { kind: 'rethrow', error: err };\n }\n const backstop = await this.machineStores.backstop.getByKey(ctx.transferId);\n if (backstop !== undefined && backstop.disposition === 'open') {\n return this.convergePartial(ctx);\n }\n this.settleFailure(ctx.transferId, ctx.coinId, ctx.sourceIds);\n if (classifyError(err) !== 'conflict') return { kind: 'rethrow', error: err };\n const demoted = await this.demoteSpentSources(ctx);\n return demoted > 0 ? { kind: 'retry-full', error: err } : { kind: 'rethrow', error: err };\n }\n\n /** #677/#690: ≥1 leg committed — the SAME machine, resumed in-process, converges it. */\n private async convergePartial(ctx: AttemptCtx): Promise<AttemptDisposition> {\n let outcome;\n try {\n outcome = await this.machine.resumeIntent({\n transferId: ctx.transferId,\n payload: ctx.plan.payload,\n sources: ctx.plan.sources,\n journaled: await this.machineStores.deliveryJournal.byTransfer(ctx.transferId),\n });\n } catch (err) {\n return this.disposeConvergeFailure(ctx, err);\n }\n if (outcome.partial === null) {\n this.settleSuccess(ctx, ctx.sourceIds);\n return { kind: 'success', deliveryPending: outcome.deliveryPending };\n }\n return { kind: 'partial', entry: outcome.partial, deliveryPending: outcome.deliveryPending };\n }\n\n private async disposeConvergeFailure(ctx: AttemptCtx, err: unknown): Promise<AttemptDisposition> {\n if (isPossiblyCommittedSendOutcome(err)) {\n this.settleKeepOpen(ctx);\n stampTransferId(err, ctx.transferId);\n return { kind: 'rethrow', error: err };\n }\n if (classifyError(err) === 'conflict') {\n // Nothing was delivered after all (E.2 pure lost race): soft-abort and\n // fall back to the clean-conflict path.\n await this.softAbort(ctx.transferId);\n this.settleFailure(ctx.transferId, ctx.coinId, ctx.sourceIds);\n const demoted = await this.demoteSpentSources(ctx);\n return demoted > 0 ? { kind: 'retry-full', error: err } : { kind: 'rethrow', error: err };\n }\n return { kind: 'rethrow', error: err };\n }\n\n private async planAndMaterialize(recipientPubkey: string, job: SendJob, run: SendRun): Promise<AttemptCtx> {\n const transferId = this.newId();\n run.lastTransferId = transferId;\n // The ONE divergence: a coin spend SELECTS sources to cover an amount and may\n // queue for them; a token spend reserves the one it was NAMED and never queues.\n if (job.kind === 'whole') {\n const spend = this.queue.planWhole(transferId, job.request.tokenId);\n const sourceIds = this.markPlanned(transferId, '', spend);\n try {\n return await materializeWholeSpend(\n { engine: this.engine(), storagePort: this.deps.storagePort, registry: this.deps.registry, now: this.nowMs() },\n {\n transferId,\n recipientPubkey,\n request: job.request,\n sourceIds,\n requireCoinless: job.requireCoinless,\n }\n );\n } catch (err) {\n this.settleFailure(transferId, '', sourceIds);\n throw err;\n }\n }\n const request = { ...job.request, amount: run.amount };\n const planned = this.queue.plan(transferId, { coinId: request.coinId, amount: request.amount });\n const spend = planned.kind === 'planned' ? planned.spend : await planned.settled;\n const sourceIds = this.markPlanned(transferId, request.coinId, spend);\n try {\n return await this.materialize(transferId, recipientPubkey, request, spend, sourceIds);\n } catch (err) {\n this.settleFailure(transferId, request.coinId, sourceIds);\n throw err;\n }\n }\n\n /** Reserve happened synchronously inside queue.plan; mark + declare with no await between. */\n private markPlanned(transferId: string, coinId: string, spend: PlannedSpend): string[] {\n const sourceIds = [\n ...spend.plan.direct,\n ...(spend.plan.split !== undefined ? [spend.plan.split.tokenId] : []),\n ];\n this.view.markInFlightMany(sourceIds);\n if (spend.plan.split !== undefined) {\n this.queue.declareExpectedChange(transferId, coinId, spend.plan.split.remainderAmount);\n }\n return sourceIds;\n }\n\n private async materialize(\n transferId: string,\n recipientPubkey: string,\n request: SendRequest,\n spend: PlannedSpend,\n sourceIds: readonly string[]\n ): Promise<AttemptCtx> {\n const engine = this.engine();\n const blobs = await takeSourceBlobs(this.warmDeps(), sourceIds);\n const sources = new Map<string, SphereToken>();\n const sourceTokens: Token[] = [];\n const spentStates: Record<string, { local: string; protocol: string }> = {};\n for (const tokenId of sourceIds) {\n const bytes = blobs.get(tokenId);\n if (bytes === undefined) {\n throw new SphereError(`Selected source ${tokenId} has no blob in storage`, 'STORAGE_ERROR');\n }\n const token = await engine.decodeToken({ tokenId, token: bytes });\n const keys = await engine.deliveryKeys(bytes);\n // local === protocol by construction; the dual field is wire compat (types.ts).\n spentStates[tokenId] = { local: keys.stateHash, protocol: keys.stateHash };\n sources.set(tokenId, token);\n sourceTokens.push(transferringToken(tokenId, request.coinId, engine.balanceOf(token, request.coinId), this.deps.registry, this.nowMs()));\n }\n const payload = buildPayload(recipientPubkey, request, spend, spentStates);\n const plan: MachinePlan = {\n transferId,\n recipientPubkey,\n payload,\n ops: buildOps(payload),\n sources,\n ...(request.memo !== undefined ? { memo: request.memo } : {}),\n };\n return { transferId, coinId: request.coinId, plan, sourceIds, sourceTokens };\n }\n\n\n /** isSpent sweep over the attempt's sources; demote proven-spent states (durable). */\n private async demoteSpentSources(ctx: AttemptCtx): Promise<number> {\n const engine = this.engine();\n let demoted = 0;\n for (const [tokenId, token] of ctx.plan.sources) {\n const state = ctx.plan.payload.spentStates?.[tokenId];\n if (state === undefined) continue;\n try {\n if (await engine.isSpent(token)) {\n await this.view.demote(tokenId, state.protocol);\n demoted += 1;\n }\n } catch {\n // Probe outage: never demote on a guess — the attempt budget bounds us.\n }\n }\n return demoted;\n }\n\n // ── attempt settlement (reservation / in-flight / expected-change hygiene) ─\n\n private settleSuccess(ctx: AttemptCtx, spentIds: readonly string[]): void {\n this.ledger.commit(ctx.transferId);\n this.queue.clearExpectedChange(ctx.transferId);\n this.trackTail(this.refreshThenRelease(ctx.coinId, spentIds));\n }\n\n private settleFailure(transferId: string, coinId: string, releaseIds: readonly string[]): void {\n this.ledger.cancel(transferId);\n this.queue.clearExpectedChange(transferId);\n this.view.releaseMany(releaseIds);\n this.queue.notifyChange(coinId);\n }\n\n /** Open intent: sources stay reserved + in-flight (§5.2) until resume adopts them. */\n private settleKeepOpen(ctx: AttemptCtx): void {\n this.queue.clearExpectedChange(ctx.transferId);\n // The reservation is now the intent's pin, and lives and dies with it (#737).\n this.pins.adopt(ctx.transferId);\n this.heartbeat.arm(); // the parked intent converges in-session — no restart\n }\n\n private settlePartial(ctx: AttemptCtx, partial: ShortfallEntry): void {\n this.ledger.cancel(ctx.transferId);\n this.queue.clearExpectedChange(ctx.transferId);\n const committed = new Set(partial.committedTokenIds);\n for (const tokenId of ctx.sourceIds) {\n if (committed.has(tokenId)) continue;\n // The conflicted leg's source is proven foreign-spent — demote + release.\n const state = ctx.plan.payload.spentStates?.[tokenId];\n if (state !== undefined) this.trackTail(this.view.demote(tokenId, state.protocol));\n this.view.release(tokenId);\n }\n this.trackTail(this.refreshThenRelease(ctx.coinId, [...committed]));\n }\n\n /** Release spent sources only AFTER the mirror refresh tombstoned them. */\n private async refreshThenRelease(coinId: string, spentIds: readonly string[]): Promise<void> {\n try {\n await this.view.delta();\n this.view.releaseMany(spentIds);\n } finally {\n this.queue.notifyChange(coinId);\n }\n }\n\n private accumulate(ctx: AttemptCtx, committedIds: readonly string[], run: SendRun): void {\n const committed = new Set(committedIds);\n for (const op of ctx.plan.ops) {\n if (!committed.has(op.sourceTokenId)) continue;\n run.tokenTransfers.push({ sourceTokenId: op.sourceTokenId, method: op.kind });\n }\n for (const token of ctx.sourceTokens) {\n if (committed.has(token.id)) run.sentTokens.push(token);\n }\n }\n\n private async finishSend(transferId: string, run: SendRun): Promise<TransferResult> {\n for (const id of run.settledShortfalls.splice(0)) {\n await this.machineStores.shortfalls.removeByKey(id).catch(() => undefined);\n }\n if (run.pendingAny) this.heartbeat.arm(); // deposits owed in the journal — heartbeat work\n const result: TransferResult = {\n id: transferId,\n status: run.pendingAny ? 'confirmed' : 'delivered',\n tokens: [...run.sentTokens],\n tokenTransfers: [...run.tokenTransfers],\n deliveryPending: run.pendingAny,\n deliveryState: run.pendingAny ? 'pending-delivery' : 'landed',\n };\n this.deps.emit('transfer:updated', result);\n return result;\n }\n\n /** Nothing delivered → UNWRAPPED; after ≥1 delivered leg every failure surfaces as PartialSendConflictError over the settled set. */\n private async softAbort(transferId: string): Promise<void> {\n try {\n await this.deps.client.abortIntent(transferId);\n await this.machineStores.backstop.removeByKey(transferId);\n } catch {\n // Stays locally recorded; the #676 resume gate converges it later.\n }\n }\n\n // ── mint (§5.9: journal-first, replayed at start, never blind re-mint) ─────\n\n private async mintInner(coinId: string, amount: bigint): Promise<MintResult> {\n if (!/^(?:[0-9a-f]{2})+$/.test(coinId) || amount <= 0n) {\n return { success: false, error: 'coinId must be even-length lowercase hex and amount positive' };\n }\n return this.ownedMint((mintId) => runMintUnderJournal(this.mintDeps(), { mintId, coinId, amount }));\n }\n\n /** A live mint under a fresh id — its replay stays hands-off while this attempt runs. */\n private async ownedMint(run: (mintId: string) => Promise<MintResult>): Promise<MintResult> {\n const mintId = this.newId();\n this.activeMoneyOps.add(mintId);\n try {\n return await run(mintId);\n } finally {\n this.activeMoneyOps.delete(mintId);\n }\n }\n\n private async tokenInServerInventory(tokenId: string): Promise<boolean> {\n let page = await this.deps.storagePort.listInventory();\n for (let i = 0; i < INVENTORY_SCAN_PAGE_LIMIT; i++) {\n if (page.items.some((item) => item.tokenId === tokenId && item.status === 'active')) {\n return true;\n }\n if (!page.more) return false;\n page = await this.deps.storagePort.listInventory(page.cursor);\n }\n return false;\n }\n\n // ── wiring internals ───────────────────────────────────────────────────────\n\n private engine(): ITokenEngine {\n return this.currentEngine ?? this.deps.engineRef();\n }\n\n private newId(): string {\n return (this.deps.newId ?? randomUUID)();\n }\n\n private async seedHeldStates(): Promise<void> {\n let page = await this.deps.storagePort.listInventory();\n for (let i = 0; i < INVENTORY_SCAN_PAGE_LIMIT; i++) {\n for (const item of page.items) {\n if (item.status === 'active') this.heldStates.set(item.tokenId, item.stateHash);\n }\n if (!page.more) return;\n page = await this.deps.storagePort.listInventory(page.cursor);\n }\n }\n\n private track<T>(op: Promise<T>): Promise<T> {\n const settled = op.then(() => undefined, () => undefined);\n this.pendingOps.add(settled);\n void settled.finally(() => this.pendingOps.delete(settled));\n return op;\n }\n\n private trackTail(op: Promise<unknown>): void {\n this.track(op).catch(() => undefined);\n }\n}\n\n"],"mappings":"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","names":["isLE","isBytes","isBytes","abytes","aexists","aoutput","clean","createView","abytes","isLE","createView","abytes","clean","abytes","clean","aexists","aoutput","abytes","clean","CURSOR_KEY","page","spend","sourceIds"]}
|
|
1
|
+
{"version":3,"sources":["../../../modules/payments-v2/index.ts","../../../node_modules/@noble/hashes/src/utils.ts","../../../node_modules/@noble/hashes/src/_md.ts","../../../node_modules/@noble/hashes/src/sha2.ts","../../../core/errors.ts","../../../token-engine/sdk.ts","../../../token-engine/nft-payload.ts","../../../core/crypto.ts","../../../modules/payments-v2/machine/payload.ts","../../../modules/payments-v2/async.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","../../../modules/payments-v2/machine/payload-view.ts","../../../core/uuid.ts","../../../modules/payments-v2/history/History.ts","../../../core/logger.ts","../../../modules/payments-v2/stores.ts","../../../modules/payments-v2/inventory/presentation.ts","../../../modules/payments-v2/inventory/InventoryView.ts","../../../token-engine/value-envelope.ts","../../../modules/payments-v2/ports.ts","../../../modules/payments-v2/receive/Receive.ts","../../../modules/payments-v2/requests/Requests.ts","../../../modules/payments-v2/machine/journal.ts","../../../token-engine/errors.ts","../../../modules/payments-v2/machine/TransferMachine.ts","../../../modules/payments-v2/machine/resume.ts","../../../modules/payments-v2/convergence.ts","../../../modules/payments-v2/select/ledger.ts","../../../modules/payments-v2/select/pins.ts","../../../modules/payments-v2/select/selector.ts","../../../modules/payments-v2/select/queue.ts","../../../modules/payments-v2/compose.ts","../../../modules/payments-v2/mint-params.ts","../../../modules/payments-v2/mint.ts","../../../modules/payments-v2/mint-nft.ts","../../../modules/payments-v2/inventory/nft-read.ts","../../../modules/payments-v2/inventory/token-data.ts","../../../modules/payments-v2/send-whole.ts","../../../modules/payments-v2/send-errors.ts","../../../modules/payments-v2/recipient.ts","../../../modules/payments-v2/restore.ts","../../../modules/payments-v2/prewarm-cache.ts","../../../modules/payments-v2/PaymentsFacade.ts"],"sourcesContent":["export type { PaymentsV2, PaymentsV2Events, ConnectionStatus, SendRequest, SendWholeTokenRequest, SendCoinlessRequest, MintResult, HistoryEntry, HistoryPage, PaymentRequestView, PaymentRequestStatus, PaymentsRequestsApi, PendingTransfer } from './api';\n// NFT metadata (#785; normative spec docs/NFT-METADATA.md).\nexport type {\n MintNftRequest,\n NftView,\n NftAttribute,\n NftContent,\n NftLink,\n NftMedia,\n NftMediaRef,\n NftMetadata,\n NftSignatureStatus,\n} from './api';\nexport type { NftSignatureContext } from '../../token-engine/nft-payload';\nexport {\n NFT_DOCUMENT_MEDIA_TYPE,\n NFT_LINK_TAG,\n NFT_MEDIA_TAG,\n NFT_METADATA_TAG,\n NFT_SIGNED_TAG,\n encodeNftContent,\n isNftDocumentLink,\n parseNftDocument,\n parseNftPayload,\n verifyNftLinkContent,\n} from '../../token-engine/nft-payload';\nexport { NFT_MAX_PAYLOAD_BYTES } from './mint-nft';\nexport type {\n StoragePort,\n DeliveryPort,\n InventoryItem,\n InventoryPage,\n InventoryAsset,\n ApplyDeltaResult,\n DeliveryReceipt,\n IncomingDelivery,\n DeliverOptions,\n AckRequest,\n AckOutcome,\n RetryableAckError,\n} from './ports';\n// A port implementing the optional ackBatch cannot express the contract without\n// these: the request/outcome shapes, and the retryable signal that stops the\n// caller falling back to one ack per entry against a wall that rejected a batch.\nexport { isRetryableAckError } from './ports';\nexport type { IntentPayload, PlannedOp, OpOutcome, OutcomeClass } from './machine/types';\nexport * from './stores';\nexport {\n PaymentsFacade,\n MAX_RESELECT,\n ATTENTION_MINT_UNRESOLVED,\n ATTENTION_RECIPIENT_NETWORK_UNVERIFIED,\n ATTENTION_RESEED_REJECTED,\n supportsDeterministicMint,\n} from './PaymentsFacade';\nexport { HEARTBEAT_SEED_MS, HEARTBEAT_CAP_MS } from './convergence';\nexport type {\n PaymentsFacadeDeps,\n FacadeSession,\n FacadeClient,\n CheckpointReseeder,\n RecipientInfo,\n DeterministicMintCapable,\n} from './PaymentsFacade';\n","/**\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 * 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 // The op's certification is INDETERMINATE (submit accepted / proof fetch\n // inconclusive) — raised as ProofUnconfirmedError; keep the intent OPEN (#631).\n | 'CERTIFICATION_UNCONFIRMED'\n // Split burn checkpoint (sdk-changes E.4, sphere-sdk#501) — all keep-open (token-engine/errors.ts):\n // burn certified but the checkpoint could not be persisted (no mint submitted);\n | 'CHECKPOINT_PERSIST_FAILED'\n // a certified mint leaf has no reproducing stored bytes, or a stored checkpoint fails byte-binding;\n | 'SPLIT_CHECKPOINT_LOST'\n // a byte-bound checkpoint proof no longer verifies against the current trust base (validator rotation).\n | 'CHECKPOINT_TRUSTBASE_MISMATCH'\n | 'STORAGE_ERROR'\n // #665: the on-chain spend committed but the post-commit wallet-api mirror\n // sync (inventory apply / blob upload / save) failed. NOT a lost payment —\n // the intent is kept open and resume converges the mirror (idempotent apply,\n // #664). Surfaced distinctly so a UI can reassure (\"sent — wallet catching\n // up\") instead of showing a hard send failure.\n | 'SEND_SYNC_PENDING'\n // #677: a multi-leg send lost a source to a concurrent transfer AFTER ≥1\n // earlier leg had already certified on-chain AND been journaled/delivered.\n // The delivered value has irreversibly left the wallet, so this is NOT a\n // plain, re-sendable failure: surfacing a bare TransferConflictError makes\n // the caller re-send the FULL amount and pay the delivered leg twice. Raised\n // as PartialSendConflictError; the caller MUST re-plan ONLY the remainder\n // under a NEW transferId, never the whole amount.\n | 'SEND_PARTIALLY_COMPLETED'\n | 'TRANSPORT_ERROR'\n | 'AGGREGATOR_ERROR'\n | 'VALIDATION_ERROR'\n | 'INVALID_AMOUNT'\n | 'NETWORK_ERROR'\n | 'TIMEOUT'\n | 'DECRYPTION_ERROR'\n | 'MODULE_NOT_AVAILABLE'\n // #793: this Sphere was initialised with `walletApi: 'none'` — the explicit\n // messaging-only composition. Distinct from NOT_INITIALIZED, which is transient\n // (init in flight, mid address-switch, destroyed): this one never resolves.\n | 'PAYMENTS_NOT_COMPOSED'\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 * #441 deferred-paid linkage: the transferId of the possibly-committed send,\n * stamped by `sendOnce` before the error leaves so a payment-request consumer\n * can durably journal request→transfer and resolve 'paid' only when that\n * transfer actually completes (never optimistically). Present ONLY on\n * possibly-committed outcomes ({@link isPossiblyCommittedSendOutcome}).\n */\n transferId?: string;\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 * #677: a send that PARTIALLY completed before losing a source to a concurrent\n * transfer. At least one earlier leg certified on-chain and was journaled for\n * delivery (its {@link committedTokenIds}) — that value has irreversibly left\n * the wallet — but a LATER leg raised `TransferConflictError` (a lost race), and\n * `send()` could NOT COMPLETE the {@link remainingAmount} from the remaining live\n * sources. This is the fallback after the internal remainder re-plan gave up —\n * either insufficient funds OR a transient/transport error during the re-plan\n * (the underlying reason is on `cause`), not necessarily an \"out of funds\" state.\n *\n * Distinct from `TransferConflictError` on purpose: a bare conflict makes the\n * caller re-send the FULL amount, paying the already-delivered leg a second\n * time. Catching THIS type (or `code === 'SEND_PARTIALLY_COMPLETED'`) tells the\n * caller/UI: the delivered legs are final, the conflicted intent stays OPEN\n * (resume converges its certified legs), and only the REMAINDER\n * ({@link remainingAmount}) may be re-planned — under a NEW transferId, never\n * re-sending the whole amount.\n *\n * NOT a subclass of `TransferConflictError` by design: existing conflict\n * handlers that re-send in full must NOT treat this as an ordinary conflict.\n */\nexport class PartialSendConflictError extends SphereError {\n /**\n * The FIRST partial attempt's transferId — its intent stays open for resume,\n * and it is the §6 handoff anchor. NOTE: `send()` may re-plan the remainder across\n * SEVERAL internal attempts before giving up, so {@link committedTokenIds} can\n * span MULTIPLE transferIds — they do NOT all map to this single id.\n */\n readonly transferId: string;\n /**\n * Source token ids whose spend already certified on-chain (and whose finished\n * output blob is journaled for delivery). Their value has already been\n * delivered; NEVER re-send these. May accumulate across several internal\n * remainder-re-plan attempts (so not all are journaled under {@link transferId}).\n */\n readonly committedTokenIds: readonly string[];\n /**\n * The still-undelivered portion (base units, decimal string) — `send()` could\n * not COMPLETE it from the remaining live sources (insufficient funds or a\n * transient error; see `cause`). Re-plan ONLY this amount, under a new\n * transferId; the delivered legs converge via the recipient's §6 claim.\n */\n readonly remainingAmount: string;\n\n constructor(\n message: string,\n transferId: string,\n committedTokenIds: readonly string[],\n remainingAmount: string,\n cause?: unknown,\n ) {\n super(message, 'SEND_PARTIALLY_COMPLETED', cause);\n this.name = 'PartialSendConflictError';\n this.transferId = transferId;\n this.committedTokenIds = [...committedTokenIds];\n this.remainingAmount = remainingAmount;\n }\n}\n\n/**\n * Error codes for a send outcome where money has (or may have) already left the\n * wallet on-chain, so the send is NOT a clean, re-sendable failure. A consumer\n * that persists a \"paid\" flag (e.g. a payment request) must keep the request\n * NON-payable on any of these — reverting to a re-payable state would double-pay\n * (#441). Covers the post-commit mirror-sync-pending / keep-open certification\n * states AND the partial-conflict outcome.\n */\nconst POSSIBLY_COMMITTED_SEND_CODES: ReadonlySet<SphereErrorCode> = new Set([\n 'SEND_SYNC_PENDING',\n 'CERTIFICATION_UNCONFIRMED',\n 'CHECKPOINT_PERSIST_FAILED',\n 'SPLIT_CHECKPOINT_LOST',\n 'CHECKPOINT_TRUSTBASE_MISMATCH',\n 'SEND_PARTIALLY_COMPLETED',\n]);\n\n/**\n * #441: true when a send failed with an outcome where the payment has (or may\n * have) irreversibly left the wallet — a post-commit sync-pending / keep-open\n * certification state, or a `PartialSendConflictError`. Such a send completes (or\n * has already partially completed) via resume/claim and MUST NOT be re-sent, so\n * a persisted \"paid\" state must stay non-payable. A `false` result is a clean\n * pre-commit failure — nothing left the wallet, safe to re-pay.\n */\nexport function isPossiblyCommittedSendOutcome(err: unknown): boolean {\n return isSphereError(err) && POSSIBLY_COMMITTED_SEND_CODES.has(err.code);\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 * 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';\n// #739: the 'not yet certified' answer the proof loop tolerates; tests model the\n// pre-finalization window with it, which is how the deadline path is reachable.\nexport { JsonRpcNetworkError } from '@unicitylabs/state-transition-sdk/lib/api/json-rpc/JsonRpcNetworkError.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 { StateMask } from '@unicitylabs/state-transition-sdk/lib/transaction/StateMask.js';\nexport { MintJustificationVerifierService } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/MintJustificationVerifierService.js';\nexport { TokenIssuanceVerifierService } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/TokenIssuanceVerifierService.js';\nexport { VerificationContext } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/VerificationContext.js';\nexport { UnicityCertificateVerifier } from '@unicitylabs/state-transition-sdk/lib/api/bft/verification/UnicityCertificateVerifier.js';\nexport { UnicitySealQuorumSignaturesVerificationRule } from '@unicitylabs/state-transition-sdk/lib/api/bft/verification/rule/UnicitySealQuorumSignaturesVerificationRule.js';\nexport { VerifiedSealCache } from '@unicitylabs/state-transition-sdk/lib/api/bft/verification/VerifiedSealCache.js';\nexport { Secp256k1SignatureVerifier } from '@unicitylabs/state-transition-sdk/lib/crypto/secp256k1/Secp256k1SignatureVerifier.js';\nexport type { ITokenVerifier } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/ITokenVerifier.js';\nexport { WorkerTokenVerifier } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/worker/WorkerTokenVerifier.js';\nexport type { IWorker } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/worker/IWorker.js';\nexport type { IVerificationContext } from '@unicitylabs/state-transition-sdk/lib/verification/IVerificationContext.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// Head-only CBOR reads, for classifying a value envelope WITHOUT parsing its body\n// (`value-envelope.ts`): `CborDeserializer.decodeTag` asserts exhaustion, so it\n// cannot tell a corrupt envelope from a payload that carries no envelope at all.\nexport { CborReader } from '@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborReader.js';\nexport { MajorType } from '@unicitylabs/state-transition-sdk/lib/serialization/cbor/MajorType.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 { SplitAllocationProof } from '@unicitylabs/state-transition-sdk/lib/payment/SplitAllocationProof.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// ── 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 * NFT payload codec (#785, normative spec: docs/NFT-METADATA.md). Recognition is\n * display-only and never throws, so no path that can refuse a token may depend on\n * it. One validator set serves the encoder and the decoder alike.\n */\nimport { sha256 } from '@noble/hashes/sha2.js';\n\nimport { SphereError } from '../core/errors';\n\nimport {\n CborDeserializer,\n CborReader,\n CborSerializer,\n type DataHash,\n DataHasher,\n HashAlgorithm,\n HexConverter,\n MajorType,\n NetworkId,\n Signature,\n SigningService,\n} from './sdk';\n\nexport const NFT_METADATA_TAG = 39052n;\nexport const NFT_MEDIA_TAG = 39053n;\nexport const NFT_LINK_TAG = 39054n;\nexport const NFT_SIGNED_TAG = 39055n;\nexport const NFT_FORMAT_VERSION = 1n;\n/** The media type of an NftLink that points at a metadata document instead of a media file. */\nexport const NFT_DOCUMENT_MEDIA_TYPE = 'application/vnd.unicity.nft+cbor';\n\n/** An inline file. */\nexport interface NftMedia {\n readonly kind: 'media';\n readonly media_type: string;\n readonly bytes: Uint8Array;\n}\n\n/** A hosted file, pinned by the SHA-256 of its bytes (64 hex; decoded lowercase). */\nexport interface NftLink {\n readonly kind: 'link';\n readonly media_type: string;\n readonly uri: string;\n readonly sha256: string;\n}\n\nexport type NftMediaRef = NftMedia | NftLink;\n\nexport interface NftAttribute {\n readonly trait_type: string;\n /** Text, or an integer within ±(2^53 − 1). Decimals and larger numbers are text. */\n readonly value: string | number;\n}\n\n/** ERC-721 field names; an absent optional field is `null`, never `''`. */\nexport interface NftMetadata {\n readonly kind: 'metadata';\n readonly name: string;\n readonly description: string | null;\n readonly image: NftMediaRef | null;\n readonly animation_url: NftMediaRef | null;\n readonly external_url: string | null;\n readonly attributes: readonly NftAttribute[];\n readonly collection: string | null;\n /** The collection the item claims: 1–64 bytes as even-length hex (decoded lowercase). Never verified here. */\n readonly collection_id: string | null;\n}\n\nexport type NftContent = NftMetadata | NftMedia | NftLink;\nexport type NftSignatureStatus = 'unsigned' | 'valid' | 'invalid';\ntype NftDocument = NftMetadata | NftMedia;\n\nexport interface ParsedNft {\n readonly content: NftContent;\n /** Present iff the top level is NftSigned. */\n readonly signed: {\n readonly creator: Uint8Array;\n readonly payload: Uint8Array;\n readonly signature: Uint8Array;\n } | null;\n}\n\n/** What an NftSigned signature binds besides its payload, exactly as the token's mint records it. */\nexport interface NftSignatureContext {\n /** The network identifier α (`NetworkId.id`). */\n readonly networkId: number | bigint;\n /** The genesis recipient predicate, as `EncodedPredicate.toCBOR()` bytes. */\n readonly recipientPredicate: Uint8Array;\n /** The 32 raw token id bytes. */\n readonly tokenId: Uint8Array;\n readonly tokenType: Uint8Array;\n}\n\nconst METADATA_ARITY = 9;\nconst MEDIA_ARITY = 3;\nconst LINK_ARITY = 4;\nconst SIGNED_ARITY = 4;\nconst CREATOR_BYTES = 33;\nconst SIGNATURE_BYTES = 65;\nconst MAX_URI_LENGTH = 2048;\nconst LINK_SCHEMES = ['https://', 'ipfs://', 'ar://'];\nconst SIGNED_DOMAIN = new TextEncoder().encode('UNICITY_NFT_SIGNED');\nconst MEDIA_TYPE_PATTERN = /^[a-z0-9][a-z0-9!#$&^_.+-]{0,126}\\/[a-z0-9][a-z0-9!#$&^_.+-]{0,126}$/;\nconst SHA256_HEX_PATTERN = /^[0-9a-f]{64}$/i;\nconst COLLECTION_ID_PATTERN = /^(?:[0-9a-f]{2}){1,64}$/i;\nconst LONE_SURROGATE = /\\p{Cs}/u;\nconst CBOR_MAJOR_TYPE_MASK = 0b1110_0000;\nconst ATTRIBUTE_VALUE_RULE =\n 'must be non-empty text or an integer within ±(2^53 − 1) — write decimals and larger numbers as text';\nconst COLLECTION_ID_RULE = 'must be null or 1–64 bytes as even-length hex (2–128 characters)';\nconst DOCUMENT_AS_MEDIA_RULE = `must not be ${NFT_DOCUMENT_MEDIA_TYPE}: a document link is a token's content, never media`;\n// The SDK's text decoder substitutes U+FFFD, which would recognise invalid UTF-8;\n// ignoreBOM keeps a leading U+FEFF so a decoded string re-encodes byte-identically.\nconst UTF8 = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true });\n\n// ── shared field rules (encoder and decoder) ────────────────────────────────\n\nfunction refuse(field: string, rule: string, cause?: unknown): SphereError {\n return new SphereError(`Invalid NFT ${field}: ${rule}`, 'VALIDATION_ERROR', cause);\n}\n\nfunction ensure(ok: boolean, field: string, rule: string): void {\n if (!ok) throw refuse(field, rule);\n}\n\nconst fieldName = (prefix: string, name: string): string => (prefix === '' ? name : `${prefix}.${name}`);\n\n/** Non-empty and representable as UTF-8 exactly (a lone surrogate is not). */\nconst isText = (value: unknown): value is string =>\n typeof value === 'string' && value.length > 0 && !LONE_SURROGATE.test(value);\n\nconst isBytes = (value: unknown, length?: number): value is Uint8Array =>\n value instanceof Uint8Array && (length === undefined ? value.length > 0 : value.length === length);\n\nconst isMediaType = (value: unknown): boolean => typeof value === 'string' && MEDIA_TYPE_PATTERN.test(value);\n\nconst isCollectionId = (value: unknown): boolean => typeof value === 'string' && COLLECTION_ID_PATTERN.test(value);\n\nconst isAttributeValue = (value: unknown): boolean =>\n typeof value === 'number' ? Number.isSafeInteger(value) : isText(value);\n\nfunction hasSpaceOrControl(value: string): boolean {\n for (let i = 0; i < value.length; i++) {\n const code = value.charCodeAt(i);\n if (code <= 0x20 || code === 0x7f) return true;\n }\n return false;\n}\n\nfunction isLinkUri(value: unknown): boolean {\n if (!isText(value) || value.length > MAX_URI_LENGTH || hasSpaceOrControl(value)) return false;\n const scheme = LINK_SCHEMES.find((prefix) => value.startsWith(prefix));\n return scheme !== undefined && value.length > scheme.length;\n}\n\nfunction checkText(field: string, value: unknown): void {\n ensure(isText(value), field, 'must be non-empty, well-formed text');\n}\n\nfunction checkOptionalText(field: string, value: unknown): void {\n ensure(value === null || isText(value), field, 'must be null or non-empty, well-formed text');\n}\n\nfunction checkMediaType(field: string, value: unknown): void {\n ensure(isMediaType(value), field, 'must be a lowercase type/subtype media type without parameters');\n}\n\nfunction checkMedia(prefix: string, media: NftMedia): void {\n checkMediaType(fieldName(prefix, 'media_type'), media.media_type);\n ensure(isBytes(media.bytes), fieldName(prefix, 'bytes'), 'must be non-empty bytes');\n}\n\nfunction checkLink(prefix: string, link: NftLink): void {\n checkMediaType(fieldName(prefix, 'media_type'), link.media_type);\n ensure(\n isLinkUri(link.uri),\n fieldName(prefix, 'uri'),\n `must be an https://, ipfs:// or ar:// URI of at most ${MAX_URI_LENGTH} characters with no whitespace or control characters`,\n );\n ensure(\n typeof link.sha256 === 'string' && SHA256_HEX_PATTERN.test(link.sha256),\n fieldName(prefix, 'sha256'),\n 'must be the 64-hex SHA-256 of the linked file',\n );\n}\n\nfunction checkMediaRef(field: string, ref: NftMediaRef | null): void {\n if (ref === null) return;\n if (ref?.kind === 'media') return checkMedia(field, ref);\n if (ref?.kind !== 'link') throw refuse(field, 'must be an NftMedia, an NftLink or null');\n checkLink(field, ref);\n ensure(!isNftDocumentLink(ref), fieldName(field, 'media_type'), DOCUMENT_AS_MEDIA_RULE);\n}\n\nfunction checkAttributes(attributes: readonly NftAttribute[]): void {\n ensure(Array.isArray(attributes), 'attributes', 'must be an array — [] when there are none');\n // entries(), not forEach: a sparse array's holes must be refused, not skipped.\n for (const [index, attribute] of attributes.entries()) {\n checkText(`attributes[${index}].trait_type`, attribute?.trait_type);\n ensure(isAttributeValue(attribute?.value), `attributes[${index}].value`, ATTRIBUTE_VALUE_RULE);\n }\n}\n\nfunction checkMetadata(metadata: NftMetadata): void {\n checkText('name', metadata.name);\n checkOptionalText('description', metadata.description);\n checkMediaRef('image', metadata.image);\n checkMediaRef('animation_url', metadata.animation_url);\n checkOptionalText('external_url', metadata.external_url);\n checkAttributes(metadata.attributes);\n checkOptionalText('collection', metadata.collection);\n ensure(metadata.collection_id === null || isCollectionId(metadata.collection_id), 'collection_id', COLLECTION_ID_RULE);\n}\n\nfunction checkContent(content: NftContent): void {\n switch (content?.kind) {\n case 'metadata':\n return checkMetadata(content);\n case 'media':\n return checkMedia('', content);\n case 'link':\n return checkLink('', content);\n default:\n throw refuse('content', \"kind must be 'metadata', 'media' or 'link'\");\n }\n}\n\nfunction checkSignedParts(creator: unknown, signature: unknown): void {\n ensure(isBytes(creator, CREATOR_BYTES), 'creator', 'must be a 33-byte compressed secp256k1 public key');\n ensure(isBytes(signature, SIGNATURE_BYTES), 'signature', 'must be 65 bytes: r(32) ‖ s(32) ‖ recovery(1)');\n}\n\n// ── encoder ─────────────────────────────────────────────────────────────────\n\nconst text = (value: string): Uint8Array => CborSerializer.encodeTextString(value);\n\nconst optionalText = (value: string | null): Uint8Array =>\n CborSerializer.encodeNullable(value, CborSerializer.encodeTextString);\n\nfunction versioned(tag: bigint, ...fields: Uint8Array[]): Uint8Array {\n return CborSerializer.encodeTag(\n tag,\n CborSerializer.encodeArray(CborSerializer.encodeUnsignedInteger(NFT_FORMAT_VERSION), ...fields),\n );\n}\n\n/** Major type 1 shares the unsigned head layout; the SDK serializer has no encoder for it. */\nfunction integerCbor(value: number): Uint8Array {\n if (value >= 0) return CborSerializer.encodeUnsignedInteger(value);\n const head = CborSerializer.encodeUnsignedInteger(-1 - value);\n head[0] |= MajorType.NEGATIVE_INTEGER;\n return head;\n}\n\nfunction mediaCbor(media: NftMedia): Uint8Array {\n return versioned(NFT_MEDIA_TAG, text(media.media_type), CborSerializer.encodeByteString(media.bytes));\n}\n\nfunction linkCbor(link: NftLink): Uint8Array {\n const digest = HexConverter.decode(link.sha256.toLowerCase());\n return versioned(NFT_LINK_TAG, text(link.media_type), text(link.uri), CborSerializer.encodeByteString(digest));\n}\n\nfunction mediaRefCbor(ref: NftMediaRef | null): Uint8Array {\n if (ref === null) return CborSerializer.encodeNull();\n return ref.kind === 'media' ? mediaCbor(ref) : linkCbor(ref);\n}\n\nfunction attributeCbor({ trait_type, value }: NftAttribute): Uint8Array {\n return CborSerializer.encodeArray(text(trait_type), typeof value === 'string' ? text(value) : integerCbor(value));\n}\n\n/**\n * The SDK's array head over a list of any length. Spreading the list into\n * `encodeArray` arguments overflows the call stack past ~125k items (fewer in JSC).\n */\nfunction arrayCbor(items: readonly Uint8Array[]): Uint8Array {\n const head = CborSerializer.encodeUnsignedInteger(items.length);\n head[0] |= MajorType.ARRAY;\n const out = new Uint8Array(items.reduce((length, item) => length + item.length, head.length));\n out.set(head);\n let offset = head.length;\n for (const item of items) {\n out.set(item, offset);\n offset += item.length;\n }\n return out;\n}\n\nconst optionalHexBytes = (value: string | null): Uint8Array =>\n CborSerializer.encodeNullable(value, (hex) => CborSerializer.encodeByteString(HexConverter.decode(hex.toLowerCase())));\n\nfunction metadataCbor(metadata: NftMetadata): Uint8Array {\n return versioned(\n NFT_METADATA_TAG,\n text(metadata.name),\n optionalText(metadata.description),\n mediaRefCbor(metadata.image),\n mediaRefCbor(metadata.animation_url),\n optionalText(metadata.external_url),\n arrayCbor(metadata.attributes.map(attributeCbor)),\n optionalText(metadata.collection),\n optionalHexBytes(metadata.collection_id),\n );\n}\n\n/** Encode one unsigned item. Throws SphereError('…', 'VALIDATION_ERROR') naming the offending field. */\nexport function encodeNftContent(content: NftContent): Uint8Array {\n checkContent(content);\n if (content.kind === 'metadata') return metadataCbor(content);\n return content.kind === 'media' ? mediaCbor(content) : linkCbor(content);\n}\n\n/** Wrap an encoded unsigned item; `signature` is `Signature.encode()` over {@link nftSignedDigest}. */\nexport function encodeNftSigned(creator: Uint8Array, payload: Uint8Array, signature: Uint8Array): Uint8Array {\n checkSignedParts(creator, signature);\n checkContent(signablePayload(payload));\n return versioned(\n NFT_SIGNED_TAG,\n CborSerializer.encodeByteString(creator),\n payload,\n CborSerializer.encodeByteString(signature),\n );\n}\n\nfunction signablePayload(payload: Uint8Array): NftContent {\n try {\n return decodeItem(UNSIGNED_DECODERS, 'payload', payload);\n } catch (error) {\n throw refuse('payload', 'must be exactly one encoded NftMetadata, NftMedia or NftLink item', error);\n }\n}\n\n// ── decoder (structure only; value rules are the shared checks above) ──────\n\ntype BodyDecoder<T> = (body: Uint8Array) => T;\n\nconst majorTypeOf = (item: Uint8Array): MajorType => (item.at(0) ?? 0) & CBOR_MAJOR_TYPE_MASK;\n\nfunction decodeText(item: Uint8Array): string {\n const reader = new CborReader(item);\n const bytes = reader.read(Number(reader.readLength(MajorType.TEXT_STRING)));\n reader.assertExhausted();\n return UTF8.decode(bytes);\n}\n\nconst decodeOptionalText = (item: Uint8Array): string | null => CborDeserializer.decodeNullable(item, decodeText);\n\nfunction decodeAttributeValue(item: Uint8Array): string | number {\n const major = majorTypeOf(item);\n if (major === MajorType.TEXT_STRING) return decodeText(item);\n const isInteger = major === MajorType.UNSIGNED_INTEGER || major === MajorType.NEGATIVE_INTEGER;\n ensure(isInteger, 'attribute value', ATTRIBUTE_VALUE_RULE);\n const reader = new CborReader(item);\n const magnitude = reader.readLength(major);\n reader.assertExhausted();\n return Number(major === MajorType.UNSIGNED_INTEGER ? magnitude : -1n - magnitude);\n}\n\nfunction decodeAttributes(item: Uint8Array): NftAttribute[] {\n return CborDeserializer.decodeArray(item).map((entry) => {\n const [traitType, value] = CborDeserializer.decodeArray(entry, 2);\n return { trait_type: decodeText(traitType), value: decodeAttributeValue(value) };\n });\n}\n\nfunction versionedFields(body: Uint8Array, arity: number): Uint8Array[] {\n const fields = CborDeserializer.decodeArray(body, arity);\n ensure(CborDeserializer.decodeUnsignedInteger(fields[0]) === NFT_FORMAT_VERSION, 'version', 'must be 1');\n return fields;\n}\n\nfunction decodeMedia(body: Uint8Array): NftMedia {\n const [, mediaType, bytes] = versionedFields(body, MEDIA_ARITY);\n return { kind: 'media', media_type: decodeText(mediaType), bytes: CborDeserializer.decodeByteString(bytes) };\n}\n\nconst decodeHex = (item: Uint8Array): string => HexConverter.encode(CborDeserializer.decodeByteString(item));\n\nfunction decodeLink(body: Uint8Array): NftLink {\n const [, mediaType, uri, digest] = versionedFields(body, LINK_ARITY);\n return {\n kind: 'link',\n media_type: decodeText(mediaType),\n uri: decodeText(uri),\n sha256: decodeHex(digest),\n };\n}\n\nfunction decodeMetadata(body: Uint8Array): NftMetadata {\n const fields = versionedFields(body, METADATA_ARITY);\n return {\n kind: 'metadata',\n name: decodeText(fields[1]),\n description: decodeOptionalText(fields[2]),\n image: decodeMediaRef('image', fields[3]),\n animation_url: decodeMediaRef('animation_url', fields[4]),\n external_url: decodeOptionalText(fields[5]),\n attributes: decodeAttributes(fields[6]),\n collection: decodeOptionalText(fields[7]),\n collection_id: CborDeserializer.decodeNullable(fields[8], decodeHex),\n };\n}\n\n// The nesting rules: a media slot holds NftMedia or NftLink (never a document link,\n// which checkMediaRef refuses); NftSigned wraps any unsigned item and itself appears\n// only at the top level; a linked document is NftMetadata or NftMedia.\nconst MEDIA_REF_DECODERS: ReadonlyMap<bigint, BodyDecoder<NftMediaRef>> = new Map<bigint, BodyDecoder<NftMediaRef>>([\n [NFT_MEDIA_TAG, decodeMedia],\n [NFT_LINK_TAG, decodeLink],\n]);\nconst UNSIGNED_DECODERS: ReadonlyMap<bigint, BodyDecoder<NftContent>> = new Map<bigint, BodyDecoder<NftContent>>([\n [NFT_METADATA_TAG, decodeMetadata],\n [NFT_MEDIA_TAG, decodeMedia],\n [NFT_LINK_TAG, decodeLink],\n]);\nconst DOCUMENT_DECODERS: ReadonlyMap<bigint, BodyDecoder<NftDocument>> = new Map<bigint, BodyDecoder<NftDocument>>([\n [NFT_METADATA_TAG, decodeMetadata],\n [NFT_MEDIA_TAG, decodeMedia],\n]);\n\nfunction decodeBody<T>(decoders: ReadonlyMap<bigint, BodyDecoder<T>>, field: string, tag: bigint, body: Uint8Array): T {\n const decode = decoders.get(tag);\n if (decode === undefined) throw refuse(field, `tag ${tag} is not allowed here`);\n return decode(body);\n}\n\nfunction decodeItem<T>(decoders: ReadonlyMap<bigint, BodyDecoder<T>>, field: string, item: Uint8Array): T {\n const { tag, data } = CborDeserializer.decodeTag(item);\n return decodeBody(decoders, field, tag, data);\n}\n\nfunction decodeMediaRef(field: string, item: Uint8Array): NftMediaRef | null {\n return CborDeserializer.decodeNullable(item, (ref) => decodeItem(MEDIA_REF_DECODERS, field, ref));\n}\n\nfunction decodeSigned(body: Uint8Array): ParsedNft {\n const [, creatorItem, payload, signatureItem] = versionedFields(body, SIGNED_ARITY);\n const creator = CborDeserializer.decodeByteString(creatorItem);\n const signature = CborDeserializer.decodeByteString(signatureItem);\n checkSignedParts(creator, signature);\n return { content: decodeItem(UNSIGNED_DECODERS, 'payload', payload), signed: { creator, payload, signature } };\n}\n\nfunction decodePayload(data: Uint8Array): ParsedNft {\n const { tag, data: body } = CborDeserializer.decodeTag(data);\n if (tag === NFT_SIGNED_TAG) return decodeSigned(body);\n return { content: decodeBody(UNSIGNED_DECODERS, 'payload', tag, body), signed: null };\n}\n\n/** Structural parse of a genesis payload. NEVER throws; null = not a recognised NFT. */\nexport function parseNftPayload(data: Uint8Array | null): ParsedNft | null {\n if (data === null) return null;\n try {\n const parsed = decodePayload(data);\n checkContent(parsed.content);\n return parsed;\n } catch {\n return null;\n }\n}\n\n/**\n * Parse the file a document link points at: exactly one NftMetadata or NftMedia item.\n * NEVER throws; null = not a document. Check the bytes with verifyNftLinkContent first.\n */\nexport function parseNftDocument(bytes: Uint8Array): NftMetadata | NftMedia | null {\n try {\n const document = decodeItem(DOCUMENT_DECODERS, 'document', bytes);\n checkContent(document);\n return document;\n } catch {\n return null;\n }\n}\n\n/** Is this an NftLink to a metadata document ({@link NFT_DOCUMENT_MEDIA_TYPE}), resolved with parseNftDocument? */\nexport function isNftDocumentLink(content: NftContent): boolean {\n return content?.kind === 'link' && content.media_type === NFT_DOCUMENT_MEDIA_TYPE;\n}\n\n// ── signature ───────────────────────────────────────────────────────────────\n\n/**\n * SHA-256 of CBOR `[h'UNICITY_NFT_SIGNED', 1, α, h(recipient predicate), h(token id), h(token type), h(payload)]`:\n * every term a byte string except the version and α, as in the yellowpaper genesis commitment.\n */\nexport function nftSignedDigest(context: NftSignatureContext, payload: Uint8Array): Promise<DataHash> {\n const preimage = CborSerializer.encodeArray(\n CborSerializer.encodeByteString(SIGNED_DOMAIN),\n CborSerializer.encodeUnsignedInteger(NFT_FORMAT_VERSION),\n CborSerializer.encodeUnsignedInteger(NetworkId.fromId(context.networkId).id),\n CborSerializer.encodeByteString(context.recipientPredicate),\n CborSerializer.encodeByteString(context.tokenId),\n CborSerializer.encodeByteString(context.tokenType),\n CborSerializer.encodeByteString(payload),\n );\n return new DataHasher(HashAlgorithm.SHA256).update(preimage).digest();\n}\n\n/** Recovering verification: binds the recovery byte and refuses high-s. Never throws. */\nexport async function verifyNftSignature(\n signed: NonNullable<ParsedNft['signed']>,\n context: NftSignatureContext,\n): Promise<Exclude<NftSignatureStatus, 'unsigned'>> {\n try {\n if (!SigningService.isPublicKeyValid(signed.creator)) return 'invalid';\n const signature = Signature.decode(signed.signature);\n const digest = await nftSignedDigest(context, signed.payload);\n return (await SigningService.verifyWithPublicKey(digest, signature, signed.creator)) ? 'valid' : 'invalid';\n } catch {\n return 'invalid';\n }\n}\n\n/** Does `bytes` match the link's sha256? Pure, sync. */\nexport function verifyNftLinkContent(link: NftLink, bytes: Uint8Array): boolean {\n return HexConverter.encode(sha256(bytes)) === link.sha256.toLowerCase();\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 { secp256k1 } from '@noble/curves/secp256k1.js';\nimport * as bip39 from 'bip39';\nimport CryptoJS from 'crypto-js';\nimport { SphereError } from './errors';\n\n// =============================================================================\n// Constants\n// =============================================================================\n\n/** secp256k1 curve order */\nconst CURVE_ORDER = BigInt(\n '0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141'\n);\n\n/** A secp256k1 private key is exactly 32 bytes — 64 hex chars. */\nconst PRIVKEY_HEX_RE = /^[0-9a-fA-F]{64}$/;\n\n/**\n * Reject a malformed private key BEFORE it reaches the curve (#674 review).\n * `hexToBytes` coerces any non-hex character to a zero byte\n * (`parseInt('gg', 16)` → NaN → 0), so a right-length string with a stray\n * non-hex char would otherwise derive/sign with a DIFFERENT valid key and no\n * error — silently signing with an unintended key. secp256k1 already rejects\n * wrong-*length* input; this closes the same-length-wrong-chars hole.\n */\nfunction assertPrivKeyHex(privateKeyHex: string): void {\n if (!PRIVKEY_HEX_RE.test(privateKeyHex)) {\n throw new SphereError(\n `Invalid private key: expected 64 hex chars, got ${privateKeyHex.length}`,\n 'VALIDATION_ERROR',\n );\n }\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 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 compressedPubKey = getPublicKey(parentPrivKey, true);\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 assertPrivKeyHex(privateKey);\n // SEC1 encoding: compressed = 02/03 prefix + x (33 bytes),\n // uncompressed = 04 prefix + x + y (65 bytes) — identical to elliptic's output.\n return bytesToHex(secp256k1.getPublicKey(hexToBytes(privateKey), compressed));\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// 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 key 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 */\nexport function deriveAddressInfo(\n masterKey: MasterKey,\n basePath: string,\n index: number,\n isChange: boolean = false\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\n return {\n privateKey: derived.privateKey,\n publicKey,\n path: fullPath,\n index,\n };\n}\n\n/**\n * Generate full key info from private key with index and path\n */\nexport function generateAddressInfo(\n privateKey: string,\n index: number,\n path: string\n): AddressInfo {\n const publicKey = getPublicKey(privateKey);\n return {\n privateKey,\n publicKey,\n path,\n index,\n };\n}\n\n/**\n * Generate key info from master private key using HMAC-SHA512 derivation\n * This matches exactly the original index.html implementation\n * NOTE: This is NON-STANDARD derivation for legacy wallet compatibility.\n *\n * Dual-use: in `wif_hmac` derivation mode (legacy wallet import) this derives\n * the wallet's chainPubkey (used for L3 identity).\n *\n * @param masterPrivateKey - 32-byte hex private key (64 chars)\n * @param index - Address index\n */\nexport function generateAddressFromMasterKey(\n masterPrivateKey: string,\n index: number\n): AddressInfo {\n const derivationPath = `m/44'/0'/${index}'`;\n\n // HMAC-SHA512 with path as key (matching index.html exactly)\n const hmacInput = CryptoJS.enc.Hex.parse(masterPrivateKey);\n const hmacKey = CryptoJS.enc.Utf8.parse(derivationPath);\n const hmacOutput = CryptoJS.HmacSHA512(hmacInput, hmacKey).toString();\n\n // Use left 32 bytes for private key\n const childPrivateKey = hmacOutput.substring(0, 64);\n\n return generateAddressInfo(childPrivateKey, index, derivationPath);\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 assertPrivKeyHex(privateKeyHex);\n const hashHex = hashSignMessage(message);\n // prehash:false — the message is already hashed (double-SHA256 above);\n // lowS:true — canonical low-S signatures (same as elliptic's {canonical:true});\n // format:'recovered' — recoveryId(1) || r(32) || s(32), RFC6979-deterministic.\n const sigBytes = secp256k1.sign(hexToBytes(hashHex), hexToBytes(privateKeyHex), {\n prehash: false,\n lowS: true,\n format: 'recovered',\n });\n\n const recoveryParam = sigBytes[0];\n const v = (31 + recoveryParam).toString(16).padStart(2, '0');\n // r and s are fixed-width 32-byte big-endian — already left-padded.\n return v + bytesToHex(sigBytes.subarray(1));\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\n try {\n const recovered = secp256k1.Signature\n .fromHex(r + s, 'compact')\n .addRecoveryBit(v)\n .recoverPublicKey(hexToBytes(hashHex));\n return recovered.toHex(true) === expectedPubkey; // compressed\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\n const recovered = secp256k1.Signature\n .fromHex(r + s, 'compact')\n .addRecoveryBit(v)\n .recoverPublicKey(hexToBytes(hashHex));\n return recovered.toHex(true); // compressed\n}\n","// The plan → intent-payload codec (§5.5): what a send attempt PUTs as its\n// durable server intent. Extracted from PaymentsFacade (pure, no state).\n\nimport type { SendRequest } from '../api';\nimport type { PlannedSpend } from '../select/queue';\nimport type { CoinIntentPayload, WholeIntentPayload } from './types';\n\nexport function buildPayload(\n recipientPubkey: string,\n request: SendRequest,\n spend: PlannedSpend,\n spentStates: Record<string, { local: string; protocol: string }>\n): CoinIntentPayload {\n return {\n v: 2,\n kind: 'coin',\n recipient: recipientPubkey,\n coinId: request.coinId,\n amount: request.amount,\n ...(request.memo !== undefined ? { memo: request.memo } : {}),\n direct: [...spend.plan.direct],\n ...(spend.plan.split !== undefined\n ? {\n split: {\n tokenId: spend.plan.split.tokenId,\n splitAmount: spend.plan.split.splitAmount.toString(),\n remainderAmount: spend.plan.split.remainderAmount.toString(),\n },\n }\n : {}),\n spentStates,\n };\n}\n\nexport function messageOf(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\n/**\n * A token-addressed spend (#777). Takes no PlannedSpend because nothing was\n * selected: the source is named, so there is no amount, no split and no change.\n */\nexport function buildWholePayload(\n recipientPubkey: string,\n request: { tokenId: string; memo?: string },\n spentStates: Record<string, { local: string; protocol: string }>\n): WholeIntentPayload {\n return {\n v: 2,\n kind: 'whole',\n recipient: recipientPubkey,\n ...(request.memo !== undefined ? { memo: request.memo } : {}),\n direct: [request.tokenId],\n spentStates,\n };\n}\n","// Shared concurrency primitives. Both advance on SETTLED, never fulfilled —\n// a rejection never bricks the next run (async.test.ts pins the recovery).\n\nexport class SingleFlight<T> {\n private flight: Promise<T> | null = null;\n\n run(fn: () => Promise<T>): Promise<T> {\n if (this.flight !== null) return this.flight;\n const current = fn().finally(() => {\n this.flight = null;\n });\n this.flight = current;\n return current;\n }\n}\n\nexport class SerialChain {\n private tail: Promise<unknown> = Promise.resolve();\n\n /** FIFO; starts after every prior fn settled; returns this fn's own outcome. */\n enqueue<T>(fn: () => Promise<T>): Promise<T> {\n const run = this.tail.then(fn, fn);\n this.tail = run.then(\n () => undefined,\n () => undefined\n );\n return run;\n }\n}\n\n/** Fire-and-forget sibling of {@link SingleFlight}: one in flight, one queued behind it. */\nexport function coalesced(\n run: () => Promise<unknown>,\n observe?: (op: Promise<unknown>) => void\n): () => void {\n let inFlight = false;\n let queued = false;\n const start = (): void => {\n inFlight = true;\n // A synchronous throw would escape before .catch attaches and strand\n // inFlight, wedging every later trigger. Started eagerly, not on a\n // microtask, so a caller can rely on the first run having begun.\n let running: Promise<unknown>;\n try {\n running = run();\n } catch {\n running = Promise.resolve();\n }\n observe?.(running);\n void running\n .catch(() => undefined)\n .finally(() => {\n inFlight = false;\n if (!queued) return;\n queued = false;\n start();\n });\n };\n return () => {\n if (inFlight) {\n queued = true;\n return;\n }\n start();\n };\n}\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 * NOTE: the server-side INTENT cap is being raised (wallet-api#102); the SDK\n * deliberately does NOT pre-flight-enforce it on sends (#670) — the server\n * decides, and a deterministic 422 is handled as terminal by the send path.\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 BINARY plaintext into the S6 wire envelope, optionally bound to associated data (AAD):\n * `\"enc1.\" + base64(nonce ‖ ciphertext)` (XChaCha20-Poly1305, random 24-byte nonce). The AAD is\n * authenticated but NOT stored in the envelope — the reader re-derives it from context, so a\n * record decrypted against a different AAD fails the poly1305 tag (E.4: AAD = `transferId:opIndex`\n * binds a checkpoint to its slot, defeating a mis-served / cross-intent replay at the crypto layer).\n */\nexport function encryptFieldBytes(key: Uint8Array, plaintext: Uint8Array, aad?: Uint8Array): string {\n const nonce = randomBytes(FIELD_ENVELOPE_NONCE_BYTES);\n const ciphertext = xchacha20poly1305(key, nonce, aad).encrypt(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 to BINARY bytes, requiring the same `aad` used at encrypt time.\n * Any tampering, wrong key, OR wrong AAD throws `SphereError('DECRYPTION_ERROR')`.\n */\nexport function decryptFieldBytes(key: Uint8Array, envelope: string, aad?: Uint8Array): Uint8Array {\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 return xchacha20poly1305(key, nonce, aad).decrypt(ciphertext);\n } catch (err) {\n throw new SphereError('Field envelope authentication failed (tampered, wrong key, or wrong AAD)', 'DECRYPTION_ERROR', err);\n }\n}\n\n/**\n * Encrypt a UTF-8 string field into the S6 wire envelope (AAD-less). Thin wrapper over\n * {@link encryptFieldBytes} — the memo/nametag/intent-payload path.\n */\nexport function encryptField(key: Uint8Array, plaintext: string): string {\n return encryptFieldBytes(key, new TextEncoder().encode(plaintext));\n}\n\n/**\n * Decrypt an AAD-less S6 wire envelope to a UTF-8 string (memo/nametag/intent payload). Any\n * tampering throws `SphereError('DECRYPTION_ERROR')`.\n */\nexport function decryptField(key: Uint8Array, envelope: string): string {\n return new TextDecoder().decode(decryptFieldBytes(key, envelope));\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","import type { CoinIntentPayload, IntentPayload, WholeIntentPayload } from './types';\n\nexport function isWholeIntent(p: IntentPayload): p is WholeIntentPayload {\n return p.kind === 'whole' || p.kind === 'coinless';\n}\n\nexport function isCoinIntent(p: IntentPayload): p is CoinIntentPayload {\n return p.kind === 'coin';\n}\n\nexport function splitOf(p: IntentPayload): CoinIntentPayload['split'] {\n return p.kind === 'coin' ? p.split : undefined;\n}\n\n/** The coin spent, or undefined when token-addressed. Handle absence, never ''. */\nexport function coinIdOf(p: IntentPayload): string | undefined {\n return p.kind === 'coin' ? p.coinId : undefined;\n}\n\n","/**\n * Browser-safe UUID v4 generation.\n *\n * Kept dependency-free (no node:crypto require, unlike core/utils.ts) so it is\n * safe to import from the platform:'browser' bundles and the token-engine\n * subpath without dragging a Node builtin into them.\n */\n\n/**\n * Generate a v4 UUID.\n *\n * Prefers `crypto.randomUUID()` (secure context; Safari 15.4+, Chrome 92+,\n * Node 19+). Falls back to deriving one from `crypto.getRandomValues()`, which\n * is available in every browser — including insecure / non-HTTPS contexts and\n * older WebViews — and in Node 20+. This avoids\n * `crypto.randomUUID is not a function` on sub-15.4 / insecure-context runtimes\n * (sphere-sdk#619), with no node:crypto fallback that would break browser bundles.\n */\nexport function randomUUID(): string {\n const c = globalThis.crypto;\n if (typeof c !== 'undefined' && typeof c.randomUUID === 'function') {\n return c.randomUUID();\n }\n // RFC 4122 v4 from CSPRNG bytes.\n const b = c.getRandomValues(new Uint8Array(16));\n b[6] = (b[6] & 0x0f) | 0x40; // version 4\n b[8] = (b[8] & 0x3f) | 0x80; // variant 10xx\n const h = Array.from(b, (x) => x.toString(16).padStart(2, '0'));\n return `${h[0]}${h[1]}${h[2]}${h[3]}-${h[4]}${h[5]}-${h[6]}${h[7]}-${h[8]}${h[9]}-${h[10]}${h[11]}${h[12]}${h[13]}${h[14]}${h[15]}`;\n}\n","// §5.9 of docs/PAYMENTS-V2-DESIGN.md — history is a server read-through plus\n// client POSTs. No local ledger; the server log is the store of record.\n\nimport { encryptField, decryptField } from '../../../core/field-encryption';\nimport { randomUUID } from '../../../core/uuid';\n\nimport type { HistoryEntry, HistoryPage } from '../api';\n\nexport interface HistoryWireAsset {\n coinId: string;\n amount: string;\n}\n\n// §16 wire record (structural slice of impl/wallet-api-v2 HistoryRecordWire).\nexport interface HistoryWireRecord {\n dedupKey: string;\n id: string;\n type: 'SENT' | 'RECEIVED' | 'MINT';\n assets: HistoryWireAsset[];\n ts: string;\n transferId?: string;\n tokenId?: string;\n counterpartyPubkey?: string;\n counterpartyNametag?: string;\n memo?: string;\n}\n\n// WalletApiV2Client satisfies this structurally; tests drive FakeWalletApi\n// through a thin adapter of the same shape.\nexport interface HistoryClient {\n listHistory(options?: { before?: string; limit?: number }): Promise<{\n records: readonly HistoryWireRecord[];\n more: boolean;\n cursor: string | null;\n }>;\n postHistory(records: HistoryWireRecord[]): Promise<unknown>;\n}\n\nexport interface HistoryRegistryReader {\n getSymbol(coinId: string): string;\n}\n\nexport interface HistoryDeps {\n readonly client: HistoryClient;\n /** S6 self-scoped field-encryption key (core/field-encryption, `enc1.`). */\n readonly fieldKey: Uint8Array;\n readonly registry: HistoryRegistryReader;\n /** §4: the event carries the recorded entry, client-shaped (never `{}`). */\n readonly emit: (event: 'history:updated', entry: HistoryEntry) => void;\n readonly log?: (message: string, error?: unknown) => void;\n readonly now?: () => number;\n readonly newId?: () => string;\n}\n\nexport interface RecordSentInput {\n transferId: string;\n /** EMPTY when nothing with a coin moved (#780). Every type accepts an empty list. */\n assets: readonly { coinId: string; amount: string }[];\n recipientPubkey?: string;\n recipientNametag?: string;\n memo?: string;\n tokenId?: string;\n timestamp?: number;\n}\n\nexport interface RecordReceivedInput {\n tokenId: string;\n stateHash: string;\n /**\n * What arrived. EMPTY for a coinless token (#777) — wallet-api#151 accepts an\n * empty list and keeps refusing `coinId: ''`, so a synthetic empty-coin entry\n * 422s and the row is lost. §10 forbids a record naming neither assets nor a\n * tokenId; `tokenId` is always set here, so an empty list is legal.\n */\n assets: readonly { coinId: string; amount: string }[];\n transferId?: string;\n senderPubkey?: string;\n senderNametag?: string;\n memo?: string;\n timestamp?: number;\n}\n\nexport interface RecordMintInput {\n tokenId: string;\n assets: readonly { coinId: string; amount: string }[];\n timestamp?: number;\n}\n\n/** Copied, never aliased: the wire record must not share the caller's array. */\nfunction wireAssets(\n assets: readonly { coinId: string; amount: string }[]\n): { coinId: string; amount: string }[] {\n return assets.map((a) => ({ coinId: a.coinId, amount: a.amount }));\n}\n\n/**\n * A 4xx other than 408/429 is the server refusing this record's SHAPE — permanent,\n * so no retry can fix it. Duck-typed on `status` so the module keeps no dependency\n * on a transport implementation.\n */\nfunction isPermanentReject(err: unknown): boolean {\n const status = (err as { status?: unknown } | null)?.status;\n if (typeof status !== 'number') return false;\n return status >= 400 && status < 500 && status !== 408 && status !== 429;\n}\n\nconst WIRE_TOKEN_ID = /^(?:[0-9a-f]{2}){1,64}$/;\nconst WIRE_PUBKEY = /^0[23][0-9a-f]{64}$/;\n\nexport class History {\n constructor(private readonly deps: HistoryDeps) {}\n\n // ── read-through ───────────────────────────────────────────────────────────\n\n async page(opts: { before?: string; limit?: number } = {}): Promise<HistoryPage> {\n const result = await this.deps.client.listHistory({\n ...(opts.before !== undefined ? { before: opts.before } : {}),\n ...(opts.limit !== undefined ? { limit: opts.limit } : {}),\n });\n return {\n entries: result.records.map((record) => this.toEntry(record)),\n more: result.more,\n cursor: result.cursor,\n };\n }\n\n // ── client POSTs (best-effort — NEVER throw into the money path) ────────────\n\n async recordSent(input: RecordSentInput): Promise<void> {\n await this.post(() => ({\n dedupKey: input.transferId,\n id: (this.deps.newId ?? randomUUID)(),\n type: 'SENT' as const,\n assets: wireAssets(input.assets),\n ts: this.ts(input.timestamp),\n transferId: input.transferId,\n ...this.wireTokenId(input.tokenId),\n ...this.wireCounterparty(input.recipientPubkey, input.recipientNametag),\n ...this.wireMemo(input.memo),\n }));\n }\n\n async recordReceived(input: RecordReceivedInput): Promise<void> {\n await this.post(() => ({\n dedupKey: `RECEIVED:${input.tokenId.toLowerCase()}:${input.stateHash.toLowerCase()}`,\n id: (this.deps.newId ?? randomUUID)(),\n type: 'RECEIVED' as const,\n assets: wireAssets(input.assets),\n ts: this.ts(input.timestamp),\n ...(input.transferId !== undefined ? { transferId: input.transferId } : {}),\n ...this.wireTokenId(input.tokenId),\n ...this.wireCounterparty(input.senderPubkey, input.senderNametag),\n ...this.wireMemo(input.memo),\n }));\n }\n\n async recordMint(input: RecordMintInput): Promise<void> {\n await this.post(() => ({\n dedupKey: `MINT:${input.tokenId.toLowerCase()}`,\n id: (this.deps.newId ?? randomUUID)(),\n type: 'MINT' as const,\n assets: wireAssets(input.assets),\n ts: this.ts(input.timestamp),\n ...this.wireTokenId(input.tokenId),\n }));\n }\n\n // ── internals ────────────────────────────────────────────────────────────────\n\n private async post(build: () => HistoryWireRecord): Promise<void> {\n const record = build();\n try {\n await this.deps.client.postHistory([record]);\n } catch (err) {\n // §5.9 keeps this off the money path, but a 4xx is PERMANENT: no retry can\n // fix a shape the server refuses, and logging it as retry-safe is what let a\n // coinless receipt vanish silently (#780). Name the two apart.\n this.deps.log?.(\n isPermanentReject(err)\n ? 'history POST REJECTED — the record shape is refused; no retry can fix it'\n : 'history POST failed (dedupKey makes retry safe)',\n err\n );\n return;\n }\n // The recorded entry is in hand — emit it through the SAME read-through\n // mapping page() serves (decrypted memo/nametag, `timestamp` name).\n this.deps.emit('history:updated', this.toEntry(record));\n }\n\n private ts(timestamp?: number): string {\n return new Date(timestamp ?? (this.deps.now ?? Date.now)()).toISOString();\n }\n\n private wireTokenId(tokenId?: string): { tokenId?: string } {\n const lower = tokenId?.toLowerCase();\n return lower !== undefined && WIRE_TOKEN_ID.test(lower) ? { tokenId: lower } : {};\n }\n\n // Server zod is strict — a non-pubkey counterparty stays off the wire; the\n // nametag rides regardless (S6-encrypted, operator-blind).\n private wireCounterparty(\n pubkey?: string,\n nametag?: string\n ): { counterpartyPubkey?: string; counterpartyNametag?: string } {\n const lower = pubkey?.toLowerCase();\n return {\n ...(lower !== undefined && WIRE_PUBKEY.test(lower) ? { counterpartyPubkey: lower } : {}),\n ...(nametag !== undefined ? { counterpartyNametag: encryptField(this.deps.fieldKey, nametag) } : {}),\n };\n }\n\n private wireMemo(memo?: string): { memo?: string } {\n return memo !== undefined ? { memo: encryptField(this.deps.fieldKey, memo) } : {};\n }\n\n // Consumed mapping: wire `ts` (ISO 8601, any offset) → epoch-ms `timestamp`;\n // coinId/amount from the FIRST asset (multi-asset remainder surfaces via\n // tokenIds[]); counterparty lands on the role-appropriate side by type.\n private toEntry(wire: HistoryWireRecord): HistoryEntry {\n const first = wire.assets[0];\n const coinId = first?.coinId ?? '';\n const received = wire.type === 'RECEIVED';\n const memo = this.tryDecrypt(wire.memo);\n const nametag = this.tryDecrypt(wire.counterpartyNametag);\n return {\n id: wire.id,\n type: wire.type,\n coinId,\n amount: first?.amount ?? '0',\n symbol: this.deps.registry.getSymbol(coinId),\n timestamp: Date.parse(wire.ts),\n ...(wire.transferId !== undefined ? { transferId: wire.transferId } : {}),\n ...(wire.tokenId !== undefined ? { tokenId: wire.tokenId } : {}),\n ...(wire.assets.length > 1\n ? { tokenIds: wire.assets.map((asset) => ({ id: asset.coinId, amount: asset.amount })) }\n : {}),\n ...(wire.counterpartyPubkey !== undefined\n ? received\n ? { senderPubkey: wire.counterpartyPubkey }\n : { recipientPubkey: wire.counterpartyPubkey }\n : {}),\n ...(nametag !== undefined\n ? received\n ? { senderNametag: nametag }\n : { recipientNametag: nametag }\n : {}),\n ...(memo !== undefined ? { memo } : {}),\n };\n }\n\n // Self-scoped decrypt: a foreign/undecryptable/plaintext value is absent,\n // never ciphertext and never a throw.\n private tryDecrypt(envelope?: string): string | undefined {\n if (envelope === undefined) return undefined;\n try {\n return decryptField(this.deps.fieldKey, envelope);\n } catch {\n return undefined;\n }\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","// The complete §6 durable-state inventory. One writer per store.\n\nimport { logger } from '../../core/logger';\nimport type { StorageProvider } from '../../storage';\n\n/** Generation 2 of the durable client state; renaming IS the 3.x migration\n * (kv-generation.test.ts). Must not START with a superseded prefix — the sweep\n * below matches by `startsWith`. */\nconst KV_PREFIX = 'pv2g2:';\n\nconst SUPERSEDED_KV_PREFIXES = ['pv2:'] as const;\n\n/** Never `storage.clear()` — that takes the keys too. */\nexport async function sweepSupersededState(storage: StorageProvider): Promise<void> {\n for (const prefix of SUPERSEDED_KV_PREFIXES) {\n try {\n await storage.clear(prefix);\n } catch (err) {\n logger.warn('PaymentsV2', `could not clear superseded state under \"${prefix}\": ${String(err)}`);\n }\n }\n}\n\nexport interface ScopedKV {\n get<T>(key: string): Promise<T | null>;\n set<T>(key: string, value: T): Promise<void>;\n remove(key: string): Promise<void>;\n}\n\nexport function createScopedKV(\n storage: StorageProvider,\n network: string,\n chainPubkey: string\n): ScopedKV {\n const prefix = `${KV_PREFIX}${network}:${chainPubkey}:`;\n return {\n async get<T>(key: string): Promise<T | null> {\n const raw = await storage.get(prefix + key);\n if (raw === null || raw === undefined) return null;\n return typeof raw === 'string' ? (JSON.parse(raw) as T) : (raw as T);\n },\n async set<T>(key: string, value: T): Promise<void> {\n await storage.set(prefix + key, JSON.stringify(value));\n },\n async remove(key: string): Promise<void> {\n await storage.remove(prefix + key);\n },\n };\n}\n\n\nexport interface IntentBackstopEntry {\n transferId: string;\n payloadEnvelope: string;\n requiresSeedClose: boolean;\n // #676: a locally-aborted intent is NEVER resumed.\n disposition: 'open' | 'abortPending' | 'aborted';\n createdAt: number;\n}\n\n\n// #621 delivery journal.\nexport interface DeliveryJournalEntry {\n transferId: string;\n opIndex: number;\n recipientPubkey: string;\n blobHex: string;\n memo?: string;\n // Poison budget (#517); 429 deferrals do NOT count.\n attempts: number;\n deferredUntil?: number;\n undeliverable?: boolean;\n}\n\n// §5.9 mint journal.\nexport interface MintJournalEntry {\n mintId: string;\n coinId: string;\n amount: string;\n tokenId: string;\n createdAt: number;\n}\n\n// §5.9 NFT mint journal (#785). Its own store: an older client reading a coin\n// journal entry without coinId/amount would retry it every pass, forever.\n// Every field a byte-identical re-mint needs is journaled, so resume never re-signs.\nexport interface NftMintJournalEntry {\n mintId: string;\n tokenId: string;\n dataHex: string;\n saltHex: string;\n tokenTypeHex: string;\n createdAt: number;\n}\n\n// #690 shortfall record.\nexport interface ShortfallEntry {\n transferId: string;\n remainingAmount: string;\n coinId: string;\n recipient: string;\n // Already delivered — NEVER re-send these sources.\n committedTokenIds: string[];\n createdAt: number;\n}\n\n// #441 settling link.\nexport interface SettlingLink {\n requestId: string;\n transferId: string;\n committed: boolean;\n createdAt: number;\n}\n\nexport type StreamName = 'inventory' | 'mailbox' | 'payment_requests' | 'history';\n\n// Cursor+epoch persist as ONE record — never two keys (#692 F10).\nexport interface StreamCursor {\n cursor: number | string;\n syncEpoch: string;\n}\n\nexport const STORE_KEYS = {\n intentBackstop: 'intents',\n checkpointCache: 'checkpoints',\n deliveryJournal: 'delivery-journal',\n mintJournal: 'mint-journal',\n nftMintJournal: 'nft-mint-journal',\n shortfalls: 'shortfalls',\n settlingLinks: 'settling',\n streamCursor: (s: StreamName) => `cursor:${s}`,\n epochLatch: 'epoch-latch',\n // §5.2 InventoryView durable overlays (#625/#679).\n suspectedSpent: 'suspected-spent',\n knownSpends: 'known-spends',\n} as const;\n","// §5.2 presentation half (split out per PR #727 review): pure registry/fiat\n// display mapping over mirror snapshots. No mirror mutation, no concurrency —\n// InventoryView owns the money mirror; this file only formats it.\n\nimport type { Asset, Token } from '../../../types';\nimport type { InventoryAsset } from '../ports';\n\nexport interface RegistryReader {\n getSymbol(coinId: string): string;\n getName(coinId: string): string;\n getDecimals(coinId: string): number;\n getIconUrl(coinId: string): string | null;\n /** Coinless token CLASS metadata, keyed by token type — a separate namespace. */\n getTypeMeta?(tokenType: string): { name: string; iconUrl: string | null } | null;\n}\n\nexport interface PriceQuote {\n readonly priceUsd: number;\n readonly priceEur?: number;\n readonly change24h?: number;\n}\n\nexport interface PriceReader {\n getPrices(tokenNames: string[]): Promise<Map<string, PriceQuote>>;\n}\n\nexport interface TokenSnapshot {\n readonly assets: readonly InventoryAsset[];\n readonly createdAt: number;\n readonly updatedAt: number;\n}\n\nexport interface TokenFlags {\n readonly transferring: boolean;\n readonly suspectedSpent: boolean;\n}\n\nexport function toToken(\n tokenId: string,\n snapshot: TokenSnapshot,\n asset: InventoryAsset,\n registry: RegistryReader,\n flags: TokenFlags\n): Token {\n const iconUrl = registry.getIconUrl(asset.coinId);\n return {\n id: tokenId,\n coinId: asset.coinId,\n symbol: registry.getSymbol(asset.coinId),\n name: registry.getName(asset.coinId),\n decimals: registry.getDecimals(asset.coinId),\n ...(iconUrl !== null ? { iconUrl } : {}),\n amount: asset.amount,\n status: flags.transferring ? 'transferring' : 'confirmed',\n createdAt: snapshot.createdAt,\n updatedAt: snapshot.updatedAt,\n lazy: true,\n ...(flags.suspectedSpent ? { suspectedSpent: true } : {}),\n };\n}\n\ninterface CoinTotals {\n total: bigint;\n count: number;\n transferring: bigint;\n transferringCount: number;\n}\n\nexport function aggregateAssets(\n entries: Iterable<[string, TokenSnapshot]>,\n isTransferring: (tokenId: string) => boolean,\n registry: RegistryReader\n): Asset[] {\n const groups = new Map<string, CoinTotals>();\n for (const [tokenId, entry] of entries) {\n const moving = isTransferring(tokenId);\n for (const asset of entry.assets) {\n let group = groups.get(asset.coinId);\n if (!group) {\n group = { total: 0n, count: 0, transferring: 0n, transferringCount: 0 };\n groups.set(asset.coinId, group);\n }\n if (moving) {\n group.transferring += BigInt(asset.amount);\n group.transferringCount += 1;\n } else {\n group.total += BigInt(asset.amount);\n group.count += 1;\n }\n }\n }\n return [...groups].map(([coinId, totals]) => toAsset(coinId, totals, registry));\n}\n\nfunction toAsset(coinId: string, totals: CoinTotals, registry: RegistryReader): Asset {\n const iconUrl = registry.getIconUrl(coinId);\n return {\n coinId,\n symbol: registry.getSymbol(coinId),\n name: registry.getName(coinId),\n decimals: registry.getDecimals(coinId),\n ...(iconUrl !== null ? { iconUrl } : {}),\n totalAmount: totals.total.toString(),\n tokenCount: totals.count,\n confirmedAmount: totals.total.toString(),\n unconfirmedAmount: '0',\n confirmedTokenCount: totals.count,\n unconfirmedTokenCount: 0,\n transferringTokenCount: totals.transferringCount,\n transferringAmount: totals.transferring.toString(),\n priceUsd: null,\n priceEur: null,\n change24h: null,\n fiatValueUsd: null,\n fiatValueEur: null,\n };\n}\n\n/**\n * The price-platform id for a coin.\n *\n * `RegistryReader.getName()` returns the DISPLAY name — the registry's raw name\n * with its first letter capitalized (\"Bitcoin\", \"Unicity\"). Price platform ids\n * (CoinGecko) are the raw lowercase names, and CoinGecko answers under the\n * canonical lowercase id even when asked with a capitalized one — so a\n * capitalized key MISSES on the way back and every asset silently prices at 0.\n * Lowercasing recovers the raw registry name exactly (a coinId fallback is hex,\n * already lowercase). Display keeps using getName(); only the price key differs.\n */\nfunction priceIdOf(registry: RegistryReader, coinId: string): string {\n return registry.getName(coinId).toLowerCase();\n}\n\nexport async function withPrices(\n raw: Asset[],\n registry: RegistryReader,\n price: PriceReader\n): Promise<Asset[]> {\n try {\n const ids = [...new Set(raw.map((a) => priceIdOf(registry, a.coinId)))];\n const quotes = await price.getPrices(ids);\n return raw.map((a) => priceOne(a, quotes.get(priceIdOf(registry, a.coinId))));\n } catch {\n return raw;\n }\n}\n\n// Fiat display conversion is the one sanctioned Number use (display only).\nfunction priceOne(asset: Asset, quote: PriceQuote | undefined): Asset {\n if (!quote) return asset;\n const human = Number(asset.totalAmount) / Math.pow(10, asset.decimals);\n return {\n ...asset,\n priceUsd: quote.priceUsd,\n priceEur: quote.priceEur ?? null,\n change24h: quote.change24h ?? null,\n fiatValueUsd: human * quote.priceUsd,\n fiatValueEur: quote.priceEur != null ? human * quote.priceEur : null,\n };\n}\n\n/** A source token as it appears mid-send: no snapshot yet, flagged transferring. */\nexport function transferringToken(\n tokenId: string,\n coinId: string,\n amount: bigint,\n registry: RegistryReader,\n now: number\n): Token {\n const snapshot = { assets: [], createdAt: now, updatedAt: now };\n return toToken(tokenId, snapshot, { coinId, amount: amount.toString() }, registry, {\n transferring: true,\n suspectedSpent: false,\n });\n}\n","// §5.2 of docs/PAYMENTS-V2-DESIGN.md — in-memory mirror of the server\n// inventory (a view, never a store of record). Single writer of the mirror,\n// the suspectedSpent overlay, the knownSpends set, the in-flight registry and\n// the §6 inventory StreamCursor record. Display mapping lives in presentation.ts.\n\nimport type { Asset, Token } from '../../../types';\nimport { SerialChain, SingleFlight } from '../async';\nimport type { CoinlessToken } from '../api';\nimport type { InventoryAsset, InventoryItem, InventoryPage, StoragePort } from '../ports';\nimport { STORE_KEYS, type ScopedKV, type StreamCursor } from '../stores';\nimport {\n aggregateAssets,\n toToken,\n withPrices,\n type PriceReader,\n type RegistryReader,\n} from './presentation';\n\nexport type { PriceQuote, PriceReader, RegistryReader } from './presentation';\n\n// F6: state-scoped by schema — a bare-tokenId spend record is unrepresentable.\nexport interface KnownSpend {\n readonly tokenId: string;\n readonly stateHash: string;\n}\n\nexport interface PoolEntry {\n readonly tokenId: string;\n readonly amount: bigint;\n}\n\nexport type ReAddResult = 'added' | 'evidenced-tombstone';\n\nexport interface RecoverOutcome {\n readonly recovered: readonly string[];\n readonly confirmedSpent: readonly KnownSpend[];\n}\n\nexport interface InventoryViewDeps {\n readonly port: StoragePort;\n readonly kv: ScopedKV;\n readonly emit: (event: 'inventory:updated') => void;\n readonly now?: () => number;\n /**\n * #737: tokens pinned by a §5.4 reservation — an open intent keeps its sources\n * reserved, and a token the selector cannot pick is NOT spendable balance. The\n * reporting side reads the pin instead of guessing from `inFlight` alone, which\n * only knows about the attempt still running in THIS session.\n */\n readonly isPinned?: (tokenId: string) => boolean;\n}\n\ninterface MirrorEntry {\n stateHash: string;\n seq: number;\n status: 'active' | 'removed';\n assets: readonly InventoryAsset[];\n /**\n * Positive statement that this ACTIVE row names no coin (wallet-api#140).\n * Computed here, where `status` is in hand, because absent `assets` means two\n * different things: a tombstone omits them for an unrelated reason, and\n * `assets` is INHERITED from the previous entry on a delta that omits them.\n */\n coinless: boolean;\n tokenType?: string;\n createdAt: number;\n updatedAt: number;\n}\n\nconst SUSPECTED_KEY = STORE_KEYS.suspectedSpent;\nconst KNOWN_SPENDS_KEY = STORE_KEYS.knownSpends;\nconst CURSOR_KEY = STORE_KEYS.streamCursor('inventory');\n\nfunction stateKey(tokenId: string, stateHash: string): string {\n return `${tokenId}:${stateHash}`;\n}\n\n/**\n * Only an ACTIVE row's absent `assets` positively states coinlessness. A tombstone\n * omits them for an unrelated reason, so it inherits rather than being reclassified\n * (wallet-api sdk-changes S2: discriminate on `status`, never on assets-absent).\n */\n/**\n * A type is a function of tokenId so it never CHANGES, but it can appear late\n * (wallet-api writes it on insert and reactivate; migration 0015 does not\n * backfill). The RESOLVED value is compared: comparing `item.tokenType` would\n * rewrite the entry on every delta that merely omits it.\n */\nfunction unchanged(prev: MirrorEntry, item: InventoryItem, tokenType: string | undefined): boolean {\n return (\n prev.seq === item.seq &&\n prev.status === item.status &&\n prev.stateHash === item.stateHash &&\n tokenType === prev.tokenType\n );\n}\n\nfunction isCoinless(item: InventoryItem, prev: MirrorEntry | undefined): boolean {\n if (item.status !== 'active') return prev?.coinless ?? false;\n return (item.assets?.length ?? 0) === 0;\n}\n\nexport class InventoryView {\n private readonly mirror = new Map<string, MirrorEntry>();\n private readonly suspected = new Set<string>();\n private readonly knownSpends = new Set<string>();\n private readonly inFlight = new Set<string>();\n private firstPullOk = false;\n private hydrated: Promise<void> | null = null;\n private readonly chain = new SerialChain();\n private readonly overlayChain = new SerialChain();\n private readonly pullFlight = new SingleFlight<void>();\n\n constructor(private readonly deps: InventoryViewDeps) {}\n\n fullPull(): Promise<void> {\n return this.pullFlight.run(() => this.chain.enqueue(() => this.doFullPull(false)));\n }\n\n // §5.2/§6: incremental pull from the persisted (cursor, epoch) record; a\n // stale epoch (server restore) voids cursor continuity → full re-pull.\n delta(): Promise<void> {\n return this.chain.enqueue(async () => {\n await this.hydrate();\n const record = this.firstPullOk ? await this.deps.kv.get<StreamCursor>(CURSOR_KEY) : null;\n if (record === null) return this.doFullPull(false);\n const first = await this.deps.port.listInventory(Number(record.cursor));\n if (first.syncEpoch !== record.syncEpoch) return this.doFullPull(true);\n const flags = { changed: false };\n try {\n await this.consumePages(first, undefined, flags);\n } finally {\n if (flags.changed) this.deps.emit('inventory:updated');\n }\n });\n }\n\n // Epoch reset (§5.1): full re-pull with per-key replace; entries absent from\n // the restored server drop only AFTER the new snapshot is fully applied.\n onEpochReset(): Promise<void> {\n return this.chain.enqueue(() => this.doFullPull(true));\n }\n\n async demote(tokenId: string, stateHash: string): Promise<void> {\n if (tokenId === '' || stateHash === '') {\n throw new Error('demote requires both tokenId and stateHash');\n }\n const key = stateKey(tokenId, stateHash);\n if (this.suspected.has(key)) return;\n const added = await this.overlayChain.enqueue(async () => {\n await this.hydrate();\n if (this.suspected.has(key)) return false;\n await this.deps.kv.set(SUSPECTED_KEY, [...this.suspected, key]);\n this.suspected.add(key);\n return true;\n });\n if (added) this.deps.emit('inventory:updated');\n }\n\n recoverRemoved(\n getBlobs: (tokenIds: string[]) => Promise<Map<string, Uint8Array>>,\n isSpent: (tokenId: string, blob: Uint8Array) => Promise<boolean>,\n reAdd: (tokenId: string, blob: Uint8Array) => Promise<ReAddResult>\n ): Promise<RecoverOutcome> {\n return this.chain.enqueue(() => this.doRecover(getBlobs, isSpent, reAdd));\n }\n\n markInFlight(tokenId: string): void {\n if (this.inFlight.has(tokenId)) return;\n this.inFlight.add(tokenId);\n this.deps.emit('inventory:updated');\n }\n\n /** Reserve a whole plan as ONE change — per token emitted 54 events per send. */\n markInFlightMany(tokenIds: Iterable<string>): void {\n let changed = false;\n for (const tokenId of tokenIds) {\n if (this.inFlight.has(tokenId)) continue;\n this.inFlight.add(tokenId);\n changed = true;\n }\n if (changed) this.deps.emit('inventory:updated');\n }\n\n release(tokenId: string): void {\n if (this.inFlight.delete(tokenId)) this.deps.emit('inventory:updated');\n }\n\n /** Release a whole set as ONE change (per-token emitted 54 events per send). */\n releaseMany(tokenIds: Iterable<string>): void {\n let changed = false;\n for (const tokenId of tokenIds) if (this.inFlight.delete(tokenId)) changed = true;\n if (changed) this.deps.emit('inventory:updated');\n }\n\n private pinned(tokenId: string): boolean {\n return this.deps.isPinned?.(tokenId) ?? false;\n }\n\n /** In flight here OR pinned by a reservation: either way not spendable (#737). */\n private held(tokenId: string): boolean {\n return this.inFlight.has(tokenId) || this.pinned(tokenId);\n }\n\n // A PINNED token stays in the pool: the queue applies the ledger filter itself\n // and needs the entry to say how much is pinned when it refuses (#737). In\n // flight without a pin (spent, awaiting the mirror refresh) stays out.\n pool(coinId: string): PoolEntry[] {\n const out: PoolEntry[] = [];\n for (const [tokenId, entry] of this.mirror) {\n if (!this.isSpendable(tokenId, entry)) continue;\n const asset = entry.assets.find((a) => a.coinId === coinId);\n if (asset) out.push({ tokenId, amount: BigInt(asset.amount) });\n }\n return out;\n }\n\n /**\n * The eligibility gates every spend shares, coin or token — ONE definition, so a\n * single probe covers both verbs and neither can drift from the other.\n */\n private isSpendable(tokenId: string, entry: MirrorEntry): boolean {\n if (entry.status !== 'active') return false;\n if (this.inFlight.has(tokenId) && !this.pinned(tokenId)) return false;\n return !this.suspected.has(stateKey(tokenId, entry.stateHash));\n }\n\n /** Is this NAMED token spendable whole — coinless or valued (#777)? */\n spendableToken(tokenId: string): boolean {\n const entry = this.mirror.get(tokenId);\n return entry !== undefined && this.isSpendable(tokenId, entry);\n }\n\n /**\n * Current mirrored state of an ACTIVE token, or undefined when it is unknown\n * or tombstoned. Exists so a cached blob can be state-scoped (F6): a blob is\n * only reusable while the token still sits at the state it was fetched at.\n */\n stateHashOf(tokenId: string): string | undefined {\n const entry = this.mirror.get(tokenId);\n return entry !== undefined && entry.status === 'active' ? entry.stateHash : undefined;\n }\n\n tokens(registry: RegistryReader, filter?: { coinId?: string }): Token[] {\n const out: Token[] = [];\n for (const [tokenId, entry] of this.mirror) {\n if (entry.status !== 'active') continue;\n const asset = entry.assets[0];\n if (!asset) continue;\n if (filter?.coinId !== undefined && asset.coinId !== filter.coinId) continue;\n out.push(\n toToken(tokenId, entry, asset, registry, {\n transferring: this.held(tokenId),\n suspectedSpent: this.suspected.has(stateKey(tokenId, entry.stateHash)),\n })\n );\n }\n return out;\n }\n\n /**\n * Coinless holdings (#777) — DISJOINT from tokens(): an entry is coinless\n * exactly when it is not, so no mirror row can appear in both reads.\n */\n coinless(registry: RegistryReader): CoinlessToken[] {\n const out: CoinlessToken[] = [];\n for (const [tokenId, entry] of this.mirror) {\n if (entry.status !== 'active' || !entry.coinless) continue;\n const meta = entry.tokenType !== undefined ? registry.getTypeMeta?.(entry.tokenType) : null;\n out.push({\n tokenId,\n ...(entry.tokenType !== undefined ? { tokenType: entry.tokenType } : {}),\n ...(meta ? { name: meta.name } : {}),\n ...(meta?.iconUrl != null ? { iconUrl: meta.iconUrl } : {}),\n stateHash: entry.stateHash,\n transferring: this.held(tokenId),\n ...(this.suspected.has(stateKey(tokenId, entry.stateHash))\n ? { suspectedSpent: true }\n : {}),\n createdAt: entry.createdAt,\n updatedAt: entry.updatedAt,\n });\n }\n return out;\n }\n\n async assets(registry: RegistryReader, price?: PriceReader): Promise<Asset[]> {\n const raw = aggregateAssets(this.activeEntries(), (tokenId) => this.held(tokenId), registry);\n if (!price || raw.length === 0) return raw;\n return withPrices(raw, registry, price);\n }\n\n private *activeEntries(): Iterable<[string, MirrorEntry]> {\n for (const [tokenId, entry] of this.mirror) {\n if (entry.status === 'active') yield [tokenId, entry];\n }\n }\n\n private hydrate(): Promise<void> {\n this.hydrated ??= this.loadDurable().catch((error: unknown) => {\n this.hydrated = null;\n throw error;\n });\n return this.hydrated;\n }\n\n private async loadDurable(): Promise<void> {\n const suspected = await this.deps.kv.get<string[]>(SUSPECTED_KEY);\n for (const key of suspected ?? []) this.suspected.add(key);\n const known = await this.deps.kv.get<string[]>(KNOWN_SPENDS_KEY);\n for (const key of known ?? []) this.knownSpends.add(key);\n }\n\n private now(): number {\n return (this.deps.now ?? Date.now)();\n }\n\n private async doFullPull(reconcileAbsent: boolean): Promise<void> {\n await this.hydrate();\n const seen = reconcileAbsent ? new Set<string>() : undefined;\n const flags = { changed: false };\n try {\n let page = await this.deps.port.listInventory();\n const firstCursor = page.cursor;\n if (this.applyItems(page.items, seen)) flags.changed = true;\n while (page.more) {\n page = await this.deps.port.listInventory(page.cursor);\n if (this.applyItems(page.items, seen)) flags.changed = true;\n }\n // One immediate since-delta from the page-1 cursor: pulls span snapshots,\n // its tombstones/upserts repair any inter-page flips.\n await this.consumePages(await this.deps.port.listInventory(firstCursor), seen, flags);\n if (seen && this.dropAbsent(seen)) flags.changed = true;\n this.firstPullOk = true;\n } finally {\n // A partially applied pull still emits — the view DID change.\n if (flags.changed) this.deps.emit('inventory:updated');\n }\n }\n\n /** Applies a since-page and its more-loop, then persists the ONE (cursor, epoch) record. */\n private async consumePages(\n first: InventoryPage,\n seen: Set<string> | undefined,\n flags: { changed: boolean }\n ): Promise<void> {\n let page = first;\n if (this.applyItems(page.items, seen)) flags.changed = true;\n while (page.more) {\n page = await this.deps.port.listInventory(page.cursor);\n if (this.applyItems(page.items, seen)) flags.changed = true;\n }\n const record: StreamCursor = { cursor: page.cursor, syncEpoch: page.syncEpoch };\n await this.deps.kv.set(CURSOR_KEY, record);\n }\n\n // Synchronous per-key application; the overlay prune runs in this same\n // synchronous step (F7) — never against a cleared or half-filled view.\n private applyItems(items: readonly InventoryItem[], seen?: Set<string>): boolean {\n const now = this.now();\n let changed = false;\n for (const item of items) {\n seen?.add(item.tokenId);\n if (this.applyOne(item, now)) changed = true;\n }\n const pruned = this.pruneOverlaySync(false);\n return changed || pruned;\n }\n\n private applyOne(item: InventoryItem, now: number): boolean {\n const prev = this.mirror.get(item.tokenId);\n if (prev && item.seq < prev.seq) return false;\n const tokenType = item.tokenType ?? prev?.tokenType;\n if (prev && unchanged(prev, item, tokenType)) return false;\n this.mirror.set(item.tokenId, {\n stateHash: item.stateHash,\n seq: item.seq,\n status: item.status,\n // ONLY a tombstone inherits: it omits assets for an unrelated reason and\n // recoverRemoved must know the amount it restores. An ACTIVE row that omits\n // them is stating coinlessness, and inheriting there would keep stale assets\n // in tokens() while `coinless` is true — the row in BOTH reads (§16).\n assets: item.assets ?? (item.status === 'removed' ? (prev?.assets ?? []) : []),\n coinless: isCoinless(item, prev),\n ...(tokenType !== undefined ? { tokenType } : {}),\n createdAt: prev?.createdAt ?? now,\n updatedAt: now,\n });\n return true;\n }\n\n // Prunes only on positive evidence (state advance or tombstone). Absence is\n // evidence only when the caller holds a complete post-reset snapshot.\n private pruneOverlaySync(allowAbsent: boolean): boolean {\n let pruned = false;\n for (const key of this.suspected) {\n const cut = key.lastIndexOf(':');\n const entry = this.mirror.get(key.slice(0, cut));\n const live = entry !== undefined\n ? entry.status === 'active' && entry.stateHash === key.slice(cut + 1)\n : !allowAbsent;\n if (!live) {\n this.suspected.delete(key);\n pruned = true;\n }\n }\n if (pruned) this.schedulePersistSuspected();\n return pruned;\n }\n\n private schedulePersistSuspected(): void {\n void this.overlayChain\n .enqueue(() => this.deps.kv.set(SUSPECTED_KEY, [...this.suspected]))\n .catch(() => undefined);\n }\n\n private dropAbsent(seen: Set<string>): boolean {\n let changed = false;\n for (const tokenId of [...this.mirror.keys()]) {\n if (!seen.has(tokenId)) {\n this.mirror.delete(tokenId);\n changed = true;\n }\n }\n if (changed) this.pruneOverlaySync(true);\n return changed;\n }\n\n private async doRecover(\n getBlobs: (tokenIds: string[]) => Promise<Map<string, Uint8Array>>,\n isSpent: (tokenId: string, blob: Uint8Array) => Promise<boolean>,\n reAdd: (tokenId: string, blob: Uint8Array) => Promise<ReAddResult>\n ): Promise<RecoverOutcome> {\n await this.hydrate();\n const candidates = this.firstPullOk ? this.recoveryCandidates() : [];\n if (candidates.length === 0) return { recovered: [], confirmedSpent: [] };\n const blobs = await getBlobs(candidates.map((c) => c.tokenId));\n const recovered: string[] = [];\n const confirmedSpent: KnownSpend[] = [];\n try {\n for (const candidate of candidates) {\n const blob = blobs.get(candidate.tokenId);\n if (!blob) continue;\n const outcome = await this.recoverOne(candidate, blob, isSpent, reAdd);\n if (outcome === 'recovered') recovered.push(candidate.tokenId);\n if (outcome === 'spent') confirmedSpent.push(candidate);\n }\n } finally {\n if (recovered.length > 0) this.deps.emit('inventory:updated');\n }\n return { recovered, confirmedSpent };\n }\n\n private recoveryCandidates(): KnownSpend[] {\n const out: KnownSpend[] = [];\n for (const [tokenId, entry] of this.mirror) {\n if (entry.status !== 'removed') continue;\n if (this.knownSpends.has(stateKey(tokenId, entry.stateHash))) continue;\n out.push({ tokenId, stateHash: entry.stateHash });\n }\n return out;\n }\n\n private async recoverOne(\n candidate: KnownSpend,\n blob: Uint8Array,\n isSpent: (tokenId: string, blob: Uint8Array) => Promise<boolean>,\n reAdd: (tokenId: string, blob: Uint8Array) => Promise<ReAddResult>\n ): Promise<'recovered' | 'spent' | 'skipped'> {\n if (await isSpent(candidate.tokenId, blob)) {\n await this.recordKnownSpend(candidate);\n return 'spent';\n }\n if ((await reAdd(candidate.tokenId, blob)) === 'evidenced-tombstone') {\n await this.recordKnownSpend(candidate);\n return 'spent';\n }\n const current = this.mirror.get(candidate.tokenId);\n if (!current || current.status !== 'removed' || current.stateHash !== candidate.stateHash) {\n return 'skipped';\n }\n current.status = 'active';\n current.updatedAt = this.now();\n return 'recovered';\n }\n\n private async recordKnownSpend(spend: KnownSpend): Promise<void> {\n if (spend.tokenId === '' || spend.stateHash === '') {\n throw new Error('knownSpend requires both tokenId and stateHash');\n }\n this.knownSpends.add(stateKey(spend.tokenId, spend.stateHash));\n await this.deps.kv.set(KNOWN_SPENDS_KEY, [...this.knownSpends]);\n }\n}\n","/**\n * Genesis value-envelope classification: the client half of wallet-api's §8.2\n * step 6. This throw set stays a SUBSET of wallet-api's 422 set — throwing where\n * it accepts loses a token (`Receive.screen()` acks a decode throw as invalid).\n */\nimport { SphereError } from '../core/errors';\n\nimport {\n CborDeserializer,\n CborReader,\n HexConverter,\n MajorType,\n type Token,\n} from './sdk';\nimport { SpherePaymentData } from './SpherePaymentData';\nimport type { SphereToken, SphereValue, TokenBlob } from './types';\n\n/** `none_*` = coinless; `bare_collection` = a dialect this SDK cannot read. */\nexport type ValueEnvelope =\n | 'sphere'\n | 'bare_collection'\n | 'none_tag'\n | 'none_other'\n | 'none_absent';\n\n/**\n * Does the token genuinely name NO coin? NOT the same question as `value === null`:\n * `bare_collection` is null too while carrying coins this SDK cannot read.\n */\nexport function isCoinlessEnvelope(envelope: ValueEnvelope): boolean {\n return envelope.startsWith('none_');\n}\n\nexport interface ClassifiedValue {\n readonly envelope: ValueEnvelope;\n /** Populated only for `'sphere'`; null for every other envelope. */\n readonly value: SphereValue | null;\n}\n\nconst SELF_DESCRIBED_CBOR_TAG = 55799n;\nconst CBOR_MAJOR_TYPE_MASK = 0b1110_0000;\n\nconst describe = (error: unknown): string =>\n error instanceof Error ? error.message : String(error);\n\nconst invalid = (message: string): SphereError => new SphereError(message, 'VALIDATION_ERROR');\n\nfunction majorTypeOf(bytes: Uint8Array): MajorType | null {\n const first = bytes.at(0);\n return first === undefined ? null : first & CBOR_MAJOR_TYPE_MASK;\n}\n\n/** Tag number from the HEAD ALONE; `null` = truncated or non-canonical head. */\nfunction headTagNumber(bytes: Uint8Array): bigint | null {\n try {\n return new CborReader(bytes).readLength(MajorType.TAG);\n } catch {\n return null;\n }\n}\n\n/** `Asset.toCBOR()`'s signature: a 2-array of byte strings. Arity and types only. */\nfunction isAssetShaped(item: Uint8Array): boolean {\n try {\n return CborDeserializer.decodeArray(item, 2).every(\n (field) => majorTypeOf(field) === MajorType.BYTE_STRING,\n );\n } catch {\n return false;\n }\n}\n\nfunction arrayItemsOrNull(bytes: Uint8Array): readonly Uint8Array[] | null {\n try {\n return CborDeserializer.decodeArray(bytes);\n } catch {\n return null;\n }\n}\n\nfunction decodeSphere(genesisData: Uint8Array): SphereValue {\n try {\n return SpherePaymentData.fromCBOR(genesisData).toValue();\n } catch (error) {\n throw invalid(`Failed to decode token payment data: ${describe(error)}`);\n }\n}\n\n/** Tagged items must frame cleanly, so raw binary in the tag range is refused. */\nfunction taggedItemBody(genesisData: Uint8Array): Uint8Array {\n try {\n return CborDeserializer.decodeTag(genesisData).data;\n } catch (error) {\n throw invalid(\n `Token value payload is a CBOR tag whose item is malformed or carries trailing bytes: ${describe(error)}`,\n );\n }\n}\n\n/** Does a 55799 wrapper hide a value envelope? Nested wrappers are refused, not walked. */\nfunction selfDescribedBodyCarriesValue(body: Uint8Array): boolean {\n const major = majorTypeOf(body);\n if (major === MajorType.TAG) {\n const inner = headTagNumber(body);\n return inner === SpherePaymentData.CBOR_TAG || inner === SELF_DESCRIBED_CBOR_TAG;\n }\n if (major === MajorType.ARRAY) {\n const items = arrayItemsOrNull(body);\n return items !== null && items.some(isAssetShaped);\n }\n return false;\n}\n\n/** Tag 39050 decodes; 55799-over-value is refused; any other tag is coinless. */\nfunction classifyTagged(genesisData: Uint8Array): ClassifiedValue {\n const tag = headTagNumber(genesisData);\n if (tag === null) {\n throw invalid(\n 'Token value payload has an unreadable or non-canonically encoded CBOR tag head — it could be a malformed SpherePaymentData envelope',\n );\n }\n if (tag === SpherePaymentData.CBOR_TAG) {\n return { envelope: 'sphere', value: decodeSphere(genesisData) };\n }\n const body = taggedItemBody(genesisData);\n if (tag === SELF_DESCRIBED_CBOR_TAG && selfDescribedBodyCarriesValue(body)) {\n throw invalid(\n 'Token value payload is a value envelope wrapped in the self-described CBOR tag 55799 (RFC 8949 §3.4.6), which no codec here unwraps — its coins would be invisible. Emit the envelope without the self-describe prefix',\n );\n }\n return { envelope: 'none_tag', value: null };\n}\n\n/** Must frame cleanly (a truncation may be a corrupt collection). `.some`, never `.every`. */\nfunction classifyArray(genesisData: Uint8Array): ClassifiedValue {\n const items = arrayItemsOrNull(genesisData);\n if (items === null) {\n throw invalid('Token value payload is not PaymentAssetCollection: malformed CBOR array');\n }\n return items.some(isAssetShaped)\n ? { envelope: 'bare_collection', value: null }\n : { envelope: 'none_other', value: null };\n}\n\n/** Not a value envelope ⇒ null value (coinless); claims one and fails to decode ⇒ throws. */\nexport function classifyValueEnvelope(genesisData: Uint8Array | null): ClassifiedValue {\n if (genesisData === null) return { envelope: 'none_absent', value: null };\n const major = majorTypeOf(genesisData);\n if (major === null) return { envelope: 'none_absent', value: null };\n if (major === MajorType.TAG) return classifyTagged(genesisData);\n if (major === MajorType.ARRAY) return classifyArray(genesisData);\n return { envelope: 'none_other', value: null };\n}\n\n/** Wrap an SDK token: blob (incl. stable tokenId), classified envelope, decoded value. */\nexport function wrapToken(sdkToken: Token): SphereToken {\n const { envelope, value } = classifyValueEnvelope(sdkToken.genesis.data);\n const blob: TokenBlob = {\n tokenId: HexConverter.encode(sdkToken.id.bytes),\n token: sdkToken.toCBOR(),\n };\n return {\n sdkToken,\n blob,\n value,\n valueEnvelope: envelope,\n tokenType: HexConverter.encode(sdkToken.type.bytes),\n };\n}\n\n/**\n * Pre-flight for `mintDataToken`'s opaque payload, BEFORE any chain op — otherwise\n * the refusal surfaces from `wrapToken` after the mint certified, stranding a token\n * this SDK can no longer decode and wallet-api would refuse at deposit anyway.\n */\nexport function assertMintableData(data: Uint8Array): void {\n try {\n classifyValueEnvelope(data);\n } catch (error) {\n throw invalid(\n `Cannot mint a data token with this payload: ${describe(error)}. Raw bytes starting in the CBOR array (0x80-0x9f) or tag (0xc0-0xdf) range must be well-formed canonical CBOR; wrap them in a CBOR byte string, map, text string, or a tag other than 39050/55799.`,\n );\n }\n}\n","// S2/S7 interfaces (amended 2026-07-31). Blob bytes = RAW v2 Token.toCBOR().\n\nexport interface InventoryAsset {\n coinId: string;\n amount: string;\n}\n\nexport interface InventoryItem {\n tokenId: string;\n status: 'active' | 'removed';\n seq: number;\n stateHash: string;\n /** Absent for a tombstone AND for an active COINLESS token — read `status`, not this. */\n assets?: InventoryAsset[];\n tokenType?: string;\n}\n\nexport interface InventoryPage {\n cursor: number;\n syncEpoch: string;\n more: boolean;\n items: InventoryItem[];\n}\n\nexport interface ApplyDeltaResult {\n cursor: number;\n syncEpoch: string;\n}\n\nexport interface StoragePort {\n listInventory(since?: number): Promise<InventoryPage>;\n getBlobs(tokenIds: string[]): Promise<Map<string, Uint8Array>>;\n uploadBlobs(blobs: { sha256: string; bytes: Uint8Array }[]): Promise<Map<string, string>>;\n // The one authoritative spend write, after the deposit ATTEMPT (§5.5). Rejects DeltaConflictError('DELTA_CONFLICT',409) / DeltaValidationError('DELTA_VALIDATION',422) — impl/wallet-api-v2/storage.ts; match on `code`.\n applyDelta(delta: {\n transferId: string;\n spent: string[];\n added: { tokenId: string; key: string }[];\n }): Promise<ApplyDeltaResult>;\n}\n\nexport interface DeliveryReceipt {\n // hex(SHA-256(tokenId ‖ stateHash)) — content-derived, never a row id/seq.\n deliveryId: string;\n}\n\nexport interface IncomingDelivery {\n deliveryId: string;\n transferId?: string;\n senderPubkey?: string;\n senderNametag?: string;\n memo?: string;\n fetchBlob(): Promise<Uint8Array>;\n cursor: string;\n}\n\nexport interface DeliverOptions {\n transferId: string;\n memo?: string;\n senderNametag?: string;\n}\n\nexport interface DeliveryPort {\n bindDeliveryKeys(\n derive: (blob: Uint8Array) => Promise<{ tokenId: string; stateHash: string }>\n ): void;\n // Idempotent per (token, state), bytes MAY differ — absorb the key-variant 409.\n deliver(\n recipientPubkey: string,\n blob: Uint8Array,\n options: DeliverOptions\n ): Promise<DeliveryReceipt>;\n deliverBatch?(\n recipientPubkey: string,\n blobs: Uint8Array[],\n options: DeliverOptions\n ): Promise<DeliveryReceipt[]>;\n // At-least-once; the impl owns the persistent seen-set (S7).\n incoming(sinceCursor?: string): AsyncIterable<IncomingDelivery>;\n /**\n * The syncEpoch of the most recent incoming() page — updated per page, null\n * before the first. §5.7 restore self-detection: the mailbox page is the\n * honest epoch source, so Receive voids its (cursor, epoch) continuity on a\n * mismatch even when the wake socket missed a server restore. (Pinned by the\n * S7 contract suite; wallet-api#119's S7 text carries the same sentence.)\n */\n incomingEpoch(): string | null;\n ack(\n deliveryId: string,\n disposition: 'claimed' | 'rejected',\n reason?: 'invalid' | 'not-owned' | 'storage-rejected' | 'other'\n ): Promise<void>;\n /** Settle many acks at once (#757). Contract pinned by the delivery-port contract suite. */\n ackBatch?(acks: readonly AckRequest[]): Promise<readonly AckOutcome[]>;\n onWake?(cb: () => void): () => void;\n}\n\nexport interface AckRequest {\n readonly deliveryId: string;\n readonly disposition: 'claimed' | 'rejected';\n readonly reason?: 'invalid' | 'not-owned' | 'storage-rejected' | 'other';\n}\n\nexport type AckOutcome =\n | { readonly deliveryId: string; readonly status: 'settled' }\n | { readonly deliveryId: string; readonly status: 'conflict' };\n\n/** ackBatch failed in a way a per-entry retry would hit too — do not fall back. */\nexport interface RetryableAckError extends Error {\n readonly retryable: true;\n}\n\nexport function isRetryableAckError(err: unknown): err is RetryableAckError {\n return err !== null && typeof err === 'object' && (err as { retryable?: unknown }).retryable === true;\n}\n","// §5.7 of docs/PAYMENTS-V2-DESIGN.md — the single-flighted receive drain.\n// Entry order is money-load-bearing: the view store precedes the claimed ack (#724).\n\nimport { logger } from '../../../core/logger';\nimport type { ITokenEngine, SphereToken } from '../../../token-engine';\nimport { isCoinlessEnvelope } from '../../../token-engine/value-envelope';\nimport type { IncomingTransfer, Token } from '../../../types';\nimport { SingleFlight } from '../async';\nimport type { RegistryReader } from '../inventory/InventoryView';\nimport type { AttentionEmitter } from '../machine/journal';\nimport { isRetryableAckError } from '../ports';\nimport type { AckOutcome, AckRequest, DeliveryPort, IncomingDelivery } from '../ports';\nimport { STORE_KEYS, type ScopedKV, type StreamCursor } from '../stores';\n\nexport type ReceiveEngine = Pick<\n ITokenEngine,\n 'getIdentity' | 'decodeToken' | 'verify' | 'isOwnedBy' | 'isSpent' | 'tokenId' | 'deliveryKeys'\n>;\n\nexport interface IncomingAssetAmount {\n readonly coinId: string;\n readonly amount: string;\n}\n\nexport interface StoredIncoming {\n readonly tokenId: string;\n readonly stateHash: string;\n readonly assets: readonly IncomingAssetAmount[];\n /** Genesis type of an arrival that names no coin (#777) — its only display handle. */\n readonly tokenType?: string;\n}\n\n// Per-key seam over the inventory view (adapted by the facade in P9).\nexport interface ReceiveView {\n heldState(tokenId: string): string | null;\n store(entry: StoredIncoming): Promise<void>;\n}\n\nexport interface ReceivedRecord {\n readonly dedupKey: string;\n readonly tokenId: string;\n readonly stateHash: string;\n readonly assets: readonly IncomingAssetAmount[];\n readonly tokenType?: string;\n readonly senderPubkey?: string;\n readonly senderNametag?: string;\n readonly memo?: string;\n readonly receivedAt: number;\n}\n\nexport interface ReceiveDeps {\n readonly delivery: DeliveryPort;\n /** Snapshot taken once per drain (§7 collaborator-snapshot rule). */\n readonly engine: () => ReceiveEngine;\n readonly view: ReceiveView;\n readonly kv: ScopedKV;\n readonly registry: RegistryReader;\n readonly recordReceived: (record: ReceivedRecord) => Promise<void>;\n readonly emit: (event: 'transfer:incoming', transfer: IncomingTransfer) => void;\n /** Refresh the inventory mirror mid-drain; fire-and-forget. Receive throttles the calls. */\n readonly refreshView?: () => void;\n readonly attention: AttentionEmitter;\n readonly syncEpoch: () => string;\n readonly track?: (op: Promise<unknown>) => void;\n readonly now?: () => number;\n}\n\nexport const ACK_BATCH_SIZE = 200;\n/**\n * Mid-drain mirror refresh cadence. Coarse because a refresh flushes acks and\n * costs an inventory round trip, both on the drain's critical path. It shipped\n * at 750 ms first, which is SHORTER than the ~1 s a token takes, so the throttle\n * never throttled: every token paid for one and a 54-token receive stretched to\n * ~58 s. Any value below the per-token cost has that effect.\n */\nexport const REFRESH_INTERVAL_MS = 2500;\nexport const POLL_INTERVAL_MS = 30_000;\nexport const ATTENTION_CLAIM_CONFLICT = 'claim:conflict';\n\nexport function receivedDedupKey(tokenId: string, stateHash: string): string {\n // Lowercased like History's keys — a case-variant would defeat server dedup.\n return `RECEIVED:${tokenId.toLowerCase()}:${stateHash.toLowerCase()}`;\n}\n\ninterface PendingAck {\n readonly deliveryId: string;\n readonly disposition: 'claimed' | 'rejected';\n readonly reason?: 'invalid' | 'not-owned' | 'other';\n readonly cursor: string;\n readonly transferId?: string;\n}\n\ntype Screened = { kind: 'ack'; ack: PendingAck } | { kind: 'accept'; record: StoredIncoming };\n\n/** The mutable state one listing pass threads through (max-params ≤ 5). */\ninterface DrainPass {\n readonly deps: ReceiveDeps;\n readonly engine: ReceiveEngine;\n readonly pending: PendingAck[];\n readonly stored: IncomingTransfer[];\n readonly pageEpoch: () => string;\n /** Entries this drain made claimable — stored, or a held-state claim retry. */\n readonly claimable: { n: number };\n}\n\nfunction isClaimConflict(err: unknown): boolean {\n const e = err !== null && typeof err === 'object' ? (err as { code?: unknown; failureCode?: unknown }) : null;\n return e !== null && e.code === 'MAILBOX_CLAIM_FAILED' && e.failureCode === 'CONFLICT';\n}\n\nexport class Receive {\n private readonly drainFlight = new SingleFlight<IncomingTransfer[]>();\n private pollTimer: ReturnType<typeof setInterval> | null = null;\n private unsubscribeWake: (() => void) | null = null;\n private lastRefreshAt = 0;\n\n constructor(private readonly deps: ReceiveDeps) {}\n\n drainOnce(): Promise<IncomingTransfer[]> {\n return this.drainFlight.run(() => this.doDrain());\n }\n\n start(pollIntervalMs: number = POLL_INTERVAL_MS): void {\n this.unsubscribeWake ??= this.deps.delivery.onWake?.(() => this.spawnDrain()) ?? null;\n this.pollTimer ??= setInterval(() => this.spawnDrain(), pollIntervalMs);\n }\n\n private spawnDrain(): void {\n const op = this.drainOnce();\n if (this.deps.track !== undefined) this.deps.track(op);\n else void op;\n }\n\n stop(): void {\n if (this.pollTimer !== null) clearInterval(this.pollTimer);\n this.pollTimer = null;\n this.unsubscribeWake?.();\n this.unsubscribeWake = null;\n }\n\n /**\n * Flush what has been accepted, then ask for a mirror refresh — at most once\n * per REFRESH_INTERVAL_MS.\n *\n * The flush is not incidental. A `claimed` ack is what materializes a token\n * into SERVER inventory, and acks otherwise sit queued until ACK_BATCH_SIZE\n * (200) — so for any ordinary drain, including the 54-token case this exists\n * for, refreshing before the flush would query an inventory holding none of\n * the tokens just accepted, and the balance would still only move at the end.\n * Ordering is preserved: store() still precedes the ack (§5.7).\n */\n private async maybeRefresh(ctx: DrainPass): Promise<void> {\n const { deps, pending, pageEpoch } = ctx;\n if (deps.refreshView === undefined) return;\n const now = deps.now?.() ?? Date.now();\n if (now - this.lastRefreshAt < REFRESH_INTERVAL_MS) return;\n this.lastRefreshAt = now;\n // A blocked flush materialized nothing, so the delta would show today's balance.\n if ((await flushAcks(deps, pending, pageEpoch)).progressed) deps.refreshView();\n }\n\n /** One listing pass: process each entry, flushing and refreshing as it goes. */\n private async drainPages(ctx: DrainPass, basis: StreamCursor | null): Promise<void> {\n const { deps, pending, pageEpoch, claimable } = ctx;\n for await (const entry of deps.delivery.incoming(basis === null ? undefined : String(basis.cursor))) {\n const claimableBefore = claimable.n;\n await this.processEntry(ctx, entry);\n if (pending.length >= ACK_BATCH_SIZE) {\n // Nothing settled = the head is blocked; continuing re-flushes it once per\n // remaining entry, amplifying one failure into hundreds.\n if (!(await flushAcks(deps, pending, pageEpoch)).progressed) return;\n }\n // Only when THIS entry entered the balance: a rejected one changes nothing.\n // Keyed on claimable, not stored — a held-state RETRY claims without storing,\n // and a long retry drain is the frozen balance this PR exists to fix.\n if (claimable.n > claimableBefore) await this.maybeRefresh(ctx);\n }\n await flushAcks(deps, pending, pageEpoch);\n }\n\n private async doDrain(): Promise<IncomingTransfer[]> {\n const deps = this.deps;\n // Clock starts at the drain: one finishing inside an interval refreshes once,\n // at the end, exactly as before. Only a slow drain pays for mid-flight ones.\n this.lastRefreshAt = deps.now?.() ?? Date.now();\n const engine = deps.engine();\n const stored: IncomingTransfer[] = [];\n const pending: PendingAck[] = [];\n // The port's page epoch is the honest source for the persisted record.\n const pageEpoch = (): string => deps.delivery.incomingEpoch() ?? deps.syncEpoch();\n // Every exit refreshes (automatic drains never call receive(), and the §5.7\n // wake is best-effort), counted where the entry becomes claimable — every\n // downstream proxy had a path that destroyed it.\n const claimable = { n: 0 };\n const finish = (): IncomingTransfer[] => {\n if (claimable.n > 0) deps.refreshView?.();\n return stored;\n };\n try {\n const record = await deps.kv.get<StreamCursor>(STORE_KEYS.streamCursor('mailbox'));\n // Cursor continuity holds only within one syncEpoch (§6); the session\n // latch gates the resume decision.\n let basis = record !== null && record.syncEpoch === deps.syncEpoch() ? record : null;\n for (let pass = 0; pass < 2; pass++) {\n await this.drainPages({ deps, engine, pending, stored, pageEpoch, claimable }, basis);\n const served = deps.delivery.incomingEpoch();\n if (basis === null || served === null || served === basis.syncEpoch) break;\n // §5.7 restore self-detection: the page reports a different epoch than\n // the cursor record's — post-restore seqs restart, so the resumed\n // listing may have SKIPPED entries. Void the continuity record and\n // re-list from the start (dedup: seen-set + (tokenId, stateHash)).\n await deps.kv.remove(STORE_KEYS.streamCursor('mailbox'));\n basis = null;\n }\n } catch (err) {\n // Infra failure (engine/blob/view/ack): the failed entry stays UNACKED and\n // re-lists next drain; the fully-processed prefix still flushes below.\n logger.warn('PaymentsV2', 'receive drain interrupted — unacked entries retry next drain:', err);\n // Retryable = the wall is still up; re-flushing spends another slot. Exits\n // via finish() because ackBatch kept its committed chunks, which never re-list.\n if (isRetryableAckError(err)) return finish();\n await flushAcks(deps, pending, pageEpoch).catch((flushErr: unknown) => {\n logger.warn('PaymentsV2', 'receive ack flush failed — cursor holds at the acked prefix:', flushErr);\n return { progressed: false };\n });\n }\n return finish();\n }\n\n private async processEntry(ctx: DrainPass, entry: IncomingDelivery): Promise<void> {\n const { deps, engine, pending, stored, claimable } = ctx;\n const screened = await screen(deps, engine, entry);\n if (screened.kind === 'ack') {\n pending.push(screened.ack);\n // A held-state re-list is the retry after a failed ack: nothing to store,\n // but it still materializes server-side.\n if (screened.ack.disposition === 'claimed') claimable.n += 1;\n return;\n }\n await deps.view.store(screened.record);\n pending.push(claimAck(entry));\n claimable.n += 1;\n const transfer = await announce(deps, entry, screened.record);\n stored.push(transfer);\n deps.emit('transfer:incoming', transfer);\n }\n}\n\nasync function screen(deps: ReceiveDeps, engine: ReceiveEngine, entry: IncomingDelivery): Promise<Screened> {\n const blobBytes = await entry.fetchBlob();\n let token: SphereToken;\n try {\n token = await engine.decodeToken({ tokenId: '', token: blobBytes });\n } catch (err) {\n logger.warn('PaymentsV2', `receive: undecodable blob rejected — ${String(err)}`);\n return { kind: 'ack', ack: rejectAck(entry, 'invalid') };\n }\n const verdict = await engine.verify(token);\n if (!verdict.ok) return { kind: 'ack', ack: rejectAck(entry, 'invalid') };\n if (!engine.isOwnedBy(token, engine.getIdentity().chainPubkey)) {\n return { kind: 'ack', ack: rejectAck(entry, 'not-owned') };\n }\n const keys = await engine.deliveryKeys(blobBytes);\n const held = deps.view.heldState(keys.tokenId);\n if (held === keys.stateHash) return { kind: 'ack', ack: claimAck(entry) };\n if (held !== null && (await engine.isSpent(token))) {\n // #687 gate: a replayed OLDER, already-spent state never displaces the live one.\n return { kind: 'ack', ack: rejectAck(entry, 'invalid') };\n }\n return {\n kind: 'accept',\n record: {\n tokenId: keys.tokenId,\n stateHash: keys.stateHash,\n assets: toAssetAmounts(token),\n ...(isCoinlessEnvelope(token.valueEnvelope) ? { tokenType: token.tokenType } : {}),\n },\n };\n}\n\nasync function announce(\n deps: ReceiveDeps,\n entry: IncomingDelivery,\n record: StoredIncoming\n): Promise<IncomingTransfer> {\n const receivedAt = (deps.now ?? Date.now)();\n try {\n await deps.recordReceived({\n dedupKey: receivedDedupKey(record.tokenId, record.stateHash),\n tokenId: record.tokenId,\n stateHash: record.stateHash,\n assets: record.assets,\n ...(record.tokenType !== undefined ? { tokenType: record.tokenType } : {}),\n ...(entry.senderPubkey !== undefined ? { senderPubkey: entry.senderPubkey } : {}),\n ...(entry.senderNametag !== undefined ? { senderNametag: entry.senderNametag } : {}),\n ...(entry.memo !== undefined ? { memo: entry.memo } : {}),\n receivedAt,\n });\n } catch (err) {\n // §5.9: the history hook never fails the money path.\n logger.debug('PaymentsV2', 'RECEIVED history hook failed (money path unaffected):', err);\n }\n return {\n id: record.tokenId,\n senderPubkey: entry.senderPubkey ?? '',\n ...(entry.senderNametag !== undefined ? { senderNametag: entry.senderNametag } : {}),\n tokens: record.assets.map((asset) => toUiToken(record.tokenId, asset, deps.registry, receivedAt)),\n // #777: named here rather than mapped from assets, which announced an EMPTY list.\n ...(record.tokenType !== undefined\n ? {\n coinless: [\n {\n tokenId: record.tokenId,\n tokenType: record.tokenType,\n stateHash: record.stateHash,\n transferring: false,\n createdAt: receivedAt,\n updatedAt: receivedAt,\n },\n ],\n }\n : {}),\n ...(entry.memo !== undefined ? { memo: entry.memo } : {}),\n receivedAt,\n };\n}\n\n/** Cursor reaches only the last CONSECUTIVE success. progressed=false means nothing settled. */\nasync function flushAcks(\n deps: ReceiveDeps,\n pending: PendingAck[],\n epochOf: () => string\n): Promise<{ progressed: boolean }> {\n if (pending.length === 0) return { progressed: true };\n const before = pending.length;\n let lastAcked: string | null = null;\n try {\n const settled = await settleAcks(deps, pending);\n let i = 0;\n while (i < pending.length && settled.has(pending[i].deliveryId)) {\n lastAcked = pending[i].cursor;\n i += 1;\n }\n // Drop every settled entry, not just the prefix: a later flush must never\n // re-ack one that already settled.\n const stuck = pending.filter((p) => !settled.has(p.deliveryId));\n pending.length = 0;\n pending.push(...stuck);\n } finally {\n if (lastAcked !== null) {\n const record: StreamCursor = { cursor: lastAcked, syncEpoch: epochOf() };\n await deps.kv.set(STORE_KEYS.streamCursor('mailbox'), record);\n }\n }\n return { progressed: pending.length < before };\n}\n\n/** Batched when the port offers it, one at a time otherwise; never reorders `pending`. */\nasync function settleAcks(deps: ReceiveDeps, pending: readonly PendingAck[]): Promise<Set<string>> {\n const batch = deps.delivery.ackBatch?.bind(deps.delivery);\n if (batch === undefined) return settleOneByOne(deps, pending);\n let outcomes: readonly AckOutcome[];\n try {\n outcomes = await batch(pending.map(toAckRequest));\n } catch (err) {\n // A wall a per-entry retry would hit too (429, outage): falling back turns\n // one transient failure into N of them.\n if (isRetryableAckError(err)) throw err;\n logger.warn('PaymentsV2', 'batched mailbox ack failed — settling one at a time:', err);\n return settleOneByOne(deps, pending);\n }\n const settled = new Set(outcomes.filter((o) => o.status === 'settled').map((o) => o.deliveryId));\n const conflicts = outcomes.filter((o) => o.status === 'conflict').map((o) => o.deliveryId);\n if (conflicts.length > 0) await resolveConflicts(deps, pending, conflicts, settled);\n return settled;\n}\n\n/** Settled only once its reject succeeded, so a failed reject holds the cursor. */\nasync function resolveConflicts(\n deps: ReceiveDeps,\n pending: readonly PendingAck[],\n conflicts: readonly string[],\n settled: Set<string>\n): Promise<void> {\n for (const deliveryId of conflicts) {\n const entry = pending.find((p) => p.deliveryId === deliveryId);\n try {\n await rejectStaleClaim(deps, deliveryId, entry?.transferId);\n } catch (err) {\n logger.warn('PaymentsV2', `stale-reject failed for ${deliveryId} — cursor holds here:`, err);\n continue;\n }\n settled.add(deliveryId);\n }\n}\n\n/** §5.7: a stale claim is terminal for discovery, or the entry re-processes forever. */\nasync function rejectStaleClaim(deps: ReceiveDeps, deliveryId: string, transferId?: string): Promise<void> {\n logger.warn('PaymentsV2', `mailbox claim CONFLICT for ${deliveryId} — rejected('other') as stale`);\n await deps.delivery.ack(deliveryId, 'rejected', 'other');\n deps.attention(transferId ?? '', ATTENTION_CLAIM_CONFLICT, deliveryId);\n}\n\n/** Today's loop, in seq order, stopping at the first failure. */\nasync function settleOneByOne(deps: ReceiveDeps, pending: readonly PendingAck[]): Promise<Set<string>> {\n const settled = new Set<string>();\n for (const ack of pending) {\n try {\n await ackOne(deps, ack);\n } catch (err) {\n logger.warn('PaymentsV2', `mailbox ack failed for ${ack.deliveryId} — cursor holds here:`, err);\n break;\n }\n settled.add(ack.deliveryId);\n }\n return settled;\n}\n\nfunction toAckRequest(ack: PendingAck): AckRequest {\n return {\n deliveryId: ack.deliveryId,\n disposition: ack.disposition,\n ...(ack.reason !== undefined ? { reason: ack.reason } : {}),\n };\n}\n\nasync function ackOne(deps: ReceiveDeps, ack: PendingAck): Promise<void> {\n try {\n await deps.delivery.ack(ack.deliveryId, ack.disposition, ack.reason);\n } catch (err) {\n if (ack.disposition !== 'claimed' || !isClaimConflict(err)) throw err;\n await rejectStaleClaim(deps, ack.deliveryId, ack.transferId);\n }\n}\n\nfunction claimAck(entry: IncomingDelivery): PendingAck {\n return {\n deliveryId: entry.deliveryId,\n disposition: 'claimed',\n cursor: entry.cursor,\n ...(entry.transferId !== undefined ? { transferId: entry.transferId } : {}),\n };\n}\n\nfunction rejectAck(entry: IncomingDelivery, reason: 'invalid' | 'not-owned'): PendingAck {\n return { deliveryId: entry.deliveryId, disposition: 'rejected', reason, cursor: entry.cursor };\n}\n\n\nfunction toAssetAmounts(token: SphereToken): IncomingAssetAmount[] {\n return (token.value?.assets ?? []).map((asset) => ({\n coinId: asset.coinId,\n amount: asset.amount.toString(),\n }));\n}\n\nfunction toUiToken(\n tokenId: string,\n asset: IncomingAssetAmount,\n registry: RegistryReader,\n receivedAt: number\n): Token {\n const iconUrl = registry.getIconUrl(asset.coinId);\n return {\n id: tokenId,\n coinId: asset.coinId,\n symbol: registry.getSymbol(asset.coinId),\n name: registry.getName(asset.coinId),\n decimals: registry.getDecimals(asset.coinId),\n ...(iconUrl !== null ? { iconUrl } : {}),\n amount: asset.amount,\n status: 'confirmed',\n createdAt: receivedAt,\n updatedAt: receivedAt,\n lazy: true,\n };\n}\n","// §5.8 of docs/PAYMENTS-V2-DESIGN.md — the incoming payment-request mirror\n// over the wallet-api `?since=` stream, plus the #441 settling journal\n// (verbatim semantics: durable link BEFORE any possibly-committed throw\n// surfaces; direction of error is always PAID-NEVER-RE-PAYABLE).\n\nimport { logger } from '../../../core/logger';\nimport {\n SphereError,\n PartialSendConflictError,\n isPossiblyCommittedSendOutcome,\n} from '../../../core/errors';\nimport type { TransferResult } from '../../../types';\nimport type {\n PaymentRequestStatus,\n PaymentRequestView,\n PaymentsRequestsApi,\n PaymentsV2Events,\n SendRequest,\n} from '../api';\nimport { SerialChain, SingleFlight } from '../async';\nimport { STORE_KEYS, type ScopedKV, type SettlingLink, type StreamCursor } from '../stores';\n\nexport type RequestWireStatus = 'open' | 'paid' | 'declined' | 'expired';\n\nexport interface RequestWire {\n readonly id: string;\n readonly seq: number;\n readonly fromPubkey: string;\n readonly toPubkey: string;\n readonly assets: readonly { readonly coinId: string; readonly amount: string }[];\n readonly memo?: string;\n readonly status: RequestWireStatus;\n readonly transferId: string | null;\n readonly createdAt: string;\n readonly expiresAt?: string;\n}\n\nexport interface RequestsPageWire {\n readonly requests: readonly RequestWire[];\n readonly more: boolean;\n readonly cursor: number | string | null;\n readonly syncEpoch: number;\n}\n\n// Structural subset of WalletApiV2Client — the real client is assignable.\nexport interface RequestsWireClient {\n createPaymentRequest(input: {\n toPubkey: string;\n assets: { coinId: string; amount: string }[];\n memo?: string;\n expiresAt?: string;\n }): Promise<RequestWire>;\n listPaymentRequests(params: { role: 'incoming'; since?: number }): Promise<RequestsPageWire>;\n respondPaymentRequest(\n id: string,\n response: { action: 'paid'; transferId: string } | { action: 'declined' }\n ): Promise<RequestWire>;\n}\n\n// Recipient-ECDH bundle codec (core/delivery-envelope.ts, shared with Delivery).\nexport interface RequestMemoCodec {\n encrypt(peerPubkey: string, bundle: { memo?: string; senderNametag?: string }): string | undefined;\n decrypt(peerPubkey: string, envelope: string): { memo?: string; senderNametag?: string };\n}\n\nexport type RequestsEmit = <K extends 'payment_request:incoming' | 'payment_request:updated'>(\n event: K,\n payload: PaymentsV2Events[K]\n) => void;\n\nexport interface RequestsDeps {\n readonly client: RequestsWireClient;\n readonly kv: ScopedKV;\n readonly ownPubkey: string;\n readonly send: (request: SendRequest) => Promise<TransferResult>;\n readonly resolvePubkey: (identifier: string) => Promise<string | null>;\n // Server `listIntents('aborted')` authority for unaccounted settling links.\n readonly listAbortedTransferIds: () => Promise<string[]>;\n readonly emit: RequestsEmit;\n readonly memo: RequestMemoCodec;\n readonly ownNametag?: () => string | undefined;\n readonly now?: () => number;\n}\n\n// Resume outcomes keyed by transferId (§5.8 reconcile).\nexport interface ResumeOutcomes {\n readonly resumed: readonly string[];\n readonly conflicted: readonly string[];\n readonly open: readonly string[];\n}\n\nconst WIRE_STATUS: Record<RequestWireStatus, PaymentRequestStatus> = {\n open: 'pending',\n paid: 'paid',\n declined: 'rejected',\n expired: 'expired',\n};\n\nconst TERMINAL: ReadonlySet<PaymentRequestStatus> = new Set(['paid', 'rejected', 'expired']);\n\nconst MAX_HYDRATION_PAGES = 100;\nconst CHAIN_PUBKEY_RE = /^0[23][0-9a-fA-F]{64}$/;\nconst CURSOR_KEY = STORE_KEYS.streamCursor('payment_requests');\n\nfunction isConflict409(err: unknown): boolean {\n if (typeof err !== 'object' || err === null) return false;\n const e = err as { status?: unknown; statusCode?: unknown; code?: unknown };\n return e.status === 409 || e.statusCode === 409 || e.code === 'CONFLICT';\n}\n\nexport class Requests implements PaymentsRequestsApi {\n private readonly mirror = new Map<string, PaymentRequestView>();\n private hydrated = false;\n private readonly drainFlight = new SingleFlight<void>();\n\n private journal: Map<string, SettlingLink> | null = null;\n private journalLoad: Promise<void> | null = null;\n private readonly journalChain = new SerialChain();\n\n private readonly payInFlight = new Map<string, Promise<TransferResult>>();\n private readonly reconcileFlight = new SingleFlight<void>();\n\n constructor(private readonly deps: RequestsDeps) {}\n\n private now(): number {\n return this.deps.now?.() ?? Date.now();\n }\n\n // ── settling journal (#441; single-flight load, serialized RMW) ──────────\n\n private ensureJournalLoaded(): Promise<void> {\n return (this.journalLoad ??= (async () => {\n let entries: [string, SettlingLink][] = [];\n try {\n const raw = await this.deps.kv.get<Record<string, SettlingLink>>(STORE_KEYS.settlingLinks);\n if (raw !== null && typeof raw === 'object') entries = Object.entries(raw);\n } catch (err) {\n // Corrupt blob: fail OPEN to empty (never wedge the pump/resume).\n logger.error('PaymentsV2', 'Settling journal unreadable — failing open to empty:', err);\n }\n this.journal = new Map(entries);\n })());\n }\n\n private mutateJournal(fn: (m: Map<string, SettlingLink>) => boolean): Promise<void> {\n return this.journalChain.enqueue(async () => {\n await this.ensureJournalLoaded();\n if (fn(this.journal!)) {\n await this.deps.kv.set(STORE_KEYS.settlingLinks, Object.fromEntries(this.journal!));\n }\n });\n }\n\n /** Idempotent for a same-transferId re-write: committed only ratchets up, createdAt kept. */\n private writeLink(requestId: string, transferId: string, committed: boolean): Promise<void> {\n return this.mutateJournal((m) => {\n const prev = m.get(requestId);\n const same = prev !== undefined && prev.transferId === transferId;\n const next: SettlingLink = {\n requestId,\n transferId,\n committed: committed || (same && prev.committed),\n createdAt: same ? prev.createdAt : this.now(),\n };\n if (same && prev.committed === next.committed) return false;\n m.set(requestId, next);\n return true;\n });\n }\n\n private clearLink(requestId: string): Promise<void> {\n return this.mutateJournal((m) => m.delete(requestId));\n }\n\n // ── incoming stream (gap-free ?since= upsert-by-id) ──────────────────────\n\n drainIncoming(): Promise<void> {\n return this.drainFlight.run(() => this.doDrain());\n }\n\n private async doDrain(): Promise<void> {\n // Journal must be in memory BEFORE any wire surfaces (settling hold).\n await this.ensureJournalLoaded();\n const persisted = await this.deps.kv.get<StreamCursor>(CURSOR_KEY);\n\n if (!this.hydrated) {\n // Fresh instance: the mirror is memory-only, rebuild ALL current state\n // from since=0 (open AND resolved), bounded pages; id-dedup absorbs replays.\n let page = await this.deps.client.listPaymentRequests({ role: 'incoming', since: 0 });\n for (let i = 0; i < MAX_HYDRATION_PAGES; i++) {\n for (const wire of page.requests) this.surface(wire);\n if (!page.more || typeof page.cursor !== 'number') break;\n page = await this.deps.client.listPaymentRequests({ role: 'incoming', since: page.cursor });\n }\n this.hydrated = true;\n }\n\n let since = typeof persisted?.cursor === 'number' ? persisted.cursor : 0;\n let page = await this.deps.client.listPaymentRequests({ role: 'incoming', since });\n if (persisted !== null && String(page.syncEpoch) !== persisted.syncEpoch) {\n since = 0; // epoch changed (server restore) — cursor continuity is void\n page = await this.deps.client.listPaymentRequests({ role: 'incoming', since: 0 });\n }\n for (;;) {\n for (const wire of page.requests) this.surface(wire);\n const record: StreamCursor = {\n cursor: typeof page.cursor === 'number' ? page.cursor : since,\n syncEpoch: String(page.syncEpoch),\n };\n await this.deps.kv.set(CURSOR_KEY, record);\n if (!page.more || typeof page.cursor !== 'number') break;\n since = page.cursor;\n page = await this.deps.client.listPaymentRequests({ role: 'incoming', since });\n }\n }\n\n private surface(wire: RequestWire): void {\n if (wire.toPubkey !== this.deps.ownPubkey) {\n logger.warn('PaymentsV2', `payment request ${wire.id.slice(0, 12)}… addressed to a different owner — dropped`);\n return;\n }\n\n let status = WIRE_STATUS[wire.status];\n const link = this.journal?.get(wire.id);\n if (link !== undefined) {\n if (wire.status === 'open') {\n status = 'settling'; // live link holds the request non-payable\n } else {\n // Server already resolved — the deferred tell landed elsewhere; drop the stale link.\n void this.clearLink(wire.id).catch((err) =>\n logger.warn('PaymentsV2', `failed to clear stale settling link for ${wire.id}:`, err)\n );\n }\n }\n\n const existing = this.mirror.get(wire.id);\n if (existing !== undefined) {\n // Upsert: advance INTO a terminal state, never out of one; never re-notify.\n if (TERMINAL.has(status) && !TERMINAL.has(existing.status)) this.setStatus(wire.id, status);\n return;\n }\n\n const bundle = this.decryptMemo(wire);\n const view: PaymentRequestView = {\n id: wire.id,\n requestId: wire.id,\n senderPubkey: wire.fromPubkey,\n ...(bundle.senderNametag !== undefined ? { senderNametag: bundle.senderNametag } : {}),\n amount: wire.assets[0]?.amount ?? '0',\n coinId: wire.assets[0]?.coinId ?? '',\n ...(bundle.memo !== undefined ? { message: bundle.memo } : {}),\n timestamp: Date.parse(wire.createdAt),\n status,\n };\n this.mirror.set(wire.id, view);\n if (status === 'pending') this.deps.emit('payment_request:incoming', { ...view });\n }\n\n private decryptMemo(wire: RequestWire): { memo?: string; senderNametag?: string } {\n if (wire.memo === undefined) return {};\n try {\n return this.deps.memo.decrypt(wire.fromPubkey, wire.memo);\n } catch {\n logger.debug('PaymentsV2', `payment request ${wire.id.slice(0, 12)}… memo not decryptable here`);\n return {};\n }\n }\n\n private setStatus(id: string, status: PaymentRequestStatus): void {\n const entry = this.mirror.get(id);\n if (entry === undefined || entry.status === status) return;\n entry.status = status;\n this.deps.emit('payment_request:updated', { id, status });\n }\n\n // ── public surface (PaymentsRequestsApi) ─────────────────────────────────\n\n list(): PaymentRequestView[] {\n const views = [...this.mirror.values()].map((entry) => ({\n ...entry,\n // A live settling link is NEVER payable, whatever the mirror says.\n status:\n entry.status === 'pending' && this.journal?.has(entry.id) ? ('settling' as const) : entry.status,\n }));\n return views.sort((a, b) => b.timestamp - a.timestamp || (a.id < b.id ? -1 : 1));\n }\n\n async create(\n to: string,\n terms: { coinId: string; amount: string; memo?: string }\n ): Promise<{ success: boolean; requestId?: string; error?: string }> {\n try {\n const toPubkey = CHAIN_PUBKEY_RE.test(to) ? to.toLowerCase() : await this.deps.resolvePubkey(to);\n if (toPubkey === null || toPubkey === undefined) {\n return { success: false, error: `Recipient ${to} has no published chain pubkey` };\n }\n const amount = BigInt(terms.amount);\n if (amount <= 0n) return { success: false, error: 'Amount must be a positive base-unit decimal string' };\n const senderNametag = this.deps.ownNametag?.();\n const envelope = this.deps.memo.encrypt(toPubkey, {\n ...(terms.memo !== undefined ? { memo: terms.memo } : {}),\n ...(senderNametag !== undefined ? { senderNametag } : {}),\n });\n const wire = await this.deps.client.createPaymentRequest({\n toPubkey,\n assets: [{ coinId: terms.coinId, amount: amount.toString() }],\n ...(envelope !== undefined ? { memo: envelope } : {}),\n });\n return { success: true, requestId: wire.id };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n }\n\n pay(id: string): Promise<TransferResult> {\n // Per-request single-flight: a double-tap coalesces onto ONE send.\n const inFlight = this.payInFlight.get(id);\n if (inFlight !== undefined) return inFlight;\n const run = this.payInner(id).finally(() => {\n this.payInFlight.delete(id);\n });\n this.payInFlight.set(id, run);\n return run;\n }\n\n private async payInner(id: string): Promise<TransferResult> {\n await this.ensureJournalLoaded();\n const entry = this.mirror.get(id);\n if (entry === undefined) throw new SphereError(`Payment request not found: ${id}`, 'VALIDATION_ERROR');\n if (entry.status !== 'pending' || this.journal!.has(id)) {\n throw new SphereError(`Payment request is not payable: ${entry.status}`, 'VALIDATION_ERROR');\n }\n\n let result: TransferResult;\n try {\n result = await this.deps.send({\n recipient: entry.senderPubkey,\n amount: entry.amount,\n coinId: entry.coinId,\n ...(entry.message !== undefined ? { memo: entry.message } : {}),\n });\n } catch (error) {\n if (isPossiblyCommittedSendOutcome(error)) {\n const transferId =\n error instanceof SphereError && error.transferId !== undefined ? error.transferId : undefined;\n if (transferId !== undefined) {\n // Outcome unknown — link + 'settling', respond deferred to reconcile.\n const committed = error instanceof PartialSendConflictError;\n await this.settle(id, transferId, { committed, respond: false });\n } else {\n logger.error('PaymentsV2', `possibly-committed send for ${id} carried no transferId — paid (fail-closed)`);\n this.setStatus(id, 'paid');\n }\n } else {\n // Proven clean pre-commit failure — removal cause (b): payable, no link.\n await this.revertPayable(id);\n }\n throw error;\n }\n\n await this.settle(id, result.id, { committed: true, respond: true });\n return result;\n }\n\n /**\n * THE settlement invariant (#441 + the failed-respond P1): a settling link is\n * removed ONLY by (a) a CONFIRMED paid respond — a 2xx, or the 409\n * already-resolved absorb — or (b) a proven clean pre-commit failure\n * (revertPayable). Nothing else removes one: not a network error, not a 5xx,\n * not a reload. Every path that binds a request to a transfer outcome funnels\n * through here — pay()'s clean success (respond now), pay()'s\n * possibly-committed throw (respond deferred), and reconcile's deferred arms\n * — so a failed respond always leaves the link + 'settling' and the next\n * reconcile pass (the committed-link override) retries the respond.\n */\n private async settle(\n requestId: string,\n transferId: string,\n opts: { committed: boolean; respond: boolean }\n ): Promise<void> {\n // #441 — order is load-bearing: durable link BEFORE any flip, respond, or\n // rethrow. A crash in between leaves the link, so reload re-applies\n // 'settling', never re-payable.\n let journalDown = false;\n try {\n await this.writeLink(requestId, transferId, opts.committed);\n } catch (err) {\n if (!opts.respond) throw err; // deferred-respond arm: the link IS the outcome\n // Respond-now arm fails CLOSED on a dead journal: the server record\n // becomes the anchor — never leave a completed send re-payable silently.\n journalDown = true;\n logger.error('PaymentsV2', `settling link write failed for ${requestId} — responding fail-closed:`, err);\n }\n if (!(opts.respond && (await this.respondPaid(requestId, transferId)))) {\n this.setStatus(requestId, journalDown ? 'paid' : 'settling');\n return;\n }\n // A failed removal is safe (paid-never-re-payable holds); surface() drops\n // the stale link once the wire shows the terminal state.\n if (!journalDown) await this.clearLink(requestId).catch(() => undefined);\n this.setStatus(requestId, 'paid');\n }\n\n /** 'paid' respond leg: 409 = already resolved = idempotent success; other errors defer. */\n private async respondPaid(id: string, transferId: string): Promise<boolean> {\n try {\n await this.deps.client.respondPaymentRequest(id, { action: 'paid', transferId });\n return true;\n } catch (err) {\n if (isConflict409(err)) return true;\n logger.warn('PaymentsV2', `paid respond failed for ${id} (deferred):`, err);\n return false;\n }\n }\n\n async decline(id: string): Promise<void> {\n const entry = this.mirror.get(id);\n if (entry === undefined) throw new SphereError(`Payment request not found: ${id}`, 'VALIDATION_ERROR');\n // A refused decline must never look like success — server 403/409 PROPAGATE.\n await this.deps.client.respondPaymentRequest(id, { action: 'declined' });\n this.setStatus(id, 'rejected');\n }\n\n dismissProcessed(): void {\n for (const [id, entry] of this.mirror) {\n if (TERMINAL.has(entry.status)) this.mirror.delete(id);\n }\n }\n\n // ── reconcile (#441, fed by resume outcomes) ─────────────────────────────\n\n reconcile(outcomes: ResumeOutcomes): Promise<void> {\n // Single-flight (§7: no sampled *InFlight booleans) — a concurrent call\n // coalesces onto the running pass instead of racing the journal.\n return this.reconcileFlight.run(() => this.doReconcile(outcomes));\n }\n\n private async doReconcile(outcomes: ResumeOutcomes): Promise<void> {\n await this.ensureJournalLoaded();\n if (this.journal!.size === 0) return;\n const resumed = new Set(outcomes.resumed);\n const conflicted = new Set(outcomes.conflicted);\n const open = new Set(outcomes.open);\n let aborted: Set<string> | null = null;\n\n for (const [requestId, link] of [...this.journal!]) {\n if (link.committed || resumed.has(link.transferId)) {\n // Value left the wallet (or the transfer completed) → deferred paid.\n await this.resolvePaid(requestId, link);\n } else if (conflicted.has(link.transferId)) {\n await this.revertPayable(requestId);\n } else if (open.has(link.transferId)) {\n // Still settling — keep the link, retry next session.\n } else {\n aborted = await this.reconcileUnaccounted(requestId, link, aborted);\n }\n }\n }\n\n // Unaccounted link: consult the server aborted authority (lazy, memoized);\n // a probe failure defers the link to the next session.\n private async reconcileUnaccounted(\n requestId: string,\n link: SettlingLink,\n aborted: Set<string> | null\n ): Promise<Set<string> | null> {\n try {\n aborted ??= new Set(await this.deps.listAbortedTransferIds());\n if (aborted.has(link.transferId)) await this.revertPayable(requestId);\n else await this.resolvePaid(requestId, link); // PAID-NEVER-RE-PAYABLE\n } catch (err) {\n logger.warn('PaymentsV2', `aborted-intent probe failed — ${requestId} deferred:`, err);\n }\n return aborted;\n }\n\n /** Deferred paid: the ONE settlement path again — a failed respond keeps the link. */\n private resolvePaid(requestId: string, link: SettlingLink): Promise<void> {\n return this.settle(requestId, link.transferId, { committed: link.committed, respond: true });\n }\n\n /** Removal cause (b): a PROVEN clean outcome (pre-commit failure / server-aborted). */\n private async revertPayable(requestId: string): Promise<void> {\n await this.clearLink(requestId);\n this.setStatus(requestId, 'pending');\n }\n}\n","// §5.6/§6 durable machine stores over ScopedKV: content-idempotent saves keyed\n// by (transferId, opIndex), one serialized RMW tail-chain per (kv, store key),\n// and the bounded delivery replay (#621) with 429 deferrals outside the poison\n// budget (#517).\n\nimport { hexToBytes } from '../../../core/crypto';\nimport { SerialChain, SingleFlight } from '../async';\nimport type { DeliveryPort } from '../ports';\nimport {\n STORE_KEYS,\n type DeliveryJournalEntry,\n type IntentBackstopEntry,\n type MintJournalEntry,\n type NftMintJournalEntry,\n type ScopedKV,\n type ShortfallEntry,\n} from '../stores';\n\nexport const MAX_DELIVERY_ATTEMPTS = 6;\nexport const RATE_LIMIT_DEFER_MS = 30_000;\n\nexport const ATTENTION_DELIVERY_DEFERRED = 'delivery:deferred';\nexport const ATTENTION_DELIVERY_UNDELIVERABLE = 'delivery:undeliverable';\nexport const ATTENTION_CHECKPOINT_STUCK = 'split:checkpoint-stuck';\nexport const ATTENTION_SYNC_PENDING = 'sync:pending';\n\nexport type AttentionEmitter = (transferId: string, code: string, detail?: string) => void;\n\ninterface WireErrorShape {\n status?: unknown;\n statusCode?: unknown;\n code?: unknown;\n}\n\nfunction wireShape(err: unknown): WireErrorShape | null {\n return err !== null && typeof err === 'object' ? (err as WireErrorShape) : null;\n}\n\nexport function isRateLimited(err: unknown): boolean {\n const e = wireShape(err);\n if (e === null) return false;\n return e.status === 429 || e.statusCode === 429 || e.code === 'QUOTA_EXCEEDED' || e.code === 'RATE_LIMITED';\n}\n\nexport function isValidationReject(err: unknown): boolean {\n const e = wireShape(err);\n if (e === null) return false;\n return e.status === 422 || e.statusCode === 422 || e.code === 'VALIDATION' || e.code === 'VALIDATION_FAILED';\n}\n\n/**\n * Duck-typed `WalletApiHttpError.retryAfter` (milliseconds) — modules never\n * import from impl/, so the heartbeat honors the header structurally.\n */\nexport function retryAfterMsOf(err: unknown): number | null {\n const retryAfter =\n err !== null && typeof err === 'object' ? (err as { retryAfter?: unknown }).retryAfter : undefined;\n return typeof retryAfter === 'number' && Number.isFinite(retryAfter) && retryAfter >= 0 ? retryAfter : null;\n}\n\n// Registered per (kv, store key) so EVERY store instance over the same\n// ScopedKV serializes its read-modify-writes with every other instance.\nconst chainRegistry = new WeakMap<ScopedKV, Map<string, SerialChain>>();\nconst replayRegistry = new WeakMap<ScopedKV, Map<string, SingleFlight<ReplayStats>>>();\n\nfunction registryFor<T>(\n registry: WeakMap<ScopedKV, Map<string, T>>,\n kv: ScopedKV,\n storeKey: string,\n make: () => T\n): T {\n let perKv = registry.get(kv);\n if (perKv === undefined) {\n perKv = new Map();\n registry.set(kv, perKv);\n }\n let entry = perKv.get(storeKey);\n if (entry === undefined) {\n entry = make();\n perKv.set(storeKey, entry);\n }\n return entry;\n}\n\nexport class ListStore<T> {\n constructor(\n protected readonly kv: ScopedKV,\n protected readonly storeKey: string,\n protected readonly keyOf: (entry: T) => string\n ) {}\n\n list(): Promise<T[]> {\n return this.chained(() => this.read());\n }\n\n getByKey(key: string): Promise<T | undefined> {\n return this.chained(async () => (await this.read()).find((e) => this.keyOf(e) === key));\n }\n\n /** Upsert; a byte-identical re-save is a no-op (content-idempotent). */\n upsert(entry: T): Promise<void> {\n return this.mutate((list) => {\n const key = this.keyOf(entry);\n const at = list.findIndex((e) => this.keyOf(e) === key);\n if (at >= 0 && JSON.stringify(list[at]) === JSON.stringify(entry)) return { result: undefined };\n const next = [...list];\n if (at >= 0) next[at] = entry;\n else next.push(entry);\n return { list: next, result: undefined };\n });\n }\n\n removeByKey(key: string): Promise<void> {\n return this.mutate((list) => {\n const next = list.filter((e) => this.keyOf(e) !== key);\n return next.length === list.length ? { result: undefined } : { list: next, result: undefined };\n });\n }\n\n patch(key: string, fn: (entry: T) => T): Promise<T | undefined> {\n return this.mutate((list) => {\n const at = list.findIndex((e) => this.keyOf(e) === key);\n if (at < 0) return { result: undefined };\n const next = [...list];\n next[at] = fn(next[at]);\n return { list: next, result: next[at] };\n });\n }\n\n protected mutate<R>(fn: (list: T[]) => { list?: T[]; result: R }): Promise<R> {\n return this.chained(async () => {\n const { list, result } = fn(await this.read());\n if (list !== undefined) await this.kv.set(this.storeKey, list);\n return result;\n });\n }\n\n protected chained<R>(run: () => Promise<R>): Promise<R> {\n return registryFor(chainRegistry, this.kv, this.storeKey, () => new SerialChain()).enqueue(run);\n }\n\n private async read(): Promise<T[]> {\n return (await this.kv.get<T[]>(this.storeKey)) ?? [];\n }\n}\n\nexport interface ReplayStats {\n delivered: number;\n deferred: number;\n failed: number;\n poisoned: number;\n}\n\nexport interface ReplayDeps {\n readonly delivery: DeliveryPort;\n readonly now: () => number;\n readonly attention: AttentionEmitter;\n /** sphere#487 — see {@link senderNametagOption}. */\n readonly ownNametag?: () => string | undefined;\n}\n\n/**\n * sphere#487: the recipient learns the sender's Unicity ID from the delivery\n * envelope and NOWHERE else (no lookup, no second rail) — so every deliver\n * carries it, or the recipient renders \"Someone\".\n *\n * Read LIVE at deliver time, never snapshotted into the plan or the journal:\n * registration (or an address switch) can land between a send and the replay\n * of one of its deferred legs, and the wallet's name today is the honest one.\n * A wallet with no Unicity ID omits the field — `''` is not a name.\n *\n * A throwing getter degrades to no name: by the time a leg is delivered its\n * token is already CERTIFIED, so raising here would replay the journaled blob\n * into the poison budget and end at `delivery:undeliverable`. A display name\n * must never cost a settled transfer its delivery.\n */\nexport function senderNametagOption(\n ownNametag?: () => string | undefined\n): { senderNametag?: string } {\n let nametag: string | undefined;\n try {\n nametag = ownNametag?.();\n } catch {\n return {};\n }\n return nametag === undefined || nametag === '' ? {} : { senderNametag: nametag };\n}\n\nexport class DeliveryJournal extends ListStore<DeliveryJournalEntry> {\n constructor(kv: ScopedKV) {\n super(kv, STORE_KEYS.deliveryJournal, (e) => `${e.transferId}:${String(e.opIndex)}`);\n }\n\n async byTransfer(transferId: string): Promise<Map<number, DeliveryJournalEntry>> {\n const mine = (await this.list()).filter((e) => e.transferId === transferId);\n return new Map(mine.map((e) => [e.opIndex, e]));\n }\n\n remove(transferId: string, opIndex: number): Promise<void> {\n return this.removeByKey(`${transferId}:${String(opIndex)}`);\n }\n\n /** 429 deferral: pushes deferredUntil out WITHOUT touching the poison budget. */\n async defer(transferId: string, opIndex: number, until: number): Promise<void> {\n await this.patch(`${transferId}:${String(opIndex)}`, (e) => ({ ...e, deferredUntil: until }));\n }\n\n /** Genuine failure: attempts++, poisoning (undeliverable) at the budget. */\n async recordFailure(transferId: string, opIndex: number, attention: AttentionEmitter): Promise<boolean> {\n const updated = await this.patch(`${transferId}:${String(opIndex)}`, (e) => {\n if (e.undeliverable === true) return e;\n const attempts = e.attempts + 1;\n return attempts >= MAX_DELIVERY_ATTEMPTS ? { ...e, attempts, undeliverable: true } : { ...e, attempts };\n });\n const poisoned = updated?.undeliverable === true;\n if (poisoned && updated.attempts === MAX_DELIVERY_ATTEMPTS) {\n attention(transferId, ATTENTION_DELIVERY_UNDELIVERABLE, `op ${String(opIndex)} after ${String(updated.attempts)} attempts`);\n }\n return poisoned;\n }\n\n /** Single-flight per (kv, store); concurrent calls coalesce onto one pass. */\n replay(deps: ReplayDeps): Promise<ReplayStats> {\n return registryFor(replayRegistry, this.kv, this.storeKey, () => new SingleFlight<ReplayStats>()).run(\n () => this.replayOnce(deps)\n );\n }\n\n private async replayOnce(deps: ReplayDeps): Promise<ReplayStats> {\n const stats: ReplayStats = { delivered: 0, deferred: 0, failed: 0, poisoned: 0 };\n for (const entry of await this.list()) {\n if (entry.undeliverable === true) continue;\n if (entry.deferredUntil !== undefined && entry.deferredUntil > deps.now()) {\n stats.deferred += 1;\n continue;\n }\n await this.replayEntry(entry, deps, stats);\n }\n return stats;\n }\n\n private async replayEntry(entry: DeliveryJournalEntry, deps: ReplayDeps, stats: ReplayStats): Promise<void> {\n try {\n await deps.delivery.deliver(entry.recipientPubkey, hexToBytes(entry.blobHex), {\n transferId: entry.transferId,\n ...(entry.memo !== undefined ? { memo: entry.memo } : {}),\n ...senderNametagOption(deps.ownNametag),\n });\n await this.remove(entry.transferId, entry.opIndex);\n stats.delivered += 1;\n } catch (err) {\n if (isRateLimited(err)) {\n await this.defer(entry.transferId, entry.opIndex, deps.now() + RATE_LIMIT_DEFER_MS);\n deps.attention(entry.transferId, ATTENTION_DELIVERY_DEFERRED);\n stats.deferred += 1;\n } else if (await this.recordFailure(entry.transferId, entry.opIndex, deps.attention)) {\n stats.poisoned += 1;\n } else {\n stats.failed += 1;\n }\n }\n }\n}\n\nexport interface MachineStores {\n readonly backstop: ListStore<IntentBackstopEntry>;\n readonly deliveryJournal: DeliveryJournal;\n readonly mintJournal: ListStore<MintJournalEntry>;\n readonly nftMintJournal: ListStore<NftMintJournalEntry>;\n readonly shortfalls: ListStore<ShortfallEntry>;\n}\n\nexport function createMachineStores(kv: ScopedKV): MachineStores {\n return {\n backstop: new ListStore<IntentBackstopEntry>(kv, STORE_KEYS.intentBackstop, (e) => e.transferId),\n deliveryJournal: new DeliveryJournal(kv),\n mintJournal: new ListStore<MintJournalEntry>(kv, STORE_KEYS.mintJournal, (e) => e.mintId),\n nftMintJournal: new ListStore<NftMintJournalEntry>(kv, STORE_KEYS.nftMintJournal, (e) => e.mintId),\n shortfalls: new ListStore<ShortfallEntry>(kv, STORE_KEYS.shortfalls, (e) => e.transferId),\n };\n}\n","/**\n * token-engine/errors.ts — the engine's typed error surface (Part E.2).\n */\n\nimport { SphereError } from '../core/errors';\n\n/**\n * The source state was already consumed by a *different* transaction — the\n * fetched inclusion proof does not match the rebuilt transaction\n * (`TRANSACTION_HASH_MISMATCH`). Typically the owner's other device raced the\n * same source under a different `transferId` (ARCHITECTURE §7).\n *\n * This is a lost race, **not** an interrupted resume: the engine never applies\n * the foreign proof and never retries. The caller's recovery is to abort the\n * intent, drop the lost source from its plan, and re-plan the remainder under\n * a NEW `transferId` (never reusing the old realization) — sdk-changes E.2.\n */\nexport class TransferConflictError extends SphereError {\n /**\n * #625: the source token id (the caller's id, e.g. `v2_<genesis>`) whose state was already spent.\n * Set by PaymentsModule at the engine call site so the self-healing retry can demote it and re-plan.\n */\n conflictedSourceId?: string;\n\n constructor(message: string, cause?: unknown) {\n super(message, 'TRANSFER_CONFLICT', cause);\n this.name = 'TransferConflictError';\n }\n}\n\n/**\n * The op's certification is INDETERMINATE: the submit was accepted (`SUCCESS`)\n * or failed ambiguously (a thrown submit POST that may have been processed\n * server-side), and the inclusion-proof fetch/verify returned NO verdict — a\n * transient network/timeout error, NOT a matching proof and NOT\n * `TRANSACTION_HASH_MISMATCH`. The source's spend MAY already be on-chain under\n * THIS `transferId`.\n *\n * Unlike {@link TransferConflictError} (a foreign tx won — abort + re-plan under\n * a NEW id), the caller MUST keep the intent OPEN: resume re-derives the\n * byte-identical transaction from `(seed, transferId, opIndex)` and recovers the\n * certified proof + recipient blob, or records the spend if a foreign tx won the\n * race — never a second on-chain spend (sdk-changes E.2/E.3, #631).\n */\nexport class ProofUnconfirmedError extends SphereError {\n readonly mayHaveCertified = true as const;\n\n constructor(message: string, cause?: unknown) {\n super(message, 'CERTIFICATION_UNCONFIRMED', cause);\n this.name = 'ProofUnconfirmedError';\n }\n}\n\n/**\n * A split's burn certified but its checkpoint (sdk-changes E.4, sphere-sdk#501) could NOT be\n * durably persisted — the `SplitCheckpointStore.put` rejected (network / 5xx / timeout / quota) —\n * so NO mint leg was submitted. The burn is on-chain (funds in-flight, not lost); the outputs are\n * fully recoverable on resume.\n *\n * Keep-open family (like {@link ProofUnconfirmedError}): the caller MUST keep the intent OPEN and\n * resume under the SAME `transferId` — the next attempt re-derives the byte-identical burn,\n * re-persists the checkpoint (content-idempotent), and mints. NEVER abort.\n */\nexport class CheckpointPersistFailedError extends SphereError {\n readonly mayHaveCertified = true as const;\n\n constructor(message: string, cause?: unknown) {\n super(message, 'CHECKPOINT_PERSIST_FAILED', cause);\n this.name = 'CheckpointPersistFailedError';\n }\n}\n\n/**\n * A split cannot be rebuilt from its checkpoint, in a way that is NOT a lost race: either a mint\n * leaf is already certified on-chain but no stored bytes reproduce its certified transactionHash\n * (server data loss / withholding, or a pre-E.4 legacy intent), or a stored checkpoint fails its\n * byte-binding checks (the re-derived burn tx ≠ the stored bytes — cross-version derivation drift\n * — or a corrupt stored proof, or a burnt-token re-encode mismatch).\n *\n * Distinct from {@link TransferConflictError}: a split-mint stateId is HKDF-derived from\n * `(seed, transferId)`, so only a seed-holder under THIS `transferId` can have certified it — this\n * is never a foreign spend. Keep-open, alert loudly: the caller MUST NOT abort, NOT complete, and\n * NOT record the source as foreign-spent (sdk-changes E.4).\n */\nexport class SplitCheckpointLostError extends SphereError {\n constructor(message: string, cause?: unknown) {\n super(message, 'SPLIT_CHECKPOINT_LOST', cause);\n this.name = 'SplitCheckpointLostError';\n }\n}\n\n/**\n * A stored split checkpoint (sdk-changes E.4) is authentic and byte-bound to the re-derived burn\n * transaction, but its inclusion proof no longer verifies against the CURRENT trust base\n * (`INVALID_TRUSTBASE`) — a validator-set / quorum rotation while the intent was open. The bytes\n * are NOT wrong; re-burning would strand the certified split, so the engine never falls through to\n * a re-burn.\n *\n * Keep-open, distinct signal: the operational remedy is to drain open split intents BEFORE a\n * validator rotation (the SDK has no epoch map — single-epoch trust base, ARCHITECTURE §8.2/§19).\n */\nexport class CheckpointTrustbaseMismatchError extends SphereError {\n constructor(message: string, cause?: unknown) {\n super(message, 'CHECKPOINT_TRUSTBASE_MISMATCH', cause);\n this.name = 'CheckpointTrustbaseMismatchError';\n }\n}\n","// §5.5/§5.6 of docs/PAYMENTS-V2-DESIGN.md — ONE machine for send AND resume.\n// Persisted state is the server intent + the E.4 checkpoint + the delivery\n// journal; every transition is pinned by tests/unit/payments-v2/machine*.test.ts.\n\nimport { sha256 } from '@noble/hashes/sha2.js';\n\nimport { bytesToHex, hexToBytes } from '../../../core/crypto';\nimport { SphereError } from '../../../core/errors';\nimport type { TransferResult } from '../../../types';\nimport type { ITokenEngine, SplitCheckpointStore } from '../../../token-engine/engine';\nimport type { SphereToken } from '../../../token-engine/types';\nimport {\n CheckpointPersistFailedError,\n CheckpointTrustbaseMismatchError,\n ProofUnconfirmedError,\n SplitCheckpointLostError,\n TransferConflictError,\n} from '../../../token-engine/errors';\nimport type { DeliverOptions, DeliveryPort, StoragePort } from '../ports';\nimport { coinIdOf, splitOf } from './payload-view';\nimport type { DeliveryJournalEntry, ScopedKV, ShortfallEntry } from '../stores';\nimport type { IntentPayload, OpOutcome, OutcomeClass, PlannedOp } from './types';\nimport {\n ATTENTION_DELIVERY_DEFERRED,\n ATTENTION_SYNC_PENDING,\n RATE_LIMIT_DEFER_MS,\n createMachineStores,\n isRateLimited,\n isValidationReject,\n senderNametagOption,\n type AttentionEmitter,\n type MachineStores,\n} from './journal';\n\n// #746: measured live, a 4-op wave cost the same as an 8-op wave — at 8 we were\n// latency-bound, so each wave paid a proof round-trip and the barrier multiplied\n// it. Safe to widen only because a rate-limited submit now retries instead of\n// burning a full deadline per op (proof-wait.retryTransient).\nconst CERTIFY_WIDTH = 20;\n\nconst KEEP_OPEN_CODES = new Set([\n 'CERTIFICATION_UNCONFIRMED',\n 'CHECKPOINT_PERSIST_FAILED',\n 'SPLIT_CHECKPOINT_LOST',\n 'CHECKPOINT_TRUSTBASE_MISMATCH',\n]);\n\nexport interface IntentApi {\n put(transferId: string, envelope: string, requiresSeedClose: boolean): Promise<void>;\n listOpen(): Promise<{ transferId: string; payload: string; createdAt: string }[]>;\n abort(transferId: string): Promise<void>;\n complete(transferId: string, signature?: string): Promise<void>;\n}\n\nexport interface MachineDeps {\n /** Snapshot taken once per operation entry (the setEngine hot-swap seam). */\n engine: () => ITokenEngine;\n storage: StoragePort;\n delivery: DeliveryPort;\n intents: IntentApi;\n checkpointStore: SplitCheckpointStore;\n kv: ScopedKV;\n encryptPayload: (p: IntentPayload) => Promise<string>;\n decryptPayload: (envelope: string) => Promise<unknown>;\n signComplete: (transferId: string) => Promise<string>;\n ownPubkey: Uint8Array;\n /** sphere#487: the wallet's own Unicity ID — see {@link senderNametagOption}. */\n ownNametag?: () => string | undefined;\n emit: (event: string, payload: unknown) => void;\n now: () => number;\n /** `committedAmount` = what SETTLED (the certified recipient blobs' value), never the plan. */\n recordHistory?: (info: {\n transferId: string;\n payload: IntentPayload;\n phase: 'sent' | 'resumed';\n committedAmount: string;\n /** A WHOLE-token spend moves the token, not an amount: its real assets, [] when coinless. */\n committedAssets?: readonly { coinId: string; amount: string }[];\n }) => Promise<void>;\n}\n\nexport interface MachinePlan {\n transferId: string;\n recipientPubkey: string;\n payload: IntentPayload;\n ops: PlannedOp[];\n /** Source SphereTokens keyed by tokenId — materialized (blob-fetched) pre-run. */\n sources: Map<string, SphereToken>;\n memo?: string;\n}\n\nexport interface RehydratedIntent {\n transferId: string;\n payload: IntentPayload;\n sources: Map<string, SphereToken>;\n journaled: Map<number, DeliveryJournalEntry>;\n}\n\nexport interface ResumeIntentOutcome {\n deliveryPending: boolean;\n /** Non-null when ≥1 leg delivered but a later leg conflicted (#677/#690). */\n partial: ShortfallEntry | null;\n}\n\ninterface CertifyCtx {\n transferId: string;\n recipientPubkey: string;\n payload: IntentPayload;\n memo?: string;\n}\n\ninterface ResumeConflict {\n op: PlannedOp;\n error: unknown;\n amount: bigint;\n}\n\n/** opIndex is plan-derived: the op's position in direct[], split at direct.length (E.1). */\nexport function buildOps(payload: IntentPayload): PlannedOp[] {\n const ops: PlannedOp[] = payload.direct.map((sourceTokenId, opIndex) => ({\n kind: 'direct',\n opIndex,\n sourceTokenId,\n deliveredAmount: 0n,\n }));\n if (payload.split !== undefined) {\n ops.push({\n kind: 'split',\n opIndex: payload.direct.length,\n sourceTokenId: payload.split.tokenId,\n deliveredAmount: BigInt(payload.split.splitAmount),\n });\n }\n return ops;\n}\n\nexport function classifyError(e: unknown): OutcomeClass {\n if (\n e instanceof ProofUnconfirmedError ||\n e instanceof SplitCheckpointLostError ||\n e instanceof CheckpointPersistFailedError ||\n e instanceof CheckpointTrustbaseMismatchError\n ) {\n return 'keep-open';\n }\n if (e instanceof TransferConflictError) return 'conflict';\n const coded = e !== null && typeof e === 'object' ? (e as { code?: unknown; mayHaveCertified?: unknown }) : null;\n if (coded !== null) {\n if (coded.mayHaveCertified === true) return 'keep-open';\n if (typeof coded.code === 'string' && KEEP_OPEN_CODES.has(coded.code)) return 'keep-open';\n if (coded.code === 'TRANSFER_CONFLICT') return 'conflict';\n }\n return 'other';\n}\n\n/** Precedence keep-open > conflict > other; committed = certified regardless of error (#441). */\n/** Settlement tolerates conflicts and nothing else; `cls` cannot say that, because\n * it ranks conflict ABOVE 'other' and so hides an ordinary failure (#745 review). */\nexport function firstNonConflictError(outcomes: OpOutcome[]): OpOutcome | undefined {\n return outcomes.find((o) => o.error !== undefined && classifyError(o.error) !== 'conflict');\n}\n\nexport function summarize(outcomes: OpOutcome[]): {\n committed: OpOutcome[];\n cls: OutcomeClass | null;\n firstError: unknown;\n} {\n const committed = outcomes.filter((o) => o.certified);\n const rank: Record<OutcomeClass, number> = { 'keep-open': 3, conflict: 2, other: 1 };\n let cls: OutcomeClass | null = null;\n let firstError: unknown;\n for (const o of outcomes) {\n if (o.error === undefined) continue;\n const c = classifyError(o.error);\n if (cls === null || rank[c] > rank[cls]) {\n cls = c;\n firstError = o.error;\n }\n }\n return { committed, cls, firstError };\n}\n\nexport class TransferMachine {\n private readonly stores: MachineStores;\n\n constructor(private readonly deps: MachineDeps) {\n this.stores = createMachineStores(deps.kv);\n }\n\n // ── send path ─────────────────────────────────────────────────────────────\n async run(plan: MachinePlan): Promise<{ committed: OpOutcome[]; deliveryPending: boolean }> {\n const engine = this.deps.engine();\n const envelope = await this.deps.encryptPayload(plan.payload);\n await this.stores.backstop.upsert({\n transferId: plan.transferId,\n payloadEnvelope: envelope,\n requiresSeedClose: plan.payload.split !== undefined,\n disposition: 'open',\n createdAt: this.deps.now(),\n });\n await this.putIntentGate(plan, envelope);\n\n const outcomes = await this.certifyAll(plan, engine);\n const { committed, cls, firstError } = summarize(outcomes);\n\n let deliveryPending = false;\n if (committed.length > 0) {\n deliveryPending = await this.deliverSet(plan.transferId, plan.recipientPubkey, plan.memo, committed);\n }\n if (cls === null) {\n await this.applyCommitted(engine, plan.transferId, committed);\n this.closeTail(engine, plan.transferId, plan.payload, committed);\n return { committed, deliveryPending };\n }\n if (cls === 'conflict' && committed.length > 0) {\n await this.applyBestEffort(engine, plan.transferId, committed);\n }\n await this.disposeOnFailure(plan.transferId, committed, cls);\n throw firstError;\n }\n\n // ── resume path: the SAME machine, rehydrated from an open intent ─────────\n async resumeIntent(r: RehydratedIntent): Promise<ResumeIntentOutcome> {\n const engine = this.deps.engine();\n const ctx: CertifyCtx = {\n transferId: r.transferId,\n recipientPubkey: r.payload.recipient,\n payload: r.payload,\n ...(r.payload.memo !== undefined ? { memo: r.payload.memo } : {}),\n };\n const outcomes = await this.resumeOps(ctx, engine, r);\n const { committed } = summarize(outcomes);\n const conflicts = this.toConflicts(engine, r, outcomes);\n if (committed.length === 0 && conflicts.length > 0) throw conflicts[0].error;\n\n let deliveryPending = false;\n if (committed.length > 0) {\n deliveryPending = await this.deliverSet(r.transferId, r.payload.recipient, r.payload.memo, committed);\n }\n // An intent closes only when every op settled cleanly (#744) — judged per\n // outcome, since a conflict outranks and would hide an ordinary failure whose\n // amount is in neither committed[] nor conflicts[] (#745 review).\n const blocking = firstNonConflictError(outcomes);\n if (blocking !== undefined) throw blocking.error;\n\n await this.applyCommitted(engine, r.transferId, committed);\n if (conflicts.length > 0) {\n return { deliveryPending, partial: await this.settlePartial(engine, r, committed, conflicts) };\n }\n await this.completeIntent(r.transferId, r.payload);\n await this.finishBookkeeping(engine, r.transferId, r.payload, 'resumed', committed);\n return { deliveryPending, partial: null };\n }\n\n // ── shared transitions ─────────────────────────────────────────────────────\n\n private async putIntentGate(plan: MachinePlan, envelope: string): Promise<void> {\n try {\n await this.deps.intents.put(plan.transferId, envelope, plan.payload.split !== undefined);\n } catch (err) {\n // #670: only the deterministic pre-submit 422 proves no server row exists.\n if (isValidationReject(err)) await this.stores.backstop.removeByKey(plan.transferId);\n throw err;\n }\n }\n\n private async certifyAll(plan: MachinePlan, engine: ITokenEngine): Promise<OpOutcome[]> {\n const ctx: CertifyCtx = {\n transferId: plan.transferId,\n recipientPubkey: plan.recipientPubkey,\n payload: plan.payload,\n ...(plan.memo !== undefined ? { memo: plan.memo } : {}),\n };\n const outcomes: OpOutcome[] = [];\n const certified: OpOutcome[] = [];\n for (let at = 0; at < plan.ops.length; at += CERTIFY_WIDTH) {\n const batch = plan.ops.slice(at, at + CERTIFY_WIDTH);\n const settled = await Promise.all(\n batch.map((op) =>\n this.certifyOne(ctx, engine, op, plan.sources.get(op.sourceTokenId)).then((o) => {\n // Report each leg as it lands, not each wave: a <=CERTIFY_WIDTH send is\n // one wave, so per-wave reporting would jump 0% -> 100%. Rides the\n // existing transfer:updated / tokenTransfers surface — nothing new.\n if (o.certified) {\n certified.push(o);\n this.emitProgress(plan, certified);\n }\n return o;\n })\n )\n );\n outcomes.push(...settled);\n if (settled.some((o) => o.error !== undefined && !o.certified)) break;\n }\n return outcomes;\n }\n\n /** In-flight snapshot: `tokenTransfers` holds the legs certified SO FAR. */\n private emitProgress(plan: MachinePlan, certified: readonly OpOutcome[]): void {\n this.deps.emit('transfer:updated', {\n id: plan.transferId,\n status: 'submitted',\n tokens: [],\n tokenTransfers: certified.map((o) => ({\n sourceTokenId: o.op.sourceTokenId,\n method: o.op.kind,\n })),\n } satisfies TransferResult);\n }\n\n private async certifyOne(\n ctx: CertifyCtx,\n engine: ITokenEngine,\n op: PlannedOp,\n source: SphereToken | undefined\n ): Promise<OpOutcome> {\n if (source === undefined) {\n return {\n op,\n certified: false,\n error: new SphereError(`source ${op.sourceTokenId} is not materialized`, 'VALIDATION_ERROR'),\n };\n }\n let produced: { recipientBlob: Uint8Array; changeBlob?: Uint8Array };\n try {\n produced = await this.certifyOnChain(ctx, engine, op, source);\n } catch (error) {\n return { op, certified: false, error };\n }\n const outcome: OpOutcome = { op, certified: true, ...produced };\n try {\n // #621: journal the instant the op certifies, BEFORE any delivery attempt.\n await this.stores.deliveryJournal.upsert({\n transferId: ctx.transferId,\n opIndex: op.opIndex,\n recipientPubkey: ctx.recipientPubkey,\n blobHex: bytesToHex(produced.recipientBlob),\n ...(ctx.memo !== undefined ? { memo: ctx.memo } : {}),\n attempts: 0,\n });\n return outcome;\n } catch (error) {\n return { ...outcome, error };\n }\n }\n\n private async certifyOnChain(\n ctx: CertifyCtx,\n engine: ITokenEngine,\n op: PlannedOp,\n source: SphereToken\n ): Promise<{ recipientBlob: Uint8Array; changeBlob?: Uint8Array }> {\n const recipientPubkey = hexToBytes(ctx.recipientPubkey);\n const opts = { transferId: ctx.transferId, opIndex: op.opIndex, checkpointStore: this.deps.checkpointStore };\n if (op.kind === 'direct') {\n const finished = await engine.transfer({ token: source, recipientPubkey }, opts);\n return { recipientBlob: finished.blob.token };\n }\n const split = splitOf(ctx.payload)!;\n // A split is planned only for a coin spend, so the coin id is present by\n // construction; a token-addressed intent never reaches this branch.\n const splitCoinId = coinIdOf(ctx.payload)!;\n const { outputs } = await engine.split(\n {\n token: source,\n outputs: [\n { recipientPubkey, coinId: splitCoinId, amount: BigInt(split.splitAmount) },\n { recipientPubkey: this.deps.ownPubkey, coinId: splitCoinId, amount: BigInt(split.remainderAmount) },\n ],\n },\n opts\n );\n return { recipientBlob: outputs[0].blob.token, changeBlob: outputs[1].blob.token };\n }\n\n /** Raw outcomes; `summarize` alone decides what they mean — same as the send path. */\n private async resumeOps(\n ctx: CertifyCtx,\n engine: ITokenEngine,\n r: RehydratedIntent\n ): Promise<OpOutcome[]> {\n const outcomes: OpOutcome[] = [];\n for (const op of buildOps(r.payload)) {\n // #621 direct legs re-deliver from the journal, never re-certify; a split\n // ALWAYS re-runs through its E.4 checkpoint to recover the change (#634).\n const journaled = op.kind === 'direct' ? r.journaled.get(op.opIndex) : undefined;\n if (journaled !== undefined) {\n outcomes.push({ op, certified: true, recipientBlob: hexToBytes(journaled.blobHex) });\n continue;\n }\n outcomes.push(await this.certifyOne(ctx, engine, op, r.sources.get(op.sourceTokenId)));\n // Fail-fast on anything but a conflict, as before — but the outcome is\n // RECORDED, so the shared decision below sees it (#744).\n const last = outcomes[outcomes.length - 1];\n if (last.error !== undefined && classifyError(last.error) !== 'conflict') break;\n }\n return outcomes;\n }\n\n /** Conflicted ops with the amount each leaves undelivered (#690 shortfall math). */\n private toConflicts(engine: ITokenEngine, r: RehydratedIntent, outcomes: OpOutcome[]): ResumeConflict[] {\n return outcomes\n .filter((o) => !o.certified && classifyError(o.error) === 'conflict')\n .map((o) => ({\n op: o.op,\n error: o.error,\n amount: conflictAmount(engine, r.payload, o.op, r.sources.get(o.op.sourceTokenId)),\n }));\n }\n\n private async deliverSet(\n transferId: string,\n recipientPubkey: string,\n memo: string | undefined,\n committed: OpOutcome[]\n ): Promise<boolean> {\n const journaled = committed.filter((o) => o.error === undefined && o.recipientBlob !== undefined);\n let pending = journaled.length < committed.length;\n if (journaled.length === 0) return pending;\n const options = {\n transferId,\n ...(memo !== undefined ? { memo } : {}),\n ...senderNametagOption(this.deps.ownNametag),\n };\n if (await this.tryBatchDeposit(recipientPubkey, journaled, options)) return pending;\n for (const outcome of journaled) {\n const stillPending = await this.deliverOne(recipientPubkey, outcome, options);\n pending = pending || stillPending;\n }\n return pending;\n }\n\n private async tryBatchDeposit(\n recipientPubkey: string,\n journaled: OpOutcome[],\n options: DeliverOptions\n ): Promise<boolean> {\n const batch = this.deps.delivery.deliverBatch?.bind(this.deps.delivery);\n if (batch === undefined) return false;\n try {\n await batch(recipientPubkey, journaled.map((o) => o.recipientBlob!), options);\n } catch {\n return false; // §5.6: batch failure falls back to the per-entry loop\n }\n for (const o of journaled) await this.removeJournaled(options.transferId, o.op.opIndex);\n return true;\n }\n\n private async deliverOne(\n recipientPubkey: string,\n outcome: OpOutcome,\n options: DeliverOptions\n ): Promise<boolean> {\n try {\n await this.deps.delivery.deliver(recipientPubkey, outcome.recipientBlob!, options);\n await this.removeJournaled(options.transferId, outcome.op.opIndex);\n return false;\n } catch (err) {\n if (isRateLimited(err)) {\n await this.stores.deliveryJournal.defer(options.transferId, outcome.op.opIndex, this.deps.now() + RATE_LIMIT_DEFER_MS);\n this.attention()(options.transferId, ATTENTION_DELIVERY_DEFERRED);\n } else {\n await this.stores.deliveryJournal.recordFailure(options.transferId, outcome.op.opIndex, this.attention());\n }\n return true;\n }\n }\n\n private async removeJournaled(transferId: string, opIndex: number): Promise<void> {\n try {\n await this.stores.deliveryJournal.remove(transferId, opIndex);\n } catch {\n /* deposit is idempotent — the replay converges a lingering entry */\n }\n }\n\n private async applyCommitted(engine: ITokenEngine, transferId: string, committed: OpOutcome[]): Promise<void> {\n try {\n const added = await this.uploadChangeBlobs(engine, committed);\n await this.deps.storage.applyDelta({\n transferId,\n spent: committed.map((o) => o.op.sourceTokenId),\n added,\n });\n } catch (cause) {\n // #665: post-commit mirror lag — never transfer:failed; resume converges.\n const pending = new SphereError(\n 'The spend committed on-chain; the wallet-api mirror is catching up.',\n 'SEND_SYNC_PENDING',\n cause\n );\n pending.transferId = transferId;\n throw pending;\n }\n }\n\n private async applyBestEffort(engine: ITokenEngine, transferId: string, committed: OpOutcome[]): Promise<void> {\n if (committed.some((o) => o.error !== undefined)) return; // unjournaled leg: resume owns it\n try {\n await this.applyCommitted(engine, transferId, committed);\n } catch {\n this.attention()(transferId, ATTENTION_SYNC_PENDING);\n }\n }\n\n private async uploadChangeBlobs(\n engine: ITokenEngine,\n committed: OpOutcome[]\n ): Promise<{ tokenId: string; key: string }[]> {\n const added: { tokenId: string; key: string }[] = [];\n for (const o of committed) {\n if (o.changeBlob === undefined) continue;\n const digest = bytesToHex(sha256(o.changeBlob));\n const keys = await this.deps.storage.uploadBlobs([{ sha256: digest, bytes: o.changeBlob }]);\n const key = keys.get(digest);\n if (key === undefined) throw new SphereError(`no upload key returned for ${digest}`, 'STORAGE_ERROR');\n const { tokenId } = await engine.deliveryKeys(o.changeBlob);\n added.push({ tokenId, key });\n }\n return added;\n }\n\n private async settlePartial(\n engine: ITokenEngine,\n r: RehydratedIntent,\n committed: OpOutcome[],\n conflicts: ResumeConflict[]\n ): Promise<ShortfallEntry> {\n const undelivered = conflicts.reduce((sum, c) => sum + c.amount, 0n);\n const entry: ShortfallEntry = {\n transferId: r.transferId,\n remainingAmount: undelivered.toString(),\n // '' only on a token-addressed intent, which is one leg: it either lands or\n // conflicts, so a shortfall row is unreachable there (settlePartial needs >1).\n coinId: coinIdOf(r.payload) ?? '',\n recipient: r.payload.recipient,\n committedTokenIds: committed.map((o) => o.op.sourceTokenId),\n createdAt: this.deps.now(),\n };\n // #690: durable BEFORE complete — after complete the intent is unlistable\n // and no resume could ever rebuild the remainder the app never saw.\n await this.stores.shortfalls.upsert(entry);\n await this.completeIntent(r.transferId, r.payload);\n await this.finishBookkeeping(engine, r.transferId, r.payload, 'resumed', committed);\n return entry;\n }\n\n private closeTail(engine: ITokenEngine, transferId: string, payload: IntentPayload, committed: OpOutcome[]): void {\n void (async () => {\n try {\n await this.completeIntent(transferId, payload);\n } catch {\n return; // idempotent backstop — resume converges the unevidenced edge\n }\n await this.finishBookkeeping(engine, transferId, payload, 'sent', committed);\n })();\n }\n\n private async completeIntent(transferId: string, payload: IntentPayload): Promise<void> {\n const signature = payload.split !== undefined ? await this.deps.signComplete(transferId) : undefined;\n await this.deps.intents.complete(transferId, signature);\n }\n\n private async finishBookkeeping(\n engine: ITokenEngine,\n transferId: string,\n payload: IntentPayload,\n phase: 'sent' | 'resumed',\n committed: OpOutcome[]\n ): Promise<void> {\n try {\n // A token-addressed spend has no coin to sum: what settled is the token itself.\n const coinId = coinIdOf(payload);\n const committedAmount =\n coinId === undefined ? '0' : await this.settledAmount(engine, coinId, committed);\n // A whole-token spend has no coin to sum — record what the moved token ACTUALLY\n // carried, so a valued one is not logged as `assets: []`.\n const committedAssets =\n coinId === undefined ? await this.settledAssets(engine, committed) : undefined;\n await this.deps.recordHistory?.({\n transferId,\n payload,\n phase,\n committedAmount,\n ...(committedAssets !== undefined ? { committedAssets } : {}),\n });\n } catch {\n /* a history failure never fails the money path */\n }\n try {\n await this.stores.backstop.removeByKey(transferId);\n } catch {\n /* stale 'open' backstops are inert — resume lists server-open only */\n }\n }\n\n /**\n * §5.9: SENT history records what SETTLED, never the plan — the value of the\n * certified recipient blobs (summarize()'s committed set is the only source;\n * a journal-rehydrated resume leg has no source token, but every committed\n * leg carries its recipient blob, so the outcome-derived rule is uniform).\n */\n /** Every asset across the certified recipient blobs — the whole-spend twin of settledAmount. */\n private async settledAssets(\n engine: ITokenEngine,\n committed: OpOutcome[]\n ): Promise<{ coinId: string; amount: string }[]> {\n const total = new Map<string, bigint>();\n for (const outcome of committed) {\n if (outcome.recipientBlob === undefined) continue;\n const token = await engine.decodeToken({ tokenId: '', token: outcome.recipientBlob });\n for (const asset of engine.readValue(token)?.assets ?? []) {\n total.set(asset.coinId, (total.get(asset.coinId) ?? 0n) + asset.amount);\n }\n }\n return [...total].map(([coinId, amount]) => ({ coinId, amount: amount.toString() }));\n }\n\n private async settledAmount(engine: ITokenEngine, coinId: string, committed: OpOutcome[]): Promise<string> {\n let total = 0n;\n for (const outcome of committed) {\n if (outcome.recipientBlob === undefined) continue;\n const token = await engine.decodeToken({ tokenId: '', token: outcome.recipientBlob });\n total += engine.balanceOf(token, coinId);\n }\n return total.toString();\n }\n\n private async disposeOnFailure(transferId: string, committed: OpOutcome[], cls: OutcomeClass): Promise<void> {\n // Abort ONLY when nothing certified AND the class is clean; the keep-open\n // family and any partially-certified send leave the intent open (E.2/E.3).\n if (committed.length > 0 || cls === 'keep-open') return;\n try {\n await this.stores.backstop.patch(transferId, (e) => ({ ...e, disposition: 'abortPending' }));\n } catch {\n /* server abort below still converges; #676 gate covers the gap */\n }\n try {\n await this.deps.intents.abort(transferId);\n await this.stores.backstop.removeByKey(transferId);\n } catch {\n /* stays abortPending — the #676 resume gate converges, never re-executes */\n }\n }\n\n private attention(): AttentionEmitter {\n return (transferId, code, detail) => {\n this.deps.emit('transfer:attention', detail === undefined ? { transferId, code } : { transferId, code, detail });\n };\n }\n}\n\nfunction conflictAmount(\n engine: ITokenEngine,\n payload: IntentPayload,\n op: PlannedOp,\n source: SphereToken | undefined\n): bigint {\n const split = splitOf(payload);\n if (op.kind === 'split') return BigInt(split!.splitAmount);\n const coinId = coinIdOf(payload);\n if (coinId === undefined) return 0n; // token-addressed: the unit is the token\n return source !== undefined ? engine.balanceOf(source, coinId) : 0n;\n}\n","// §5.5 P6 — resume = the SAME TransferMachine, rehydrated from server-open\n// intents: the #676 local-disposition gate, v:2 payload validation, batched\n// cross-intent source reads, and {resumed, conflicted, failed} classification.\n\nimport { SphereError } from '../../../core/errors';\nimport { logger } from '../../../core/logger';\nimport type { SphereToken } from '../../../token-engine/types';\nimport type { DeliveryJournalEntry, IntentBackstopEntry } from '../stores';\nimport { isWholeIntent } from './payload-view';\nimport type { CoinIntentPayload, IntentPayload, WholeIntentPayload } from './types';\nimport { ATTENTION_CHECKPOINT_STUCK, createMachineStores, type MachineStores } from './journal';\nimport { TransferMachine, buildOps, classifyError, type MachineDeps } from './TransferMachine';\n\nexport interface ResumeReport {\n resumed: string[];\n conflicted: string[];\n failed: string[];\n}\n\ninterface ResumeJob {\n transferId: string;\n payload: IntentPayload;\n journaled: Map<number, DeliveryJournalEntry>;\n}\n\nexport interface ResumeAllOptions {\n /** Ids with an in-process machine attempt — their backstop entries are never GC'd. */\n isLocallyActive?: (transferId: string) => boolean;\n}\n\nexport async function resumeAll(deps: MachineDeps, options: ResumeAllOptions = {}): Promise<ResumeReport> {\n const report: ResumeReport = { resumed: [], conflicted: [], failed: [] };\n const stores = createMachineStores(deps.kv);\n const open = await deps.intents.listOpen();\n\n let locals: Map<string, IntentBackstopEntry>;\n try {\n locals = new Map((await stores.backstop.list()).map((e) => [e.transferId, e]));\n } catch {\n // #676: local dispositions unknowable — a server-open intent could be\n // locally aborted, so resuming ANY would risk re-executing one. Defer all.\n return report;\n }\n await dropStaleBackstops(\n stores,\n locals,\n new Set(open.map((i) => i.transferId)),\n options.isLocallyActive ?? (() => false)\n );\n\n const jobs = await gateAndDecode(deps, stores, open, locals, report);\n const ctx: RunCtx = {\n deps,\n stores,\n machine: new TransferMachine(deps),\n sources: await fetchSources(deps, jobs),\n };\n for (const job of jobs) {\n await runOne(ctx, job, report);\n }\n return report;\n}\n\ninterface RunCtx {\n deps: MachineDeps;\n stores: MachineStores;\n machine: TransferMachine;\n sources: Map<string, SphereToken>;\n}\n\n/**\n * Reconciliation GC (never money logic — when in doubt, KEEP the entry).\n * Non-'open' entries not server-open: stale local aborts, dropped as before.\n * S1: an 'open' entry that is NOT server-open (= completed-or-never: tail\n * crash after complete, or crash before the intent PUT was acked) with NO\n * journal legs owed and no in-process attempt is pure residue — without this\n * sweep it is a permanent phantom pendingTransfers() row and the heartbeat\n * re-arms forever. Any journal leg or active op keeps the entry.\n */\nasync function dropStaleBackstops(\n stores: MachineStores,\n locals: Map<string, IntentBackstopEntry>,\n openIds: Set<string>,\n isLocallyActive: (transferId: string) => boolean\n): Promise<void> {\n for (const entry of locals.values()) {\n if (openIds.has(entry.transferId)) continue;\n if (entry.disposition !== 'open') {\n await stores.backstop.removeByKey(entry.transferId);\n continue;\n }\n if (isLocallyActive(entry.transferId)) continue;\n if ((await stores.deliveryJournal.byTransfer(entry.transferId)).size > 0) continue;\n await stores.backstop.removeByKey(entry.transferId);\n }\n}\n\nasync function gateAndDecode(\n deps: MachineDeps,\n stores: MachineStores,\n open: { transferId: string; payload: string }[],\n locals: Map<string, IntentBackstopEntry>,\n report: ResumeReport\n): Promise<ResumeJob[]> {\n const jobs: ResumeJob[] = [];\n for (const intent of open) {\n const local = locals.get(intent.transferId);\n if (local !== undefined && local.disposition !== 'open') {\n // #676: a locally-aborted intent is NEVER resumed — converge the server.\n try {\n await deps.intents.abort(intent.transferId);\n await stores.backstop.removeByKey(intent.transferId);\n } catch {\n /* stays locally aborted; converged at the next resume */\n }\n report.conflicted.push(intent.transferId);\n continue;\n }\n let payload: IntentPayload;\n try {\n payload = validatePayload(await deps.decryptPayload(intent.payload));\n } catch {\n report.failed.push(intent.transferId);\n continue;\n }\n jobs.push({\n transferId: intent.transferId,\n payload,\n journaled: await stores.deliveryJournal.byTransfer(intent.transferId),\n });\n }\n return jobs;\n}\n\n/** One batched blob read across every intent (§7 start() posture). */\nasync function fetchSources(deps: MachineDeps, jobs: ResumeJob[]): Promise<Map<string, SphereToken>> {\n const needed = new Set<string>();\n for (const job of jobs) {\n for (const op of buildOps(job.payload)) {\n if (op.kind === 'direct' && job.journaled.has(op.opIndex)) continue;\n needed.add(op.sourceTokenId);\n }\n }\n const decoded = new Map<string, SphereToken>();\n if (needed.size === 0) return decoded;\n let blobs: Map<string, Uint8Array>;\n try {\n blobs = await deps.storage.getBlobs([...needed]);\n } catch {\n return decoded; // jobs that needed a source fail closed below\n }\n const engine = deps.engine();\n for (const [tokenId, bytes] of blobs) {\n try {\n decoded.set(tokenId, await engine.decodeToken({ tokenId, token: bytes }));\n } catch (err) {\n logger.warn('PaymentsV2', `resume: source ${tokenId} did not decode — ${String(err)}`);\n }\n }\n return decoded;\n}\n\nasync function runOne(ctx: RunCtx, job: ResumeJob, report: ResumeReport): Promise<void> {\n const mine = new Map<string, SphereToken>();\n for (const op of buildOps(job.payload)) {\n if (op.kind === 'direct' && job.journaled.has(op.opIndex)) continue;\n const token = ctx.sources.get(op.sourceTokenId);\n if (token === undefined) {\n report.failed.push(job.transferId); // fail closed: intent stays open, untouched\n return;\n }\n // The blob is the authority on what a source carries — the same rule the send\n // path applies at materialize. A durable intent labelled whole whose named\n // source actually holds coins would move them while history records assets: [].\n if (isWholeIntent(job.payload) && token.valueEnvelope === 'bare_collection') {\n logger.warn(\n 'PaymentsV2',\n `resume: token intent ${job.transferId} names a source carrying coin value — refusing`\n );\n report.failed.push(job.transferId);\n return;\n }\n mine.set(op.sourceTokenId, token);\n }\n try {\n await ctx.machine.resumeIntent({\n transferId: job.transferId,\n payload: job.payload,\n sources: mine,\n journaled: job.journaled,\n });\n report.resumed.push(job.transferId);\n } catch (err) {\n await classifyResumeFailure(ctx.deps, ctx.stores, job.transferId, err, report);\n }\n}\n\nasync function classifyResumeFailure(\n deps: MachineDeps,\n stores: MachineStores,\n transferId: string,\n err: unknown,\n report: ResumeReport\n): Promise<void> {\n if (classifyError(err) === 'conflict') {\n // E.2 pure lost race — nothing was delivered under this intent: soft-abort,\n // never apply the foreign proof; the caller re-plans under a NEW transferId.\n try {\n await deps.intents.abort(transferId);\n await stores.backstop.removeByKey(transferId);\n } catch {\n /* retried at the next resume */\n }\n report.conflicted.push(transferId);\n return;\n }\n const code = err !== null && typeof err === 'object' ? (err as { code?: unknown }).code : undefined;\n if (code === 'SPLIT_CHECKPOINT_LOST' || code === 'CHECKPOINT_TRUSTBASE_MISMATCH') {\n deps.emit('transfer:attention', { transferId, code: ATTENTION_CHECKPOINT_STUCK, detail: String(code) });\n }\n report.failed.push(transferId);\n}\n\n/**\n * A token-addressed intent is EXACTLY one named source and never a split. Both are\n * enforced here rather than trusted: a second leg would make `settlePartial`\n * reachable with every conflict amount 0n, so a remainder of '0' would complete the\n * intent and report success for a leg that never landed.\n */\nfunction validateCoinPayload(c: Partial<CoinIntentPayload>): CoinIntentPayload {\n if (typeof c.coinId !== 'string' || typeof c.amount !== 'string') {\n throw new SphereError('intent payload is missing coinId/amount', 'VALIDATION_ERROR');\n }\n const s = c.split;\n if (\n s !== undefined &&\n (typeof s.tokenId !== 'string' || typeof s.splitAmount !== 'string' || typeof s.remainderAmount !== 'string')\n ) {\n throw new SphereError('intent payload split spec is malformed', 'VALIDATION_ERROR');\n }\n return { ...(c as CoinIntentPayload), kind: 'coin' };\n}\n\nfunction validateWholePayload(p: Partial<WholeIntentPayload>): WholeIntentPayload {\n if (p.direct?.length !== 1 || typeof p.direct[0] !== 'string' || p.direct[0] === '') {\n throw new SphereError(\n 'token intent payload must name exactly one source token',\n 'VALIDATION_ERROR'\n );\n }\n if (p.split !== undefined) {\n throw new SphereError('token intent payload cannot carry a split', 'VALIDATION_ERROR');\n }\n return { ...(p as WholeIntentPayload), kind: 'whole', direct: [p.direct[0]] };\n}\n\nfunction validatePayload(raw: unknown): IntentPayload {\n const p = raw !== null && typeof raw === 'object' ? (raw as Partial<IntentPayload>) : null;\n if (p === null || p.v !== 2 || !Array.isArray(p.direct) || p.direct.some((t) => typeof t !== 'string')) {\n throw new SphereError(\n `unsupported intent payload shape (v=${String((raw as { v?: unknown } | null)?.v)}) — not resumable`,\n 'VALIDATION_ERROR'\n );\n }\n if (typeof p.recipient !== 'string') {\n throw new SphereError('intent payload is missing recipient', 'VALIDATION_ERROR');\n }\n // ABSENT migrates to 'coin' (the only pre-#777 shape); an EXPLICIT unknown one\n // does NOT. 'coinless' is 0.17.0's spelling of 'whole' — durable server state, so\n // a client that wrote one must still resume it.\n const kind = p.kind ?? 'coin';\n if (kind !== 'coin' && kind !== 'whole' && kind !== 'coinless') {\n throw new SphereError(\n `unsupported intent kind '${String(kind)}' — not resumable by this client`,\n 'VALIDATION_ERROR'\n );\n }\n return kind === 'coin'\n ? validateCoinPayload(p as Partial<CoinIntentPayload>)\n : validateWholePayload(p as Partial<WholeIntentPayload>);\n}\n","// §7 in-session convergence: the heartbeat timing cell (in-memory timer +\n// backoff value ONLY), the single convergence pass, and the §4\n// pendingTransfers() on-read derivation. The facade owns lifecycle,\n// the resume single-flight, and the active-op ownership registry.\n\nimport type { PendingTransfer } from './api';\nimport type { DeliveryPort } from './ports';\nimport type { DeliveryJournalEntry, IntentBackstopEntry, ShortfallEntry } from './stores';\nimport type { CoinIntentPayload, IntentPayload } from './machine/types';\nimport { retryAfterMsOf, type MachineStores, type ReplayDeps } from './machine/journal';\nimport { resumeAll } from './machine/resume';\nimport type { MachineDeps } from './machine/TransferMachine';\n\n// Backoff: seed 5 s, ×2 per unproductive pass, cap 120 s; reset on progress\n// and on connection recovery; a surfaced Retry-After floors the next pass.\nexport const HEARTBEAT_SEED_MS = 5_000;\nexport const HEARTBEAT_CAP_MS = 120_000;\n\nexport interface ConvergeOutcome {\n progress: boolean;\n retryAfterMs: number | null;\n}\n\ninterface HeartbeatDeps {\n now: () => number;\n onTick: () => void;\n}\n\nexport class ConvergenceHeartbeat {\n private timer: ReturnType<typeof setTimeout> | null = null;\n private delayMs = HEARTBEAT_SEED_MS;\n private notBefore = 0;\n private running = false;\n\n constructor(private readonly deps: HeartbeatDeps) {}\n\n start(): void {\n this.running = true;\n this.delayMs = HEARTBEAT_SEED_MS;\n this.notBefore = 0;\n }\n\n /** §7 quiescence unchanged: a mid-backoff stop() cancels cleanly. */\n stop(): void {\n this.running = false;\n this.clearTimer();\n }\n\n /** Reset to seed on progress, ×2 to the cap otherwise; idle stops rescheduling. */\n settle(outcome: ConvergeOutcome, pending: boolean): void {\n if (outcome.retryAfterMs !== null) {\n this.notBefore = Math.max(this.notBefore, this.deps.now() + outcome.retryAfterMs);\n }\n if (!pending) {\n // Never clearTimer here: an arm() for work that appeared AFTER this\n // pass read the pending set must survive the pass's idle settle — the\n // armed tick re-reads the stores and idles itself if truly quiescent.\n this.delayMs = HEARTBEAT_SEED_MS;\n return;\n }\n const delay = outcome.progress ? HEARTBEAT_SEED_MS : this.delayMs;\n this.delayMs = Math.min(delay * 2, HEARTBEAT_CAP_MS);\n this.schedule(delay);\n }\n\n /** New pending work (keep-open park / journaled delivery / mint hold): prompt retry. */\n arm(): void {\n if (!this.running) return;\n this.delayMs = Math.min(HEARTBEAT_SEED_MS * 2, HEARTBEAT_CAP_MS);\n this.schedule(HEARTBEAT_SEED_MS);\n }\n\n /** connection:status recovery: the backoff resets; a pending tick re-fires at the seed. */\n recovered(): void {\n this.delayMs = HEARTBEAT_SEED_MS;\n if (this.timer !== null) this.arm();\n }\n\n private schedule(delayMs: number): void {\n this.clearTimer();\n if (!this.running) return;\n const floored = Math.max(delayMs, this.notBefore - this.deps.now());\n this.timer = setTimeout(() => {\n this.timer = null;\n this.deps.onTick();\n }, floored);\n }\n\n private clearTimer(): void {\n if (this.timer !== null) clearTimeout(this.timer);\n this.timer = null;\n }\n}\n\nexport interface ConvergerDeps {\n machineDeps: MachineDeps;\n stores: MachineStores;\n delivery: DeliveryPort;\n reconcile(report: { resumed: string[]; conflicted: string[]; open: string[] }): Promise<void>;\n refreshView(): Promise<void>;\n replayMints(): Promise<number>;\n replayNftMints(): Promise<number>;\n /** §7 ownership: the pass never adopts an op whose machine runs in-process. */\n isActiveOp(id: string): boolean;\n emit(event: string, payload: unknown): void;\n now(): number;\n}\n\nexport class Converger {\n constructor(private readonly deps: ConvergerDeps) {}\n\n /** Resume open intents, then drain the delivery + mint journals (all idempotent). */\n async convergeOnce(): Promise<ConvergeOutcome> {\n let progress = false;\n let retryAfterMs: number | null = null;\n try {\n progress = await this.resumePass();\n } catch (err) {\n retryAfterMs = retryAfterMsOf(err);\n }\n try {\n const stats = await this.deps.stores.deliveryJournal.replay(this.replayDeps());\n progress = progress || stats.delivered > 0;\n } catch (err) {\n retryAfterMs ??= retryAfterMsOf(err);\n }\n // Caught apart: an unreadable coin journal must not starve the NFT one.\n for (const replay of [() => this.deps.replayMints(), () => this.deps.replayNftMints()]) {\n try {\n progress = (await replay()) > 0 || progress;\n } catch (err) {\n retryAfterMs ??= retryAfterMsOf(err);\n }\n }\n return { progress, retryAfterMs };\n }\n\n /** §4 heartbeat predicate — read fresh from the §6 stores, never cached. */\n async pendingWork(): Promise<boolean> {\n const [backstop, journal, mints, nftMints] = await Promise.all([\n this.deps.stores.backstop.list(),\n this.deps.stores.deliveryJournal.list(),\n this.deps.stores.mintJournal.list(),\n this.deps.stores.nftMintJournal.list(),\n ]);\n const mintsOpen = mints.length > 0 || nftMints.length > 0;\n return backstop.length > 0 || journal.some((e) => e.undeliverable !== true) || mintsOpen;\n }\n\n private async resumePass(): Promise<boolean> {\n const report = await resumeAll(this.filteredMachineDeps(), {\n isLocallyActive: (id) => this.deps.isActiveOp(id),\n });\n const progress = report.resumed.length > 0 || report.conflicted.length > 0;\n await this.deps.reconcile({\n resumed: report.resumed,\n conflicted: report.conflicted,\n open: report.failed,\n });\n if (progress) await this.deps.refreshView().catch(() => undefined);\n return progress;\n }\n\n private filteredMachineDeps(): MachineDeps {\n const intents = this.deps.machineDeps.intents;\n return {\n ...this.deps.machineDeps,\n intents: {\n ...intents,\n listOpen: async () =>\n (await intents.listOpen()).filter((intent) => !this.deps.isActiveOp(intent.transferId)),\n },\n };\n }\n\n private replayDeps(): ReplayDeps {\n return {\n delivery: this.deps.delivery,\n now: () => this.deps.now(),\n // sphere#487: a replayed leg carries the sender's name too — the machine\n // deps hold the one live getter, so replay can never drift from a send.\n ...(this.deps.machineDeps.ownNametag !== undefined\n ? { ownNametag: this.deps.machineDeps.ownNametag }\n : {}),\n attention: (transferId, code, detail) => {\n this.deps.emit(\n 'transfer:attention',\n detail === undefined ? { transferId, code } : { transferId, code, detail }\n );\n },\n };\n }\n}\n\n/** §4 pendingTransfers(): derived ON READ from the §6 stores — never cached. */\nexport async function derivePendingTransfers(\n stores: MachineStores,\n decryptPayload: (envelope: string) => Promise<unknown>\n): Promise<PendingTransfer[]> {\n const [backstop, journal, shortfalls] = await Promise.all([\n stores.backstop.list(),\n stores.deliveryJournal.list(),\n stores.shortfalls.list(),\n ]);\n const byTransfer = groupJournal(journal);\n const out: PendingTransfer[] = [];\n const seen = new Set<string>();\n for (const entry of backstop) {\n // abortPending/aborted rows are rollbacks in convergence, not user-visible sends.\n if (entry.disposition !== 'open') continue;\n seen.add(entry.transferId);\n out.push(await openRow(entry, byTransfer.get(entry.transferId) ?? [], decryptPayload));\n }\n for (const [transferId, entries] of byTransfer) {\n if (seen.has(transferId)) continue;\n seen.add(transferId);\n out.push(journalOnlyRow(transferId, entries));\n }\n for (const entry of shortfalls) {\n if (!seen.has(entry.transferId)) out.push(shortfallRow(entry));\n }\n return out;\n}\n\n/**\n * #737: the source tokenIds each still-open intent pins, derived ON READ from the\n * same §6 backstop `derivePendingTransfers` reads — the pin needs no store of its\n * own, so a restart re-derives it instead of re-offering the tokens as spendable.\n */\nexport async function deriveOpenIntentHolds(\n stores: MachineStores,\n decryptPayload: (envelope: string) => Promise<unknown>\n): Promise<{ open: Map<string, string[]>; complete: boolean }> {\n const holds = new Map<string, string[]>();\n let complete = true;\n for (const entry of await stores.backstop.list()) {\n if (entry.disposition !== 'open') continue;\n let payload: Partial<IntentPayload> | null = null;\n try {\n const raw = await decryptPayload(entry.payloadEnvelope);\n if (raw !== null && typeof raw === 'object') payload = raw as Partial<IntentPayload>;\n } catch {\n // Undecodable envelope on a STILL-OPEN intent: its sources are unknown, so\n // they cannot be proven safe. Report incompleteness — the caller fails\n // closed rather than treating \"unknown sources\" as \"no sources\" (#738).\n complete = false;\n continue;\n }\n if (payload === null) {\n complete = false;\n continue;\n }\n const direct = Array.isArray(payload?.direct) ? payload.direct.filter((id) => typeof id === 'string') : [];\n const split = typeof payload?.split?.tokenId === 'string' ? [payload.split.tokenId] : [];\n holds.set(entry.transferId, [...direct, ...split]);\n }\n return { open: holds, complete };\n}\n\nfunction groupJournal(journal: DeliveryJournalEntry[]): Map<string, DeliveryJournalEntry[]> {\n const byTransfer = new Map<string, DeliveryJournalEntry[]>();\n for (const entry of journal) {\n const mine = byTransfer.get(entry.transferId);\n if (mine === undefined) byTransfer.set(entry.transferId, [entry]);\n else mine.push(entry);\n }\n return byTransfer;\n}\n\nasync function openRow(\n entry: IntentBackstopEntry,\n journal: DeliveryJournalEntry[],\n decryptPayload: (envelope: string) => Promise<unknown>\n): Promise<PendingTransfer> {\n let payload: Partial<IntentPayload> | null = null;\n try {\n const raw = await decryptPayload(entry.payloadEnvelope);\n if (raw !== null && typeof raw === 'object') payload = raw as Partial<IntentPayload>;\n } catch {\n payload = null; // undecodable envelope: surface the row, not the fields\n }\n const total = Array.isArray(payload?.direct)\n ? payload.direct.length + (payload.split !== undefined ? 1 : 0)\n : 0;\n const certified = distinctOpCount(journal);\n return {\n transferId: entry.transferId,\n kind: 'open',\n recipient: typeof payload?.recipient === 'string' ? payload.recipient : '',\n ...subject(payload),\n legs: { certified, total: Math.max(total, certified) },\n deliveryPending: journal.length > 0,\n createdAt: entry.createdAt,\n };\n}\n\n/**\n * What the row is FOR: a coin and an amount, or the token being moved. A\n * token-addressed intent names no coin, so it renders as its token rather than\n * as `coinId: ''` / `amount: ''`.\n */\nfunction subject(\n payload: Partial<IntentPayload> | null\n): { coinId: string; amount: string; tokenId?: string } {\n // Both spellings: this reads the RAW decrypted payload, never normalised by\n // validatePayload, so a 0.17-written intent still says 'coinless'.\n const rawKind = (payload as { kind?: string } | null)?.kind;\n if (rawKind === 'whole' || rawKind === 'coinless') {\n const tokenId = payload?.direct?.[0];\n return { coinId: '', amount: '', ...(typeof tokenId === 'string' ? { tokenId } : {}) };\n }\n const coin = payload as Partial<CoinIntentPayload> | null;\n return {\n coinId: typeof coin?.coinId === 'string' ? coin.coinId : '',\n amount: typeof coin?.amount === 'string' ? coin.amount : '',\n };\n}\n\n/** The intent already completed but a deposit is still owed from the journal. */\nfunction journalOnlyRow(transferId: string, entries: DeliveryJournalEntry[]): PendingTransfer {\n const certified = distinctOpCount(entries);\n return {\n transferId,\n kind: 'open',\n recipient: entries[0].recipientPubkey,\n coinId: '',\n amount: '',\n legs: { certified, total: certified },\n deliveryPending: true,\n createdAt: 0,\n };\n}\n\nfunction shortfallRow(entry: ShortfallEntry): PendingTransfer {\n return {\n transferId: entry.transferId,\n kind: 'shortfall',\n recipient: entry.recipient,\n coinId: entry.coinId,\n amount: entry.remainingAmount,\n legs: { certified: entry.committedTokenIds.length, total: entry.committedTokenIds.length },\n deliveryPending: false,\n createdAt: entry.createdAt,\n };\n}\n\nfunction distinctOpCount(entries: readonly DeliveryJournalEntry[]): number {\n return new Set(entries.map((entry) => entry.opIndex)).size;\n}\n","// §5.4 Reservations — whole-token set semantics, fully synchronous. The queue\n// reserves whole tokens only (doc §5.4), so a token is either free or held by\n// exactly one reservation; partial-amount arithmetic was dead surface (#727).\n\nexport interface ReservationRequest {\n readonly tokenId: string;\n}\n\nexport class ReservationLedger {\n private readonly reservations = new Map<string, ReadonlySet<string>>();\n private readonly tokenHolder = new Map<string, string>();\n // #738: the held-set is RECONSTRUCTED from the open intents, so until\n // IntentPins proves every one of them \"no holder\" means unknown, not free.\n private authoritative = false;\n\n /** Sole writer: IntentPins.sync(), true only if it reconstructed every open intent.\n * Returns whether the gate actually moved, so callers signal transitions, not passes. */\n setAuthoritative(value: boolean): boolean {\n const moved = this.authoritative !== value;\n this.authoritative = value;\n return moved;\n }\n\n /** Non-null while the held-set is unproven: nothing plans, nothing reads free. */\n unprovenReason(): string | null {\n return this.authoritative\n ? null\n : 'Cannot yet verify which tokens are held by transfers still converging — spending is paused until that check succeeds';\n }\n\n // All-or-nothing: every entry is validated before any state mutates.\n reserve(reservationId: string, entries: readonly ReservationRequest[]): void {\n if (entries.length === 0) throw new Error('EMPTY_RESERVATION');\n if (this.reservations.has(reservationId)) throw new Error('DUPLICATE_RESERVATION_ID');\n const tokenIds = new Set(entries.map((e) => e.tokenId));\n for (const tokenId of tokenIds) {\n if (this.tokenHolder.has(tokenId)) throw new Error('INSUFFICIENT_FREE_AMOUNT');\n }\n this.reservations.set(reservationId, tokenIds);\n for (const tokenId of tokenIds) this.tokenHolder.set(tokenId, reservationId);\n }\n\n commit(reservationId: string): void {\n this.release(reservationId);\n }\n\n cancel(reservationId: string): void {\n this.release(reservationId);\n }\n\n cancelForToken(tokenId: string, excludeReservationId?: string): string[] {\n const holder = this.tokenHolder.get(tokenId);\n if (holder === undefined || holder === excludeReservationId) return [];\n this.release(holder);\n return [holder];\n }\n\n getFreeAmount(tokenId: string, tokenAmount: bigint): bigint {\n return this.tokenHolder.has(tokenId) ? 0n : tokenAmount;\n }\n\n /** #737: who pins this token — the reporting side reads it so a held token is never called spendable. */\n holderOf(tokenId: string): string | undefined {\n return this.tokenHolder.get(tokenId);\n }\n\n tokensOf(reservationId: string): readonly string[] {\n return [...(this.reservations.get(reservationId) ?? [])];\n }\n\n clear(): void {\n this.reservations.clear();\n this.tokenHolder.clear();\n }\n\n private release(reservationId: string): void {\n const tokenIds = this.reservations.get(reservationId);\n if (!tokenIds) return;\n this.reservations.delete(reservationId);\n for (const tokenId of tokenIds) this.tokenHolder.delete(tokenId);\n }\n}\n","// #737: the ledger holds exactly the sources of the intents the §6 backstop still\n// calls OPEN — adopting what a dead session left open (that spend may be on-chain)\n// and dropping what stopped being open (source spent, or ours again).\n\nimport type { ReservationLedger } from './ledger';\n\nexport interface IntentPinsDeps {\n readonly ledger: ReservationLedger;\n /** Open intents → source tokenIds, re-derived per call; `complete: false` if any could not be. */\n readonly openIntents: () => Promise<{ open: Map<string, string[]>; complete: boolean }>;\n readonly isActive: (transferId: string) => boolean;\n readonly release: (tokenId: string) => void;\n readonly changed: () => void;\n}\n\nexport class IntentPins {\n private readonly pinned = new Set<string>();\n\n constructor(private readonly deps: IntentPinsDeps) {}\n\n /** The keep-open reservation IS this intent's pin from now on. */\n adopt(transferId: string): void {\n this.pinned.add(transferId);\n }\n\n async sync(): Promise<void> {\n // A throw leaves the ledger unproven — never an empty held-set (#738).\n const { open, complete } = await this.deps.openIntents();\n let changed = false;\n for (const transferId of [...this.pinned]) {\n if (open.has(transferId) || this.deps.isActive(transferId)) continue;\n this.pinned.delete(transferId);\n for (const tokenId of this.deps.ledger.tokensOf(transferId)) this.deps.release(tokenId);\n this.deps.ledger.cancel(transferId);\n changed = true;\n }\n for (const [transferId, tokenIds] of open) {\n if (this.deps.isActive(transferId)) continue;\n this.pinned.add(transferId);\n changed = this.pin(transferId, tokenIds) || changed;\n }\n const gateMoved = this.deps.ledger.setAuthoritative(complete);\n if (changed || gateMoved) this.deps.changed();\n }\n\n /** Every pass, not just on adoption; the free subset, since a partial pin beats none. */\n private pin(transferId: string, tokenIds: readonly string[]): boolean {\n if (this.deps.ledger.tokensOf(transferId).length > 0) return false;\n const free = tokenIds.filter((tokenId) => this.deps.ledger.holderOf(tokenId) === undefined);\n if (free.length === 0) return false;\n this.deps.ledger.reserve(transferId, free.map((tokenId) => ({ tokenId })));\n return true;\n }\n}\n","// §5.3 CoinSelector — pure function, no I/O, no engine, no blobs.\n\nexport interface PoolEntry {\n readonly tokenId: string;\n readonly amount: bigint;\n}\n\nexport interface SplitSpec {\n readonly tokenId: string;\n readonly splitAmount: bigint;\n readonly remainderAmount: bigint;\n}\n\nexport interface SelectionPlan {\n readonly direct: readonly string[];\n readonly split?: SplitSpec;\n}\n\nexport interface SelectorStats {\n combinationsExamined: number;\n}\n\nexport interface SelectorOptions {\n readonly workBudget?: number;\n /** Instrumentation out-param: pins the tested work-budget invariant (select.test.ts). */\n readonly stats?: SelectorStats;\n}\n\nexport const DEFAULT_WORK_BUDGET = 20_000;\nexport const MAX_COMBINATION_SIZE = 5;\n\ninterface ComboSearch {\n examined: number;\n readonly budget: number;\n}\n\nexport function selectCoins(\n pool: readonly PoolEntry[],\n target: bigint,\n options: SelectorOptions = {}\n): SelectionPlan | null {\n if (target <= 0n) return null;\n const candidates = pool.filter((e) => e.amount > 0n).sort(byAmountAscending);\n let total = 0n;\n for (const c of candidates) total += c.amount;\n if (total < target) return null;\n\n const single = candidates.find((c) => c.amount === target);\n if (single) return { direct: [single.tokenId] };\n\n const search: ComboSearch = {\n examined: 0,\n budget: options.workBudget ?? DEFAULT_WORK_BUDGET,\n };\n const combo = findExactCombination(candidates, target, search);\n if (options.stats) options.stats.combinationsExamined = search.examined;\n if (combo) return { direct: combo.map((c) => c.tokenId) };\n\n return greedyWithSplit(candidates, target);\n}\n\nfunction byAmountAscending(a: PoolEntry, b: PoolEntry): number {\n if (a.amount !== b.amount) return a.amount < b.amount ? -1 : 1;\n return a.tokenId < b.tokenId ? -1 : a.tokenId > b.tokenId ? 1 : 0;\n}\n\nfunction greedyWithSplit(\n sortedAscending: readonly PoolEntry[],\n target: bigint\n): SelectionPlan | null {\n const direct: string[] = [];\n let sum = 0n;\n for (const candidate of sortedAscending) {\n const next = sum + candidate.amount;\n if (next < target) {\n direct.push(candidate.tokenId);\n sum = next;\n } else if (next === target) {\n direct.push(candidate.tokenId);\n return { direct };\n } else {\n const splitAmount = target - sum;\n return {\n direct,\n split: {\n tokenId: candidate.tokenId,\n splitAmount,\n remainderAmount: candidate.amount - splitAmount,\n },\n };\n }\n }\n return null;\n}\n\nfunction findExactCombination(\n sortedAscending: readonly PoolEntry[],\n target: bigint,\n search: ComboSearch\n): readonly PoolEntry[] | null {\n const maxSize = Math.min(MAX_COMBINATION_SIZE, sortedAscending.length);\n for (let size = 2; size <= maxSize; size++) {\n if (search.examined >= search.budget) return null;\n const window = orderNearestTo(sortedAscending, target / BigInt(size));\n const found = searchCombinationsOfSize(window, size, target, search);\n if (found) return found;\n }\n return null;\n}\n\n// Window ordering: candidates nearest target/size are tried first, so the\n// budget spends its work where exact sums are most likely.\nfunction orderNearestTo(entries: readonly PoolEntry[], pivot: bigint): PoolEntry[] {\n const distance = (e: PoolEntry): bigint =>\n e.amount >= pivot ? e.amount - pivot : pivot - e.amount;\n return [...entries].sort((a, b) => {\n const da = distance(a);\n const db = distance(b);\n if (da !== db) return da < db ? -1 : 1;\n return byAmountAscending(a, b);\n });\n}\n\nfunction searchCombinationsOfSize(\n window: readonly PoolEntry[],\n size: number,\n target: bigint,\n search: ComboSearch\n): readonly PoolEntry[] | null {\n const chosen: PoolEntry[] = [];\n const recurse = (start: number, sum: bigint): readonly PoolEntry[] | null => {\n if (chosen.length === size) {\n search.examined += 1;\n return sum === target ? [...chosen] : null;\n }\n for (let i = start; i < window.length; i++) {\n if (search.examined >= search.budget) return null;\n chosen.push(window[i]);\n const found = recurse(i + 1, sum + window[i].amount);\n chosen.pop();\n if (found) return found;\n }\n return null;\n };\n return recurse(0, 0n);\n}\n","// §5.4 SpendQueue — per-coin FIFO with skip-ahead; plan+reserve is one\n// synchronous critical section (no await between free-view read and reserve).\n\nimport { SphereError } from '../../../core/errors';\nimport { selectCoins, type PoolEntry, type SelectionPlan } from './selector';\nimport type { ReservationLedger } from './ledger';\n\nexport const QUEUE_TIMEOUT_MS = 30_000;\nexport const QUEUE_MAX_SIZE = 100;\n\nexport interface PlannedSpend {\n readonly reservationId: string;\n readonly plan: SelectionPlan;\n}\n\nexport type PlanOutcome =\n | { readonly kind: 'planned'; readonly spend: PlannedSpend }\n | { readonly kind: 'queued'; readonly settled: Promise<PlannedSpend> };\n\nexport interface SpendQueueDeps {\n readonly ledger: ReservationLedger;\n readonly getPool: (coinId: string) => readonly PoolEntry[];\n /** #777: is this NAMED token spendable whole right now? Same gates as pool(). */\n readonly spendableToken?: (tokenId: string) => boolean;\n readonly workBudget?: number;\n}\n\ninterface QueueEntry {\n readonly id: string;\n readonly coinId: string;\n readonly amount: bigint;\n readonly enqueuedAt: number;\n readonly resolve: (spend: PlannedSpend) => void;\n readonly reject: (error: Error) => void;\n readonly timer: ReturnType<typeof setTimeout>;\n}\n\ninterface ExpectedChange {\n readonly coinId: string;\n readonly amount: bigint;\n}\n\ninterface FreeView {\n readonly freeView: PoolEntry[];\n readonly freeTotal: bigint;\n /** Held by a reservation — an open intent's sources stay pinned until it converges. */\n readonly pinnedTotal: bigint;\n readonly pinnedBy: number;\n /** #738: non-null = the held-set is unproven, so NOTHING in this view is free. */\n readonly unproven: string | null;\n}\n\n/**\n * #737: the CODE is load-bearing (dApps key on it) but \"insufficient balance\" sent\n * a user auditing a treasury that was never short — every token was pinned by an\n * intent still converging. When something is pinned, the message says so.\n */\nfunction insufficientBalance(view: FreeView, amount: bigint): SphereError {\n if (view.unproven !== null) return new SphereError(view.unproven, 'SEND_INSUFFICIENT_BALANCE');\n const message =\n view.pinnedTotal > 0n\n ? `Insufficient spendable balance: need ${amount.toString()}, ${view.freeTotal.toString()} free, ` +\n `${view.pinnedTotal.toString()} pinned by ${String(view.pinnedBy)} transfer(s) still converging — ` +\n 'see payments.pendingTransfers(); do not re-send.'\n : 'Insufficient balance for this transaction';\n return new SphereError(message, 'SEND_INSUFFICIENT_BALANCE');\n}\n\nexport class SpendQueue {\n private readonly queues = new Map<string, QueueEntry[]>();\n private readonly expectedChange = new Map<string, ExpectedChange>();\n private destroyed = false;\n\n constructor(private readonly deps: SpendQueueDeps) {}\n\n plan(reservationId: string, request: { coinId: string; amount: string }): PlanOutcome {\n if (this.destroyed) {\n throw new SphereError('Module has been destroyed', 'MODULE_DESTROYED');\n }\n const amount = parseAmount(request.amount);\n const view = this.freeView(request.coinId);\n const { freeView, freeTotal } = view;\n if (freeTotal + this.expectedChangeTotal(request.coinId) < amount) {\n throw insufficientBalance(view, amount);\n }\n const plan = selectCoins(freeView, amount, { workBudget: this.deps.workBudget });\n if (plan !== null) {\n this.reservePlan(reservationId, plan, freeView);\n return { kind: 'planned', spend: { reservationId, plan } };\n }\n return { kind: 'queued', settled: this.enqueue(reservationId, request.coinId, amount) };\n }\n\n /**\n * #777: reserve a NAMED coinless source. Never queues — there is nothing to wait\n * for. A coin plan waits because some OTHER combination may free up; a named\n * token is either free now or held by a reservation that only its own transfer\n * can release, so queueing would block until a timeout on a spend that cannot\n * become possible.\n */\n planWhole(reservationId: string, tokenId: string): PlannedSpend {\n if (this.destroyed) {\n throw new SphereError('Module has been destroyed', 'MODULE_DESTROYED');\n }\n // #738 fail-closed, the same gate freeView() applies: while the held-set is\n // unproven nothing is spendable, or a restart could double-spend a source an\n // open intent already holds.\n const unproven = this.deps.ledger.unprovenReason();\n if (unproven !== null) {\n throw new SphereError(`Cannot spend yet: ${unproven}`, 'SEND_SYNC_PENDING');\n }\n if (this.deps.spendableToken?.(tokenId) !== true) {\n throw new SphereError(`Token ${tokenId} is not a spendable holding`, 'VALIDATION_ERROR');\n }\n const holder = this.deps.ledger.holderOf(tokenId);\n if (holder !== undefined) {\n throw new SphereError(\n `Token ${tokenId} is already reserved by transfer ${holder}`,\n 'VALIDATION_ERROR'\n );\n }\n this.deps.ledger.reserve(reservationId, [{ tokenId }]);\n return { reservationId, plan: { direct: [tokenId] } };\n }\n\n /**\n * The sources `plan()` WOULD pick right now, reserving nothing and queueing\n * nothing — a read-only probe used to warm blobs while the user is still\n * looking at the confirm screen.\n *\n * Deliberately side-effect free: reserving here would pin the user's balance\n * across think-time and strand it if they never press send. The consequence is\n * that the real `plan()` may pick differently (inventory moves, another send\n * reserves first); callers must treat the result as a HINT and tolerate a miss,\n * never as a commitment that these sources will be spent.\n */\n previewSelection(request: { coinId: string; amount: string }): readonly string[] {\n if (this.destroyed) return [];\n let amount: bigint;\n try {\n amount = parseAmount(request.amount);\n } catch {\n return []; // a malformed amount is the caller's problem at plan() time, not here\n }\n const { freeView, freeTotal } = this.freeView(request.coinId);\n if (freeTotal < amount) return []; // would throw or queue — nothing worth warming\n const plan = selectCoins(freeView, amount, { workBudget: this.deps.workBudget });\n if (plan === null) return [];\n return [...plan.direct, ...(plan.split !== undefined ? [plan.split.tokenId] : [])];\n }\n\n // Coverage math: free + Σ declared expected change of in-flight sends —\n // never the full amount of in-flight sources (§5.3).\n declareExpectedChange(transferId: string, coinId: string, amount: bigint): void {\n this.expectedChange.set(transferId, { coinId, amount });\n }\n\n clearExpectedChange(transferId: string): void {\n this.expectedChange.delete(transferId);\n }\n\n notifyChange(coinId: string): void {\n if (this.destroyed) return;\n const entries = this.queues.get(coinId);\n if (!entries) return;\n let i = 0;\n while (i < entries.length) {\n const entry = entries[i];\n if (this.tryServe(entry) === 'blocked') {\n i += 1;\n continue;\n }\n clearTimeout(entry.timer);\n entries.splice(i, 1);\n }\n if (entries.length === 0) this.queues.delete(coinId);\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n for (const entries of this.queues.values()) {\n for (const entry of entries) {\n clearTimeout(entry.timer);\n entry.reject(new SphereError('Module destroyed', 'MODULE_DESTROYED'));\n }\n }\n this.queues.clear();\n this.expectedChange.clear();\n }\n\n private tryServe(entry: QueueEntry): 'served' | 'rejected' | 'blocked' {\n if (Date.now() - entry.enqueuedAt > QUEUE_TIMEOUT_MS) {\n entry.reject(new SphereError('Send queue timeout', 'SEND_QUEUE_TIMEOUT'));\n return 'rejected';\n }\n const view = this.freeView(entry.coinId);\n const { freeView, freeTotal } = view;\n if (freeTotal + this.expectedChangeTotal(entry.coinId) < entry.amount) {\n entry.reject(insufficientBalance(view, entry.amount));\n return 'rejected';\n }\n const plan = selectCoins(freeView, entry.amount, { workBudget: this.deps.workBudget });\n if (plan === null) return 'blocked';\n try {\n this.reservePlan(entry.id, plan, freeView);\n } catch (e) {\n entry.reject(e instanceof Error ? e : new Error(String(e)));\n return 'rejected';\n }\n entry.resolve({ reservationId: entry.id, plan });\n return 'served';\n }\n\n private enqueue(id: string, coinId: string, amount: bigint): Promise<PlannedSpend> {\n if (this.totalQueued() >= QUEUE_MAX_SIZE) {\n throw new SphereError('Send queue is full', 'SEND_QUEUE_FULL');\n }\n let resolve!: (spend: PlannedSpend) => void;\n let reject!: (error: Error) => void;\n const settled = new Promise<PlannedSpend>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n settled.catch(() => {});\n const timer = setTimeout(() => this.expire(id, coinId), QUEUE_TIMEOUT_MS);\n const entry: QueueEntry = { id, coinId, amount, enqueuedAt: Date.now(), resolve, reject, timer };\n let queue = this.queues.get(coinId);\n if (!queue) {\n queue = [];\n this.queues.set(coinId, queue);\n }\n queue.push(entry);\n return settled;\n }\n\n private expire(id: string, coinId: string): void {\n const entries = this.queues.get(coinId);\n if (!entries) return;\n const index = entries.findIndex((e) => e.id === id);\n if (index === -1) return;\n const [entry] = entries.splice(index, 1);\n entry.reject(new SphereError('Send queue timeout', 'SEND_QUEUE_TIMEOUT'));\n if (entries.length === 0) this.queues.delete(coinId);\n }\n\n // Whole-token semantics: only fully-free tokens enter the selector pool. What\n // the reservations hold back is counted too — the refusal has to name it (#737).\n private freeView(coinId: string): FreeView {\n const freeView: PoolEntry[] = [];\n let freeTotal = 0n;\n let pinnedTotal = 0n;\n const holders = new Set<string>();\n // #738: the same rule the reporter applies — while the held-set is unproven\n // nothing is free. Placed here because freeView() is what plan() AND the\n // queued path (tryServe) both go through; gating only plan() left a queued\n // entry servable through a closed gate.\n const unproven = this.deps.ledger.unprovenReason();\n for (const entry of this.deps.getPool(coinId)) {\n if (entry.amount <= 0n) continue;\n const holder = unproven === null ? this.deps.ledger.holderOf(entry.tokenId) : entry.tokenId;\n if (holder === undefined) {\n freeView.push(entry);\n freeTotal += entry.amount;\n } else {\n pinnedTotal += entry.amount;\n holders.add(holder);\n }\n }\n return { freeView, freeTotal, pinnedTotal, pinnedBy: holders.size, unproven };\n }\n\n private expectedChangeTotal(coinId: string): bigint {\n let total = 0n;\n for (const change of this.expectedChange.values()) {\n if (change.coinId === coinId) total += change.amount;\n }\n return total;\n }\n\n private reservePlan(\n reservationId: string,\n plan: SelectionPlan,\n freeView: readonly PoolEntry[]\n ): void {\n const pool = new Set(freeView.map((e) => e.tokenId));\n const tokenIds = [...plan.direct, ...(plan.split ? [plan.split.tokenId] : [])];\n for (const tokenId of tokenIds) {\n if (!pool.has(tokenId)) {\n throw new SphereError('Planned token missing from pool', 'VALIDATION_ERROR');\n }\n }\n this.deps.ledger.reserve(reservationId, tokenIds.map((tokenId) => ({ tokenId })));\n }\n\n private totalQueued(): number {\n let total = 0;\n for (const entries of this.queues.values()) total += entries.length;\n return total;\n }\n}\n\nfunction parseAmount(raw: string): bigint {\n if (!/^\\d+$/.test(raw)) {\n throw new SphereError('Invalid send amount', 'VALIDATION_ERROR');\n }\n const amount = BigInt(raw);\n if (amount <= 0n) {\n throw new SphereError('Send amount must be positive', 'VALIDATION_ERROR');\n }\n return amount;\n}\n","// Composition helper for PaymentsFacade: the injected-deps surface and the\n// wiring of every built component (§5 layout). Policy stays in PaymentsFacade.\n\nimport { coalesced } from './async';\nimport { hexToBytes } from '../../core/crypto';\nimport { decryptField, encryptField } from '../../core/field-encryption';\nimport type { ITokenEngine, SplitCheckpointStore } from '../../token-engine/engine';\nimport type { TransferResult } from '../../types';\n\nimport type { ConnectionStatus, SendRequest } from './api';\nimport { isWholeIntent } from './machine/payload-view';\nimport type { DeliveryPort, StoragePort } from './ports';\nimport type { ScopedKV } from './stores';\nimport { History, type HistoryClient } from './history/History';\nimport { InventoryView, type PriceReader, type RegistryReader } from './inventory/InventoryView';\nimport { Receive, type ReceivedRecord, type StoredIncoming } from './receive/Receive';\nimport { Requests, type RequestMemoCodec, type RequestsWireClient } from './requests/Requests';\nimport { deriveOpenIntentHolds } from './convergence';\nimport type { RestoreDeps } from './restore';\nimport { ReservationLedger } from './select/ledger';\nimport { IntentPins } from './select/pins';\nimport { SpendQueue } from './select/queue';\nimport { createMachineStores, type MachineStores } from './machine/journal';\nimport { TransferMachine, type MachineDeps } from './machine/TransferMachine';\n\n/**\n * F13 makes `mint(params, { transferId, opIndex })` idempotent-recoverable — a\n * same-seed re-CALL recovers the existing certification via the E.2 probe\n * (pinned by tests/unit/token-engine/mint-recovery.test.ts) — so replay needs\n * no pre-derivation, just a safe re-call; a non-advertising engine falls back\n * to the inventory-guard + hold path (never a blind re-mint).\n */\nexport interface DeterministicMintCapable {\n readonly deterministicMint: true;\n}\n\nexport function supportsDeterministicMint(\n engine: ITokenEngine\n): engine is ITokenEngine & DeterministicMintCapable {\n return (engine as Partial<DeterministicMintCapable>).deterministicMint === true;\n}\n\nexport interface RecipientInfo {\n chainPubkey: string;\n /** The recipient's PROVEN network — `null` when nothing proved one (§5.6). */\n network: string | null;\n nametag?: string;\n}\n\nexport interface FacadeSession {\n start(): Promise<void>;\n stop(): Promise<void>;\n subscribeStream(\n stream: 'inventory' | 'mailbox' | 'payment_requests',\n handler: () => void\n ): () => void;\n /** §5.1: the latched server syncEpoch ('' before first server contact). */\n currentEpoch(): string;\n /**\n * §5.1 restore hook — REQUIRED so an unwired restore protocol is a COMPILE\n * ERROR: handlers run and are AWAITED on a syncEpoch change BEFORE any\n * stream nudge resumes. The facade registers handleEpochChange here.\n */\n subscribeEpochChange(handler: (epoch: string) => Promise<void>): () => void;\n /**\n * The session's CURRENT status — REQUIRED, and the ONE source `connectionStatus()`\n * and `connection:status` both come from ('offline' before first contact).\n */\n status(): ConnectionStatus;\n /**\n * Optional connection-status feed (same wiring pattern as the streams; the\n * emission point is the session's existing `connection:status` transition).\n * The facade's heartbeat resets its backoff on a 'connected' recovery.\n */\n subscribeStatus?(handler: (status: ConnectionStatus) => void): () => void;\n}\n\n/**\n * §5.1/§6 restore surface of the checkpoint store: re-POST the slot's cached\n * encrypt-once ciphertext byte-identical after a server restore (insert-once,\n * first-write-wins server-side). Returns false when no ciphertext is cached.\n */\nexport interface CheckpointReseeder {\n reseedCheckpoint(transferId: string, opIndex: number): Promise<boolean>;\n}\n\ninterface IntentWireLike {\n transferId: string;\n payload: string;\n createdAt: string;\n}\n\n/** Structural slice of WalletApiV2Client the facade consumes directly. */\nexport interface FacadeClient extends HistoryClient, RequestsWireClient {\n putIntent(transferId: string, payloadEnvelope: string, requiresSeedClose?: boolean): Promise<void>;\n listIntents(status?: 'open' | 'aborted'): Promise<IntentWireLike[]>;\n abortIntent(transferId: string): Promise<void>;\n completeIntent(transferId: string, signature?: string): Promise<void>;\n}\n\nexport interface PaymentsFacadeDeps {\n session: FacadeSession;\n client: FacadeClient;\n storagePort: StoragePort;\n deliveryPort: DeliveryPort;\n /** Reseeder REQUIRED: the restore protocol re-POSTs cached ciphertexts (§5.1). */\n checkpointStore: SplitCheckpointStore & CheckpointReseeder;\n /** Initial engine source; setEngine() swaps what FUTURE operations snapshot. */\n engineRef: () => ITokenEngine;\n kv: ScopedKV;\n registry: RegistryReader;\n price?: PriceReader;\n emit: (event: string, payload: unknown) => void;\n resolveRecipient: (identifier: string) => Promise<RecipientInfo | null>;\n signComplete: (transferId: string) => Promise<string>;\n /** S6 self-scoped field key: intent payload envelope + history memo/nametag. */\n fieldKey: Uint8Array;\n /** The session's network — a recipient not verifiably on it is refused (§5.6). */\n network: string;\n /** The network's NFT vessel token type (64 hex) every mintNft() mints under (#785). */\n nftTokenType: string;\n ownPubkey: string;\n ownNametag?: () => string | undefined;\n requestMemo: RequestMemoCodec;\n /** REQUIRED (§5.1): reads the session's current epoch — never a default. */\n syncEpoch: () => string;\n now?: () => number;\n newId?: () => string;\n workBudget?: number;\n receivePollMs?: number;\n}\n\n/** Derived (non-authoritative) tokenId→stateHash cache backing the ReceiveView seam. */\nexport type HeldStateCache = Map<string, string>;\n\nexport interface FacadeHooks {\n engine(): ITokenEngine;\n send(request: SendRequest): Promise<TransferResult>;\n /** §7 ownership — an attempt running in-process owns its own reservation (#737). */\n isActiveOp(transferId: string): boolean;\n /** Register a background op so stop() cannot return while it is still writing. */\n track(op: Promise<unknown>): void;\n}\n\nexport interface FacadeParts {\n ownPubkeyBytes: Uint8Array;\n view: InventoryView;\n ledger: ReservationLedger;\n pins: IntentPins;\n queue: SpendQueue;\n historyStore: History;\n machineStores: MachineStores;\n machineDeps: MachineDeps;\n machine: TransferMachine;\n heldStates: HeldStateCache;\n /** ONE coalescer over view.delta(), shared by the §9 wake and the receive drain. */\n refreshView: () => void;\n receiveLoop: Receive;\n requests: Requests;\n restoreDeps: RestoreDeps;\n}\n\nexport function composeFacadeParts(deps: PaymentsFacadeDeps, hooks: FacadeHooks): FacadeParts {\n const ownPubkeyBytes = hexToBytes(deps.ownPubkey);\n const ledger = new ReservationLedger();\n const view = new InventoryView({\n port: deps.storagePort,\n kv: deps.kv,\n emit: (event) => deps.emit(event, {}),\n // #737: a reserved token is unselectable, so it is never confirmed balance.\n // #738: while the held-set is unproven, EVERY token reads pinned — the report\n // must not call a token spendable that the queue is about to refuse to spend.\n isPinned: (tokenId) => ledger.unprovenReason() !== null || ledger.holderOf(tokenId) !== undefined,\n ...(deps.now !== undefined ? { now: deps.now } : {}),\n });\n const queue = new SpendQueue({\n ledger,\n getPool: (coinId) => view.pool(coinId),\n spendableToken: (tokenId) => view.spendableToken(tokenId),\n ...(deps.workBudget !== undefined ? { workBudget: deps.workBudget } : {}),\n });\n const historyStore = new History({\n client: deps.client,\n fieldKey: deps.fieldKey,\n registry: deps.registry,\n emit: (event, entry) => deps.emit(event, entry),\n ...(deps.now !== undefined ? { now: deps.now } : {}),\n ...(deps.newId !== undefined ? { newId: deps.newId } : {}),\n });\n const machineDeps = buildMachineDeps(deps, hooks, historyStore);\n const machineStores = createMachineStores(deps.kv);\n const heldStates: HeldStateCache = new Map();\n\n const refreshView = coalesced(() => view.delta(), hooks.track);\n return {\n ownPubkeyBytes,\n view,\n refreshView,\n ledger,\n pins: buildPins(deps, hooks, { ledger, view, machineStores, machineDeps }),\n queue,\n historyStore,\n machineStores,\n machineDeps,\n machine: new TransferMachine(machineDeps),\n heldStates,\n receiveLoop: buildReceive(deps, hooks, historyStore, heldStates, refreshView),\n requests: buildRequests(deps, hooks),\n restoreDeps: buildRestoreDeps(deps, machineDeps, machineStores, view),\n };\n}\n\n/** #737 pin lifecycle wiring (see select/pins.ts); the facade owns when it runs. */\nfunction buildPins(\n deps: PaymentsFacadeDeps,\n hooks: FacadeHooks,\n parts: {\n ledger: ReservationLedger;\n view: InventoryView;\n machineStores: MachineStores;\n machineDeps: MachineDeps;\n }\n): IntentPins {\n return new IntentPins({\n ledger: parts.ledger,\n openIntents: () => deriveOpenIntentHolds(parts.machineStores, parts.machineDeps.decryptPayload),\n isActive: (transferId) => hooks.isActiveOp(transferId),\n release: (tokenId) => {\n parts.view.release(tokenId);\n },\n changed: () => deps.emit('inventory:updated', {}),\n });\n}\n\n/** §5.1 restore protocol wiring (reseedAndReset's deps) — policy stays in the facade. */\nfunction buildRestoreDeps(\n deps: PaymentsFacadeDeps,\n machineDeps: MachineDeps,\n machineStores: MachineStores,\n view: InventoryView\n): RestoreDeps {\n return {\n stores: machineStores,\n kv: deps.kv,\n reput: (transferId, envelope, requiresSeedClose) =>\n machineDeps.intents.put(transferId, envelope, requiresSeedClose),\n reseedCheckpoint: (transferId, opIndex) => deps.checkpointStore.reseedCheckpoint(transferId, opIndex),\n decryptPayload: machineDeps.decryptPayload,\n fullRePull: () => view.onEpochReset(),\n attention: (transferId, code, detail) => {\n deps.emit(\n 'transfer:attention',\n detail === undefined ? { transferId, code } : { transferId, code, detail }\n );\n },\n };\n}\n\nfunction buildMachineDeps(\n deps: PaymentsFacadeDeps,\n hooks: FacadeHooks,\n historyStore: History\n): MachineDeps {\n return {\n engine: () => hooks.engine(),\n storage: deps.storagePort,\n delivery: deps.deliveryPort,\n intents: {\n put: (transferId, envelope, requiresSeedClose) =>\n deps.client.putIntent(transferId, envelope, requiresSeedClose),\n listOpen: () => deps.client.listIntents('open'),\n abort: (transferId) => deps.client.abortIntent(transferId),\n complete: (transferId, signature) => deps.client.completeIntent(transferId, signature),\n },\n checkpointStore: deps.checkpointStore,\n kv: deps.kv,\n encryptPayload: async (payload) => encryptField(deps.fieldKey, JSON.stringify(payload)),\n decryptPayload: async (envelope) => JSON.parse(decryptField(deps.fieldKey, envelope)) as unknown,\n signComplete: deps.signComplete,\n ownPubkey: hexToBytes(deps.ownPubkey),\n // sphere#487: the same live getter Requests uses — the delivery envelope is\n // the recipient's ONLY source for the sender's Unicity ID.\n ...(deps.ownNametag !== undefined ? { ownNametag: deps.ownNametag } : {}),\n emit: deps.emit,\n now: deps.now ?? Date.now,\n recordHistory: async ({ transferId, payload, committedAmount, committedAssets }) => {\n await historyStore.recordSent({\n transferId,\n // §5.9: the SETTLED amount, never payload.amount — the plan. A token\n // spend moved no coin: `assets: []` + tokenId (wallet-api#151 / §10).\n ...(isWholeIntent(payload)\n ? { assets: committedAssets ?? [], tokenId: payload.direct[0] }\n : { assets: [{ coinId: payload.coinId, amount: committedAmount }] }),\n recipientPubkey: payload.recipient,\n ...(payload.memo !== undefined ? { memo: payload.memo } : {}),\n });\n },\n };\n}\n\nfunction buildReceive(\n deps: PaymentsFacadeDeps,\n hooks: FacadeHooks,\n historyStore: History,\n heldStates: HeldStateCache,\n refreshView: () => void\n): Receive {\n return new Receive({\n delivery: deps.deliveryPort,\n engine: () => hooks.engine(),\n view: {\n heldState: (tokenId) => heldStates.get(tokenId) ?? null,\n store: async (entry: StoredIncoming) => {\n heldStates.set(entry.tokenId, entry.stateHash);\n },\n },\n kv: deps.kv,\n registry: deps.registry,\n recordReceived: (record) => recordReceived(historyStore, record),\n emit: (event, transfer) => deps.emit(event, transfer),\n refreshView,\n attention: (transferId, code, detail) => {\n deps.emit(\n 'transfer:attention',\n detail === undefined ? { transferId, code } : { transferId, code, detail }\n );\n },\n syncEpoch: deps.syncEpoch,\n // #770: the poll/wake drains Receive spawns itself must hold stop() too.\n track: hooks.track,\n ...(deps.now !== undefined ? { now: deps.now } : {}),\n });\n}\n\nasync function recordReceived(historyStore: History, record: ReceivedRecord): Promise<void> {\n await historyStore.recordReceived({\n tokenId: record.tokenId,\n stateHash: record.stateHash,\n assets: record.assets,\n ...(record.senderPubkey !== undefined ? { senderPubkey: record.senderPubkey } : {}),\n ...(record.senderNametag !== undefined ? { senderNametag: record.senderNametag } : {}),\n ...(record.memo !== undefined ? { memo: record.memo } : {}),\n timestamp: record.receivedAt,\n });\n}\n\nfunction buildRequests(deps: PaymentsFacadeDeps, hooks: FacadeHooks): Requests {\n return new Requests({\n client: deps.client,\n kv: deps.kv,\n ownPubkey: deps.ownPubkey,\n send: (request) => hooks.send(request),\n resolvePubkey: async (identifier) =>\n (await deps.resolveRecipient(identifier))?.chainPubkey ?? null,\n listAbortedTransferIds: async () =>\n (await deps.client.listIntents('aborted')).map((intent) => intent.transferId),\n emit: deps.emit,\n memo: deps.requestMemo,\n ...(deps.ownNametag !== undefined ? { ownNametag: deps.ownNametag } : {}),\n ...(deps.now !== undefined ? { now: deps.now } : {}),\n });\n}\n","import type { MintParams } from '../../token-engine';\n\nexport function mintParams(recipientPubkey: Uint8Array, coinId: string, amount: bigint): MintParams {\n return { recipientPubkey, value: { assets: [{ coinId, amount }] } };\n}\n","import { sha256 } from '@noble/hashes/sha2.js';\n\nimport { bytesToHex } from '../../core/crypto';\nimport { SphereError } from '../../core/errors';\nimport type { ITokenEngine } from '../../token-engine/engine';\nimport type { SphereToken } from '../../token-engine/types';\n\nimport type { MintResult } from './api';\nimport { supportsDeterministicMint } from './compose';\nimport type { RecordMintInput } from './history/History';\nimport { messageOf } from './machine/payload';\nimport { mintParams } from './mint-params';\nimport type { ListStore } from './machine/journal';\nimport type { MintJournalEntry } from './stores';\nimport type { StoragePort } from './ports';\n\nexport const ATTENTION_MINT_UNRESOLVED = 'mint:unresolved';\n\n/** What finalising a certified mint needs — shared by the coin and the NFT mint. */\nexport interface FinalizeMintDeps {\n readonly engine: ITokenEngine;\n readonly storagePort: Pick<StoragePort, 'uploadBlobs' | 'applyDelta'>;\n readonly recordMint: (input: RecordMintInput) => Promise<void>;\n readonly noteHeldState: (tokenId: string, stateHash: string) => void;\n readonly refreshView: () => void;\n}\n\n/** Everything the journal-first mint needs, injected so the path stays testable. */\nexport interface MintDeps extends FinalizeMintDeps {\n readonly mintJournal: ListStore<MintJournalEntry>;\n readonly armHeartbeat: () => void;\n readonly ownPubkeyBytes: Uint8Array;\n readonly now: () => number;\n}\n\n/** What replaying a mint journal needs on top of minting. */\nexport interface MintReplayDeps {\n /** §7 ownership: an entry whose live call is still running is never replayed. */\n readonly isActiveOp: (mintId: string) => boolean;\n readonly tokenInServerInventory: (tokenId: string) => Promise<boolean>;\n}\n\nexport interface CoinReplayDeps extends MintDeps, MintReplayDeps {\n readonly emit: (event: string, payload: unknown) => void;\n}\n\nexport interface FinalizeMintInput {\n readonly mintId: string;\n readonly token: SphereToken;\n /** `[]` for an NFT: a mint that names no coin never writes `coinId: ''` (wallet-api#151). */\n readonly assets: RecordMintInput['assets'];\n /** The journal holding `mintId`; its entry goes only after the apply and the record. */\n readonly journal: { removeByKey(key: string): Promise<void> };\n}\n\n/**\n * Journal-first self-mint: the entry is durable BEFORE the chain op, so a crash\n * converges by the F13 same-seed re-call rather than minting twice.\n */\nexport function runMintUnderJournal(\n deps: MintDeps,\n input: { mintId: string; coinId: string; amount: bigint }\n): Promise<MintResult> {\n return mintUnderJournal(deps, input);\n}\n\nasync function mintUnderJournal(\ndeps: MintDeps,\ninput: { mintId: string; coinId: string; amount: bigint }\n): Promise<MintResult> {\nconst { mintId, coinId, amount } = input;\nconst engine = deps.engine;\n // tokenId stays '' until mint returns; replay converges via the F13 same-seed re-call.\n const entry: MintJournalEntry = {\n mintId,\n coinId,\n amount: amount.toString(),\n tokenId: '',\n createdAt: deps.now(),\n };\n await deps.mintJournal.upsert(entry);\n let token: SphereToken;\n try {\n token = await engine.mint(mintParams(deps.ownPubkeyBytes, coinId, amount), { transferId: mintId });\n } catch (err) {\n // Entry retained: the heartbeat / start() replay resolves it (inventory check / F13 seed).\n deps.armHeartbeat();\n return { success: false, error: messageOf(err) };\n }\n if (token.blob.tokenId !== entry.tokenId) {\n await deps.mintJournal.upsert({ ...entry, tokenId: token.blob.tokenId });\n }\n try {\n const assets = [{ coinId, amount: amount.toString() }];\n await finalizeMint(deps, { mintId, token, assets, journal: deps.mintJournal });\n } catch (err) {\n deps.armHeartbeat();\n return { success: false, tokenId: token.blob.tokenId, error: messageOf(err) };\n }\n return { success: true, tokenId: token.blob.tokenId };\n}\n\nexport async function finalizeMint(deps: FinalizeMintDeps, input: FinalizeMintInput): Promise<void> {\n const { mintId, token } = input;\n const bytes = token.blob.token;\n const digest = bytesToHex(sha256(bytes));\n const keys = await deps.storagePort.uploadBlobs([{ sha256: digest, bytes }]);\n const key = keys.get(digest);\n if (key === undefined) {\n throw new SphereError(`no upload key returned for mint blob ${digest}`, 'STORAGE_ERROR');\n }\n await deps.storagePort.applyDelta({\n transferId: mintId,\n spent: [],\n added: [{ tokenId: token.blob.tokenId, key }],\n });\n await deps.recordMint({ tokenId: token.blob.tokenId, assets: input.assets });\n await input.journal.removeByKey(mintId);\n deps.noteHeldState(token.blob.tokenId, (await deps.engine.deliveryKeys(bytes)).stateHash);\n deps.refreshView();\n}\n\n/** @returns how many coin journal entries were RESOLVED (cleared) — heartbeat progress. */\nexport async function replayCoinMints(deps: CoinReplayDeps): Promise<number> {\n let resolved = 0;\n for (const entry of await deps.mintJournal.list()) {\n if (deps.isActiveOp(entry.mintId)) continue; // its live mint still owns it\n try {\n if (await replayCoinMint(deps, entry)) resolved += 1;\n } catch {\n // Entry retained — replayed again at the next pass / start().\n }\n }\n return resolved;\n}\n\nasync function replayCoinMint(deps: CoinReplayDeps, entry: MintJournalEntry): Promise<boolean> {\n if (entry.tokenId !== '' && (await deps.tokenInServerInventory(entry.tokenId))) {\n await deps.mintJournal.removeByKey(entry.mintId);\n return true;\n }\n if (!supportsDeterministicMint(deps.engine)) {\n // Without the F13 seed a re-mint would create a SECOND token: hold + alert.\n deps.emit('transfer:attention', { transferId: entry.mintId, code: ATTENTION_MINT_UNRESOLVED });\n return false; // held, not resolved — never counts as heartbeat progress\n }\n const token = await deps.engine.mint(mintParams(deps.ownPubkeyBytes, entry.coinId, BigInt(entry.amount)), {\n transferId: entry.mintId,\n });\n if (token.blob.tokenId !== entry.tokenId) {\n await deps.mintJournal.upsert({ ...entry, tokenId: token.blob.tokenId });\n }\n const assets = [{ coinId: entry.coinId, amount: entry.amount }];\n await finalizeMint(deps, { mintId: entry.mintId, token, assets, journal: deps.mintJournal });\n return true;\n}\n","// §5.9 NFT mint (#785): journal-first like the coin mint, but the journal holds the\n// planned BYTES — payload, salt and type — so a resume re-submits exactly what the\n// first attempt did, whatever the engine's signing or salt source.\n\nimport { bytesToHex, hexToBytes } from '../../core/crypto';\nimport { SphereError } from '../../core/errors';\nimport type { NftMintPlan } from '../../token-engine/types';\n\nimport type { MintNftRequest, MintResult } from './api';\nimport type { ListStore } from './machine/journal';\nimport { messageOf } from './machine/payload';\nimport { finalizeMint, type FinalizeMintDeps, type MintReplayDeps } from './mint';\nimport type { NftMintJournalEntry } from './stores';\n\nexport interface NftMintDeps extends FinalizeMintDeps {\n readonly nftMintJournal: ListStore<NftMintJournalEntry>;\n readonly armHeartbeat: () => void;\n /** The first owner: an NFT always mints to the wallet itself. */\n readonly ownPubkeyBytes: Uint8Array;\n /** The composed network's NFT vessel token type, 64 hex. */\n readonly nftTokenType: string;\n readonly now: () => number;\n}\n\nexport type NftReplayDeps = NftMintDeps & MintReplayDeps;\n\n/** Genesis payload cap, NftSigned wrapper included: wallet-api refuses an oversize blob only after the mint certified. */\nexport const NFT_MAX_PAYLOAD_BYTES = 1024 * 1024;\n\nfunction assertPayloadSize(data: Uint8Array): void {\n if (data.length <= NFT_MAX_PAYLOAD_BYTES) return;\n throw new SphereError(\n `NFT payload is ${data.length} bytes, over the ${NFT_MAX_PAYLOAD_BYTES}-byte limit: link large files with NftLink`,\n 'VALIDATION_ERROR'\n );\n}\n\n/** Plan, journal, mint, finalise. A refused payload fails with nothing journaled and nothing minted. */\nexport async function runNftMintUnderJournal(\n deps: NftMintDeps,\n input: { mintId: string; request: MintNftRequest }\n): Promise<MintResult> {\n let plan: NftMintPlan;\n try {\n plan = await deps.engine.buildNftMint({\n recipientPubkey: deps.ownPubkeyBytes,\n content: input.request.content,\n sign: input.request.sign ?? true,\n tokenType: hexToBytes(deps.nftTokenType),\n });\n // Before the journal: a blob the server will refuse must never reach the chain.\n assertPayloadSize(plan.data);\n } catch (err) {\n return { success: false, error: messageOf(err) };\n }\n const entry = journalEntryOf(input.mintId, plan, deps.now());\n await deps.nftMintJournal.upsert(entry);\n try {\n await mintJournaled(deps, entry);\n } catch (err) {\n // Entry retained: the heartbeat / start() replay re-submits these same bytes.\n deps.armHeartbeat();\n return { success: false, tokenId: entry.tokenId, error: messageOf(err) };\n }\n return { success: true, tokenId: entry.tokenId };\n}\n\n/** @returns how many NFT journal entries were RESOLVED (cleared) — heartbeat progress. */\nexport async function replayNftMints(deps: NftReplayDeps): Promise<number> {\n let resolved = 0;\n for (const entry of await deps.nftMintJournal.list()) {\n if (deps.isActiveOp(entry.mintId)) continue; // its live mintNft still owns it\n try {\n if (await deps.tokenInServerInventory(entry.tokenId)) {\n await deps.nftMintJournal.removeByKey(entry.mintId);\n } else {\n await mintJournaled(deps, entry);\n }\n resolved += 1;\n } catch {\n // Entry retained — replayed again at the next pass / start().\n }\n }\n return resolved;\n}\n\nfunction journalEntryOf(mintId: string, plan: NftMintPlan, createdAt: number): NftMintJournalEntry {\n return {\n mintId,\n tokenId: plan.tokenId,\n dataHex: bytesToHex(plan.data),\n saltHex: bytesToHex(plan.salt),\n tokenTypeHex: bytesToHex(plan.tokenType),\n createdAt,\n };\n}\n\n/** Mint exactly the journaled bytes, then finalise. A throw leaves the entry journaled. */\nasync function mintJournaled(deps: NftMintDeps, entry: NftMintJournalEntry): Promise<void> {\n const params = {\n recipientPubkey: deps.ownPubkeyBytes,\n data: hexToBytes(entry.dataHex),\n tokenType: hexToBytes(entry.tokenTypeHex),\n salt: hexToBytes(entry.saltHex),\n };\n const token = await deps.engine.mintDataToken(params, { transferId: entry.mintId });\n if (token.blob.tokenId !== entry.tokenId) {\n // Never finalise a token the plan did not name.\n throw new SphereError(`minted token ${token.blob.tokenId}, but the plan names ${entry.tokenId}`, 'VALIDATION_ERROR');\n }\n await finalizeMint(deps, { mintId: entry.mintId, token, assets: [], journal: deps.nftMintJournal });\n}\n","// §5.2 NFT reads (#785): a held token's genesis payload through the engine's\n// never-throwing NFT reader, behind a facade-owned bounded LRU.\n\nimport { SphereError } from '../../../core/errors';\nimport { logger } from '../../../core/logger';\nimport type { ITokenEngine } from '../../../token-engine/engine';\nimport type { NftView } from '../api';\nimport type { StoragePort } from '../ports';\n\nimport type { InventoryView } from './InventoryView';\n\nexport const NFT_CACHE_MAX = 256;\n\n/**\n * Token id → NFT reading, where `null` caches \"not an NFT\" so a list view never\n * refetches it. A genesis payload never changes for a token id, so no entry goes stale.\n */\nexport class NftCache {\n private readonly entries = new Map<string, NftView | null>();\n\n constructor(private readonly max = NFT_CACHE_MAX) {}\n\n /** `undefined` = not cached. A hit becomes the most recently used entry. */\n get(tokenId: string): NftView | null | undefined {\n const view = this.entries.get(tokenId);\n if (view === undefined) return undefined;\n this.entries.delete(tokenId);\n this.entries.set(tokenId, view);\n return view;\n }\n\n set(tokenId: string, view: NftView | null): void {\n this.entries.delete(tokenId);\n this.entries.set(tokenId, view);\n const oldest = this.entries.keys().next().value;\n if (this.entries.size > this.max && oldest !== undefined) this.entries.delete(oldest);\n }\n}\n\nexport interface NftReadDeps {\n readonly engine: ITokenEngine;\n readonly view: Pick<InventoryView, 'stateHashOf'>;\n readonly storagePort: Pick<StoragePort, 'getBlobs'>;\n readonly cache: NftCache;\n}\n\n/** One held token read as an NFT; `null` = not a recognised NFT. */\nexport async function readNft(deps: NftReadDeps, tokenId: string): Promise<NftView | null> {\n if (deps.view.stateHashOf(tokenId) === undefined) {\n throw new SphereError(`Token ${tokenId} is not in inventory`, 'VALIDATION_ERROR');\n }\n const cached = deps.cache.get(tokenId);\n if (cached !== undefined) return cached;\n const bytes = (await deps.storagePort.getBlobs([tokenId])).get(tokenId);\n if (bytes === undefined) {\n throw new SphereError(`Token ${tokenId} has no blob in storage`, 'STORAGE_ERROR');\n }\n return decodeView(deps, tokenId, bytes);\n}\n\n/** Held ids read as NFTs, with ONE blob fetch for all cache misses. Anything unreadable is absent. */\nexport async function readNfts(\n deps: NftReadDeps,\n tokenIds: readonly string[]\n): Promise<ReadonlyMap<string, NftView>> {\n const held = [...new Set(tokenIds)].filter((tokenId) => deps.view.stateHashOf(tokenId) !== undefined);\n const views = new Map<string, NftView | null>();\n const misses: string[] = [];\n for (const tokenId of held) {\n const cached = deps.cache.get(tokenId);\n if (cached === undefined) misses.push(tokenId);\n else views.set(tokenId, cached);\n }\n const blobs = misses.length > 0 ? await deps.storagePort.getBlobs(misses) : new Map<string, Uint8Array>();\n for (const tokenId of misses) {\n const bytes = blobs.get(tokenId);\n if (bytes !== undefined) views.set(tokenId, await decodeView(deps, tokenId, bytes).catch(() => null));\n }\n const out = new Map<string, NftView>();\n for (const tokenId of held) {\n const view = views.get(tokenId);\n if (view) out.set(tokenId, view);\n }\n return out;\n}\n\n/** Cached only once decoded: a blob that failed to decode is re-read next time, not remembered as \"not an NFT\". */\nasync function decodeView(deps: NftReadDeps, tokenId: string, bytes: Uint8Array): Promise<NftView | null> {\n let view: NftView | null;\n try {\n const token = await deps.engine.decodeToken({ tokenId, token: bytes });\n if (token.blob.tokenId !== tokenId) {\n throw new SphereError(`the blob served for ${tokenId} decodes as ${token.blob.tokenId}`, 'STORAGE_ERROR');\n }\n const reading = await deps.engine.readNft(token);\n view = reading === null ? null : { tokenId, ...reading };\n } catch (err) {\n logger.warn('PaymentsV2', `NFT read: token ${tokenId} did not decode — ${String(err)}`);\n throw err;\n }\n deps.cache.set(tokenId, view);\n return view;\n}\n","import { SphereError } from '../../../core/errors';\nimport type { ITokenEngine } from '../../../token-engine/engine';\nimport type { StoragePort } from '../ports';\n\nimport type { InventoryView } from './InventoryView';\n\nexport interface TokenDataDeps {\n readonly engine: ITokenEngine;\n readonly view: Pick<InventoryView, 'stateHashOf'>;\n readonly storagePort: Pick<StoragePort, 'getBlobs'>;\n}\n\n/** A token's genesis payload, or null. Fetched on demand. */\nexport async function readTokenData(\n deps: TokenDataDeps,\n tokenId: string\n): Promise<Uint8Array | null> {\n if (deps.view.stateHashOf(tokenId) === undefined) {\n throw new SphereError(`Token ${tokenId} is not in inventory`, 'VALIDATION_ERROR');\n }\n const bytes = (await deps.storagePort.getBlobs([tokenId])).get(tokenId);\n if (bytes === undefined) {\n throw new SphereError(`Token ${tokenId} has no blob in storage`, 'STORAGE_ERROR');\n }\n return deps.engine.readTokenData(await deps.engine.decodeToken({ tokenId, token: bytes }));\n}\n","import { SphereError } from '../../core/errors';\nimport type { ITokenEngine } from '../../token-engine/engine';\nimport type { Token } from '../../types';\n\nimport { buildWholePayload } from './machine/payload';\nimport { buildOps, type MachinePlan } from './machine/TransferMachine';\nimport type { SendWholeTokenRequest } from './api';\nimport { transferringToken, type RegistryReader } from './inventory/presentation';\nimport type { StoragePort } from './ports';\n\nexport interface WholeSpendDeps {\n readonly engine: ITokenEngine;\n readonly storagePort: Pick<StoragePort, 'getBlobs'>;\n readonly registry: RegistryReader;\n readonly now: number;\n}\n\nexport interface WholeSpendInput {\n readonly transferId: string;\n readonly recipientPubkey: string;\n readonly request: SendWholeTokenRequest;\n readonly sourceIds: readonly string[];\n /** NFT-scoped entry point sets this: `nft:transfer` must not move coins. */\n readonly requireCoinless: boolean;\n}\n\n/**\n * The token-addressed twin of the facade's `materialize`: one named source, never a\n * split. `sourceTokens` become the result's `tokens`, so they list every asset the\n * named token carries — empty only for a coinless one, which moves no amount.\n */\nexport async function materializeWholeSpend(\n deps: WholeSpendDeps,\n input: WholeSpendInput\n): Promise<{\n transferId: string;\n coinId: string;\n plan: MachinePlan;\n sourceIds: readonly string[];\n sourceTokens: Token[];\n}> {\n const { engine } = deps;\n const tokenId = input.request.tokenId;\n const bytes = (await deps.storagePort.getBlobs([tokenId])).get(tokenId);\n if (bytes === undefined) {\n throw new SphereError(`Selected source ${tokenId} has no blob in storage`, 'STORAGE_ERROR');\n }\n const token = await engine.decodeToken({ tokenId, token: bytes });\n // A whole spend moves the token AS IS, so a valued source is fine. `bare_collection`\n // is not: its coins are real but undecodable here, so the move would happen while\n // history could only say `assets: []`. The BLOB decides, never the mirror.\n if (token.valueEnvelope === 'bare_collection') {\n throw new SphereError(\n `Token ${tokenId} carries a value envelope this SDK cannot read, so its coins ` +\n 'cannot be accounted for; it cannot be sent',\n 'VALIDATION_ERROR'\n );\n }\n if (input.requireCoinless && token.value !== null) {\n throw new SphereError(\n `Token ${tokenId} carries coin value and cannot be sent with sendCoinless — use ` +\n 'sendWholeToken, which requires coin-transfer authority',\n 'VALIDATION_ERROR'\n );\n }\n const keys = await engine.deliveryKeys(bytes);\n const payload = buildWholePayload(input.recipientPubkey, input.request, {\n [tokenId]: { local: keys.stateHash, protocol: keys.stateHash },\n });\n const plan: MachinePlan = {\n transferId: input.transferId,\n recipientPubkey: input.recipientPubkey,\n payload,\n ops: buildOps(payload),\n sources: new Map([[tokenId, token]]),\n ...(input.request.memo !== undefined ? { memo: input.request.memo } : {}),\n };\n const sourceTokens = (token.value?.assets ?? []).map((asset) =>\n transferringToken(tokenId, asset.coinId, asset.amount, deps.registry, deps.now)\n );\n return { transferId: input.transferId, coinId: '', plan, sourceIds: input.sourceIds, sourceTokens };\n}\n","import { isPossiblyCommittedSendOutcome, PartialSendConflictError, SphereError } from '../../core/errors';\n\n/** The parts of a send run these shapers read. */\nexport interface PartialRun {\n readonly amount: string;\n readonly delivered: readonly string[];\n readonly firstPartialId: string | undefined;\n}\n\n/** Once anything was delivered, the failure is a SHORTFALL: re-plan the remainder, never the total. */\nexport function partialize(err: unknown, run: PartialRun): unknown {\n if (run.delivered.length === 0) return err;\n return new PartialSendConflictError(\n 'Part of your payment was sent; the remaining amount could not be completed (see cause). The delivered portion is final — re-plan only the shortfall, never the full amount.',\n run.firstPartialId ?? '',\n [...run.delivered],\n run.amount,\n err\n );\n}\n\n/** #441: possibly-committed errors must carry the transferId for the settling journal. */\nexport function stampTransferId(err: unknown, transferId: string): void {\n if (\n err instanceof SphereError &&\n isPossiblyCommittedSendOutcome(err) &&\n err.transferId === undefined\n ) {\n err.transferId = transferId;\n }\n}\n","// §5.6 recipient gate: the cross-network deposit trap — a deposit keys the\n// recipient under the SENDER's network and the server 200s an entry the\n// recipient never queries. TRANSITION (#734) — docs/PAYMENTS-V2-DESIGN.md §5.6.\n\nimport { SphereError } from '../../core/errors';\n\nimport type { RecipientInfo } from './compose';\n\nexport const ATTENTION_RECIPIENT_NETWORK_UNVERIFIED = 'recipient:network-unverified';\n\nexport interface RecipientGateDeps {\n resolveRecipient: (identifier: string) => Promise<RecipientInfo | null>;\n network: string;\n emit: (event: string, payload: unknown) => void;\n}\n\nexport async function requireSameNetworkRecipient(\n deps: RecipientGateDeps,\n identifier: string\n): Promise<RecipientInfo> {\n const recipient = await deps.resolveRecipient(identifier);\n if (recipient === null || recipient.chainPubkey === '') {\n throw new SphereError(`Recipient ${identifier} has no published chain pubkey`, 'INVALID_RECIPIENT');\n }\n if (recipient.network === null) {\n deps.emit('transfer:attention', {\n transferId: '', // the gate precedes plan allocation — no transferId exists yet\n code: ATTENTION_RECIPIENT_NETWORK_UNVERIFIED,\n detail: `could not verify the network of recipient ${identifier} — assuming this session's \"${deps.network}\"`,\n });\n return recipient;\n }\n // #734 owes this compare a canonical name (`testnet` aliases `testnet2`) — §5.6.\n if (recipient.network !== deps.network) {\n throw new SphereError(\n `Recipient ${identifier} is on network \"${recipient.network}\" but this session is on \"${deps.network}\" — a cross-network deposit is unrecoverable`,\n 'INVALID_RECIPIENT'\n );\n }\n return recipient;\n}\n","// §5.1 restore — THE invariant, once: after a syncEpoch change, intents and\n// checkpoint progress re-seed from the §6 backstops BEFORE anything resumes;\n// no stream resumes a pre-restore cursor; a rejected re-seed KEEPS+alerts (E.3).\n\nimport { STORE_KEYS, type ScopedKV, type StreamName } from './stores';\nimport type { AttentionEmitter, MachineStores } from './machine/journal';\nimport type { IntentPayload } from './machine/types';\n\nexport const ATTENTION_RESEED_REJECTED = 'intent:reseed-rejected';\n\nconst ALL_STREAMS: readonly StreamName[] = ['inventory', 'mailbox', 'payment_requests', 'history'];\n\nexport interface RestoreDeps {\n readonly stores: MachineStores;\n readonly kv: ScopedKV;\n readonly reput: (transferId: string, envelope: string, requiresSeedClose: boolean) => Promise<void>;\n readonly reseedCheckpoint: (transferId: string, opIndex: number) => Promise<boolean>;\n readonly decryptPayload: (envelope: string) => Promise<unknown>;\n readonly fullRePull: () => Promise<void>;\n readonly attention: AttentionEmitter;\n}\n\nexport async function reseedAndReset(deps: RestoreDeps): Promise<void> {\n for (const entry of await deps.stores.backstop.list()) {\n if (entry.disposition !== 'open') continue; // #676: a local abort is never resurrected\n try {\n await deps.reput(entry.transferId, entry.payloadEnvelope, entry.requiresSeedClose);\n if (entry.requiresSeedClose) {\n await deps.reseedCheckpoint(entry.transferId, await splitOpIndex(deps, entry.payloadEnvelope));\n }\n } catch (err) {\n deps.attention(entry.transferId, ATTENTION_RESEED_REJECTED, err instanceof Error ? err.message : String(err));\n }\n }\n for (const stream of ALL_STREAMS) await deps.kv.remove(STORE_KEYS.streamCursor(stream));\n await deps.fullRePull();\n}\n\n// E.1: split = direct.length.\nasync function splitOpIndex(deps: RestoreDeps, envelope: string): Promise<number> {\n const payload = (await deps.decryptPayload(envelope)) as Partial<IntentPayload>;\n return Array.isArray(payload.direct) ? payload.direct.length : 0;\n}\n","import type { InventoryView } from './inventory/InventoryView';\nimport type { StoragePort } from './ports';\nimport type { SpendQueue } from './select/queue';\n\n/** Source blobs fetched ahead of a send, scoped to the state each token sat at (F6). */\nexport class PrewarmCache {\n private readonly entries = new Map<string, Uint8Array>();\n private generation = 0;\n\n private static key(tokenId: string, stateHash: string): string {\n return `${tokenId}:${stateHash}`;\n }\n\n /** Claim the cache for a warm about to start; supersedes any warm already running. */\n begin(): number {\n this.entries.clear();\n this.generation += 1;\n return this.generation;\n }\n\n /**\n * Publish a warm's result, unless it was cancelled or superseded while its\n * fetch was in flight — a cancel that only cleared what had landed so far\n * would be undone by the continuation of the very warm it cancelled.\n */\n commit(generation: number, warmed: readonly (readonly [string, string, Uint8Array])[]): void {\n if (generation !== this.generation) return;\n for (const [tokenId, stateHash, bytes] of warmed) {\n this.entries.set(PrewarmCache.key(tokenId, stateHash), bytes);\n }\n }\n\n get(tokenId: string, stateHash: string | undefined): Uint8Array | undefined {\n if (stateHash === undefined) return undefined;\n return this.entries.get(PrewarmCache.key(tokenId, stateHash));\n }\n\n clear(): void {\n this.entries.clear();\n this.generation += 1;\n }\n\n get size(): number {\n return this.entries.size;\n }\n}\n\nexport interface WarmDeps {\n readonly queue: SpendQueue;\n readonly view: Pick<InventoryView, 'stateHashOf' | 'delta'>;\n readonly storagePort: Pick<StoragePort, 'getBlobs'>;\n readonly cache: PrewarmCache;\n}\n\n/** Reserves nothing and throws nothing: the send re-fetches whatever is missing. */\nexport async function warmSendSources(\n deps: WarmDeps,\n request: { coinId: string; amount: string }\n): Promise<void> {\n const ids = deps.queue.previewSelection(request);\n if (ids.length === 0) return;\n const generation = deps.cache.begin();\n const at = new Map(ids.map((id) => [id, deps.view.stateHashOf(id)]));\n let blobs: Map<string, Uint8Array>;\n try {\n blobs = await deps.storagePort.getBlobs([...ids]);\n } catch {\n return;\n }\n const warmed: (readonly [string, string, Uint8Array])[] = [];\n for (const [tokenId, bytes] of blobs) {\n const stateHash = at.get(tokenId);\n if (stateHash !== undefined) warmed.push([tokenId, stateHash, bytes]);\n }\n deps.cache.commit(generation, warmed);\n}\n\n/**\n * Warm where the token still sits at its warmed state; single-use. Refreshes the\n * mirror FIRST — warming and consuming both read `stateHashOf`, so they agree\n * even when the server has moved on, and the uncached path reads the server's\n * current blob. Unverifiable freshness re-fetches instead.\n */\nexport async function takeSourceBlobs(\n deps: Pick<WarmDeps, 'view' | 'storagePort' | 'cache'>,\n sourceIds: readonly string[]\n): Promise<Map<string, Uint8Array>> {\n const blobs = new Map<string, Uint8Array>();\n const missing: string[] = [];\n let trustCache = deps.cache.size > 0;\n if (trustCache) {\n try {\n await deps.view.delta();\n } catch {\n trustCache = false;\n }\n }\n for (const tokenId of sourceIds) {\n const warm = trustCache ? deps.cache.get(tokenId, deps.view.stateHashOf(tokenId)) : undefined;\n if (warm === undefined) missing.push(tokenId);\n else blobs.set(tokenId, warm);\n }\n deps.cache.clear();\n if (missing.length > 0) {\n for (const [tokenId, bytes] of await deps.storagePort.getBlobs(missing)) {\n blobs.set(tokenId, bytes);\n }\n }\n return blobs;\n}\n","// §4 of docs/PAYMENTS-V2-DESIGN.md — the PaymentsV2 facade. The send() POLICY\n// lives here (bounded re-plan, remainder accumulation, keep-open rethrow);\n// the TransferMachine stays policy-free. Wiring lives in compose.ts.\n\n\nimport {\n PartialSendConflictError,\n SphereError,\n isPossiblyCommittedSendOutcome,\n} from '../../core/errors';\nimport { randomUUID } from '../../core/uuid';\nimport type { ITokenEngine } from '../../token-engine/engine';\nimport type { SphereToken } from '../../token-engine/types';\nimport type { Asset, IncomingTransfer, Token, TokenTransferDetail, TransferResult } from '../../types';\n\nimport type { CoinlessToken, ConnectionStatus, HistoryPage, MintNftRequest, MintResult, NftView, PaymentsV2, PendingTransfer, SendRequest, SendWholeTokenRequest } from './api';\nimport { SerialChain, SingleFlight } from './async';\nimport { ConvergenceHeartbeat, Converger, derivePendingTransfers } from './convergence';\nimport { NftCache, readNft, readNfts, type NftReadDeps } from './inventory/nft-read';\nimport { readTokenData } from './inventory/token-data';\nimport { type CoinReplayDeps, replayCoinMints, runMintUnderJournal } from './mint';\nimport { type NftReplayDeps, replayNftMints, runNftMintUnderJournal } from './mint-nft';\nimport { materializeWholeSpend } from './send-whole';\nimport { partialize, stampTransferId } from './send-errors';\nimport { requireSameNetworkRecipient } from './recipient';\nimport { reseedAndReset, type RestoreDeps } from './restore';\nimport { PrewarmCache, takeSourceBlobs, warmSendSources, type WarmDeps } from './prewarm-cache';\nimport type { ShortfallEntry } from './stores';\nimport type { History } from './history/History';\nimport type { InventoryView } from './inventory/InventoryView';\nimport { transferringToken } from './inventory/presentation';\nimport type { Receive } from './receive/Receive';\nimport type { Requests } from './requests/Requests';\nimport type { ReservationLedger } from './select/ledger';\nimport type { IntentPins } from './select/pins';\nimport type { SpendQueue, PlannedSpend } from './select/queue';\nimport type { MachineStores } from './machine/journal';\nimport { buildOps, classifyError, type MachineDeps, type MachinePlan, type TransferMachine } from './machine/TransferMachine';\nimport { buildPayload, messageOf } from './machine/payload';\nimport {\n composeFacadeParts,\n type HeldStateCache,\n type PaymentsFacadeDeps,\n} from './compose';\n\nexport {\n supportsDeterministicMint,\n type CheckpointReseeder,\n type DeterministicMintCapable,\n type FacadeClient,\n type FacadeSession,\n type PaymentsFacadeDeps,\n type RecipientInfo,\n} from './compose';\nexport { ATTENTION_MINT_UNRESOLVED } from './mint';\nexport { ATTENTION_RESEED_REJECTED } from './restore';\nexport { ATTENTION_RECIPIENT_NETWORK_UNVERIFIED } from './recipient';\n\n/** Max re-plans after a conflicted attempt (#625/#677 parity with the old send loop). */\nexport const MAX_RESELECT = 8;\n\nconst INVENTORY_SCAN_PAGE_LIMIT = 50;\n\n/**\n * What this attempt is spending. The policy loop is shared; only planning and the\n * conflict rule differ, so the union is narrowed in exactly those two places.\n */\ntype SendJob =\n | { readonly kind: 'coin'; readonly request: SendRequest }\n | {\n readonly kind: 'whole';\n readonly request: SendWholeTokenRequest;\n readonly requireCoinless: boolean;\n };\n\ninterface AttemptCtx {\n readonly transferId: string;\n /** '' for a token-addressed spend: it names no coin. */\n readonly coinId: string;\n readonly plan: MachinePlan;\n readonly sourceIds: readonly string[];\n readonly sourceTokens: readonly Token[];\n}\n\ntype AttemptDisposition =\n | { kind: 'rethrow'; error: unknown }\n | { kind: 'retry-full'; error: unknown }\n | { kind: 'success'; deliveryPending: boolean }\n | { kind: 'partial'; entry: ShortfallEntry; deliveryPending: boolean };\n\n/** Accumulated state of one send() across its internal attempts. */\ninterface SendRun {\n amount: string;\n delivered: string[];\n sentTokens: Token[];\n tokenTransfers: TokenTransferDetail[];\n settledShortfalls: string[];\n firstPartialId: string | undefined;\n pendingAny: boolean;\n lastTransferId: string; // latest attempt's id ('' pre-plan) — rides a clean-failure emission\n}\n\nexport class PaymentsFacade implements PaymentsV2 {\n private readonly wakeRefresh: () => void;\n private readonly prewarmed = new PrewarmCache();\n private readonly view: InventoryView;\n private readonly ledger: ReservationLedger;\n private readonly queue: SpendQueue;\n private readonly machine: TransferMachine;\n private readonly machineDeps: MachineDeps;\n private readonly machineStores: MachineStores;\n private readonly historyStore: History;\n private readonly receiveLoop: Receive;\n private readonly heldStates: HeldStateCache;\n private readonly ownPubkeyBytes: Uint8Array;\n private readonly restoreDeps: RestoreDeps;\n readonly requests: Requests;\n\n private currentEngine: ITokenEngine | null = null;\n private readonly pendingOps = new Set<Promise<void>>();\n private unsubscribers: (() => void)[] = [];\n private started = false;\n\n // §7 heartbeat: in-memory timing cell + pass runner (see convergence.ts).\n private readonly heartbeat: ConvergenceHeartbeat;\n private readonly converger: Converger;\n /** Resume single-flight (§7): ticks, start() and resumeNow() coalesce onto ONE pass. */\n private readonly resumeFlight = new SingleFlight<void>();\n /** §5.1/§7: restore + convergence passes SERIALIZE here. */\n private readonly passChain = new SerialChain();\n /** §7 ownership: ids with an in-process machine attempt — the pass never adopts one. */\n private readonly activeMoneyOps = new Set<string>();\n /** #737: the ledger holds exactly the sources of the still-open intents. */\n private readonly pins: IntentPins;\n /** Per facade, so per address: an NFT reading is never served to another wallet. */\n private readonly nftCache = new NftCache();\n\n constructor(private readonly deps: PaymentsFacadeDeps) {\n const parts = composeFacadeParts(deps, {\n engine: () => this.engine(),\n send: (request) => this.send(request),\n isActiveOp: (id) => this.activeMoneyOps.has(id),\n track: (op) => this.trackTail(op),\n });\n this.view = parts.view;\n this.wakeRefresh = parts.refreshView;\n this.ledger = parts.ledger;\n this.queue = parts.queue;\n this.machine = parts.machine;\n this.machineDeps = parts.machineDeps;\n this.machineStores = parts.machineStores;\n this.historyStore = parts.historyStore;\n this.receiveLoop = parts.receiveLoop;\n this.heldStates = parts.heldStates;\n this.ownPubkeyBytes = parts.ownPubkeyBytes;\n this.restoreDeps = parts.restoreDeps;\n this.requests = parts.requests;\n this.pins = parts.pins;\n deps.deliveryPort.bindDeliveryKeys((blob) => this.engine().deliveryKeys(blob));\n this.heartbeat = new ConvergenceHeartbeat({\n now: () => this.nowMs(),\n onTick: () => this.trackTail(this.runConvergencePass()),\n });\n this.converger = new Converger({\n machineDeps: this.machineDeps,\n stores: this.machineStores,\n delivery: deps.deliveryPort,\n reconcile: (report) => this.requests.reconcile(report),\n refreshView: () => this.view.delta(),\n replayMints: () => replayCoinMints(this.mintDeps()),\n replayNftMints: () => replayNftMints(this.mintDeps()),\n isActiveOp: (id) => this.activeMoneyOps.has(id),\n emit: deps.emit,\n now: () => this.nowMs(),\n });\n }\n\n // ── lifecycle ──────────────────────────────────────────────────────────────\n\n async start(): Promise<void> {\n if (this.started) return;\n this.started = true;\n this.heartbeat.start();\n // Subscriptions BEFORE session.start(): no frame can beat the restore hook.\n this.unsubscribers.push(\n this.deps.session.subscribeEpochChange((epoch) => this.handleEpochChange(epoch)),\n this.deps.session.subscribeStream('mailbox', () => {\n this.trackTail(this.receiveLoop.drainOnce());\n }),\n this.deps.session.subscribeStream('inventory', this.wakeRefresh),\n this.deps.session.subscribeStream('payment_requests', () => {\n this.trackTail(this.requests.drainIncoming());\n })\n );\n const statusUnsub = this.deps.session.subscribeStatus?.((status) => {\n if (status === 'connected') this.heartbeat.recovered();\n });\n if (statusUnsub !== undefined) this.unsubscribers.push(statusUnsub);\n await this.deps.session.start();\n // BEFORE the first pass and before any send can plan: a source pinned by an\n // intent left open by the previous session must not be re-offered (#737).\n // A rejection leaves the ledger unproven: reads keep working, spending does not (#738).\n await this.pins.sync().catch(() => undefined);\n // §7 start posture: never awaited; the heartbeat re-runs this same pass.\n this.trackTail(this.runConvergencePass());\n this.trackTail(this.seedHeldStates());\n await this.view.fullPull().catch(() => undefined);\n this.receiveLoop.start(this.deps.receivePollMs);\n }\n\n /** §7 same-address restart gate: resolves only after in-flight ops settle. */\n async stop(): Promise<void> {\n this.started = false;\n this.heartbeat.stop(); // §7 quiescence unchanged: a mid-backoff stop cancels cleanly\n this.receiveLoop.stop();\n for (const unsubscribe of this.unsubscribers) unsubscribe();\n this.unsubscribers = [];\n await this.deps.session.stop();\n while (this.pendingOps.size > 0) {\n await Promise.allSettled([...this.pendingOps]);\n }\n }\n\n /** Swaps what FUTURE operations snapshot. Chain ops finish on the old engine, but it is\n * DISPOSED here, so one mid-`verify()` is cancelled — MODULE_DESTROYED, #770(4). */\n setEngine(next: ITokenEngine): void {\n const previous = this.currentEngine ?? this.deps.engineRef();\n this.currentEngine = next;\n if (previous !== next) previous.dispose?.();\n }\n\n // ── reads ──────────────────────────────────────────────────────────────────\n\n async assets(coinId?: string): Promise<Asset[]> {\n const all = await this.view.assets(this.deps.registry, this.deps.price);\n return coinId === undefined ? all : all.filter((asset) => asset.coinId === coinId);\n }\n\n tokens(filter?: { coinId?: string }): Token[] {\n return this.view.tokens(this.deps.registry, filter);\n }\n\n coinless(): CoinlessToken[] {\n return this.view.coinless(this.deps.registry);\n }\n\n tokenData(tokenId: string): Promise<Uint8Array | null> {\n return readTokenData(this.readDeps(), tokenId);\n }\n\n nft(tokenId: string): Promise<NftView | null> {\n return readNft(this.readDeps(), tokenId);\n }\n\n nfts(tokenIds: readonly string[]): Promise<ReadonlyMap<string, NftView>> {\n return readNfts(this.readDeps(), tokenIds);\n }\n\n private readDeps(): NftReadDeps {\n return { engine: this.engine(), view: this.view, storagePort: this.deps.storagePort, cache: this.nftCache };\n }\n\n history(page?: { before?: string; limit?: number }): Promise<HistoryPage> {\n return this.historyStore.page(page ?? {});\n }\n\n /** §4: read through to the session — the same value `connection:status` carries (sphere#473). No session ⇒ 'offline'. */\n connectionStatus(): ConnectionStatus {\n return this.started ? this.deps.session.status() : 'offline';\n }\n\n /** §4 pending-transfers UI surface — derived on read, never cached (convergence.ts). */\n pendingTransfers(): Promise<PendingTransfer[]> {\n return derivePendingTransfers(this.machineStores, this.machineDeps.decryptPayload);\n }\n\n // ── money movement ─────────────────────────────────────────────────────────\n\n async prewarmSend(request: SendRequest): Promise<void> {\n await warmSendSources(this.warmDeps(), request);\n }\n\n discardPrewarm(): void {\n this.prewarmed.clear();\n }\n\n private warmDeps(): WarmDeps {\n return { queue: this.queue, view: this.view, storagePort: this.deps.storagePort, cache: this.prewarmed };\n }\n\n send(request: SendRequest): Promise<TransferResult> {\n return this.track(this.runJob({ kind: 'coin', request }, request.amount));\n }\n\n sendWholeToken(request: SendWholeTokenRequest): Promise<TransferResult> {\n // '0': no amount, keeping the shortfall arithmetic total-free.\n return this.track(this.runJob({ kind: 'whole', request, requireCoinless: false }, '0'));\n }\n\n /** NFT-scoped twin: refuses a valued source. */\n sendCoinless(request: SendWholeTokenRequest): Promise<TransferResult> {\n return this.track(this.runJob({ kind: 'whole', request, requireCoinless: true }, '0'));\n }\n\n async receive(): Promise<{ transfers: IncomingTransfer[] }> {\n const transfers = await this.track(this.receiveLoop.drainOnce());\n return { transfers };\n }\n\n mint(coinId: string, amount: bigint): Promise<MintResult> {\n return this.track(this.mintInner(coinId, amount));\n }\n\n mintNft(request: MintNftRequest): Promise<MintResult> {\n return this.track(this.ownedMint((mintId) => runNftMintUnderJournal(this.mintDeps(), { mintId, request })));\n }\n\n // §4 retry verb: coalesces onto the running pass — NEVER re-issue send() (#631/#676).\n async resumeNow(): Promise<void> {\n if (!this.started) return;\n await this.track(this.runConvergencePass());\n }\n\n /** §5.1 restore — awaited by the session latch BEFORE streams resume; never coalesced onto a pre-restore pass. */\n async handleEpochChange(_newEpoch: string): Promise<void> {\n await this.passChain.enqueue(() => reseedAndReset(this.restoreDeps));\n await this.passChain.enqueue(() => this.convergeBody());\n }\n\n /** One single-flighted pass + its reschedule: concurrent callers coalesce. */\n private runConvergencePass(): Promise<void> {\n return this.resumeFlight.run(() => this.passChain.enqueue(() => this.convergeBody()));\n }\n\n private async convergeBody(): Promise<void> {\n const outcome = await this.converger.convergeOnce();\n // After the pass refreshed the mirror: an intent that stopped being open\n // stops pinning, one still open keeps pinning (#737).\n // A rejection leaves the ledger unproven: reads keep working, spending does not (#738).\n await this.pins.sync().catch(() => undefined);\n const pending = await this.converger.pendingWork().catch(() => true);\n this.heartbeat.settle(outcome, pending);\n }\n\n private nowMs(): number {\n return (this.deps.now ?? Date.now)();\n }\n\n /** One snapshot serves the coin and the NFT mint, live and replayed. */\n private mintDeps(): CoinReplayDeps & NftReplayDeps {\n return {\n engine: this.engine(),\n mintJournal: this.machineStores.mintJournal,\n nftMintJournal: this.machineStores.nftMintJournal,\n storagePort: this.deps.storagePort,\n recordMint: (input) => this.historyStore.recordMint(input),\n armHeartbeat: () => this.heartbeat.arm(),\n noteHeldState: (tokenId, stateHash) => void this.heldStates.set(tokenId, stateHash),\n refreshView: () => this.trackTail(this.view.delta()),\n ownPubkeyBytes: this.ownPubkeyBytes,\n nftTokenType: this.deps.nftTokenType,\n isActiveOp: (mintId) => this.activeMoneyOps.has(mintId),\n tokenInServerInventory: (tokenId) => this.tokenInServerInventory(tokenId),\n emit: this.deps.emit,\n now: () => this.nowMs(),\n };\n }\n\n // ── send policy (§5.5 + old-loop parity; the machine stays policy-free) ────\n\n /** The ONE place a send() outcome is shaped: success emits in finishSend, a\n * CLEAN rejection emits `transfer:updated{status:'failed'}` here (§4). */\n private async runJob(job: SendJob, amount: string): Promise<TransferResult> {\n const run: SendRun = {\n amount,\n delivered: [],\n sentTokens: [],\n tokenTransfers: [],\n settledShortfalls: [],\n firstPartialId: undefined,\n pendingAny: false,\n lastTransferId: '',\n };\n try {\n return await this.sendWithPolicy(job, run);\n } catch (err) {\n this.emitCleanFailure(err, run.lastTransferId);\n throw err;\n }\n }\n\n /** Only a CLEAN failure (nothing certified, classifyError 'other') is 'failed'.\n * Keep-open/partial/conflict outcomes are pending/converging — labelling them\n * 'failed' invites a dApp re-send, i.e. a double-pay (#631/#676). */\n private emitCleanFailure(err: unknown, transferId: string): void {\n if (isPossiblyCommittedSendOutcome(err) || classifyError(err) !== 'other') return;\n const failed: TransferResult = {\n id: transferId,\n status: 'failed',\n tokens: [],\n tokenTransfers: [],\n error: messageOf(err),\n };\n this.deps.emit('transfer:updated', failed);\n }\n\n private async sendWithPolicy(job: SendJob, run: SendRun): Promise<TransferResult> {\n const recipient = await requireSameNetworkRecipient(this.deps, job.request.recipient);\n for (let attempt = 0; ; attempt++) {\n let ctx: AttemptCtx;\n try {\n ctx = await this.planAndMaterialize(recipient.chainPubkey, job, run);\n } catch (err) {\n throw partialize(err, run);\n }\n const disposition = await this.runAttempt(ctx);\n if (disposition.kind === 'rethrow') throw partialize(disposition.error, run);\n if (disposition.kind === 'retry-full') {\n // #625's re-plan searches for a DIFFERENT source. A named token has no\n // alternative — re-planning would pick the same one or nothing — so a\n // proven conflict is TERMINAL here rather than a bounded retry.\n if (job.kind === 'whole' || attempt >= MAX_RESELECT) throw partialize(disposition.error, run);\n continue;\n }\n if (disposition.kind === 'success') {\n run.pendingAny = run.pendingAny || disposition.deliveryPending;\n this.accumulate(ctx, ctx.sourceIds, run);\n return await this.finishSend(ctx.transferId, run);\n }\n const surfaced = await this.consumePartial(ctx, disposition, run, attempt);\n if (surfaced !== null) return surfaced;\n }\n }\n\n private async runAttempt(ctx: AttemptCtx): Promise<AttemptDisposition> {\n this.activeMoneyOps.add(ctx.transferId);\n try {\n const { deliveryPending } = await this.machine.run(ctx.plan);\n this.settleSuccess(ctx, ctx.sourceIds);\n return { kind: 'success', deliveryPending };\n } catch (err) {\n return await this.disposeFailedAttempt(ctx, err);\n } finally {\n this.activeMoneyOps.delete(ctx.transferId);\n }\n }\n\n /** Partial (#677/#690): shortfall already durable (machine wrote it BEFORE\n * complete); accumulate settled, re-plan ONLY the remainder, NEW transferId. */\n private async consumePartial(\n ctx: AttemptCtx,\n disposition: { entry: ShortfallEntry; deliveryPending: boolean },\n run: SendRun,\n attempt: number\n ): Promise<TransferResult | null> {\n if (disposition.deliveryPending) {\n run.pendingAny = true;\n this.heartbeat.arm(); // deposits owed — heartbeat work even if the remainder later throws\n }\n const partial = disposition.entry;\n run.delivered.push(...partial.committedTokenIds);\n run.firstPartialId ??= partial.transferId;\n run.settledShortfalls.push(partial.transferId);\n this.accumulate(ctx, partial.committedTokenIds, run);\n this.settlePartial(ctx, partial);\n if (BigInt(partial.remainingAmount) <= 0n) {\n return this.finishSend(ctx.transferId, run);\n }\n if (attempt >= MAX_RESELECT) {\n throw new PartialSendConflictError(\n 'Part of your payment was sent, but the remainder could not be completed within the re-plan budget. The delivered portion is final — re-plan only the shortfall, never the full amount.',\n run.firstPartialId,\n run.delivered,\n partial.remainingAmount\n );\n }\n run.amount = partial.remainingAmount;\n return null;\n }\n\n /** Failure disposition: possibly-committed → rethrow UNWRAPPED; backstop\n * 'open' → converge via resumeIntent; clean demoted conflict → full re-plan. */\n private async disposeFailedAttempt(ctx: AttemptCtx, err: unknown): Promise<AttemptDisposition> {\n if (isPossiblyCommittedSendOutcome(err)) {\n this.settleKeepOpen(ctx);\n stampTransferId(err, ctx.transferId);\n return { kind: 'rethrow', error: err };\n }\n const backstop = await this.machineStores.backstop.getByKey(ctx.transferId);\n if (backstop !== undefined && backstop.disposition === 'open') {\n return this.convergePartial(ctx);\n }\n this.settleFailure(ctx.transferId, ctx.coinId, ctx.sourceIds);\n if (classifyError(err) !== 'conflict') return { kind: 'rethrow', error: err };\n const demoted = await this.demoteSpentSources(ctx);\n return demoted > 0 ? { kind: 'retry-full', error: err } : { kind: 'rethrow', error: err };\n }\n\n /** #677/#690: ≥1 leg committed — the SAME machine, resumed in-process, converges it. */\n private async convergePartial(ctx: AttemptCtx): Promise<AttemptDisposition> {\n let outcome;\n try {\n outcome = await this.machine.resumeIntent({\n transferId: ctx.transferId,\n payload: ctx.plan.payload,\n sources: ctx.plan.sources,\n journaled: await this.machineStores.deliveryJournal.byTransfer(ctx.transferId),\n });\n } catch (err) {\n return this.disposeConvergeFailure(ctx, err);\n }\n if (outcome.partial === null) {\n this.settleSuccess(ctx, ctx.sourceIds);\n return { kind: 'success', deliveryPending: outcome.deliveryPending };\n }\n return { kind: 'partial', entry: outcome.partial, deliveryPending: outcome.deliveryPending };\n }\n\n private async disposeConvergeFailure(ctx: AttemptCtx, err: unknown): Promise<AttemptDisposition> {\n if (isPossiblyCommittedSendOutcome(err)) {\n this.settleKeepOpen(ctx);\n stampTransferId(err, ctx.transferId);\n return { kind: 'rethrow', error: err };\n }\n if (classifyError(err) === 'conflict') {\n // Nothing was delivered after all (E.2 pure lost race): soft-abort and\n // fall back to the clean-conflict path.\n await this.softAbort(ctx.transferId);\n this.settleFailure(ctx.transferId, ctx.coinId, ctx.sourceIds);\n const demoted = await this.demoteSpentSources(ctx);\n return demoted > 0 ? { kind: 'retry-full', error: err } : { kind: 'rethrow', error: err };\n }\n return { kind: 'rethrow', error: err };\n }\n\n private async planAndMaterialize(recipientPubkey: string, job: SendJob, run: SendRun): Promise<AttemptCtx> {\n const transferId = this.newId();\n run.lastTransferId = transferId;\n // The ONE divergence: a coin spend SELECTS sources to cover an amount and may\n // queue for them; a token spend reserves the one it was NAMED and never queues.\n if (job.kind === 'whole') {\n const spend = this.queue.planWhole(transferId, job.request.tokenId);\n const sourceIds = this.markPlanned(transferId, '', spend);\n try {\n return await materializeWholeSpend(\n { engine: this.engine(), storagePort: this.deps.storagePort, registry: this.deps.registry, now: this.nowMs() },\n {\n transferId,\n recipientPubkey,\n request: job.request,\n sourceIds,\n requireCoinless: job.requireCoinless,\n }\n );\n } catch (err) {\n this.settleFailure(transferId, '', sourceIds);\n throw err;\n }\n }\n const request = { ...job.request, amount: run.amount };\n const planned = this.queue.plan(transferId, { coinId: request.coinId, amount: request.amount });\n const spend = planned.kind === 'planned' ? planned.spend : await planned.settled;\n const sourceIds = this.markPlanned(transferId, request.coinId, spend);\n try {\n return await this.materialize(transferId, recipientPubkey, request, spend, sourceIds);\n } catch (err) {\n this.settleFailure(transferId, request.coinId, sourceIds);\n throw err;\n }\n }\n\n /** Reserve happened synchronously inside queue.plan; mark + declare with no await between. */\n private markPlanned(transferId: string, coinId: string, spend: PlannedSpend): string[] {\n const sourceIds = [\n ...spend.plan.direct,\n ...(spend.plan.split !== undefined ? [spend.plan.split.tokenId] : []),\n ];\n this.view.markInFlightMany(sourceIds);\n if (spend.plan.split !== undefined) {\n this.queue.declareExpectedChange(transferId, coinId, spend.plan.split.remainderAmount);\n }\n return sourceIds;\n }\n\n private async materialize(\n transferId: string,\n recipientPubkey: string,\n request: SendRequest,\n spend: PlannedSpend,\n sourceIds: readonly string[]\n ): Promise<AttemptCtx> {\n const engine = this.engine();\n const blobs = await takeSourceBlobs(this.warmDeps(), sourceIds);\n const sources = new Map<string, SphereToken>();\n const sourceTokens: Token[] = [];\n const spentStates: Record<string, { local: string; protocol: string }> = {};\n for (const tokenId of sourceIds) {\n const bytes = blobs.get(tokenId);\n if (bytes === undefined) {\n throw new SphereError(`Selected source ${tokenId} has no blob in storage`, 'STORAGE_ERROR');\n }\n const token = await engine.decodeToken({ tokenId, token: bytes });\n const keys = await engine.deliveryKeys(bytes);\n // local === protocol by construction; the dual field is wire compat (types.ts).\n spentStates[tokenId] = { local: keys.stateHash, protocol: keys.stateHash };\n sources.set(tokenId, token);\n sourceTokens.push(transferringToken(tokenId, request.coinId, engine.balanceOf(token, request.coinId), this.deps.registry, this.nowMs()));\n }\n const payload = buildPayload(recipientPubkey, request, spend, spentStates);\n const plan: MachinePlan = {\n transferId,\n recipientPubkey,\n payload,\n ops: buildOps(payload),\n sources,\n ...(request.memo !== undefined ? { memo: request.memo } : {}),\n };\n return { transferId, coinId: request.coinId, plan, sourceIds, sourceTokens };\n }\n\n\n /** isSpent sweep over the attempt's sources; demote proven-spent states (durable). */\n private async demoteSpentSources(ctx: AttemptCtx): Promise<number> {\n const engine = this.engine();\n let demoted = 0;\n for (const [tokenId, token] of ctx.plan.sources) {\n const state = ctx.plan.payload.spentStates?.[tokenId];\n if (state === undefined) continue;\n try {\n if (await engine.isSpent(token)) {\n await this.view.demote(tokenId, state.protocol);\n demoted += 1;\n }\n } catch {\n // Probe outage: never demote on a guess — the attempt budget bounds us.\n }\n }\n return demoted;\n }\n\n // ── attempt settlement (reservation / in-flight / expected-change hygiene) ─\n\n private settleSuccess(ctx: AttemptCtx, spentIds: readonly string[]): void {\n this.ledger.commit(ctx.transferId);\n this.queue.clearExpectedChange(ctx.transferId);\n this.trackTail(this.refreshThenRelease(ctx.coinId, spentIds));\n }\n\n private settleFailure(transferId: string, coinId: string, releaseIds: readonly string[]): void {\n this.ledger.cancel(transferId);\n this.queue.clearExpectedChange(transferId);\n this.view.releaseMany(releaseIds);\n this.queue.notifyChange(coinId);\n }\n\n /** Open intent: sources stay reserved + in-flight (§5.2) until resume adopts them. */\n private settleKeepOpen(ctx: AttemptCtx): void {\n this.queue.clearExpectedChange(ctx.transferId);\n // The reservation is now the intent's pin, and lives and dies with it (#737).\n this.pins.adopt(ctx.transferId);\n this.heartbeat.arm(); // the parked intent converges in-session — no restart\n }\n\n private settlePartial(ctx: AttemptCtx, partial: ShortfallEntry): void {\n this.ledger.cancel(ctx.transferId);\n this.queue.clearExpectedChange(ctx.transferId);\n const committed = new Set(partial.committedTokenIds);\n for (const tokenId of ctx.sourceIds) {\n if (committed.has(tokenId)) continue;\n // The conflicted leg's source is proven foreign-spent — demote + release.\n const state = ctx.plan.payload.spentStates?.[tokenId];\n if (state !== undefined) this.trackTail(this.view.demote(tokenId, state.protocol));\n this.view.release(tokenId);\n }\n this.trackTail(this.refreshThenRelease(ctx.coinId, [...committed]));\n }\n\n /** Release spent sources only AFTER the mirror refresh tombstoned them. */\n private async refreshThenRelease(coinId: string, spentIds: readonly string[]): Promise<void> {\n try {\n await this.view.delta();\n this.view.releaseMany(spentIds);\n } finally {\n this.queue.notifyChange(coinId);\n }\n }\n\n private accumulate(ctx: AttemptCtx, committedIds: readonly string[], run: SendRun): void {\n const committed = new Set(committedIds);\n for (const op of ctx.plan.ops) {\n if (!committed.has(op.sourceTokenId)) continue;\n run.tokenTransfers.push({ sourceTokenId: op.sourceTokenId, method: op.kind });\n }\n for (const token of ctx.sourceTokens) {\n if (committed.has(token.id)) run.sentTokens.push(token);\n }\n }\n\n private async finishSend(transferId: string, run: SendRun): Promise<TransferResult> {\n for (const id of run.settledShortfalls.splice(0)) {\n await this.machineStores.shortfalls.removeByKey(id).catch(() => undefined);\n }\n if (run.pendingAny) this.heartbeat.arm(); // deposits owed in the journal — heartbeat work\n const result: TransferResult = {\n id: transferId,\n status: run.pendingAny ? 'confirmed' : 'delivered',\n tokens: [...run.sentTokens],\n tokenTransfers: [...run.tokenTransfers],\n deliveryPending: run.pendingAny,\n deliveryState: run.pendingAny ? 'pending-delivery' : 'landed',\n };\n this.deps.emit('transfer:updated', result);\n return result;\n }\n\n /** Nothing delivered → UNWRAPPED; after ≥1 delivered leg every failure surfaces as PartialSendConflictError over the settled set. */\n private async softAbort(transferId: string): Promise<void> {\n try {\n await this.deps.client.abortIntent(transferId);\n await this.machineStores.backstop.removeByKey(transferId);\n } catch {\n // Stays locally recorded; the #676 resume gate converges it later.\n }\n }\n\n // ── mint (§5.9: journal-first, replayed at start, never blind re-mint) ─────\n\n private async mintInner(coinId: string, amount: bigint): Promise<MintResult> {\n if (!/^(?:[0-9a-f]{2})+$/.test(coinId) || amount <= 0n) {\n return { success: false, error: 'coinId must be even-length lowercase hex and amount positive' };\n }\n return this.ownedMint((mintId) => runMintUnderJournal(this.mintDeps(), { mintId, coinId, amount }));\n }\n\n /** A live mint under a fresh id — its replay stays hands-off while this attempt runs. */\n private async ownedMint(run: (mintId: string) => Promise<MintResult>): Promise<MintResult> {\n const mintId = this.newId();\n this.activeMoneyOps.add(mintId);\n try {\n return await run(mintId);\n } finally {\n this.activeMoneyOps.delete(mintId);\n }\n }\n\n private async tokenInServerInventory(tokenId: string): Promise<boolean> {\n let page = await this.deps.storagePort.listInventory();\n for (let i = 0; i < INVENTORY_SCAN_PAGE_LIMIT; i++) {\n if (page.items.some((item) => item.tokenId === tokenId && item.status === 'active')) {\n return true;\n }\n if (!page.more) return false;\n page = await this.deps.storagePort.listInventory(page.cursor);\n }\n return false;\n }\n\n // ── wiring internals ───────────────────────────────────────────────────────\n\n private engine(): ITokenEngine {\n return this.currentEngine ?? this.deps.engineRef();\n }\n\n private newId(): string {\n return (this.deps.newId ?? randomUUID)();\n }\n\n private async seedHeldStates(): Promise<void> {\n let page = await this.deps.storagePort.listInventory();\n for (let i = 0; i < INVENTORY_SCAN_PAGE_LIMIT; i++) {\n for (const item of page.items) {\n if (item.status === 'active') this.heldStates.set(item.tokenId, item.stateHash);\n }\n if (!page.more) return;\n page = await this.deps.storagePort.listInventory(page.cursor);\n }\n }\n\n private track<T>(op: Promise<T>): Promise<T> {\n const settled = op.then(() => undefined, () => undefined);\n this.pendingOps.add(settled);\n void settled.finally(() => this.pendingOps.delete(settled));\n return op;\n }\n\n private trackTail(op: Promise<unknown>): void {\n this.track(op).catch(() => undefined);\n }\n}\n\n"],"mappings":"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","names":["isLE","isBytes","isBytes","abytes","aexists","aoutput","clean","createView","abytes","isLE","createView","abytes","clean","abytes","clean","aexists","aoutput","abytes","clean","CURSOR_KEY","page","spend","sourceIds"]}
|