@unicitylabs/sphere-sdk 0.15.0 → 0.16.0-dev.2
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 +15 -5
- package/dist/connect/index.cjs +26 -25
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.d.cts +4 -0
- package/dist/connect/index.d.ts +4 -0
- package/dist/connect/index.js +26 -25
- package/dist/connect/index.js.map +1 -1
- package/dist/core/index.cjs +728 -227
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +174 -23
- package/dist/core/index.d.ts +174 -23
- package/dist/core/index.js +728 -226
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/connect/index.cjs +16 -25
- package/dist/impl/browser/connect/index.cjs.map +1 -1
- package/dist/impl/browser/connect/index.js +16 -25
- package/dist/impl/browser/connect/index.js.map +1 -1
- package/dist/impl/browser/index.cjs +333 -506
- package/dist/impl/browser/index.cjs.map +1 -1
- package/dist/impl/browser/index.js +333 -506
- package/dist/impl/browser/index.js.map +1 -1
- package/dist/impl/nodejs/connect/index.cjs +15 -24
- package/dist/impl/nodejs/connect/index.cjs.map +1 -1
- package/dist/impl/nodejs/connect/index.js +15 -24
- package/dist/impl/nodejs/connect/index.js.map +1 -1
- package/dist/impl/nodejs/index.cjs +300 -571
- package/dist/impl/nodejs/index.cjs.map +1 -1
- package/dist/impl/nodejs/index.d.cts +92 -15
- package/dist/impl/nodejs/index.d.ts +92 -15
- package/dist/impl/nodejs/index.js +300 -571
- package/dist/impl/nodejs/index.js.map +1 -1
- package/dist/impl/shared/wallet-api/index.d.cts +54 -2
- package/dist/impl/shared/wallet-api/index.d.ts +54 -2
- package/dist/index.cjs +730 -227
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +229 -110
- package/dist/index.d.ts +229 -110
- package/dist/index.js +730 -226
- package/dist/index.js.map +1 -1
- package/dist/modules/payments-v2/index.cjs +11 -7
- package/dist/modules/payments-v2/index.cjs.map +1 -1
- package/dist/modules/payments-v2/index.d.cts +56 -3
- package/dist/modules/payments-v2/index.d.ts +56 -3
- package/dist/modules/payments-v2/index.js +11 -7
- package/dist/modules/payments-v2/index.js.map +1 -1
- package/dist/token-engine/index.cjs +46 -0
- package/dist/token-engine/index.cjs.map +1 -1
- package/dist/token-engine/index.js +46 -0
- package/dist/token-engine/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../token-engine/sdk.ts","../../token-engine/identity.ts","../../core/errors.ts","../../core/logger.ts","../../token-engine/SpherePaymentData.ts","../../token-engine/proof-wait.ts","../../token-engine/errors.ts","../../token-engine/certification-outcome.ts","../../core/uuid.ts","../../token-engine/blob-keys.ts","../../node_modules/@noble/hashes/src/utils.ts","../../node_modules/@noble/hashes/src/hmac.ts","../../node_modules/@noble/hashes/src/hkdf.ts","../../node_modules/@noble/hashes/src/_md.ts","../../node_modules/@noble/hashes/src/sha2.ts","../../token-engine/realization.ts","../../token-engine/split-checkpoint.ts","../../token-engine/SphereTokenEngine.ts","../../token-engine/factory.ts"],"sourcesContent":["/**\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\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 * token-engine/identity.ts — legacy `DIRECT://` identity address (Path A, A6).\n *\n * Reproduces the wallet's stable L3 identity address EXACTLY as the v1\n * `UnmaskedPredicateReference` → `DirectAddress` path did, but VENDORED (no v1 SDK\n * import) so the v1 dependency can be removed at the final cut-over. Quest XP is\n * keyed on this address, so it MUST stay byte-identical — the multi-vector\n * golden test (identity.test.ts) locks it.\n *\n * The recipe (recovered from v1 `UnmaskedPredicateReference.create` + `DirectAddress.create`):\n * ref = SHA-256( CBOR[ bstr([UNMASKED]), bstr(tokenType.toCBOR()),\n * tstr(\"secp256k1\"), uint(SHA256), bstr(publicKey) ] )\n * imprint = 0x0000 ‖ ref (SHA-256 DataHash imprint)\n * address = \"DIRECT://\" ‖ hex(imprint) ‖ hex( SHA-256(imprint)[0:4] )\n *\n * The CBOR + SHA-256 are standard, so v2's CborSerializer/DataHasher produce\n * byte-identical output; the v1 enum values (UNMASKED=0, HashAlgorithm.SHA256=0)\n * and the SHA-256 imprint prefix (0x0000) are pinned as constants.\n */\n\nimport { CborSerializer, DataHasher, HashAlgorithm, HexConverter } from './sdk';\n\n/**\n * Unicity L3 token type used for identity-address derivation (immutable).\n * Also pinned as the fixed token type of self-issued Unicity ID tokens\n * (token-engine/unicity-id.ts) — the same constant the v1 nametag mint used,\n * keeping the mint deterministic per (name, wallet key).\n */\nexport const UNICITY_TOKEN_TYPE_HEX = 'f8aa13834268d29355ff12183066f0cb902003629bbc5eb9ef0efbe397867509';\n/** v1 `SigningService.algorithm` for secp256k1. */\nconst SIGNING_ALGORITHM = 'secp256k1';\n/** v1 `EmbeddedPredicateType.UNMASKED`. */\nconst EMBEDDED_PREDICATE_UNMASKED = 0;\n/** v1 `HashAlgorithm.SHA256` (as encoded in the reference CBOR). */\nconst HASH_ALGORITHM_SHA256 = 0n;\n/** v1 SHA-256 `DataHash` imprint algorithm tag (2-byte big-endian). */\nconst SHA256_IMPRINT_PREFIX = new Uint8Array([0x00, 0x00]);\n\nfunction hexToBytes(hex: string): Uint8Array {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\nfunction sha256(data: Uint8Array): Promise<Uint8Array> {\n return new DataHasher(HashAlgorithm.SHA256)\n .update(data)\n .digest()\n .then((h) => h.data);\n}\n\n/**\n * Derive the legacy `DIRECT://` identity address for a compressed (33-byte)\n * secp256k1 public key. Deterministic; byte-identical to the v1 path (Path A).\n */\nexport async function deriveDirectAddress(publicKey: Uint8Array): Promise<string> {\n const tokenTypeCbor = CborSerializer.encodeByteString(hexToBytes(UNICITY_TOKEN_TYPE_HEX)); // v1 TokenType.toCBOR()\n const reference = CborSerializer.encodeArray(\n CborSerializer.encodeByteString(new Uint8Array([EMBEDDED_PREDICATE_UNMASKED])),\n CborSerializer.encodeByteString(tokenTypeCbor),\n CborSerializer.encodeTextString(SIGNING_ALGORITHM),\n CborSerializer.encodeUnsignedInteger(HASH_ALGORITHM_SHA256),\n CborSerializer.encodeByteString(publicKey),\n );\n\n const refHash = await sha256(reference);\n const imprint = new Uint8Array([...SHA256_IMPRINT_PREFIX, ...refHash]);\n const checksum = (await sha256(imprint)).slice(0, 4);\n\n return `DIRECT://${HexConverter.encode(imprint)}${HexConverter.encode(checksum)}`;\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 * Centralized SDK Logger\n *\n * A lightweight singleton logger that works across all tsup bundles\n * by storing state on globalThis. Supports three log levels:\n * - debug: detailed messages (only shown when debug=true)\n * - warn: important warnings (ALWAYS shown regardless of debug flag)\n * - error: critical errors (ALWAYS shown regardless of debug flag)\n *\n * Global debug flag enables all logging. Per-tag overrides allow\n * granular control (e.g., only transport debug).\n *\n * @example\n * ```ts\n * import { logger } from '@unicitylabs/sphere-sdk';\n *\n * // Enable all debug logging\n * logger.configure({ debug: true });\n *\n * // Enable only specific tags\n * logger.setTagDebug('Nostr', true);\n *\n * // Usage in SDK classes\n * logger.debug('Payments', 'Transfer started', { amount, recipient });\n * logger.warn('Nostr', 'queryEvents timed out after 5s');\n * logger.error('Sphere', 'Critical failure', error);\n * ```\n */\n\nexport type LogLevel = 'debug' | 'warn' | 'error';\n\nexport type LogHandler = (level: LogLevel, tag: string, message: string, ...args: unknown[]) => void;\n\nexport interface LoggerConfig {\n /** Enable debug logging globally (default: false). When false, only warn and error messages are shown. */\n debug?: boolean;\n /** Custom log handler. If provided, replaces console output. Useful for tests or custom log sinks. */\n handler?: LogHandler | null;\n}\n\n// Use a unique symbol-like key on globalThis to share logger state across tsup bundles\nconst LOGGER_KEY = '__sphere_sdk_logger__';\n\ninterface LoggerState {\n debug: boolean;\n tags: Record<string, boolean>;\n handler: LogHandler | null;\n}\n\nfunction getState(): LoggerState {\n const g = globalThis as unknown as Record<string, unknown>;\n if (!g[LOGGER_KEY]) {\n g[LOGGER_KEY] = { debug: false, tags: {}, handler: null } satisfies LoggerState;\n }\n return g[LOGGER_KEY] as LoggerState;\n}\n\nfunction isEnabled(tag: string): boolean {\n const state = getState();\n // Per-tag override takes priority\n if (tag in state.tags) return state.tags[tag];\n // Fall back to global flag\n return state.debug;\n}\n\nexport const logger = {\n /**\n * Configure the logger. Can be called multiple times (last write wins).\n * Typically called by createBrowserProviders(), createNodeProviders(), or Sphere.init().\n */\n configure(config: LoggerConfig): void {\n const state = getState();\n if (config.debug !== undefined) state.debug = config.debug;\n if (config.handler !== undefined) state.handler = config.handler;\n },\n\n /**\n * Enable/disable debug logging for a specific tag.\n * Per-tag setting overrides the global debug flag.\n *\n * @example\n * ```ts\n * logger.setTagDebug('Nostr', true); // enable only Nostr logs\n * logger.setTagDebug('Nostr', false); // disable Nostr logs even if global debug=true\n * ```\n */\n setTagDebug(tag: string, enabled: boolean): void {\n getState().tags[tag] = enabled;\n },\n\n /**\n * Clear per-tag override, falling back to global debug flag.\n */\n clearTagDebug(tag: string): void {\n delete getState().tags[tag];\n },\n\n /** Returns true if debug mode is enabled for the given tag (or globally). */\n isDebugEnabled(tag?: string): boolean {\n if (tag) return isEnabled(tag);\n return getState().debug;\n },\n\n /**\n * Debug-level log. Only shown when debug is enabled (globally or for this tag).\n * Use for detailed operational information.\n */\n debug(tag: string, message: string, ...args: unknown[]): void {\n if (!isEnabled(tag)) return;\n const state = getState();\n if (state.handler) {\n state.handler('debug', tag, message, ...args);\n } else {\n console.log(`[${tag}]`, message, ...args);\n }\n },\n\n /**\n * Warning-level log. ALWAYS shown regardless of debug flag.\n * Use for important but non-critical issues (timeouts, retries, degraded state).\n */\n warn(tag: string, message: string, ...args: unknown[]): void {\n const state = getState();\n if (state.handler) {\n state.handler('warn', tag, message, ...args);\n } else {\n console.warn(`[${tag}]`, message, ...args);\n }\n },\n\n /**\n * Error-level log. ALWAYS shown regardless of debug flag.\n * Use for critical failures that should never be silenced.\n */\n error(tag: string, message: string, ...args: unknown[]): void {\n const state = getState();\n if (state.handler) {\n state.handler('error', tag, message, ...args);\n } else {\n console.error(`[${tag}]`, message, ...args);\n }\n },\n\n /** Reset all logger state (debug flag, tags, handler). Primarily for tests. */\n reset(): void {\n const g = globalThis as unknown as Record<string, unknown>;\n delete g[LOGGER_KEY];\n },\n};\n","/**\n * token-engine/SpherePaymentData.ts — the sphere value model.\n *\n * v2 `Token` carries no coins; value is app-defined and stored in\n * `MintTransaction.data`. `SpherePaymentData` is that payload: it implements the\n * SDK's `IPaymentData` (so `TokenSplit` can read it for value conservation) and\n * encodes a `PaymentAssetCollection` inside a versioned, tagged CBOR envelope.\n *\n * The SDK never inspects our raw bytes — it only calls `decodePaymentData(data)`\n * and reads `.assets` — so the envelope (tag + version) is ours, chosen for\n * forward-compatible storage. `fromValue`/`toValue` bridge sphere-domain values\n * (hex coin id + bigint amount) to/from the SDK asset collection.\n */\n\nimport {\n Asset,\n AssetId,\n CborDeserializer,\n CborError,\n CborSerializer,\n HexConverter,\n type IPaymentData,\n PaymentAssetCollection,\n} from './sdk';\nimport type { CoinId, SphereValue } from './types';\nimport { SphereError } from '../core/errors';\n\n/** Canonical coin id: non-empty, even-length lowercase hex (the form `toValue` emits). */\nconst COIN_ID_PATTERN = /^([0-9a-f]{2})+$/;\n\n/** Guard a sphere-domain asset before it crosses into the SDK value model. */\nfunction assertAsset(coinId: CoinId, amount: bigint): void {\n if (!COIN_ID_PATTERN.test(coinId)) {\n throw new SphereError(`Invalid coin id (expected even-length lowercase hex): \"${coinId}\"`, 'VALIDATION_ERROR');\n }\n if (amount <= 0n) {\n // The 2.0.0 SDK requires a strictly positive 256-bit asset value; reject\n // here with the typed sphere error before the raw SDK throw.\n throw new SphereError(`Asset amount must be positive: ${amount.toString()}`, 'VALIDATION_ERROR');\n }\n}\n\n/** Validate a sphere-domain asset and build the SDK Asset — the single validation point. */\nexport function sphereAssetToSdk(coinId: CoinId, amount: bigint): Asset {\n assertAsset(coinId, amount);\n return new Asset(new AssetId(HexConverter.decode(coinId)), amount);\n}\n\nexport class SpherePaymentData implements IPaymentData {\n /** Sphere-private CBOR tag (verified free in the v2 SDK tag space). */\n public static readonly CBOR_TAG = 39050n;\n /** Envelope version; bump when the structure changes. */\n public static readonly VERSION = 1n;\n\n private constructor(\n public readonly assets: PaymentAssetCollection,\n private readonly _memo: Uint8Array | null = null,\n ) {}\n\n /** Opaque, app-defined memo carried alongside the value (e.g. invoice attribution). */\n public get memo(): Uint8Array | null {\n return this._memo ? new Uint8Array(this._memo) : null;\n }\n\n /** Wrap an existing SDK asset collection (+ optional opaque memo). */\n public static create(assets: PaymentAssetCollection, memo: Uint8Array | null = null): SpherePaymentData {\n return new SpherePaymentData(assets, memo);\n }\n\n /** Build from a sphere-domain value (hex coin id → bigint amount) + optional opaque memo. */\n public static fromValue(value: SphereValue, memo: Uint8Array | null = null): SpherePaymentData {\n if (value.assets.length === 0) {\n throw new SphereError('SpherePaymentData requires at least one asset', 'VALIDATION_ERROR');\n }\n const assets = value.assets.map((a) => sphereAssetToSdk(a.coinId, a.amount));\n return new SpherePaymentData(PaymentAssetCollection.create(...assets), memo);\n }\n\n /** Decode from the CBOR envelope produced by {@link encode}. */\n public static fromCBOR(bytes: Uint8Array): SpherePaymentData {\n const tag = CborDeserializer.decodeTag(bytes);\n if (tag.tag !== SpherePaymentData.CBOR_TAG) {\n throw new CborError(`Invalid SpherePaymentData tag: ${tag.tag}`);\n }\n // Strict structure: exactly [version, assets, memo] (matches encode + the SDK's\n // fixed-shape decoders). Extra/missing fields are corruption, not tolerated.\n const fields = CborDeserializer.decodeArray(tag.data, 3);\n const version = CborDeserializer.decodeUnsignedInteger(fields[0]);\n if (version !== SpherePaymentData.VERSION) {\n throw new CborError(`Unsupported SpherePaymentData version: ${version}`);\n }\n const memo = CborDeserializer.decodeNullable(fields[2], CborDeserializer.decodeByteString);\n return new SpherePaymentData(PaymentAssetCollection.fromCBOR(fields[1]), memo);\n }\n\n /** Deterministic, versioned, tagged CBOR: `tag(39050)[ version, assets, memo? ]`. */\n public encode(): Promise<Uint8Array> {\n return Promise.resolve(\n CborSerializer.encodeTag(\n SpherePaymentData.CBOR_TAG,\n CborSerializer.encodeArray(\n CborSerializer.encodeUnsignedInteger(SpherePaymentData.VERSION),\n this.assets.toCBOR(),\n CborSerializer.encodeNullable(this._memo, CborSerializer.encodeByteString),\n ),\n ),\n );\n }\n\n /** Project to a sphere-domain value (hex coin id + bigint amount), preserving order. */\n public toValue(): SphereValue {\n return {\n assets: this.assets.toArray().map((a) => ({\n coinId: HexConverter.encode(a.id.bytes) as CoinId,\n amount: a.value,\n })),\n };\n }\n\n /** Balance of a single coin within this payload (0n when absent). */\n public balanceOf(coinId: CoinId): bigint {\n if (!COIN_ID_PATTERN.test(coinId)) {\n throw new SphereError(`Invalid coin id (expected even-length lowercase hex): \"${coinId}\"`, 'VALIDATION_ERROR');\n }\n const asset = this.assets.get(new AssetId(HexConverter.decode(coinId)));\n return asset ? asset.value : 0n;\n }\n}\n\n/**\n * Async payment-data decoder matching the SDK's `decodePaymentData` signature.\n * Used by `TokenSplit.split` (value conservation) and `SplitMintJustificationVerifier`.\n */\nexport function decodeSpherePaymentData(bytes: Uint8Array): Promise<IPaymentData> {\n return Promise.resolve(SpherePaymentData.fromCBOR(bytes));\n}\n","// One inclusion-proof wait: bounded by a deadline we own, and tolerant of a\n// gateway that blips (#739, #741). state-transition-sdk terminates its own poll\n// loop on abort since 2.0.3; proof-deadline.test.ts guards that it still does.\n\nimport {\n type InclusionProof,\n JsonRpcNetworkError,\n type PredicateVerifierService,\n type UnicityCertificateVerifier,\n type RootTrustBase,\n type StateTransitionClient,\n waitInclusionProof,\n} from './sdk';\nimport { SphereError } from '../core/errors';\n\nexport const DEFAULT_PROOF_TIMEOUT_MS = 10_000;\n\n/** Always bounded: an uncapped wait is the #739 hang, so there is no \"no cap\"\n * value — non-positive is refused, never read as forever or as zero delay. */\nexport function resolveProofTimeoutMs(configured: number | undefined): number {\n if (configured === undefined) return DEFAULT_PROOF_TIMEOUT_MS;\n if (!Number.isFinite(configured) || configured <= 0) {\n throw new SphereError(\n `proofTimeoutMs must be a positive number of milliseconds (got ${String(configured)}); ` +\n 'an unbounded inclusion-proof wait is not supported',\n 'INVALID_CONFIG'\n );\n }\n return configured;\n}\n\n/** \"Ask again\", not \"this certification failed\" — the loop itself tolerates only\n * 404, so without this one blip strands a certification that would land (#741). */\nconst TRANSIENT_HTTP_STATUSES = new Set([408, 425, 429, 500, 502, 503, 504]);\n\n/** A submit ANSWER meaning \"ask again\" — SERVICE_NOT_READY is a 503 in a 200 body. */\nexport class TransientSubmitAnswer extends Error {\n public constructor(public readonly status: string) {\n super(`gateway is not ready to certify yet (${status})`);\n this.name = 'TransientSubmitAnswer';\n }\n}\n\nfunction isTransientGatewayError(err: unknown): boolean {\n if (err instanceof TransientSubmitAnswer) return true;\n return err instanceof JsonRpcNetworkError && TRANSIENT_HTTP_STATUSES.has(err.status);\n}\n\n/** Resolves on elapse OR abort; the caller re-checks the signal. */\nfunction pause(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise<void>((resolve) => {\n const timer = setTimeout(resolve, ms);\n signal.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n resolve();\n },\n { once: true }\n );\n });\n}\n\n/**\n * Runs `attempt` until it succeeds, a non-transient error surfaces, or the\n * signal ends it. The metered call is the SUBMIT, so this policy has to be\n * reusable by both — a copy per call site is how the two drift.\n */\nexport async function retryTransient<T>(\n attempt: () => Promise<T>,\n signal: AbortSignal,\n intervalMs: number\n): Promise<{ value: T; retried: boolean }> {\n let retried = false;\n for (;;) {\n // `pause` resolves on abort too, so recheck before attempting (#747 review).\n if (signal.aborted) throw signal.reason as Error;\n try {\n return { value: await attempt(), retried };\n } catch (err) {\n // The deadline (or the caller) ended it: that outcome is final.\n if (signal.aborted) throw err;\n if (!isTransientGatewayError(err)) throw err;\n retried = true;\n await pause(intervalMs, signal);\n }\n }\n}\n\n/** A deadline for ONE certification attempt: submit retries and proof share it. */\nexport function certificationDeadline(\n timeoutMs: number,\n external: AbortSignal | undefined,\n label: string\n): { signal: AbortSignal; dispose: () => void } {\n const controller = new AbortController();\n const relayAbort = (): void => {\n controller.abort(external?.reason);\n };\n if (external !== undefined) {\n if (external.aborted) relayAbort();\n else external.addEventListener('abort', relayAbort, { once: true });\n }\n const timer = setTimeout(() => {\n controller.abort(new SphereError(`${label} within ${String(timeoutMs)} ms`, 'AGGREGATOR_ERROR'));\n }, timeoutMs);\n return {\n signal: controller.signal,\n dispose: () => {\n clearTimeout(timer);\n external?.removeEventListener('abort', relayAbort);\n },\n };\n}\n\nexport interface ProofWaitDeps {\n readonly client: StateTransitionClient;\n readonly trustBase: RootTrustBase;\n readonly predicateVerifier: PredicateVerifierService;\n readonly unicityCertificateVerifier: UnicityCertificateVerifier;\n readonly intervalMs: number;\n}\n\n/** Await one inclusion proof, always terminating; a deadline hit throws and the\n * caller maps it to ProofUnconfirmedError (keep-open — the spend may be on-chain). */\nexport async function awaitProofBounded(\n deps: ProofWaitDeps,\n transaction: Parameters<typeof waitInclusionProof>[4],\n signal: AbortSignal\n): Promise<InclusionProof> {\n const { value } = await retryTransient(\n () =>\n waitInclusionProof(\n deps.client,\n deps.trustBase,\n deps.predicateVerifier,\n deps.unicityCertificateVerifier,\n transaction,\n signal,\n deps.intervalMs\n ),\n signal,\n deps.intervalMs\n );\n return value;\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","import { InclusionProofVerificationStatus } from './sdk';\nimport { ProofUnconfirmedError, TransferConflictError } from './errors';\n\n/** What a failed certification means: lost race, proven-clean reject, or indeterminate. */\nexport function certificationFailure(\n err: unknown,\n failLabel: string,\n submitError: unknown,\n submitRejectedCleanly: boolean,\n): unknown {\n // The SDK reports a match-verify mismatch as a generic Error carrying the\n // status in its message; that fragile string is mapped HERE and nowhere else.\n if (\n err instanceof Error &&\n err.message === `Invalid inclusion proof status: ${InclusionProofVerificationStatus.TRANSACTION_HASH_MISMATCH}`\n ) {\n return new TransferConflictError(\n `${failLabel}: the source state was already consumed by a different transaction ` +\n '(lost race — abort this intent and re-plan under a new transferId)',\n err,\n );\n }\n if (submitRejectedCleanly) return submitError;\n return new ProofUnconfirmedError(\n `${failLabel}: certification unconfirmed — the source spend may be on-chain; ` +\n 'keep the intent open and resume under the same transferId',\n submitError ?? err,\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","/**\n * token-engine/blob-keys.ts — protocol-true delivery keys from TokenBlob bytes.\n *\n * The wallet-api backend keys mailbox entries on the SDK's PROTOCOL state hash\n * (`token.latestTransaction.calculateStateHash().imprint`, hex) — NOT a plain\n * sha256 over the token bytes (wallet-api src/validation/chain.ts; §8.2 step 4\n * validates a deposit's claimed stateHash against exactly this value, and\n * entry_id = SHA-256(tokenId ‖ stateHash) builds on it). Any client-side\n * delivery id or deposit claim MUST use this derivation; a bytes-hash variant\n * 422s on deposit and misses every entry on ack.\n *\n * Lives in token-engine because decoding requires the SDK (the one-import-point\n * rule, see ./sdk.ts).\n */\nimport { HexConverter, Token } from './sdk';\n\nexport interface DeliveryKeys {\n /** Genesis-stable 64-hex token id (TokenBlob.tokenId). */\n readonly tokenId: string;\n /** The SDK's per-state hash: hex of the DataHash imprint of the latest state. */\n readonly stateHash: string;\n}\n\n/**\n * Derive the backend-true (tokenId, stateHash) for a finished token blob.\n * The input is the raw wallet-api wire form — `Token.toCBOR()` bytes, what the\n * §16 API serves (§5.2/§8.2). Both keys come from the DECODED token, never\n * from a field alongside it, so they cannot disagree with the token itself.\n */\nexport async function deriveDeliveryKeys(blobBytes: Uint8Array): Promise<DeliveryKeys> {\n const token = await Token.fromCBOR(blobBytes);\n const stateHash = HexConverter.encode((await token.latestTransaction.calculateStateHash()).imprint);\n return { tokenId: HexConverter.encode(token.id.bytes), stateHash };\n}\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 * HMAC: RFC2104 message authentication code.\n * @module\n */\nimport {\n abytes,\n aexists,\n ahash,\n aoutput,\n clean,\n type CHash,\n type Hash,\n type TArg,\n type TRet,\n} from './utils.ts';\n\n/**\n * Internal class for HMAC.\n * Accepts any byte key, although RFC 2104 §3 recommends keys at least\n * `HashLen` bytes long.\n */\nexport class _HMAC<T extends Hash<T>> implements Hash<_HMAC<T>> {\n oHash: T;\n iHash: T;\n blockLen: number;\n outputLen: number;\n canXOF = false;\n private finished = false;\n private destroyed = false;\n\n constructor(hash: TArg<CHash>, key: TArg<Uint8Array>) {\n ahash(hash);\n abytes(key, undefined, 'key');\n this.iHash = hash.create() as T;\n if (typeof this.iHash.update !== 'function')\n throw new Error('Expected instance of class which extends utils.Hash');\n this.blockLen = this.iHash.blockLen;\n this.outputLen = this.iHash.outputLen;\n const blockLen = this.blockLen;\n const pad = new Uint8Array(blockLen);\n // blockLen can be bigger than outputLen\n pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);\n for (let i = 0; i < pad.length; i++) pad[i] ^= 0x36;\n this.iHash.update(pad);\n // By doing update (processing of the first block) of the outer hash here,\n // we can re-use it between multiple calls via clone.\n this.oHash = hash.create() as T;\n // Undo internal XOR && apply outer XOR\n for (let i = 0; i < pad.length; i++) pad[i] ^= 0x36 ^ 0x5c;\n this.oHash.update(pad);\n clean(pad);\n }\n update(buf: TArg<Uint8Array>): this {\n aexists(this);\n this.iHash.update(buf);\n return this;\n }\n digestInto(out: TArg<Uint8Array>): void {\n aexists(this);\n aoutput(out, this);\n this.finished = true;\n const buf = out.subarray(0, this.outputLen);\n // Reuse the first outputLen bytes for the inner digest; the outer hash consumes them before\n // overwriting that same prefix with the final tag, leaving any oversized tail untouched.\n this.iHash.digestInto(buf);\n this.oHash.update(buf);\n this.oHash.digestInto(buf);\n this.destroy();\n }\n digest(): TRet<Uint8Array> {\n const out = new Uint8Array(this.oHash.outputLen);\n this.digestInto(out);\n return out as TRet<Uint8Array>;\n }\n _cloneInto(to?: _HMAC<T>): _HMAC<T> {\n // Create new instance without calling constructor since the key\n // is already in state and we don't know it.\n to ||= Object.create(Object.getPrototypeOf(this), {});\n const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;\n to = to as this;\n to.finished = finished;\n to.destroyed = destroyed;\n to.blockLen = blockLen;\n to.outputLen = outputLen;\n to.oHash = oHash._cloneInto(to.oHash);\n to.iHash = iHash._cloneInto(to.iHash);\n return to;\n }\n clone(): _HMAC<T> {\n return this._cloneInto();\n }\n destroy(): void {\n this.destroyed = true;\n this.oHash.destroy();\n this.iHash.destroy();\n }\n}\n\n/**\n * HMAC: RFC2104 message authentication code.\n * @param hash - function that would be used e.g. sha256\n * @param key - authentication key bytes\n * @param message - message bytes to authenticate\n * @returns Authentication tag bytes.\n * @example\n * Compute an RFC 2104 HMAC.\n * ```ts\n * import { hmac } from '@noble/hashes/hmac.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const mac = hmac(sha256, new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6]));\n * ```\n */\ntype HmacFn = {\n (hash: TArg<CHash>, key: TArg<Uint8Array>, message: TArg<Uint8Array>): TRet<Uint8Array>;\n create(hash: TArg<CHash>, key: TArg<Uint8Array>): TRet<_HMAC<any>>;\n};\nexport const hmac: TRet<HmacFn> = /* @__PURE__ */ (() => {\n const hmac_ = ((\n hash: TArg<CHash>,\n key: TArg<Uint8Array>,\n message: TArg<Uint8Array>\n ): TRet<Uint8Array> => new _HMAC<any>(hash, key).update(message).digest()) as TRet<HmacFn>;\n hmac_.create = (hash: TArg<CHash>, key: TArg<Uint8Array>): TRet<_HMAC<any>> =>\n new _HMAC<any>(hash, key) as TRet<_HMAC<any>>;\n return hmac_;\n})();\n","/**\n * HKDF (RFC 5869): extract + expand in one step.\n * See {@link https://soatok.blog/2021/11/17/understanding-hkdf/}.\n * @module\n */\nimport { hmac } from './hmac.ts';\nimport { abytes, ahash, anumber, type CHash, clean, type TArg, type TRet } from './utils.ts';\n\n/**\n * HKDF-extract from spec. Less important part. `HKDF-Extract(IKM, salt) -> PRK`\n * Arguments position differs from spec (IKM is first one, since it is not optional)\n * Local validation only checks `hash`; `ikm` / `salt` byte validation is delegated to `hmac()`.\n * @param hash - hash function that would be used (e.g. sha256)\n * @param ikm - input keying material, the initial key\n * @param salt - optional salt value (a non-secret random value)\n * @returns Pseudorandom key derived from input keying material.\n * @example\n * Run the HKDF extract step.\n * ```ts\n * import { extract } from '@noble/hashes/hkdf.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * extract(sha256, new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6]));\n * ```\n */\nexport function extract(\n hash: TArg<CHash>,\n ikm: TArg<Uint8Array>,\n salt?: TArg<Uint8Array>\n): TRet<Uint8Array> {\n ahash(hash);\n // NOTE: some libraries treat zero-length array as 'not provided';\n // we don't, since we have undefined as 'not provided'\n // https://github.com/RustCrypto/KDFs/issues/15\n if (salt === undefined) salt = new Uint8Array(hash.outputLen);\n return hmac(hash, salt, ikm);\n}\n\n// Shared mutable scratch byte for the RFC 5869 block counter `N`.\n// Safe to reuse because `expand()` is synchronous and resets it with `clean(...)` before returning.\nconst HKDF_COUNTER = /* @__PURE__ */ Uint8Array.of(0);\n// Shared RFC 5869 empty string for both `info === undefined` and the first-block `T(0)` input.\nconst EMPTY_BUFFER = /* @__PURE__ */ Uint8Array.of();\n\n/**\n * HKDF-expand from the spec. The most important part. `HKDF-Expand(PRK, info, L) -> OKM`\n * @param hash - hash function that would be used (e.g. sha256)\n * @param prk - a pseudorandom key of at least HashLen octets\n * (usually, the output from the extract step)\n * @param info - optional context and application specific information (can be a zero-length string)\n * @param length - length of output keying material in bytes.\n * RFC 5869 §2.3 allows `0..255*HashLen`, so `0` returns an empty OKM.\n * @returns Output keying material with the requested length.\n * @throws If the requested output length exceeds the HKDF limit\n * for the selected hash. {@link Error}\n * @example\n * Run the HKDF expand step.\n * ```ts\n * import { expand } from '@noble/hashes/hkdf.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * expand(sha256, new Uint8Array(32), new Uint8Array([1, 2, 3]), 16);\n * ```\n */\nexport function expand(\n hash: TArg<CHash>,\n prk: TArg<Uint8Array>,\n info?: TArg<Uint8Array>,\n length: number = 32\n): TRet<Uint8Array> {\n ahash(hash);\n anumber(length, 'length');\n abytes(prk, undefined, 'prk');\n const olen = hash.outputLen;\n // RFC 5869 §2.3: PRK is \"a pseudorandom key of at least HashLen octets\".\n if (prk.length < olen) throw new Error('\"prk\" must be at least HashLen octets');\n // RFC 5869 §2.3 only bounds `L` by `<= 255*HashLen`; `L=0` is valid and yields empty OKM.\n if (length > 255 * olen) throw new Error('Length must be <= 255*HashLen');\n const blocks = Math.ceil(length / olen);\n if (info === undefined) info = EMPTY_BUFFER;\n else abytes(info, undefined, 'info');\n // first L(ength) octets of T\n const okm = new Uint8Array(blocks * olen);\n // Re-use HMAC instance between blocks\n const HMAC = hmac.create(hash, prk);\n const HMACTmp = HMAC._cloneInto();\n const T = new Uint8Array(HMAC.outputLen);\n for (let counter = 0; counter < blocks; counter++) {\n HKDF_COUNTER[0] = counter + 1;\n // T(0) = empty string (zero length)\n // T(N) = HMAC-Hash(PRK, T(N-1) | info | N)\n HMACTmp.update(counter === 0 ? EMPTY_BUFFER : T)\n .update(info)\n .update(HKDF_COUNTER)\n .digestInto(T);\n okm.set(T, olen * counter);\n HMAC._cloneInto(HMACTmp);\n }\n HMAC.destroy();\n HMACTmp.destroy();\n clean(T, HKDF_COUNTER);\n return okm.slice(0, length) as TRet<Uint8Array>;\n}\n\n/**\n * HKDF (RFC 5869): derive keys from an initial input.\n * Combines hkdf_extract + hkdf_expand in one step\n * @param hash - hash function that would be used (e.g. sha256)\n * @param ikm - input keying material, the initial key\n * @param salt - optional salt value (a non-secret random value)\n * @param info - optional context and application specific information bytes\n * @param length - length of output keying material in bytes.\n * RFC 5869 §2.3 allows `0..255*HashLen`, so `0` returns an empty OKM.\n * @returns Output keying material derived from the input key.\n * @throws If the requested output length exceeds the HKDF limit\n * for the selected hash. {@link Error}\n * @example\n * HKDF (RFC 5869): derive keys from an initial input.\n * ```ts\n * import { hkdf } from '@noble/hashes/hkdf.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * import { randomBytes, utf8ToBytes } from '@noble/hashes/utils.js';\n * const inputKey = randomBytes(32);\n * const salt = randomBytes(32);\n * const info = utf8ToBytes('application-key');\n * const okm = hkdf(sha256, inputKey, salt, info, 32);\n * ```\n */\nexport const hkdf = (\n hash: TArg<CHash>,\n ikm: TArg<Uint8Array>,\n salt: TArg<Uint8Array | undefined>,\n info: TArg<Uint8Array | undefined>,\n length: number\n): TRet<Uint8Array> => expand(hash, extract(hash, ikm, salt), info, length);\n","/**\n * Internal Merkle-Damgard hash utils.\n * @module\n */\nimport {\n abytes,\n aexists,\n aoutput,\n clean,\n createView,\n type Hash,\n type TArg,\n type TRet,\n} from './utils.ts';\n\n/**\n * Shared 32-bit conditional boolean primitive reused by SHA-256, SHA-1, and MD5 `F`.\n * Returns bits from `b` when `a` is set, otherwise from `c`.\n * The XOR form is equivalent to MD5's `F(X,Y,Z) = XY v not(X)Z` because the masked terms never\n * set the same bit.\n * @param a - selector word\n * @param b - word chosen when selector bit is set\n * @param c - word chosen when selector bit is clear\n * @returns Mixed 32-bit word.\n * @example\n * Combine three words with the shared 32-bit choice primitive.\n * ```ts\n * Chi(0xffffffff, 0x12345678, 0x87654321);\n * ```\n */\nexport function Chi(a: number, b: number, c: number): number {\n return (a & b) ^ (~a & c);\n}\n\n/**\n * Shared 32-bit majority primitive reused by SHA-256 and SHA-1.\n * Returns bits shared by at least two inputs.\n * @param a - first input word\n * @param b - second input word\n * @param c - third input word\n * @returns Mixed 32-bit word.\n * @example\n * Combine three words with the shared 32-bit majority primitive.\n * ```ts\n * Maj(0xffffffff, 0x12345678, 0x87654321);\n * ```\n */\nexport function Maj(a: number, b: number, c: number): number {\n return (a & b) ^ (a & c) ^ (b & c);\n}\n\n/**\n * Merkle-Damgard hash construction base class.\n * Could be used to create MD5, RIPEMD, SHA1, SHA2.\n * Accepts only byte-aligned `Uint8Array` input, even when the underlying spec describes bit\n * strings with partial-byte tails.\n * @param blockLen - internal block size in bytes\n * @param outputLen - digest size in bytes\n * @param padOffset - trailing length field size in bytes\n * @param isLE - whether length and state words are encoded in little-endian\n * @example\n * Use a concrete subclass to get the shared Merkle-Damgard update/digest flow.\n * ```ts\n * import { _SHA1 } from '@noble/hashes/legacy.js';\n * const hash = new _SHA1();\n * hash.update(new Uint8Array([97, 98, 99]));\n * hash.digest();\n * ```\n */\nexport abstract class HashMD<T extends HashMD<T>> implements Hash<T> {\n // Subclasses must treat `buf` as read-only: `update()` may pass a direct view over caller input\n // when it can process whole blocks without buffering first.\n protected abstract process(buf: DataView, offset: number): void;\n protected abstract get(): number[];\n protected abstract set(...args: number[]): void;\n abstract destroy(): void;\n protected abstract roundClean(): void;\n\n readonly blockLen: number;\n readonly outputLen: number;\n readonly canXOF = false;\n readonly padOffset: number;\n readonly isLE: boolean;\n\n // For partial updates less than block size\n protected buffer: Uint8Array;\n protected view: DataView;\n protected finished = false;\n protected length = 0;\n protected pos = 0;\n protected destroyed = false;\n\n constructor(blockLen: number, outputLen: number, padOffset: number, isLE: boolean) {\n this.blockLen = blockLen;\n this.outputLen = outputLen;\n this.padOffset = padOffset;\n this.isLE = isLE;\n this.buffer = new Uint8Array(blockLen);\n this.view = createView(this.buffer);\n }\n update(data: TArg<Uint8Array>): this {\n aexists(this);\n abytes(data);\n const { view, buffer, blockLen } = this;\n const len = data.length;\n for (let pos = 0; pos < len; ) {\n const take = Math.min(blockLen - this.pos, len - pos);\n // Fast path only when there is no buffered partial block: `take === blockLen` implies\n // `this.pos === 0`, so we can process full blocks directly from the input view.\n if (take === blockLen) {\n const dataView = createView(data);\n for (; blockLen <= len - pos; pos += blockLen) this.process(dataView, pos);\n continue;\n }\n buffer.set(data.subarray(pos, pos + take), this.pos);\n this.pos += take;\n pos += take;\n if (this.pos === blockLen) {\n this.process(view, 0);\n this.pos = 0;\n }\n }\n this.length += data.length;\n this.roundClean();\n return this;\n }\n digestInto(out: TArg<Uint8Array>): void {\n aexists(this);\n aoutput(out, this);\n this.finished = true;\n // Padding\n // We can avoid allocation of buffer for padding completely if it\n // was previously not allocated here. But it won't change performance.\n const { buffer, view, blockLen, isLE } = this;\n let { pos } = this;\n // append the bit '1' to the message\n buffer[pos++] = 0b10000000;\n clean(this.buffer.subarray(pos));\n // we have less than padOffset left in buffer, so we cannot put length in\n // current block, need process it and pad again\n if (this.padOffset > blockLen - pos) {\n this.process(view, 0);\n pos = 0;\n }\n // Pad until full block byte with zeros\n for (let i = pos; i < blockLen; i++) buffer[i] = 0;\n // `padOffset` reserves the whole length field. For SHA-384/512 the high 64 bits stay zero from\n // the padding fill above, and JS will overflow before user input can make that half non-zero.\n // So we only need to write the low 64 bits here.\n view.setBigUint64(blockLen - 8, BigInt(this.length * 8), isLE);\n this.process(view, 0);\n const oview = createView(out);\n const len = this.outputLen;\n // NOTE: we do division by 4 later, which must be fused in single op with modulo by JIT\n if (len % 4) throw new Error('_sha2: outputLen must be aligned to 32bit');\n const outLen = len / 4;\n const state = this.get();\n if (outLen > state.length) throw new Error('_sha2: outputLen bigger than state');\n for (let i = 0; i < outLen; i++) oview.setUint32(4 * i, state[i], isLE);\n }\n digest(): TRet<Uint8Array> {\n const { buffer, outputLen } = this;\n this.digestInto(buffer);\n // Copy before destroy(): subclasses wipe `buffer` during cleanup, but `digest()` must return\n // fresh bytes to the caller.\n const res = buffer.slice(0, outputLen);\n this.destroy();\n return res as TRet<Uint8Array>;\n }\n _cloneInto(to?: T): T {\n to ||= new (this.constructor as any)() as T;\n to.set(...this.get());\n const { blockLen, buffer, length, finished, destroyed, pos } = this;\n to.destroyed = destroyed;\n to.finished = finished;\n to.length = length;\n to.pos = pos;\n // Only partial-block bytes need copying: when `length % blockLen === 0`, `pos === 0` and\n // later `update()` / `digestInto()` overwrite `to.buffer` from the start before reading it.\n if (length % blockLen) to.buffer.set(buffer);\n return to as unknown as any;\n }\n clone(): T {\n return this._cloneInto();\n }\n}\n\n/**\n * Initial SHA-2 state: fractional parts of square roots of first 16 primes 2..53.\n * Check out `test/misc/sha2-gen-iv.js` for recomputation guide.\n */\n\n/** Initial SHA256 state from RFC 6234 §6.1: the first 32 bits of the fractional parts of the\n * square roots of the first eight prime numbers. Exported as a shared table; callers must treat\n * it as read-only because constructors copy words from it by index. */\nexport const SHA256_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n]);\n\n/** Initial SHA224 state `H(0)` from RFC 6234 §6.1. Exported as a shared table; callers must\n * treat it as read-only because constructors copy words from it by index. */\nexport const SHA224_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4,\n]);\n\n/** Initial SHA384 state from RFC 6234 §6.3: eight RFC 64-bit `H(0)` words stored as sixteen\n * big-endian 32-bit halves. Derived from the fractional parts of the square roots of the ninth\n * through sixteenth prime numbers. Exported as a shared table; callers must treat it as read-only\n * because constructors copy halves from it by index. */\nexport const SHA384_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0xcbbb9d5d, 0xc1059ed8, 0x629a292a, 0x367cd507, 0x9159015a, 0x3070dd17, 0x152fecd8, 0xf70e5939,\n 0x67332667, 0xffc00b31, 0x8eb44a87, 0x68581511, 0xdb0c2e0d, 0x64f98fa7, 0x47b5481d, 0xbefa4fa4,\n]);\n\n/** Initial SHA512 state from RFC 6234 §6.3: eight RFC 64-bit `H(0)` words stored as sixteen\n * big-endian 32-bit halves. Derived from the fractional parts of the square roots of the first\n * eight prime numbers. Exported as a shared table; callers must treat it as read-only because\n * constructors copy halves from it by index. */\nexport const SHA512_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b, 0xa54ff53a, 0x5f1d36f1,\n 0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179,\n]);\n","/**\n * SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256.\n * SHA256 is the fastest hash implementable in JS, even faster than Blake3.\n * Check out {@link https://www.rfc-editor.org/rfc/rfc4634 | RFC 4634} and\n * {@link https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf | FIPS 180-4}.\n * @module\n */\nimport { Chi, HashMD, Maj, SHA224_IV, SHA256_IV, SHA384_IV, SHA512_IV } from './_md.ts';\nimport * as u64 from './_u64.ts';\nimport { type CHash, clean, createHasher, oidNist, rotr, type TRet } from './utils.ts';\n\n/**\n * SHA-224 / SHA-256 round constants from RFC 6234 §5.1: the first 32 bits\n * of the cube roots of the first 64 primes (2..311).\n */\n// prettier-ignore\nconst SHA256_K = /* @__PURE__ */ Uint32Array.from([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n]);\n\n/** Reusable SHA-224 / SHA-256 message schedule buffer `W_t` from RFC 6234 §6.2 step 1. */\nconst SHA256_W = /* @__PURE__ */ new Uint32Array(64);\n\n/** Internal SHA-224 / SHA-256 compression engine from RFC 6234 §6.2. */\nabstract class SHA2_32B<T extends SHA2_32B<T>> extends HashMD<T> {\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n protected abstract A: number;\n protected abstract B: number;\n protected abstract C: number;\n protected abstract D: number;\n protected abstract E: number;\n protected abstract F: number;\n protected abstract G: number;\n protected abstract H: number;\n\n constructor(outputLen: number) {\n super(64, outputLen, 8, false);\n }\n protected get(): [number, number, number, number, number, number, number, number] {\n const { A, B, C, D, E, F, G, H } = this;\n return [A, B, C, D, E, F, G, H];\n }\n // prettier-ignore\n protected set(\n A: number, B: number, C: number, D: number, E: number, F: number, G: number, H: number\n ): void {\n this.A = A | 0;\n this.B = B | 0;\n this.C = C | 0;\n this.D = D | 0;\n this.E = E | 0;\n this.F = F | 0;\n this.G = G | 0;\n this.H = H | 0;\n }\n protected process(view: DataView, offset: number): void {\n // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array\n for (let i = 0; i < 16; i++, offset += 4) SHA256_W[i] = view.getUint32(offset, false);\n for (let i = 16; i < 64; i++) {\n const W15 = SHA256_W[i - 15];\n const W2 = SHA256_W[i - 2];\n const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);\n const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);\n SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;\n }\n // Compression function main loop, 64 rounds\n let { A, B, C, D, E, F, G, H } = this;\n for (let i = 0; i < 64; i++) {\n const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);\n const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;\n const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);\n const T2 = (sigma0 + Maj(A, B, C)) | 0;\n H = G;\n G = F;\n F = E;\n E = (D + T1) | 0;\n D = C;\n C = B;\n B = A;\n A = (T1 + T2) | 0;\n }\n // Add the compressed chunk to the current hash value\n A = (A + this.A) | 0;\n B = (B + this.B) | 0;\n C = (C + this.C) | 0;\n D = (D + this.D) | 0;\n E = (E + this.E) | 0;\n F = (F + this.F) | 0;\n G = (G + this.G) | 0;\n H = (H + this.H) | 0;\n this.set(A, B, C, D, E, F, G, H);\n }\n protected roundClean(): void {\n clean(SHA256_W);\n }\n destroy(): void {\n // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves\n // update()/digest() callable on reused instances.\n this.destroyed = true;\n this.set(0, 0, 0, 0, 0, 0, 0, 0);\n clean(this.buffer);\n }\n}\n\n/** Internal SHA-256 hash class grounded in RFC 6234 §6.2. */\nexport class _SHA256 extends SHA2_32B<_SHA256> {\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n protected A: number = SHA256_IV[0] | 0;\n protected B: number = SHA256_IV[1] | 0;\n protected C: number = SHA256_IV[2] | 0;\n protected D: number = SHA256_IV[3] | 0;\n protected E: number = SHA256_IV[4] | 0;\n protected F: number = SHA256_IV[5] | 0;\n protected G: number = SHA256_IV[6] | 0;\n protected H: number = SHA256_IV[7] | 0;\n constructor() {\n super(32);\n }\n}\n\n/** Internal SHA-224 hash class grounded in RFC 6234 §6.2 and §8.5. */\nexport class _SHA224 extends SHA2_32B<_SHA224> {\n protected A: number = SHA224_IV[0] | 0;\n protected B: number = SHA224_IV[1] | 0;\n protected C: number = SHA224_IV[2] | 0;\n protected D: number = SHA224_IV[3] | 0;\n protected E: number = SHA224_IV[4] | 0;\n protected F: number = SHA224_IV[5] | 0;\n protected G: number = SHA224_IV[6] | 0;\n protected H: number = SHA224_IV[7] | 0;\n constructor() {\n super(28);\n }\n}\n\n// SHA2-512 is slower than sha256 in js because u64 operations are slow.\n\n// SHA-384 / SHA-512 round constants from RFC 6234 §5.2:\n// 80 full 64-bit words split into high/low halves.\n// prettier-ignore\nconst K512 = /* @__PURE__ */ (() => u64.split([\n '0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc',\n '0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118',\n '0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2',\n '0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694',\n '0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65',\n '0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5',\n '0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4',\n '0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70',\n '0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df',\n '0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b',\n '0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30',\n '0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8',\n '0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8',\n '0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3',\n '0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec',\n '0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b',\n '0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178',\n '0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b',\n '0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c',\n '0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817'\n].map(n => BigInt(n))))();\nconst SHA512_Kh = /* @__PURE__ */ (() => K512[0])();\nconst SHA512_Kl = /* @__PURE__ */ (() => K512[1])();\n\n// Reusable high-half schedule buffer for the RFC 6234 §6.4 64-bit `W_t` words.\nconst SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);\n// Reusable low-half schedule buffer for the RFC 6234 §6.4 64-bit `W_t` words.\nconst SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);\n\n/** Internal SHA-384 / SHA-512 compression engine from RFC 6234 §6.4. */\nabstract class SHA2_64B<T extends SHA2_64B<T>> extends HashMD<T> {\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n // h -- high 32 bits, l -- low 32 bits\n protected abstract Ah: number;\n protected abstract Al: number;\n protected abstract Bh: number;\n protected abstract Bl: number;\n protected abstract Ch: number;\n protected abstract Cl: number;\n protected abstract Dh: number;\n protected abstract Dl: number;\n protected abstract Eh: number;\n protected abstract El: number;\n protected abstract Fh: number;\n protected abstract Fl: number;\n protected abstract Gh: number;\n protected abstract Gl: number;\n protected abstract Hh: number;\n protected abstract Hl: number;\n\n constructor(outputLen: number) {\n super(128, outputLen, 16, false);\n }\n // prettier-ignore\n protected get(): [\n number, number, number, number, number, number, number, number,\n number, number, number, number, number, number, number, number\n ] {\n const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;\n return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];\n }\n // prettier-ignore\n protected set(\n Ah: number, Al: number, Bh: number, Bl: number, Ch: number, Cl: number, Dh: number, Dl: number,\n Eh: number, El: number, Fh: number, Fl: number, Gh: number, Gl: number, Hh: number, Hl: number\n ): void {\n this.Ah = Ah | 0;\n this.Al = Al | 0;\n this.Bh = Bh | 0;\n this.Bl = Bl | 0;\n this.Ch = Ch | 0;\n this.Cl = Cl | 0;\n this.Dh = Dh | 0;\n this.Dl = Dl | 0;\n this.Eh = Eh | 0;\n this.El = El | 0;\n this.Fh = Fh | 0;\n this.Fl = Fl | 0;\n this.Gh = Gh | 0;\n this.Gl = Gl | 0;\n this.Hh = Hh | 0;\n this.Hl = Hl | 0;\n }\n protected process(view: DataView, offset: number): void {\n // Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array\n for (let i = 0; i < 16; i++, offset += 4) {\n SHA512_W_H[i] = view.getUint32(offset);\n SHA512_W_L[i] = view.getUint32((offset += 4));\n }\n for (let i = 16; i < 80; i++) {\n // s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7)\n const W15h = SHA512_W_H[i - 15] | 0;\n const W15l = SHA512_W_L[i - 15] | 0;\n const s0h = u64.rotrSH(W15h, W15l, 1) ^ u64.rotrSH(W15h, W15l, 8) ^ u64.shrSH(W15h, W15l, 7);\n const s0l = u64.rotrSL(W15h, W15l, 1) ^ u64.rotrSL(W15h, W15l, 8) ^ u64.shrSL(W15h, W15l, 7);\n // s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6)\n const W2h = SHA512_W_H[i - 2] | 0;\n const W2l = SHA512_W_L[i - 2] | 0;\n const s1h = u64.rotrSH(W2h, W2l, 19) ^ u64.rotrBH(W2h, W2l, 61) ^ u64.shrSH(W2h, W2l, 6);\n const s1l = u64.rotrSL(W2h, W2l, 19) ^ u64.rotrBL(W2h, W2l, 61) ^ u64.shrSL(W2h, W2l, 6);\n // SHA512_W[i] = s0 + s1 + SHA512_W[i - 7] + SHA512_W[i - 16];\n const SUMl = u64.add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);\n const SUMh = u64.add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);\n SHA512_W_H[i] = SUMh | 0;\n SHA512_W_L[i] = SUMl | 0;\n }\n let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;\n // Compression function main loop, 80 rounds\n for (let i = 0; i < 80; i++) {\n // S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41)\n const sigma1h = u64.rotrSH(Eh, El, 14) ^ u64.rotrSH(Eh, El, 18) ^ u64.rotrBH(Eh, El, 41);\n const sigma1l = u64.rotrSL(Eh, El, 14) ^ u64.rotrSL(Eh, El, 18) ^ u64.rotrBL(Eh, El, 41);\n //const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;\n const CHIh = (Eh & Fh) ^ (~Eh & Gh);\n const CHIl = (El & Fl) ^ (~El & Gl);\n // T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i]\n // prettier-ignore\n const T1ll = u64.add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);\n const T1h = u64.add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);\n const T1l = T1ll | 0;\n // S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39)\n const sigma0h = u64.rotrSH(Ah, Al, 28) ^ u64.rotrBH(Ah, Al, 34) ^ u64.rotrBH(Ah, Al, 39);\n const sigma0l = u64.rotrSL(Ah, Al, 28) ^ u64.rotrBL(Ah, Al, 34) ^ u64.rotrBL(Ah, Al, 39);\n const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch);\n const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl);\n Hh = Gh | 0;\n Hl = Gl | 0;\n Gh = Fh | 0;\n Gl = Fl | 0;\n Fh = Eh | 0;\n Fl = El | 0;\n ({ h: Eh, l: El } = u64.add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));\n Dh = Ch | 0;\n Dl = Cl | 0;\n Ch = Bh | 0;\n Cl = Bl | 0;\n Bh = Ah | 0;\n Bl = Al | 0;\n const All = u64.add3L(T1l, sigma0l, MAJl);\n Ah = u64.add3H(All, T1h, sigma0h, MAJh);\n Al = All | 0;\n }\n // Add the compressed chunk to the current hash value\n ({ h: Ah, l: Al } = u64.add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));\n ({ h: Bh, l: Bl } = u64.add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));\n ({ h: Ch, l: Cl } = u64.add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));\n ({ h: Dh, l: Dl } = u64.add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));\n ({ h: Eh, l: El } = u64.add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));\n ({ h: Fh, l: Fl } = u64.add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));\n ({ h: Gh, l: Gl } = u64.add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));\n ({ h: Hh, l: Hl } = u64.add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));\n this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);\n }\n protected roundClean(): void {\n clean(SHA512_W_H, SHA512_W_L);\n }\n destroy(): void {\n // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves\n // update()/digest() callable on reused instances.\n this.destroyed = true;\n clean(this.buffer);\n this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);\n }\n}\n\n/** Internal SHA-512 hash class grounded in RFC 6234 §6.3 and §6.4. */\nexport class _SHA512 extends SHA2_64B<_SHA512> {\n protected Ah: number = SHA512_IV[0] | 0;\n protected Al: number = SHA512_IV[1] | 0;\n protected Bh: number = SHA512_IV[2] | 0;\n protected Bl: number = SHA512_IV[3] | 0;\n protected Ch: number = SHA512_IV[4] | 0;\n protected Cl: number = SHA512_IV[5] | 0;\n protected Dh: number = SHA512_IV[6] | 0;\n protected Dl: number = SHA512_IV[7] | 0;\n protected Eh: number = SHA512_IV[8] | 0;\n protected El: number = SHA512_IV[9] | 0;\n protected Fh: number = SHA512_IV[10] | 0;\n protected Fl: number = SHA512_IV[11] | 0;\n protected Gh: number = SHA512_IV[12] | 0;\n protected Gl: number = SHA512_IV[13] | 0;\n protected Hh: number = SHA512_IV[14] | 0;\n protected Hl: number = SHA512_IV[15] | 0;\n\n constructor() {\n super(64);\n }\n}\n\n/** Internal SHA-384 hash class grounded in RFC 6234 §6.3 and §6.4. */\nexport class _SHA384 extends SHA2_64B<_SHA384> {\n protected Ah: number = SHA384_IV[0] | 0;\n protected Al: number = SHA384_IV[1] | 0;\n protected Bh: number = SHA384_IV[2] | 0;\n protected Bl: number = SHA384_IV[3] | 0;\n protected Ch: number = SHA384_IV[4] | 0;\n protected Cl: number = SHA384_IV[5] | 0;\n protected Dh: number = SHA384_IV[6] | 0;\n protected Dl: number = SHA384_IV[7] | 0;\n protected Eh: number = SHA384_IV[8] | 0;\n protected El: number = SHA384_IV[9] | 0;\n protected Fh: number = SHA384_IV[10] | 0;\n protected Fl: number = SHA384_IV[11] | 0;\n protected Gh: number = SHA384_IV[12] | 0;\n protected Gl: number = SHA384_IV[13] | 0;\n protected Hh: number = SHA384_IV[14] | 0;\n protected Hl: number = SHA384_IV[15] | 0;\n\n constructor() {\n super(48);\n }\n}\n\n/**\n * Truncated SHA512/256 and SHA512/224.\n * SHA512_IV is XORed with 0xa5a5a5a5a5a5a5a5, then used as \"intermediary\" IV of SHA512/t.\n * Then t hashes string to produce result IV.\n * See the repo-side derivation recipe in `test/misc/sha2-gen-iv.js`.\n * These IV literals are checked against that script rather than a dedicated\n * local RFC section.\n */\n\n/** SHA-512/224 IV derived by the SHA-512/t recipe in `test/misc/sha2-gen-iv.js` and\n * stored as sixteen big-endian 32-bit halves. */\nconst T224_IV = /* @__PURE__ */ Uint32Array.from([\n 0x8c3d37c8, 0x19544da2, 0x73e19966, 0x89dcd4d6, 0x1dfab7ae, 0x32ff9c82, 0x679dd514, 0x582f9fcf,\n 0x0f6d2b69, 0x7bd44da8, 0x77e36f73, 0x04c48942, 0x3f9d85a8, 0x6a1d36c8, 0x1112e6ad, 0x91d692a1,\n]);\n\n/** SHA-512/256 IV derived by the SHA-512/t recipe in `test/misc/sha2-gen-iv.js` and\n * stored as sixteen big-endian 32-bit halves. */\nconst T256_IV = /* @__PURE__ */ Uint32Array.from([\n 0x22312194, 0xfc2bf72c, 0x9f555fa3, 0xc84c64c2, 0x2393b86b, 0x6f53b151, 0x96387719, 0x5940eabd,\n 0x96283ee2, 0xa88effe3, 0xbe5e1e25, 0x53863992, 0x2b0199fc, 0x2c85b8aa, 0x0eb72ddc, 0x81c52ca2,\n]);\n\n/** Internal SHA-512/224 hash class using the derived `T224_IV` and the shared\n * RFC 6234 §6.4 compression engine. */\nexport class _SHA512_224 extends SHA2_64B<_SHA512_224> {\n protected Ah: number = T224_IV[0] | 0;\n protected Al: number = T224_IV[1] | 0;\n protected Bh: number = T224_IV[2] | 0;\n protected Bl: number = T224_IV[3] | 0;\n protected Ch: number = T224_IV[4] | 0;\n protected Cl: number = T224_IV[5] | 0;\n protected Dh: number = T224_IV[6] | 0;\n protected Dl: number = T224_IV[7] | 0;\n protected Eh: number = T224_IV[8] | 0;\n protected El: number = T224_IV[9] | 0;\n protected Fh: number = T224_IV[10] | 0;\n protected Fl: number = T224_IV[11] | 0;\n protected Gh: number = T224_IV[12] | 0;\n protected Gl: number = T224_IV[13] | 0;\n protected Hh: number = T224_IV[14] | 0;\n protected Hl: number = T224_IV[15] | 0;\n\n constructor() {\n super(28);\n }\n}\n\n/** Internal SHA-512/256 hash class using the derived `T256_IV` and the shared\n * RFC 6234 §6.4 compression engine. */\nexport class _SHA512_256 extends SHA2_64B<_SHA512_256> {\n protected Ah: number = T256_IV[0] | 0;\n protected Al: number = T256_IV[1] | 0;\n protected Bh: number = T256_IV[2] | 0;\n protected Bl: number = T256_IV[3] | 0;\n protected Ch: number = T256_IV[4] | 0;\n protected Cl: number = T256_IV[5] | 0;\n protected Dh: number = T256_IV[6] | 0;\n protected Dl: number = T256_IV[7] | 0;\n protected Eh: number = T256_IV[8] | 0;\n protected El: number = T256_IV[9] | 0;\n protected Fh: number = T256_IV[10] | 0;\n protected Fl: number = T256_IV[11] | 0;\n protected Gh: number = T256_IV[12] | 0;\n protected Gl: number = T256_IV[13] | 0;\n protected Hh: number = T256_IV[14] | 0;\n protected Hl: number = T256_IV[15] | 0;\n\n constructor() {\n super(32);\n }\n}\n\n/**\n * SHA2-256 hash function from RFC 4634. In JS it's the fastest: even faster than Blake3. Some info:\n *\n * - Trying 2^128 hashes would get 50% chance of collision, using birthday attack.\n * - BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.\n * - Each sha256 hash is executing 2^18 bit operations.\n * - Good 2024 ASICs can do 200Th/sec with 3500 watts of power, corresponding to 2^36 hashes/joule.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-256.\n * ```ts\n * sha256(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha256: TRet<CHash<_SHA256>> = /* @__PURE__ */ createHasher(\n () => new _SHA256(),\n /* @__PURE__ */ oidNist(0x01)\n);\n/**\n * SHA2-224 hash function from RFC 4634.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-224.\n * ```ts\n * sha224(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha224: TRet<CHash<_SHA224>> = /* @__PURE__ */ createHasher(\n () => new _SHA224(),\n /* @__PURE__ */ oidNist(0x04)\n);\n\n/**\n * SHA2-512 hash function from RFC 4634.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-512.\n * ```ts\n * sha512(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha512: TRet<CHash<_SHA512>> = /* @__PURE__ */ createHasher(\n () => new _SHA512(),\n /* @__PURE__ */ oidNist(0x03)\n);\n/**\n * SHA2-384 hash function from RFC 4634.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-384.\n * ```ts\n * sha384(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha384: TRet<CHash<_SHA384>> = /* @__PURE__ */ createHasher(\n () => new _SHA384(),\n /* @__PURE__ */ oidNist(0x02)\n);\n\n/**\n * SHA2-512/256 \"truncated\" hash function, with improved resistance to length extension attacks.\n * See the paper on {@link https://eprint.iacr.org/2010/548.pdf | truncated SHA512}.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-512/256.\n * ```ts\n * sha512_256(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha512_256: TRet<CHash<_SHA512_256>> = /* @__PURE__ */ createHasher(\n () => new _SHA512_256(),\n /* @__PURE__ */ oidNist(0x06)\n);\n/**\n * SHA2-512/224 \"truncated\" hash function, with improved resistance to length extension attacks.\n * See the paper on {@link https://eprint.iacr.org/2010/548.pdf | truncated SHA512}.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-512/224.\n * ```ts\n * sha512_224(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha512_224: TRet<CHash<_SHA512_224>> = /* @__PURE__ */ createHasher(\n () => new _SHA512_224(),\n /* @__PURE__ */ oidNist(0x05)\n);\n","/**\n * token-engine/realization.ts — deterministic realization values (Part E.1).\n *\n * Every \"random\" value a transfer/split binds to (stateMask, per-output salt,\n * tokenType where not fixed, the split burn mask) is derived from the wallet\n * key + a pre-persisted transferId instead of `crypto.getRandomValues`, so the\n * exact transaction can be rebuilt later — on any device holding the seed.\n * That is what makes an interrupted transfer resumable (sdk-changes Part E,\n * ARCHITECTURE §8.1): re-running with the same transferId reproduces the\n * byte-identical transaction, and the aggregator's existing proof applies.\n *\n * Derivation (mirrors impl/shared/ipfs/ipns-key-derivation.ts — same\n * @noble/hashes HKDF, no salt):\n *\n * HKDF-SHA256(ikm = privKey, info = \"sphere-realization-v1:\" + transferId\n * + \":\" + field + \":\" + index)[0..32)\n *\n * `field` is the domain separator between the values of one transfer;\n * `index` separates per-output values (split salts). The output is\n * per-transfer unique and unpredictable to outsiders (derived from the secret\n * key — no privacy/unlinkability regression), yet reproducible by the owner.\n */\n\nimport { hkdf } from '@noble/hashes/hkdf.js';\nimport { sha256 } from '@noble/hashes/sha2.js';\nimport { HexConverter } from './sdk';\n\n/** HKDF info prefix — versioned; the same formula appears in ARCHITECTURE §8.1. */\nexport const REALIZATION_HKDF_INFO_PREFIX = 'sphere-realization-v1';\n\n/**\n * Domain separator between the realization values of one transfer.\n * 'salt' is indexed by split-OUTPUT ordinal; a standalone mint's salt lives in\n * the separate 'mint' domain (indexed by opIndex) so the two never collide\n * under a shared transferId (#692 F13).\n */\nexport type RealizationField = 'stateMask' | 'salt' | 'tokenType' | 'burn' | 'mint';\n\n/**\n * Derive one 32-byte realization value.\n *\n * @param privKeyHex - wallet secp256k1 private key, hex (the HKDF ikm is its raw bytes)\n * @param transferId - client-generated UUIDv4 in canonical lowercase string form\n * (validated by the engine before any derivation)\n * @param index - per-output index within the transfer (0 for single-value fields)\n * @param field - which value of the transfer is being derived\n * @returns 32 deterministic bytes\n */\nexport function deriveRealization(\n privKeyHex: string,\n transferId: string,\n index: number,\n field: RealizationField,\n): Uint8Array {\n const ikm = HexConverter.decode(privKeyHex);\n const info = new TextEncoder().encode(`${REALIZATION_HKDF_INFO_PREFIX}:${transferId}:${field}:${index}`);\n return hkdf(sha256, ikm, undefined, info, 32);\n}\n","/**\n * token-engine/split-checkpoint.ts — the split burn checkpoint (sdk-changes E.4, sphere-sdk#501\n * option b). Encodes/decodes the one split-resume input the engine cannot re-derive — the burn's\n * aggregator-issued inclusion proof — and rebuilds the burnt token from STORED bytes so every\n * mint justification is byte-stable across a resume (the aggregator regenerates proofs per\n * request; only `CertificationData` is stable).\n *\n * Payload (strict-canonical CBOR array): `[v, sdkVersion, burnTx.toCBOR(), burnProof.toCBOR(),\n * sha256(burntToken.toCBOR())]`. Storing the burn-tx bytes turns any cross-version derivation\n * drift into a LOUD byte-inequality; the burnt-token hash catches a tolerant-decode wire migration\n * on resume. The engine passes PLAINTEXT through the `SplitCheckpointStore` port; AAD-encryption is\n * the transport adapter's concern.\n */\n\nimport { SplitCheckpointLostError, CheckpointTrustbaseMismatchError } from './errors';\nimport {\n CborDeserializer,\n CborSerializer,\n DataHasher,\n HashAlgorithm,\n InclusionProof,\n InclusionProofVerificationStatus,\n type PredicateVerifierService,\n type UnicityCertificateVerifier,\n type RootTrustBase,\n Token,\n type TransferTransaction,\n type VerificationContext,\n} from './sdk';\n\n/**\n * Checkpoint payload version (the CBOR array's first element).\n *\n * 2 since the state-transition-sdk 3.x bump: the burn transaction and its\n * inclusion proof are both stored as SDK CBOR, and every wire version under\n * them moved, so no v1 record can be replayed. Without this bump a stale record\n * still fails — the byte-comparison below catches it — but it fails blaming\n * \"derivation drift\", which sends the reader hunting a realization bug that\n * isn't there. The version check names the real cause.\n */\nconst CHECKPOINT_VERSION = 2;\n/**\n * The base-SDK pin whose CBOR wire form governs byte-stability — recorded for a LOUD drift\n * diagnosis only (byte-inequality of the stored burn tx is the actual guard). Bump with the pin.\n */\nconst CHECKPOINT_SDK_VERSION = '@unicitylabs/state-transition-sdk@3.0.1';\n\nexport interface CheckpointDeps {\n readonly trustBase: RootTrustBase;\n readonly predicateVerifier: PredicateVerifierService;\n readonly unicityCertificateVerifier: UnicityCertificateVerifier;\n readonly verificationContext: VerificationContext;\n}\n\n/** Constant-length-agnostic byte-equality (no early-exit timing concern — these are public bytes). */\nexport function bytesEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n}\n\nasync function sha256(bytes: Uint8Array): Promise<Uint8Array> {\n return (await new DataHasher(HashAlgorithm.SHA256).update(bytes).digest()).imprint;\n}\n\n/**\n * Encode the checkpoint for `store.put`. `burntToken` is the freshly-built burnt token whose hash\n * pins the resume-side re-encode equality check.\n */\nexport async function encodeCheckpoint(\n burnTx: TransferTransaction,\n burnProof: InclusionProof,\n burntToken: Token,\n): Promise<Uint8Array> {\n return CborSerializer.encodeArray(\n CborSerializer.encodeUnsignedInteger(CHECKPOINT_VERSION),\n CborSerializer.encodeTextString(CHECKPOINT_SDK_VERSION),\n CborSerializer.encodeByteString(burnTx.toCBOR()),\n CborSerializer.encodeByteString(burnProof.toCBOR()),\n CborSerializer.encodeByteString(await sha256(burntToken.toCBOR())),\n );\n}\n\ninterface DecodedCheckpoint {\n readonly sdkVersion: string;\n readonly burnTxBytes: Uint8Array;\n readonly burnProofBytes: Uint8Array;\n readonly burntTokenHash: Uint8Array;\n}\n\n/**\n * Decode a stored checkpoint; ANY malformed/unknown-version record is a lost checkpoint (never\n * mint). The FULL decode (array framing AND every inner field) is guarded — a well-framed 5-array\n * with a wrong-typed/non-canonical inner field throws a raw `CborError` from the per-field decoders,\n * which must still surface as the typed keep-open error, not escape `split()` untyped (AC-E6(c)).\n */\nfunction decodeCheckpoint(bytes: Uint8Array): DecodedCheckpoint {\n try {\n const fields = CborDeserializer.decodeArray(bytes, 5);\n const version = Number(CborDeserializer.decodeUnsignedInteger(fields[0]));\n if (version !== CHECKPOINT_VERSION) {\n throw new SplitCheckpointLostError(`split checkpoint version ${String(version)} is not supported`);\n }\n return {\n sdkVersion: CborDeserializer.decodeTextString(fields[1]),\n burnTxBytes: CborDeserializer.decodeByteString(fields[2]),\n burnProofBytes: CborDeserializer.decodeByteString(fields[3]),\n burntTokenHash: CborDeserializer.decodeByteString(fields[4]),\n };\n } catch (err) {\n if (err instanceof SplitCheckpointLostError) throw err;\n throw new SplitCheckpointLostError('split checkpoint is malformed (cannot decode)', err);\n }\n}\n\n/** Classify a `toCertifiedTransaction` failure: only INVALID_TRUSTBASE is a keep-open drain case. */\nfunction isTrustbaseFailure(err: unknown): boolean {\n const status = (err as { verificationResult?: { status?: unknown } })?.verificationResult?.status;\n return status === InclusionProofVerificationStatus.INVALID_TRUSTBASE;\n}\n\n/**\n * Rebuild the burnt token from a stored checkpoint (resume, or adopt-after-put). NEVER refetches\n * the burn proof — it applies the STORED proof to the re-derived burn tx, so the mint\n * justification is byte-stable. Throws (never returns a wrong burnt token):\n * - stored burn tx ≠ re-derived (cross-version drift) → SplitCheckpointLostError (names sdkVersion)\n * - stored proof fails ONLY the current trust base → CheckpointTrustbaseMismatchError\n * - stored proof otherwise invalid / corrupt → SplitCheckpointLostError\n * - rebuilt burnt token re-encodes to a different hash → SplitCheckpointLostError (wire migration)\n */\nexport async function burntTokenFromCheckpoint(\n deps: CheckpointDeps,\n storedBytes: Uint8Array,\n reDerivedBurnTx: TransferTransaction,\n sourceToken: Token,\n): Promise<Token> {\n const decoded = decodeCheckpoint(storedBytes);\n if (!bytesEqual(decoded.burnTxBytes, reDerivedBurnTx.toCBOR())) {\n throw new SplitCheckpointLostError(\n `split checkpoint burn tx does not match the re-derived burn (stored under ${decoded.sdkVersion}) — derivation drift`,\n );\n }\n // The burn-proof field is the most transit-exposed value; parsing corrupt bytes throws a raw\n // CborError, which must surface as the typed keep-open error (not escape split() untyped).\n let burnProof: InclusionProof;\n try {\n burnProof = InclusionProof.fromCBOR(decoded.burnProofBytes);\n } catch (err) {\n throw new SplitCheckpointLostError('split checkpoint proof is malformed (cannot decode)', err);\n }\n let burnCertified;\n try {\n burnCertified = await reDerivedBurnTx.toCertifiedTransaction(deps.trustBase, deps.predicateVerifier, deps.unicityCertificateVerifier, burnProof);\n } catch (err) {\n if (isTrustbaseFailure(err)) {\n throw new CheckpointTrustbaseMismatchError(\n 'split checkpoint proof no longer verifies against the current trust base (validator rotation)',\n err,\n );\n }\n throw new SplitCheckpointLostError('split checkpoint proof is invalid', err);\n }\n // Defense-in-depth: the inputs are pre-validated (byte-equal burn tx + trustbase-verified proof),\n // so this application is effectively unreachable-throwing — but keep the whole resume path free of\n // raw-error escapes (a future wire migration must still surface the typed keep-open error).\n let burntToken: Token;\n try {\n burntToken = await sourceToken.transfer(burnCertified, deps.verificationContext);\n } catch (err) {\n throw new SplitCheckpointLostError('split checkpoint could not rebuild the burnt token', err);\n }\n if (!bytesEqual(await sha256(burntToken.toCBOR()), decoded.burntTokenHash)) {\n throw new SplitCheckpointLostError('split checkpoint burnt-token hash mismatch (wire re-encoding drift)');\n }\n return burntToken;\n}\n","/**\n * token-engine/SphereTokenEngine.ts — the real ITokenEngine adapter (Track A).\n *\n * The full sender-driven engine over the v2 SDK: identity, value reads,\n * serialization, verification, mint, transfer, split and spent-status. All\n * crypto/value logic is the SDK's; this class orchestrates build → submit →\n * wait-proof → certify → realize, and maps SDK errors/states to the\n * sphere-domain ITokenEngine port.\n *\n * SDK objects are injected via `EngineDeps` (built by the factory in A4, or by\n * test wiring around TestAggregatorClient), keeping the engine logic independent\n * of how the aggregator/trust base are constructed.\n *\n * Advertises `deterministicMint` (F13): a same-seed `mint` re-call recovers an\n * existing certification instead of minting a second token.\n */\n\nimport { SphereError, type SphereErrorCode } from '../core/errors';\nimport {\n awaitProofBounded,\n certificationDeadline,\n resolveProofTimeoutMs,\n retryTransient,\n TransientSubmitAnswer,\n} from './proof-wait';\nimport { certificationFailure } from './certification-outcome';\nimport { randomUUID } from '../core/uuid';\nimport {\n CheckpointPersistFailedError,\n CheckpointTrustbaseMismatchError,\n ProofUnconfirmedError,\n SplitCheckpointLostError,\n TransferConflictError,\n} from './errors';\nimport { deriveDirectAddress } from './identity';\nimport { deriveDeliveryKeys } from './blob-keys';\nimport { deriveRealization } from './realization';\nimport { burntTokenFromCheckpoint, encodeCheckpoint } from './split-checkpoint';\nimport {\n CborDeserializer,\n CertificationData,\n CertificationStatus,\n EncodedPredicate,\n HexConverter,\n type InclusionProof,\n InclusionProofVerificationStatus,\n type ITransaction,\n type MintJustificationVerifierService,\n MintTransaction,\n type NetworkId,\n PaymentAssetCollection,\n type PredicateVerifierService,\n type UnicityCertificateVerifier,\n type RootTrustBase,\n SignaturePredicate,\n SignaturePredicateUnlockScript,\n type SigningService,\n SplitMintJustification,\n type SplitToken,\n SplitTokenRequest,\n StateId,\n StateMask,\n type StateTransitionClient,\n Token,\n TokenSalt,\n TokenSplit,\n TokenType,\n TransferTransaction,\n type VerificationContext,\n VerificationStatus,\n waitInclusionProof,\n type ITokenVerifier,\n} from './sdk';\nimport { decodeSpherePaymentData, SpherePaymentData, sphereAssetToSdk } from './SpherePaymentData';\nimport type { EngineOpOptions, ITokenEngine } from './engine';\nimport type {\n CoinId,\n EngineIdentity,\n EngineVerifyResult,\n MintDataTokenParams,\n MintParams,\n SphereToken,\n SphereValue,\n SplitParams,\n SplitResult,\n TokenBlob,\n TransferParams,\n} from './types';\n\n/** SDK objects the engine operates with; assembled by the factory (A4) or test wiring. */\n/** An `ITokenVerifier` that also owns terminable resources (a worker pool). */\nexport interface DisposableTokenVerifier extends ITokenVerifier {\n dispose(): void;\n}\n\nexport interface EngineDeps {\n readonly client: StateTransitionClient;\n readonly trustBase: RootTrustBase;\n readonly predicateVerifier: PredicateVerifierService;\n readonly unicityCertificateVerifier: UnicityCertificateVerifier;\n readonly mintJustificationVerifier: MintJustificationVerifierService;\n readonly verificationContext: VerificationContext;\n /**\n * Opt-in parallel verifier (EngineConfig.verification). Absent → tokens verify\n * sequentially via `Token.verify`, which is what every release before 2.0.2 did.\n */\n readonly tokenVerifier?: DisposableTokenVerifier;\n /** The wallet's signing key (its identity + the spender for transfers it owns). */\n readonly signingService: SigningService;\n /**\n * The same key as raw bytes — the HKDF ikm for deterministic realization\n * (Part E.1; SigningService does not expose it back).\n */\n readonly privateKey: Uint8Array;\n readonly networkId: NetworkId;\n /** Inclusion-proof poll cadence in ms (#683); undefined → the tuned default below. */\n readonly proofPollIntervalMs?: number;\n /** Deadline for one inclusion-proof wait; defaults to DEFAULT_PROOF_TIMEOUT_MS (#739). */\n readonly proofTimeoutMs?: number;\n}\n\n/**\n * #683: default inclusion-proof poll interval (ms). Finer than the sdk's 1000ms\n * default so a ~1.2s finalization is caught near ~1.2-1.5s instead of at the 2s\n * poll boundary. Bounded by waitInclusionProof's 10s abort; the extra polls are\n * cheap read-only getInclusionProof calls confined to the ~1.5s finalization window.\n */\nexport const DEFAULT_PROOF_POLL_INTERVAL_MS = 300;\n\n/**\n * #684: max split-mint legs minted concurrently. The mints are independent off the\n * one burn, but an UNBOUNDED fan-out would submit + proof-poll every leg at once\n * against the gateway (the prior sequential loop naturally paced it to one). This\n * cap keeps a typical split (K=2 — payment + change) fully parallel while bounding\n * gateway load on a large multi-output split.\n */\nconst MAX_MINT_CONCURRENCY = 8;\n\n/**\n * The keep-open engine errors a split leg can raise — mirrors PaymentsModule's `keepOpen` set.\n * When one of these settles a parallel mint fan-out, the leg's spend MAY already be certified\n * on-chain, so the intent MUST stay OPEN for checkpoint-based resume; the fan-out must surface a\n * keep-open outcome rather than an abortable clean failure that would strand a certified sibling\n * (#684). Only ProofUnconfirmedError / SplitCheckpointLostError are reachable from a mint leg\n * today; the checkpoint pair is included so the classifier stays faithful to the keep-open family.\n */\nfunction isKeepOpenSplitError(err: unknown): boolean {\n return (\n err instanceof ProofUnconfirmedError ||\n err instanceof CheckpointPersistFailedError ||\n err instanceof SplitCheckpointLostError ||\n err instanceof CheckpointTrustbaseMismatchError\n );\n}\n\n/** Canonical lowercase UUID — the spec's `transferId` wire form (sdk-changes E.1). */\nconst TRANSFER_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;\n\n/**\n * The KNOWN validation-reject submit statuses: a well-formed rejection that PROVES the\n * state was never certified (a byte-identical resume of a *valid* tx never later returns\n * a format/signature/state/shard-mismatch failure). E.2 is status-AGNOSTIC for everything\n * else: an UNKNOWN or transitional non-SUCCESS status (e.g. the gateway's transitional\n * `STATE_ID_EXISTS`) means \"a certification for this state MAY already exist\" — it must be\n * treated as possibly-certified (keep the intent OPEN — #631), NEVER a clean abort. Any\n * status outside this set therefore falls through to `ProofUnconfirmedError`.\n *\n * v3's REQUEST_EXPIRED and SERVICE_NOT_READY stay OUT despite their names: each\n * reports only that THIS submit was not admitted, never that no earlier attempt\n * certified. Pinned by expires-at.test.ts.\n */\nconst CLEAN_REJECT_STATUSES: ReadonlySet<string> = new Set([\n CertificationStatus.STATE_ID_MISMATCH,\n CertificationStatus.SIGNATURE_VERIFICATION_FAILED,\n CertificationStatus.INVALID_SIGNATURE_FORMAT,\n CertificationStatus.INVALID_PUBLIC_KEY_FORMAT,\n CertificationStatus.INVALID_SOURCE_STATE_HASH_FORMAT,\n CertificationStatus.INVALID_TRANSACTION_HASH_FORMAT,\n CertificationStatus.UNSUPPORTED_ALGORITHM,\n CertificationStatus.INVALID_SHARD,\n]);\n\n/** The deterministic split plan (burn leg + per-output mint requests) — `TokenSplit.split`'s result. */\ntype SplitPlan = Awaited<ReturnType<typeof TokenSplit.split>>;\n\n/** Threaded through the E.4 burnt-token resolution so its helpers stay within the max-params bound. */\ninterface SplitContext {\n readonly params: SplitParams;\n readonly split: SplitPlan;\n readonly transferId: string;\n readonly options?: EngineOpOptions | undefined;\n}\n\nexport class SphereTokenEngine implements ITokenEngine {\n /** F13 advertisement: mint under a (transferId, opIndex) seed is idempotent-recoverable — a same-seed re-call converges, never double-mints. */\n public readonly deterministicMint = true;\n\n /** Hex form of the wallet key — deriveRealization's ikm input (Part E.1). */\n private readonly privateKeyHex: string;\n\n private readonly proofTimeoutMs: number;\n\n public constructor(private readonly deps: EngineDeps) {\n this.privateKeyHex = HexConverter.encode(deps.privateKey);\n // Refused here, not per op: a bad deadline must not surface as a money error.\n this.proofTimeoutMs = resolveProofTimeoutMs(deps.proofTimeoutMs);\n }\n\n // ── identity ────────────────────────────────────────────────────────────────\n\n public getIdentity(): EngineIdentity {\n return { chainPubkey: new Uint8Array(this.deps.signingService.publicKey) };\n }\n\n /** Legacy DIRECT:// address (Path A). Async: the derivation hashes via the SDK. */\n public deriveIdentityAddress(pubkey?: Uint8Array): Promise<string> {\n return deriveDirectAddress(pubkey ?? this.deps.signingService.publicKey);\n }\n\n // ── value (read) ─────────────────────────────────────────────────────────────\n\n public readValue(token: SphereToken): SphereValue | null {\n return token.value;\n }\n\n public balanceOf(token: SphereToken, coinId: CoinId): bigint {\n let sum = 0n;\n for (const asset of token.value?.assets ?? []) {\n if (asset.coinId === coinId) sum += asset.amount;\n }\n return sum;\n }\n\n public tokenId(token: SphereToken): string {\n return token.blob.tokenId;\n }\n\n public readMemo(token: SphereToken): Uint8Array | null {\n const sdkToken = token.sdkToken;\n // A transferred token delivers its memo on the latest transfer.\n if (sdkToken.transactions.length > 0) {\n return sdkToken.latestTransaction.data;\n }\n // A minted output (e.g. a split output) carries the memo in its value envelope.\n const data = sdkToken.genesis.data;\n if (data && this.isSpherePaymentData(data)) {\n return SpherePaymentData.fromCBOR(data).memo;\n }\n return null;\n }\n\n public readTokenData(token: SphereToken): Uint8Array | null {\n const data = token.sdkToken.genesis.data;\n return data ? new Uint8Array(data) : null;\n }\n\n // ── lifecycle ────────────────────────────────────────────────────────────────\n\n public async mint(params: MintParams, options?: EngineOpOptions): Promise<SphereToken> {\n const recipient = SignaturePredicate.create(params.recipientPubkey);\n const data = params.value ? await SpherePaymentData.fromValue(params.value).encode() : null;\n const transferId = this.resolveTransferId(options);\n const opIndex = this.resolveOpIndex(options);\n\n // #692 F13 — E.1: HKDF-derived salt (→ tokenId → stateId) + tokenType make a\n // re-call with the same transferId rebuild the byte-identical mint. The salt\n // gets its own 'mint' field domain: 'salt' is indexed by split-OUTPUT ordinal\n // under the same transferId, so ('salt', opIndex) would collide with output\n // #opIndex of a sibling split (see RealizationField).\n const mintTx = await MintTransaction.create(this.deps.networkId, recipient, {\n data,\n tokenType: new TokenType(deriveRealization(this.privateKeyHex, transferId, opIndex, 'tokenType')),\n salt: TokenSalt.fromBytes(deriveRealization(this.privateKeyHex, transferId, opIndex, 'mint')),\n });\n const certificationData = await CertificationData.fromMintTransaction(mintTx);\n\n // The same idempotent submit-then-always-probe primitive as transfer/split (E.2):\n // OK-match = mine (resume), mismatch = typed conflict, clean reject = submit error,\n // inconclusive = ProofUnconfirmedError (keep-open) — never inferred from the status.\n const proof = await this.submitAndAwaitProof(\n certificationData,\n mintTx,\n 'Mint certification failed',\n 'AGGREGATOR_ERROR',\n options,\n );\n const certified = await mintTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);\n const token = await Token.mint(certified, this.deps.verificationContext);\n return this.wrapToken(token);\n }\n\n public async mintDataToken(params: MintDataTokenParams, options?: EngineOpOptions): Promise<SphereToken> {\n const recipient = SignaturePredicate.create(params.recipientPubkey);\n const tokenType = params.tokenType ? new TokenType(params.tokenType) : TokenType.generate();\n // A deterministic salt yields a stable, terms-derived tokenId (TokenId.fromSalt).\n const salt = params.salt ? TokenSalt.fromBytes(params.salt) : TokenSalt.generate();\n\n const mintTx = await MintTransaction.create(this.deps.networkId, recipient, { data: params.data, tokenType, salt });\n const certificationData = await CertificationData.fromMintTransaction(mintTx);\n\n // #692 F13: the caller's deterministic salt already makes the re-call byte-identical;\n // routing through the probe primitive makes the re-call actually RECOVER (E.2).\n const proof = await this.submitAndAwaitProof(\n certificationData,\n mintTx,\n 'Data-token mint failed',\n 'AGGREGATOR_ERROR',\n options,\n );\n const certified = await mintTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);\n const token = await Token.mint(certified, this.deps.verificationContext);\n return this.wrapToken(token);\n }\n\n public async transfer(params: TransferParams, options?: EngineOpOptions): Promise<SphereToken> {\n this.assertOwned(params.token);\n const transferId = this.resolveTransferId(options);\n const recipient = SignaturePredicate.create(params.recipientPubkey);\n // E.1 deterministic realization: same transferId + inputs ⇒ byte-identical\n // transaction, so an interrupted transfer can be rebuilt and resumed (AC-E1/E2).\n const stateMask = StateMask.fromBytes(\n deriveRealization(this.privateKeyHex, transferId, this.resolveOpIndex(options), 'stateMask'),\n );\n\n const transferTx = await TransferTransaction.create(params.token.sdkToken, recipient, stateMask, {\n data: params.data ?? null,\n });\n const unlockScript = await SignaturePredicateUnlockScript.create(transferTx, this.deps.signingService);\n const certificationData = await CertificationData.fromTransaction(transferTx, unlockScript);\n\n const proof = await this.submitAndAwaitProof(\n certificationData,\n transferTx,\n 'Transfer certification failed',\n 'TRANSFER_FAILED',\n options,\n );\n const certified = await transferTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);\n const transferred = await params.token.sdkToken.transfer(certified, this.deps.verificationContext);\n return this.wrapToken(transferred);\n }\n\n public async split(params: SplitParams, options?: EngineOpOptions): Promise<SplitResult> {\n this.assertOwned(params.token);\n if (params.outputs.length === 0) {\n throw new SphereError('Split requires at least one output', 'VALIDATION_ERROR');\n }\n const transferId = this.resolveTransferId(options);\n\n // E.1 deterministic realization: per-output HKDF salts make every output's\n // mint transaction (and its salt-derived tokenId) reproducible from the\n // wallet key + transferId.\n const requests = params.outputs.map((o, i) =>\n SplitTokenRequest.create(\n SignaturePredicate.create(o.recipientPubkey),\n SpherePaymentData.create(PaymentAssetCollection.create(sphereAssetToSdk(o.coinId, o.amount)), o.data ?? null),\n TokenSalt.fromBytes(deriveRealization(this.privateKeyHex, transferId, i, 'salt')),\n ),\n );\n\n // Value conservation is enforced inside the SDK split (root.value === source value).\n // E.1: the burn state mask is HKDF-derived, so the whole split — burn leg\n // included — is rebuildable from the wallet key + transferId (crash resume).\n const split = await TokenSplit.split(params.token.sdkToken, decodeSpherePaymentData, requests, {\n burnStateMask: StateMask.fromBytes(\n deriveRealization(this.privateKeyHex, transferId, this.resolveOpIndex(options), 'burn'),\n ),\n });\n\n // 1. Resolve the burnt token: from a durable checkpoint on resume, else burn now and persist\n // the checkpoint BEFORE any mint submit (E.4 — the burn proof is the one non-re-derivable\n // split input; a mint certified against proof bytes that were never stored strands #501).\n const burntToken = await this.resolveBurntToken({ params, split, transferId, options });\n\n // 2. Mint every output IN PARALLEL (#684), each justified by the burnt token + its\n // own split proofs. The mints are independent legs off the ONE already-certified,\n // already-checkpointed burn (step 1, outside this fan-out — E.4 burn-before-mint\n // is unchanged), so they carry no ordering constraint among themselves.\n //\n // MONEY-SAFETY, identical to the prior sequential loop: `allSettled` waits for\n // EVERY leg (no leg abandoned mid-submit) and rethrows the LOWEST-index rejection,\n // which is the error the sequential loop surfaced — so keep-open classification is\n // unchanged. On failure the intent stays OPEN and resume re-runs all legs from the\n // durable checkpoint; an already-certified leg is recovered idempotently (#631/E.2),\n // so legs this fan-out submitted early are never lost. MAX_MINT_CONCURRENCY paces it.\n const settled: PromiseSettledResult<SphereToken>[] = [];\n for (let start = 0; start < split.tokens.length; start += MAX_MINT_CONCURRENCY) {\n const batch = split.tokens.slice(start, start + MAX_MINT_CONCURRENCY);\n settled.push(\n ...(await Promise.allSettled(\n batch.map((token) => this.mintSplitOutput(token, burntToken, options)),\n )),\n );\n }\n // Every leg has settled. Aggregate with a KEEP-OPEN BIAS. The old sequential loop never\n // submitted a later leg once an earlier one failed, so surfacing the first failure could\n // never orphan a certified sibling. THIS fan-out submits every leg, so a lower-index CLEAN\n // failure can coexist with a higher-index leg that already CERTIFIED (fulfilled) or MAY have\n // (a keep-open rejection). Surfacing the lowest-index CLEAN error in that case would let\n // PaymentsModule abort the intent (its committed-source set is still empty here) and strand\n // the certified sibling with no checkpoint recovery (Codex P1 on #684). So, in order:\n // 1. If ANY leg rejected keep-open (ProofUnconfirmed / SplitCheckpointLost / the E.4 pair),\n // surface that verbatim (lowest-index) so its specific keep-open type drives\n // PaymentsModule's classification exactly as before.\n // 2. Else (ANY clean rejection, whether or not a sibling certified) the BURN is already\n // committed + checkpointed (resolveBurntToken, above), so the source is spent on-chain.\n // Convert to a keep-open ProofUnconfirmedError (cause = the clean failure): a plain\n // abortable error would let PaymentsModule abort the intent and STRAND the whole source\n // value (the burn cannot be undone; an aborted intent never re-runs). Keep-open so resume\n // re-runs ALL legs idempotently from the burn checkpoint (HKDF-deterministic stateId → the\n // aggregator returns the existing proof; #631/E.2/E.3). A clean mint reject after a valid,\n // value-conserving burn is transient (e.g. a shard reconfiguration), never permanent.\n const keepOpenRejection = settled.find(\n (r): r is PromiseRejectedResult => r.status === 'rejected' && isKeepOpenSplitError(r.reason),\n );\n if (keepOpenRejection !== undefined) {\n throw keepOpenRejection.reason;\n }\n const firstRejected = settled.findIndex((r) => r.status === 'rejected');\n if (firstRejected !== -1) {\n const cleanReason = (settled[firstRejected] as PromiseRejectedResult).reason;\n // 3. Else (every rejection is clean — none keep-open) the burn is STILL committed +\n // checkpointed (resolveBurntToken, above), whether or not a sibling certified. Surfacing\n // a plain abortable clean error would let PaymentsModule abort the intent and STRAND the\n // entire source value — the burn cannot be undone and an aborted intent never re-runs. So\n // EVERY post-burn mint failure is keep-open: resume re-runs all legs idempotently from the\n // burn checkpoint. (A clean mint reject after a valid, value-conserving burn is transient —\n // e.g. a shard reconfiguration — not a permanent validation failure; keep-open leaves the\n // funds RECOVERABLE, abort loses them.)\n throw new ProofUnconfirmedError(\n settled.some((r) => r.status === 'fulfilled')\n ? 'a split mint leg certified while a sibling leg failed — keep the intent open; resume ' +\n 'completes all legs idempotently from the burn checkpoint (#684 parallel fan-out)'\n : 'every split mint leg failed after the burn certified — keep the intent open; resume ' +\n 're-runs all legs idempotently from the burn checkpoint (post-burn must never abort)',\n cleanReason,\n );\n }\n const outputs = settled.map((r) => (r as PromiseFulfilledResult<SphereToken>).value);\n return { outputs };\n }\n\n /**\n * E.4 burnt-token resolution. With a checkpoint store: `get` → rebuild from the STORED proof on\n * resume; else a leg-0 pre-flight probe (a certified leaf with no checkpoint is unrecoverable),\n * then burn, persist the checkpoint (durable-ack gated), and adopt the authoritative stored\n * bytes. Without a store: burn as before (a documented residual for fully-local compositions).\n */\n private async resolveBurntToken(ctx: SplitContext): Promise<Token> {\n const store = ctx.options?.checkpointStore;\n const opIndex = this.resolveOpIndex(ctx.options);\n const source = ctx.params.token.sdkToken;\n if (store === undefined) {\n return (await this.burnSource(ctx)).burntToken;\n }\n const stored = await store.get(ctx.transferId, opIndex);\n if (stored !== null) {\n return burntTokenFromCheckpoint(this.deps, stored, ctx.split.burn.transaction, source);\n }\n await this.assertNoLegStranded(ctx);\n const { burntToken, burnProof } = await this.burnSource(ctx);\n const envelope = await encodeCheckpoint(ctx.split.burn.transaction, burnProof, burntToken);\n // The durable-ack gate: `put` resolving IS the ack, and NO mint has been submitted yet.\n let authoritative: Uint8Array;\n try {\n authoritative = await store.put(ctx.transferId, opIndex, envelope);\n } catch (err) {\n throw new CheckpointPersistFailedError(\n 'split burn certified but its checkpoint could not be persisted — keep the intent open and resume',\n err,\n );\n }\n // Decode-from-stored discipline: mint from the AUTHORITATIVE bytes (ours, or a racing resumer's\n // that won the slot), never the pre-store in-memory burnt token — so concurrent resumers agree.\n return burntTokenFromCheckpoint(this.deps, authoritative, ctx.split.burn.transaction, source);\n }\n\n /** Burn the source: certify the burn transfer and append it -> burntToken (+ its proof). */\n private async burnSource(ctx: SplitContext): Promise<{ burntToken: Token; burnProof: InclusionProof }> {\n const burnTx = ctx.split.burn.transaction;\n const burnUnlock = await SignaturePredicateUnlockScript.create(burnTx, this.deps.signingService);\n const burnCert = await CertificationData.fromTransaction(burnTx, burnUnlock);\n const burnProof = await this.submitAndAwaitProof(burnCert, burnTx, 'Split burn failed', 'TRANSFER_FAILED', ctx.options);\n const burnCertified = await burnTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, burnProof);\n const burntToken = await ctx.params.token.sdkToken.transfer(burnCertified, this.deps.verificationContext);\n return { burntToken, burnProof };\n }\n\n /**\n * Pre-flight (no-checkpoint path): if ANY mint leaf is already certified on-chain while the\n * checkpoint is missing, the burn proof is genuinely unrecoverable — fail BEFORE any re-burn. A\n * mint's stateId is justification-INDEPENDENT (only the source state hash + salt-derived mask),\n * so a probe mint with a null justification derives the true on-chain key. Every leg is probed,\n * so correctness does NOT depend on the mint loop certifying leg 0 first (E.4 step 3).\n */\n private async assertNoLegStranded(ctx: SplitContext): Promise<void> {\n // #684: probe every leg's stateId IN PARALLEL — read-only getInclusionProof calls,\n // order-independent (it throws if ANY leg is already certified). Promise.all rejects\n // on the first stranded leg, same as the prior sequential loop.\n await Promise.all(\n ctx.split.tokens.map(async (leg) => {\n const data = await leg.paymentData.encode();\n const probe = await MintTransaction.create(leg.networkId, leg.recipient, {\n data,\n tokenType: leg.tokenType,\n salt: leg.salt,\n justification: null,\n });\n const response = await this.deps.client.getInclusionProof(await StateId.fromTransaction(probe));\n // v3: a null `inclusionProof` IS \"not certified yet\"; a present one always\n // describes a real leaf, so there is no longer a field to misread here.\n if (response.inclusionProof !== null) {\n throw new SplitCheckpointLostError(\n 'a split mint leaf is certified on-chain but no burn checkpoint exists — outputs are unrecoverable',\n );\n }\n }),\n );\n }\n\n /** One split output: build the justification from the burnt token, submit, certify, wrap. */\n private async mintSplitOutput(\n splitToken: SplitToken,\n burntToken: Token,\n options?: EngineOpOptions,\n ): Promise<SphereToken> {\n const data = await splitToken.paymentData.encode();\n const justification = SplitMintJustification.create(burntToken, splitToken.proofs).toCBOR();\n const mintTx = await MintTransaction.create(splitToken.networkId, splitToken.recipient, {\n data,\n tokenType: splitToken.tokenType,\n salt: splitToken.salt,\n justification,\n });\n const certData = await CertificationData.fromMintTransaction(mintTx);\n const proof = await this.submitSplitMintLeg(certData, mintTx, options);\n const certified = await mintTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);\n const token = await Token.mint(certified, this.deps.verificationContext);\n return this.wrapToken(token);\n }\n\n /**\n * Submit one split-mint leg. A `TRANSACTION_HASH_MISMATCH` on a mint leg is NOT a foreign spend\n * (its stateId is HKDF-derived from `(seed, transferId)`, so only a seed-holder under THIS\n * transferId could have certified a different leaf): the stored checkpoint no longer reproduces\n * the certified leaf → keep-open `SplitCheckpointLostError`, never the abort-and-re-plan\n * `TransferConflictError` (E.2/E.4 split-mint arm).\n */\n private async submitSplitMintLeg(\n certData: CertificationData,\n mintTx: MintTransaction,\n options?: EngineOpOptions,\n ): Promise<InclusionProof> {\n try {\n return await this.submitAndAwaitProof(certData, mintTx, 'Split mint failed', 'AGGREGATOR_ERROR', options);\n } catch (err) {\n if (err instanceof TransferConflictError) {\n throw new SplitCheckpointLostError(\n 'a split mint leg no longer matches its certified leaf — the burn checkpoint is stale or lost',\n err,\n );\n }\n throw err;\n }\n }\n\n // ── verification ─────────────────────────────────────────────────────────────\n\n public async verify(token: SphereToken, _options?: EngineOpOptions): Promise<EngineVerifyResult> {\n // Both verifiers produce the same aggregated result; the worker one only\n // moves the independent per-transfer work off this thread.\n const result = this.deps.tokenVerifier\n ? await this.deps.tokenVerifier.verify(token.sdkToken, this.deps.verificationContext)\n : await token.sdkToken.verify(this.deps.verificationContext);\n return result.status === VerificationStatus.OK ? { ok: true } : { ok: false, reason: String(result.status) };\n }\n\n public isOwnedBy(token: SphereToken, pubkey: Uint8Array): boolean {\n const owner = token.sdkToken.latestTransaction.recipient;\n const claimed = EncodedPredicate.fromPredicate(SignaturePredicate.create(pubkey));\n return EncodedPredicate.equals(owner, claimed);\n }\n\n public async isSpent(token: SphereToken, _options?: EngineOpOptions): Promise<boolean> {\n // The token's current state id = what a future transfer would spend. Derive it via a\n // probe transfer (never submitted) — StateId depends only on the source's lock script\n // and state hash, not on the recipient or state mask.\n const probe = await TransferTransaction.create(\n token.sdkToken,\n SignaturePredicate.create(this.deps.signingService.publicKey),\n StateMask.fromBytes(new Uint8Array(32)),\n );\n const stateId = await StateId.fromTransaction(probe);\n const response = await this.deps.client.getInclusionProof(stateId);\n // Consumed iff the aggregator answers with a PROOF. Reporting an UNSPENT state\n // as spent destroys a live token via the fail-closed recovery gates.\n return response.inclusionProof !== null;\n }\n\n // ── serialization ────────────────────────────────────────────────────────────\n\n /** @inheritDoc — SDK-derived (Token.fromCBOR → latestTransaction.calculateStateHash().imprint). */\n public deliveryKeys(blobBytes: Uint8Array): Promise<{ tokenId: string; stateHash: string }> {\n return deriveDeliveryKeys(blobBytes);\n }\n\n public encodeToken(token: SphereToken): TokenBlob {\n return token.blob;\n }\n\n public async decodeToken(blob: TokenBlob): Promise<SphereToken> {\n const sdkToken = await Token.fromCBOR(blob.token);\n if (sdkToken.genesis.networkId.id !== this.deps.networkId.id) {\n throw new SphereError(\n `Token network mismatch: token is on network ${sdkToken.genesis.networkId.id}, ` +\n `engine on ${this.deps.networkId.id}`,\n 'VALIDATION_ERROR',\n );\n }\n return this.wrapToken(sdkToken);\n }\n\n // ── internals ────────────────────────────────────────────────────────────────\n\n /**\n * The effective realization seed for one transfer/split (Part E). A caller\n * that wants resumability supplies a pre-persisted UUIDv4 (sdk-changes E.3);\n * otherwise one is generated here — same derivation path, just non-resumable.\n * The canonical-lowercase-UUID check also keeps the HKDF info string\n * unambiguous (no ':' injection, no case-variant double derivations).\n */\n /** Validated op ordinal (§8.1 mask domain separation across ops of one send). */\n private resolveOpIndex(options?: EngineOpOptions): number {\n const opIndex = options?.opIndex ?? 0;\n if (!Number.isInteger(opIndex) || opIndex < 0) {\n throw new SphereError(`opIndex must be a non-negative integer, got ${String(opIndex)}`, 'VALIDATION_ERROR');\n }\n return opIndex;\n }\n\n private resolveTransferId(options?: EngineOpOptions): string {\n const transferId = options?.transferId ?? randomUUID();\n if (!TRANSFER_ID_RE.test(transferId)) {\n throw new SphereError(\n `transferId must be a canonical lowercase UUID string, got \"${transferId}\"`,\n 'VALIDATION_ERROR',\n );\n }\n return transferId;\n }\n\n /**\n * E.2 — status-agnostic idempotent submit with conflict detection\n * (sdk-changes E.2, ARCHITECTURE §8.1).\n *\n * Submit the certification request and treat ANY outcome — success status,\n * error status, or a response-parse throw (the live gateway may still emit\n * statuses this SDK no longer parses, e.g. the transitional STATE_ID_EXISTS)\n * — as \"a certification for this state may already exist\". Then ALWAYS fetch\n * the inclusion proof and match-verify it against the rebuilt transaction\n * (`waitInclusionProof` only returns an OK-verified proof):\n *\n * - match (OK) → proceed; this is how an interrupted\n * attempt with the same transferId resumes;\n * - mismatch (hash ≠ rebuilt tx) → `TransferConflictError`: the source was\n * consumed by a DIFFERENT transaction (lost\n * race) — never applied, never retried;\n * - no proof & the submit failed → the original submit error (a genuine\n * failure, not a resume case).\n */\n private async submitAndAwaitProof(\n certificationData: CertificationData,\n transaction: ITransaction,\n failLabel: string,\n failCode: SphereErrorCode,\n options?: EngineOpOptions,\n ): Promise<InclusionProof> {\n const deadline = certificationDeadline(\n this.proofTimeoutMs,\n options?.signal,\n `${failLabel}: not certified`\n );\n try {\n return await this.submitThenProve(certificationData, transaction, failLabel, failCode, deadline.signal);\n } finally {\n deadline.dispose();\n }\n }\n\n /** One certification attempt under one deadline: the metered submit retries\n * transient answers instead of falling through to a proof that cannot exist. */\n private async submitThenProve(\n certificationData: CertificationData,\n transaction: ITransaction,\n failLabel: string,\n failCode: SphereErrorCode,\n signal: AbortSignal,\n ): Promise<InclusionProof> {\n let submitError: unknown = null;\n // True ONLY for a KNOWN validation-reject status: a PROVEN clean pre-certification\n // reject. Everything else stays INDETERMINATE (keep-open, #631) — including any\n // submit that was RETRIED, since the earlier POST may already have been processed\n // server-side, which is what sawAmbiguousAttempt latches (#747 review).\n let submitRejectedCleanly = false;\n try {\n const { value: response, retried } = await retryTransient(\n async () => {\n const answer = await this.deps.client.submitCertificationRequest(certificationData);\n // A booting gateway is \"ask again\", not a certification failure — see\n // TransientSubmitAnswer. Everything else, known or unknown, keeps the\n // status-agnostic treatment below.\n if (String(answer.status) === String(CertificationStatus.SERVICE_NOT_READY)) {\n throw new TransientSubmitAnswer(String(answer.status));\n }\n return answer;\n },\n signal,\n this.deps.proofPollIntervalMs ?? DEFAULT_PROOF_POLL_INTERVAL_MS,\n );\n if (response.status !== CertificationStatus.SUCCESS) {\n submitError = new SphereError(`${failLabel}: ${response.status}`, failCode);\n submitRejectedCleanly = !retried && CLEAN_REJECT_STATUSES.has(response.status);\n }\n } catch (err) {\n submitError = err ?? new SphereError(`${failLabel}: submit failed`, failCode);\n }\n\n try {\n return await awaitProofBounded(\n {\n client: this.deps.client,\n trustBase: this.deps.trustBase,\n predicateVerifier: this.deps.predicateVerifier,\n unicityCertificateVerifier: this.deps.unicityCertificateVerifier,\n intervalMs: this.deps.proofPollIntervalMs ?? DEFAULT_PROOF_POLL_INTERVAL_MS, // #683\n },\n transaction,\n signal,\n );\n } catch (err) {\n throw certificationFailure(err, failLabel, submitError, submitRejectedCleanly);\n }\n }\n\n\n /**\n * One inclusion-proof wait, with the deadline OWNED here (#739) so it is bounded\n * and configurable rather than the SDK's fixed default. A hit throws, and the\n * caller maps it to ProofUnconfirmedError (keep-open) — the correct posture,\n * since the spend may be on-chain.\n */\n /** Fail fast if this engine's key does not own the token's current state. */\n private assertOwned(token: SphereToken): void {\n if (!this.isOwnedBy(token, this.deps.signingService.publicKey)) {\n throw new SphereError('Cannot transfer a token not owned by this engine identity', 'VALIDATION_ERROR');\n }\n }\n\n /** Wrap an SDK token into a SphereToken: cache its blob (incl. stable tokenId) + decoded value. */\n private wrapToken(sdkToken: Token): SphereToken {\n const data = sdkToken.genesis.data;\n let value: SphereValue | null = null;\n // Only value tokens carry a SpherePaymentData envelope; data tokens (e.g. invoices)\n // leave value === null. A corrupt value envelope still errors loudly.\n if (data && this.isSpherePaymentData(data)) {\n try {\n value = SpherePaymentData.fromCBOR(data).toValue();\n } catch (err) {\n throw new SphereError(\n `Failed to decode token payment data: ${err instanceof Error ? err.message : String(err)}`,\n 'VALIDATION_ERROR',\n );\n }\n }\n const blob: TokenBlob = {\n tokenId: HexConverter.encode(sdkToken.id.bytes),\n token: sdkToken.toCBOR(),\n };\n return { sdkToken, blob, value };\n }\n\n /** True if the bytes are a SpherePaymentData envelope (value token) vs a raw data token. */\n private isSpherePaymentData(data: Uint8Array): boolean {\n try {\n return CborDeserializer.decodeTag(data).tag === SpherePaymentData.CBOR_TAG;\n } catch {\n return false;\n }\n }\n /**\n * Terminate the verification worker pool, if this engine was configured with\n * one. Idempotent — the pool's dispose only touches workers it spawned.\n */\n public dispose(): void {\n this.deps.tokenVerifier?.dispose();\n }\n\n}\n","/**\n * token-engine/factory.ts — the real engine constructor (A4).\n *\n * `createSphereTokenEngine` is the public way to obtain an ITokenEngine. It maps\n * the sphere-domain EngineConfig to the SDK objects the engine needs: the\n * aggregator client (from `aggregatorUrl`), the trust base (parsed from\n * `trustBaseJson`), the wallet signing key (from `privateKey`), the network id,\n * and a mint-justification verifier with the split verifier registered (so\n * split-output tokens verify).\n *\n * Loading the trust base per environment (browser fetch / node file) stays with\n * the caller (impl/<env>/oracle, reusing the existing trust-base loaders); it\n * passes the parsed JSON in via `trustBaseJson`, keeping this factory env-agnostic.\n */\n\nimport { SphereError } from '../core/errors';\nimport { logger } from '../core/logger';\nimport {\n AggregatorClient,\n MintJustificationVerifierService,\n PredicateVerifierService,\n RootTrustBase,\n Secp256k1SignatureVerifier,\n SigningService,\n SplitMintJustificationVerifier,\n StateTransitionClient,\n TokenIssuanceVerifierService,\n UnicityCertificateVerifier,\n UnicitySealQuorumSignaturesVerificationRule,\n VerificationContext,\n VerifiedSealCache,\n WorkerTokenVerifier,\n type IWorker,\n} from './sdk';\nimport { decodeSpherePaymentData } from './SpherePaymentData';\nimport { type DisposableTokenVerifier, type EngineDeps, SphereTokenEngine } from './SphereTokenEngine';\nimport type { EngineConfig, ITokenEngine, VerificationWorker, VerificationWorkerConfig } from './engine';\n\nconst DEFAULT_VERIFICATION_POOL_SIZE = 4;\n\n/**\n * The consumer's worker factory, bound to the base SDK's pool verifier. The SDK\n * leaves `createWorker()` abstract so the platform choice stays with the consumer;\n * the cast is the port boundary (same web-`Worker` subset, payloads `unknown` on\n * our side so no SDK wire type escapes).\n */\nclass ConfiguredWorkerTokenVerifier extends WorkerTokenVerifier {\n public constructor(\n private readonly spawn: () => VerificationWorker,\n poolSize: number\n ) {\n super(poolSize);\n }\n\n protected createWorker(): IWorker {\n return this.spawn() as unknown as IWorker;\n }\n}\n\n/** Workers spawn LAZILY on first verify and are reused, so this costs nothing to build. */\nexport function createWorkerTokenVerifier(config: VerificationWorkerConfig): DisposableTokenVerifier {\n const poolSize = config.poolSize ?? DEFAULT_VERIFICATION_POOL_SIZE;\n if (!Number.isInteger(poolSize) || poolSize < 1) {\n throw new TypeError(`verification.poolSize must be a positive integer, got ${String(config.poolSize)}`);\n }\n return new ConfiguredWorkerTokenVerifier(config.createWorker, poolSize);\n}\n\nexport async function createSphereTokenEngine(config: EngineConfig): Promise<ITokenEngine> {\n if (config.trustBaseJson == null) {\n throw new SphereError('Engine config requires a trust base (trustBaseJson)', 'INVALID_CONFIG');\n }\n\n if (!config.apiKey) {\n logger.warn(\n 'TokenEngine',\n 'No aggregator apiKey — pass config.oracle.apiKey (testnet2 value in .env.example; mainnet from a secret env var). Gateway requests will be unauthenticated.',\n );\n }\n\n const trustBase = RootTrustBase.fromJSON(config.trustBaseJson);\n const predicateVerifier = PredicateVerifierService.create();\n // st-sdk 2.1.0: seal verification is memoised per rule instance. Every leaf\n // certified in one aggregator round shares a seal, so a multi-token send's\n // proofs collapse onto a handful of seals instead of re-verifying each.\n const unicityCertificateVerifier = new UnicityCertificateVerifier(\n new UnicitySealQuorumSignaturesVerificationRule(new Secp256k1SignatureVerifier(), new VerifiedSealCache(256)),\n );\n const mintJustificationVerifier = new MintJustificationVerifierService();\n mintJustificationVerifier.register(\n new SplitMintJustificationVerifier(decodeSpherePaymentData),\n );\n\n const deps: EngineDeps = {\n client: new StateTransitionClient(new AggregatorClient(config.aggregatorUrl, config.apiKey ?? null)),\n trustBase,\n predicateVerifier,\n unicityCertificateVerifier,\n mintJustificationVerifier,\n verificationContext: new VerificationContext(\n trustBase,\n predicateVerifier,\n unicityCertificateVerifier,\n mintJustificationVerifier,\n new TokenIssuanceVerifierService(false),\n ),\n signingService: new SigningService(config.privateKey),\n // Also the HKDF ikm for deterministic realization (Part E.1) — the\n // SigningService wraps the key but does not expose it back.\n privateKey: config.privateKey,\n // The trust base is the single source of truth for the network id (it carries\n // NetworkId.fromId, so any id works — e.g. testnet2 = 4 — with no enum entry).\n networkId: trustBase.networkId,\n // #683: forward the (optional) proof-poll cadence; undefined → the engine default.\n proofPollIntervalMs: config.proofPollIntervalMs,\n proofTimeoutMs: config.proofTimeoutMs, // #739: was declared but never wired\n // Opt-in parallel verification (2.0.2). Absent → the sequential verifier.\n ...(config.verification ? { tokenVerifier: createWorkerTokenVerifier(config.verification) } : {}),\n };\n\n return new SphereTokenEngine(deps);\n}\n"],"mappings":";AAaA,SAAS,6BAA6B;AACtC,SAAS,wBAAwB;AAEjC,SAAS,iBAAiB;AAC1B,SAAS,yBAAyB;AAClC,SAAS,uBAAuB,2BAA2B;AAC3D,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAC/B,SAAS,8BAA8B;AAGvC,SAAS,2BAA2B;AACpC,SAAS,qBAAqB;AAC9B,SAAS,0BAA0B;AACnC,SAAS,wCAAwC;AAGjD,SAAS,aAAa;AACtB,SAAS,uBAAuB;AAChC,SAAS,2BAA2B;AACpC,SAAS,gCAAgC;AACzC,SAAS,oCAAoC;AAC7C,SAAS,eAAe;AACxB,SAAS,iBAAiB;AAC1B,SAAS,iBAAiB;AAE1B,SAAS,iBAAiB;AAC1B,SAAS,wCAAwC;AACjD,SAAS,oCAAoC;AAC7C,SAAS,2BAA2B;AACpC,SAAS,kCAAkC;AAC3C,SAAS,mDAAmD;AAC5D,SAAS,yBAAyB;AAClC,SAAS,kCAAkC;AAE3C,SAAS,2BAA2B;AAOpC,SAAS,wBAAwB;AACjC,SAAS,0BAA0B;AACnC,SAAS,sCAAsC;AAC/C,SAAS,qBAAqB;AAC9B,SAAS,gCAAgC;AAGzC,SAAS,sBAAsB;AAC/B,SAAS,iBAAiB;AAC1B,SAAS,0BAA0B;AACnC,SAAS,qBAAqB;AAC9B,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAC3B,SAAS,yBAAyB;AAGlC,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC,SAAS,iBAAiB;AAI1B,SAAS,aAAa;AACtB,SAAS,eAAe;AACxB,SAAS,8BAA8B;AACvC,SAAS,kBAAkB;AAC3B,SAAS,yBAAyB;AAClC,SAAS,kBAAkB;AAC3B,SAAS,4BAA4B;AACrC,SAAS,8BAA8B;AACvC,SAAS,sCAAsC;AAG/C,SAAS,0BAA0B;AACnC,SAAS,0BAA0B;AAGnC,SAAS,oBAAoB;AAC7B,SAAS,uBAAuB;AAChC,SAAS,iBAAiB;;;AClEnB,IAAM,yBAAyB;AAEtC,IAAM,oBAAoB;AAE1B,IAAM,8BAA8B;AAEpC,IAAM,wBAAwB;AAE9B,IAAM,wBAAwB,IAAI,WAAW,CAAC,GAAM,CAAI,CAAC;AAEzD,SAAS,WAAW,KAAyB;AAC3C,QAAM,QAAQ,IAAI,WAAW,IAAI,SAAS,CAAC;AAC3C,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,CAAC,IAAI,SAAS,IAAI,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE;AAAA,EACrD;AACA,SAAO;AACT;AAEA,SAAS,OAAO,MAAuC;AACrD,SAAO,IAAI,WAAW,cAAc,MAAM,EACvC,OAAO,IAAI,EACX,OAAO,EACP,KAAK,CAAC,MAAM,EAAE,IAAI;AACvB;AAMA,eAAsB,oBAAoB,WAAwC;AAChF,QAAM,gBAAgB,eAAe,iBAAiB,WAAW,sBAAsB,CAAC;AACxF,QAAM,YAAY,eAAe;AAAA,IAC/B,eAAe,iBAAiB,IAAI,WAAW,CAAC,2BAA2B,CAAC,CAAC;AAAA,IAC7E,eAAe,iBAAiB,aAAa;AAAA,IAC7C,eAAe,iBAAiB,iBAAiB;AAAA,IACjD,eAAe,sBAAsB,qBAAqB;AAAA,IAC1D,eAAe,iBAAiB,SAAS;AAAA,EAC3C;AAEA,QAAM,UAAU,MAAM,OAAO,SAAS;AACtC,QAAM,UAAU,IAAI,WAAW,CAAC,GAAG,uBAAuB,GAAG,OAAO,CAAC;AACrE,QAAM,YAAY,MAAM,OAAO,OAAO,GAAG,MAAM,GAAG,CAAC;AAEnD,SAAO,YAAY,aAAa,OAAO,OAAO,CAAC,GAAG,aAAa,OAAO,QAAQ,CAAC;AACjF;;;ACgEO,IAAM,cAAN,cAA0B,MAAM;AAAA,EAC5B;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQT;AAAA,EAEA,YAAY,SAAiB,MAAuB,OAAiB;AACnE,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,QAAQ;AAAA,EACf;AACF;;;ACjHA,IAAM,aAAa;AAQnB,SAAS,WAAwB;AAC/B,QAAM,IAAI;AACV,MAAI,CAAC,EAAE,UAAU,GAAG;AAClB,MAAE,UAAU,IAAI,EAAE,OAAO,OAAO,MAAM,CAAC,GAAG,SAAS,KAAK;AAAA,EAC1D;AACA,SAAO,EAAE,UAAU;AACrB;AAEA,SAAS,UAAU,KAAsB;AACvC,QAAM,QAAQ,SAAS;AAEvB,MAAI,OAAO,MAAM,KAAM,QAAO,MAAM,KAAK,GAAG;AAE5C,SAAO,MAAM;AACf;AAEO,IAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,EAKpB,UAAU,QAA4B;AACpC,UAAM,QAAQ,SAAS;AACvB,QAAI,OAAO,UAAU,OAAW,OAAM,QAAQ,OAAO;AACrD,QAAI,OAAO,YAAY,OAAW,OAAM,UAAU,OAAO;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,YAAY,KAAa,SAAwB;AAC/C,aAAS,EAAE,KAAK,GAAG,IAAI;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,KAAmB;AAC/B,WAAO,SAAS,EAAE,KAAK,GAAG;AAAA,EAC5B;AAAA;AAAA,EAGA,eAAe,KAAuB;AACpC,QAAI,IAAK,QAAO,UAAU,GAAG;AAC7B,WAAO,SAAS,EAAE;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,KAAa,YAAoB,MAAuB;AAC5D,QAAI,CAAC,UAAU,GAAG,EAAG;AACrB,UAAM,QAAQ,SAAS;AACvB,QAAI,MAAM,SAAS;AACjB,YAAM,QAAQ,SAAS,KAAK,SAAS,GAAG,IAAI;AAAA,IAC9C,OAAO;AACL,cAAQ,IAAI,IAAI,GAAG,KAAK,SAAS,GAAG,IAAI;AAAA,IAC1C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK,KAAa,YAAoB,MAAuB;AAC3D,UAAM,QAAQ,SAAS;AACvB,QAAI,MAAM,SAAS;AACjB,YAAM,QAAQ,QAAQ,KAAK,SAAS,GAAG,IAAI;AAAA,IAC7C,OAAO;AACL,cAAQ,KAAK,IAAI,GAAG,KAAK,SAAS,GAAG,IAAI;AAAA,IAC3C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,KAAa,YAAoB,MAAuB;AAC5D,UAAM,QAAQ,SAAS;AACvB,QAAI,MAAM,SAAS;AACjB,YAAM,QAAQ,SAAS,KAAK,SAAS,GAAG,IAAI;AAAA,IAC9C,OAAO;AACL,cAAQ,MAAM,IAAI,GAAG,KAAK,SAAS,GAAG,IAAI;AAAA,IAC5C;AAAA,EACF;AAAA;AAAA,EAGA,QAAc;AACZ,UAAM,IAAI;AACV,WAAO,EAAE,UAAU;AAAA,EACrB;AACF;;;ACxHA,IAAM,kBAAkB;AAGxB,SAAS,YAAY,QAAgB,QAAsB;AACzD,MAAI,CAAC,gBAAgB,KAAK,MAAM,GAAG;AACjC,UAAM,IAAI,YAAY,0DAA0D,MAAM,KAAK,kBAAkB;AAAA,EAC/G;AACA,MAAI,UAAU,IAAI;AAGhB,UAAM,IAAI,YAAY,kCAAkC,OAAO,SAAS,CAAC,IAAI,kBAAkB;AAAA,EACjG;AACF;AAGO,SAAS,iBAAiB,QAAgB,QAAuB;AACtE,cAAY,QAAQ,MAAM;AAC1B,SAAO,IAAI,MAAM,IAAI,QAAQ,aAAa,OAAO,MAAM,CAAC,GAAG,MAAM;AACnE;AAEO,IAAM,oBAAN,MAAM,mBAA0C;AAAA,EAM7C,YACU,QACC,QAA2B,MAC5C;AAFgB;AACC;AAAA,EAChB;AAAA;AAAA,EAPH,OAAuB,WAAW;AAAA;AAAA,EAElC,OAAuB,UAAU;AAAA;AAAA,EAQjC,IAAW,OAA0B;AACnC,WAAO,KAAK,QAAQ,IAAI,WAAW,KAAK,KAAK,IAAI;AAAA,EACnD;AAAA;AAAA,EAGA,OAAc,OAAO,QAAgC,OAA0B,MAAyB;AACtG,WAAO,IAAI,mBAAkB,QAAQ,IAAI;AAAA,EAC3C;AAAA;AAAA,EAGA,OAAc,UAAU,OAAoB,OAA0B,MAAyB;AAC7F,QAAI,MAAM,OAAO,WAAW,GAAG;AAC7B,YAAM,IAAI,YAAY,iDAAiD,kBAAkB;AAAA,IAC3F;AACA,UAAM,SAAS,MAAM,OAAO,IAAI,CAAC,MAAM,iBAAiB,EAAE,QAAQ,EAAE,MAAM,CAAC;AAC3E,WAAO,IAAI,mBAAkB,uBAAuB,OAAO,GAAG,MAAM,GAAG,IAAI;AAAA,EAC7E;AAAA;AAAA,EAGA,OAAc,SAAS,OAAsC;AAC3D,UAAM,MAAM,iBAAiB,UAAU,KAAK;AAC5C,QAAI,IAAI,QAAQ,mBAAkB,UAAU;AAC1C,YAAM,IAAI,UAAU,kCAAkC,IAAI,GAAG,EAAE;AAAA,IACjE;AAGA,UAAM,SAAS,iBAAiB,YAAY,IAAI,MAAM,CAAC;AACvD,UAAM,UAAU,iBAAiB,sBAAsB,OAAO,CAAC,CAAC;AAChE,QAAI,YAAY,mBAAkB,SAAS;AACzC,YAAM,IAAI,UAAU,0CAA0C,OAAO,EAAE;AAAA,IACzE;AACA,UAAM,OAAO,iBAAiB,eAAe,OAAO,CAAC,GAAG,iBAAiB,gBAAgB;AACzF,WAAO,IAAI,mBAAkB,uBAAuB,SAAS,OAAO,CAAC,CAAC,GAAG,IAAI;AAAA,EAC/E;AAAA;AAAA,EAGO,SAA8B;AACnC,WAAO,QAAQ;AAAA,MACb,eAAe;AAAA,QACb,mBAAkB;AAAA,QAClB,eAAe;AAAA,UACb,eAAe,sBAAsB,mBAAkB,OAAO;AAAA,UAC9D,KAAK,OAAO,OAAO;AAAA,UACnB,eAAe,eAAe,KAAK,OAAO,eAAe,gBAAgB;AAAA,QAC3E;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGO,UAAuB;AAC5B,WAAO;AAAA,MACL,QAAQ,KAAK,OAAO,QAAQ,EAAE,IAAI,CAAC,OAAO;AAAA,QACxC,QAAQ,aAAa,OAAO,EAAE,GAAG,KAAK;AAAA,QACtC,QAAQ,EAAE;AAAA,MACZ,EAAE;AAAA,IACJ;AAAA,EACF;AAAA;AAAA,EAGO,UAAU,QAAwB;AACvC,QAAI,CAAC,gBAAgB,KAAK,MAAM,GAAG;AACjC,YAAM,IAAI,YAAY,0DAA0D,MAAM,KAAK,kBAAkB;AAAA,IAC/G;AACA,UAAM,QAAQ,KAAK,OAAO,IAAI,IAAI,QAAQ,aAAa,OAAO,MAAM,CAAC,CAAC;AACtE,WAAO,QAAQ,MAAM,QAAQ;AAAA,EAC/B;AACF;AAMO,SAAS,wBAAwB,OAA0C;AAChF,SAAO,QAAQ,QAAQ,kBAAkB,SAAS,KAAK,CAAC;AAC1D;;;ACxHO,IAAM,2BAA2B;AAIjC,SAAS,sBAAsB,YAAwC;AAC5E,MAAI,eAAe,OAAW,QAAO;AACrC,MAAI,CAAC,OAAO,SAAS,UAAU,KAAK,cAAc,GAAG;AACnD,UAAM,IAAI;AAAA,MACR,iEAAiE,OAAO,UAAU,CAAC;AAAA,MAEnF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAIA,IAAM,0BAA0B,oBAAI,IAAI,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG,CAAC;AAGpE,IAAM,wBAAN,cAAoC,MAAM;AAAA,EACxC,YAA4B,QAAgB;AACjD,UAAM,wCAAwC,MAAM,GAAG;AADtB;AAEjC,SAAK,OAAO;AAAA,EACd;AACF;AAEA,SAAS,wBAAwB,KAAuB;AACtD,MAAI,eAAe,sBAAuB,QAAO;AACjD,SAAO,eAAe,uBAAuB,wBAAwB,IAAI,IAAI,MAAM;AACrF;AAGA,SAAS,MAAM,IAAY,QAAoC;AAC7D,SAAO,IAAI,QAAc,CAAC,YAAY;AACpC,UAAM,QAAQ,WAAW,SAAS,EAAE;AACpC,WAAO;AAAA,MACL;AAAA,MACA,MAAM;AACJ,qBAAa,KAAK;AAClB,gBAAQ;AAAA,MACV;AAAA,MACA,EAAE,MAAM,KAAK;AAAA,IACf;AAAA,EACF,CAAC;AACH;AAOA,eAAsB,eACpB,SACA,QACA,YACyC;AACzC,MAAI,UAAU;AACd,aAAS;AAEP,QAAI,OAAO,QAAS,OAAM,OAAO;AACjC,QAAI;AACF,aAAO,EAAE,OAAO,MAAM,QAAQ,GAAG,QAAQ;AAAA,IAC3C,SAAS,KAAK;AAEZ,UAAI,OAAO,QAAS,OAAM;AAC1B,UAAI,CAAC,wBAAwB,GAAG,EAAG,OAAM;AACzC,gBAAU;AACV,YAAM,MAAM,YAAY,MAAM;AAAA,IAChC;AAAA,EACF;AACF;AAGO,SAAS,sBACd,WACA,UACA,OAC8C;AAC9C,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,aAAa,MAAY;AAC7B,eAAW,MAAM,UAAU,MAAM;AAAA,EACnC;AACA,MAAI,aAAa,QAAW;AAC1B,QAAI,SAAS,QAAS,YAAW;AAAA,QAC5B,UAAS,iBAAiB,SAAS,YAAY,EAAE,MAAM,KAAK,CAAC;AAAA,EACpE;AACA,QAAM,QAAQ,WAAW,MAAM;AAC7B,eAAW,MAAM,IAAI,YAAY,GAAG,KAAK,WAAW,OAAO,SAAS,CAAC,OAAO,kBAAkB,CAAC;AAAA,EACjG,GAAG,SAAS;AACZ,SAAO;AAAA,IACL,QAAQ,WAAW;AAAA,IACnB,SAAS,MAAM;AACb,mBAAa,KAAK;AAClB,gBAAU,oBAAoB,SAAS,UAAU;AAAA,IACnD;AAAA,EACF;AACF;AAYA,eAAsB,kBACpB,MACA,aACA,QACyB;AACzB,QAAM,EAAE,MAAM,IAAI,MAAM;AAAA,IACtB,MACE;AAAA,MACE,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACF;AAAA,IACA,KAAK;AAAA,EACP;AACA,SAAO;AACT;;;AChIO,IAAM,wBAAN,cAAoC,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA,EAKrD;AAAA,EAEA,YAAY,SAAiB,OAAiB;AAC5C,UAAM,SAAS,qBAAqB,KAAK;AACzC,SAAK,OAAO;AAAA,EACd;AACF;AAgBO,IAAM,wBAAN,cAAoC,YAAY;AAAA,EAC5C,mBAAmB;AAAA,EAE5B,YAAY,SAAiB,OAAiB;AAC5C,UAAM,SAAS,6BAA6B,KAAK;AACjD,SAAK,OAAO;AAAA,EACd;AACF;AAYO,IAAM,+BAAN,cAA2C,YAAY;AAAA,EACnD,mBAAmB;AAAA,EAE5B,YAAY,SAAiB,OAAiB;AAC5C,UAAM,SAAS,6BAA6B,KAAK;AACjD,SAAK,OAAO;AAAA,EACd;AACF;AAcO,IAAM,2BAAN,cAAuC,YAAY;AAAA,EACxD,YAAY,SAAiB,OAAiB;AAC5C,UAAM,SAAS,yBAAyB,KAAK;AAC7C,SAAK,OAAO;AAAA,EACd;AACF;AAYO,IAAM,mCAAN,cAA+C,YAAY;AAAA,EAChE,YAAY,SAAiB,OAAiB;AAC5C,UAAM,SAAS,iCAAiC,KAAK;AACrD,SAAK,OAAO;AAAA,EACd;AACF;;;ACtGO,SAAS,qBACd,KACA,WACA,aACA,uBACS;AAGT,MACE,eAAe,SACf,IAAI,YAAY,mCAAmC,iCAAiC,yBAAyB,IAC7G;AACA,WAAO,IAAI;AAAA,MACT,GAAG,SAAS;AAAA,MAEZ;AAAA,IACF;AAAA,EACF;AACA,MAAI,sBAAuB,QAAO;AAClC,SAAO,IAAI;AAAA,IACT,GAAG,SAAS;AAAA,IAEZ,eAAe;AAAA,EACjB;AACF;;;ACVO,SAAS,aAAqB;AACnC,QAAM,IAAI,WAAW;AACrB,MAAI,OAAO,MAAM,eAAe,OAAO,EAAE,eAAe,YAAY;AAClE,WAAO,EAAE,WAAW;AAAA,EACtB;AAEA,QAAM,IAAI,EAAE,gBAAgB,IAAI,WAAW,EAAE,CAAC;AAC9C,IAAE,CAAC,IAAK,EAAE,CAAC,IAAI,KAAQ;AACvB,IAAE,CAAC,IAAK,EAAE,CAAC,IAAI,KAAQ;AACvB,QAAM,IAAI,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC;AAC9D,SAAO,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC;AACnI;;;ACAA,eAAsB,mBAAmB,WAA8C;AACrF,QAAM,QAAQ,MAAM,MAAM,SAAS,SAAS;AAC5C,QAAM,YAAY,aAAa,QAAQ,MAAM,MAAM,kBAAkB,mBAAmB,GAAG,OAAO;AAClG,SAAO,EAAE,SAAS,aAAa,OAAO,MAAM,GAAG,KAAK,GAAG,UAAU;AACnE;;;ACuFM,SAAU,QAAQ,GAAU;AAKhC,SACE,aAAa,cACZ,YAAY,OAAO,CAAC,KACnB,EAAE,YAAY,SAAS,gBACvB,uBAAuB,KACvB,EAAE,sBAAsB;AAE9B;AAcM,SAAU,QAAQ,GAAW,QAAgB,IAAE;AACnD,MAAI,OAAO,MAAM,UAAU;AACzB,UAAM,SAAS,SAAS,IAAI,KAAK;AACjC,UAAM,IAAI,UAAU,GAAG,MAAM,wBAAwB,OAAO,CAAC,EAAE;EACjE;AACA,MAAI,CAAC,OAAO,cAAc,CAAC,KAAK,IAAI,GAAG;AACrC,UAAM,SAAS,SAAS,IAAI,KAAK;AACjC,UAAM,IAAI,WAAW,GAAG,MAAM,8BAA8B,CAAC,EAAE;EACjE;AACF;AAgBM,SAAU,OACd,OACA,QACA,QAAgB,IAAE;AAElB,QAAM,QAAQ,QAAQ,KAAK;AAC3B,QAAM,MAAM,OAAO;AACnB,QAAM,WAAW,WAAW;AAC5B,MAAI,CAAC,SAAU,YAAY,QAAQ,QAAS;AAC1C,UAAM,SAAS,SAAS,IAAI,KAAK;AACjC,UAAM,QAAQ,WAAW,cAAc,MAAM,KAAK;AAClD,UAAM,MAAM,QAAQ,UAAU,GAAG,KAAK,QAAQ,OAAO,KAAK;AAC1D,UAAM,UAAU,SAAS,wBAAwB,QAAQ,WAAW;AACpE,QAAI,CAAC;AAAO,YAAM,IAAI,UAAU,OAAO;AACvC,UAAM,IAAI,WAAW,OAAO;EAC9B;AACA,SAAO;AACT;AAkCM,SAAU,MAAM,GAAc;AAClC,MAAI,OAAO,MAAM,cAAc,OAAO,EAAE,WAAW;AACjD,UAAM,IAAI,UAAU,yCAAyC;AAC/D,UAAQ,EAAE,SAAS;AACnB,UAAQ,EAAE,QAAQ;AAGlB,MAAI,EAAE,YAAY;AAAG,UAAM,IAAI,MAAM,0BAA0B;AAC/D,MAAI,EAAE,WAAW;AAAG,UAAM,IAAI,MAAM,yBAAyB;AAC/D;AAgBM,SAAU,QAAQ,UAAe,gBAAgB,MAAI;AACzD,MAAI,SAAS;AAAW,UAAM,IAAI,MAAM,kCAAkC;AAC1E,MAAI,iBAAiB,SAAS;AAAU,UAAM,IAAI,MAAM,uCAAuC;AACjG;AAkBM,SAAU,QAAQ,KAAU,UAAa;AAC7C,SAAO,KAAK,QAAW,qBAAqB;AAC5C,QAAM,MAAM,SAAS;AACrB,MAAI,IAAI,SAAS,KAAK;AACpB,UAAM,IAAI,WAAW,sDAAsD,GAAG;EAChF;AACF;AAkDM,SAAU,SAAS,QAA0B;AACjD,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,WAAO,CAAC,EAAE,KAAK,CAAC;EAClB;AACF;AAYM,SAAU,WAAW,KAAqB;AAC9C,SAAO,IAAI,SAAS,IAAI,QAAQ,IAAI,YAAY,IAAI,UAAU;AAChE;AAaM,SAAU,KAAK,MAAc,OAAa;AAC9C,SAAQ,QAAS,KAAK,QAAW,SAAS;AAC5C;AAyaM,SAAU,aACd,UACA,OAAuB,CAAA,GAAE;AAEzB,QAAM,QAAa,CAAC,KAAuB,SACzC,SAAS,IAAY,EAClB,OAAO,GAAG,EACV,OAAM;AACX,QAAM,MAAM,SAAS,MAAS;AAC9B,QAAM,YAAY,IAAI;AACtB,QAAM,WAAW,IAAI;AACrB,QAAM,SAAS,IAAI;AACnB,QAAM,SAAS,CAAC,SAAgB,SAAS,IAAI;AAC7C,SAAO,OAAO,OAAO,IAAI;AACzB,SAAO,OAAO,OAAO,KAAK;AAC5B;AA8CO,IAAM,UAAU,CAAC,YAA8C;;;EAGpE,KAAK,WAAW,KAAK,CAAC,GAAM,GAAM,IAAM,KAAM,IAAM,GAAM,KAAM,GAAM,GAAM,GAAM,MAAM,CAAC;;;;ACzzBrF,IAAO,QAAP,MAAY;EAChB;EACA;EACA;EACA;EACA,SAAS;EACD,WAAW;EACX,YAAY;EAEpB,YAAY,MAAmB,KAAqB;AAClD,UAAM,IAAI;AACV,WAAO,KAAK,QAAW,KAAK;AAC5B,SAAK,QAAQ,KAAK,OAAM;AACxB,QAAI,OAAO,KAAK,MAAM,WAAW;AAC/B,YAAM,IAAI,MAAM,qDAAqD;AACvE,SAAK,WAAW,KAAK,MAAM;AAC3B,SAAK,YAAY,KAAK,MAAM;AAC5B,UAAM,WAAW,KAAK;AACtB,UAAM,MAAM,IAAI,WAAW,QAAQ;AAEnC,QAAI,IAAI,IAAI,SAAS,WAAW,KAAK,OAAM,EAAG,OAAO,GAAG,EAAE,OAAM,IAAK,GAAG;AACxE,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ;AAAK,UAAI,CAAC,KAAK;AAC/C,SAAK,MAAM,OAAO,GAAG;AAGrB,SAAK,QAAQ,KAAK,OAAM;AAExB,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ;AAAK,UAAI,CAAC,KAAK,KAAO;AACtD,SAAK,MAAM,OAAO,GAAG;AACrB,UAAM,GAAG;EACX;EACA,OAAO,KAAqB;AAC1B,YAAQ,IAAI;AACZ,SAAK,MAAM,OAAO,GAAG;AACrB,WAAO;EACT;EACA,WAAW,KAAqB;AAC9B,YAAQ,IAAI;AACZ,YAAQ,KAAK,IAAI;AACjB,SAAK,WAAW;AAChB,UAAM,MAAM,IAAI,SAAS,GAAG,KAAK,SAAS;AAG1C,SAAK,MAAM,WAAW,GAAG;AACzB,SAAK,MAAM,OAAO,GAAG;AACrB,SAAK,MAAM,WAAW,GAAG;AACzB,SAAK,QAAO;EACd;EACA,SAAM;AACJ,UAAM,MAAM,IAAI,WAAW,KAAK,MAAM,SAAS;AAC/C,SAAK,WAAW,GAAG;AACnB,WAAO;EACT;EACA,WAAW,IAAa;AAGtB,WAAO,OAAO,OAAO,OAAO,eAAe,IAAI,GAAG,CAAA,CAAE;AACpD,UAAM,EAAE,OAAO,OAAO,UAAU,WAAW,UAAU,UAAS,IAAK;AACnE,SAAK;AACL,OAAG,WAAW;AACd,OAAG,YAAY;AACf,OAAG,WAAW;AACd,OAAG,YAAY;AACf,OAAG,QAAQ,MAAM,WAAW,GAAG,KAAK;AACpC,OAAG,QAAQ,MAAM,WAAW,GAAG,KAAK;AACpC,WAAO;EACT;EACA,QAAK;AACH,WAAO,KAAK,WAAU;EACxB;EACA,UAAO;AACL,SAAK,YAAY;AACjB,SAAK,MAAM,QAAO;AAClB,SAAK,MAAM,QAAO;EACpB;;AAqBK,IAAM,OAAsC,uBAAK;AACtD,QAAM,SAAS,CACb,MACA,KACA,YACqB,IAAI,MAAW,MAAM,GAAG,EAAE,OAAO,OAAO,EAAE,OAAM;AACvE,QAAM,SAAS,CAAC,MAAmB,QACjC,IAAI,MAAW,MAAM,GAAG;AAC1B,SAAO;AACT,GAAE;;;ACrGI,SAAU,QACd,MACA,KACA,MAAuB;AAEvB,QAAM,IAAI;AAIV,MAAI,SAAS;AAAW,WAAO,IAAI,WAAW,KAAK,SAAS;AAC5D,SAAO,KAAK,MAAM,MAAM,GAAG;AAC7B;AAIA,IAAM,eAA+B,2BAAW,GAAG,CAAC;AAEpD,IAAM,eAA+B,2BAAW,GAAE;AAqB5C,SAAU,OACd,MACA,KACA,MACA,SAAiB,IAAE;AAEnB,QAAM,IAAI;AACV,UAAQ,QAAQ,QAAQ;AACxB,SAAO,KAAK,QAAW,KAAK;AAC5B,QAAM,OAAO,KAAK;AAElB,MAAI,IAAI,SAAS;AAAM,UAAM,IAAI,MAAM,uCAAuC;AAE9E,MAAI,SAAS,MAAM;AAAM,UAAM,IAAI,MAAM,+BAA+B;AACxE,QAAM,SAAS,KAAK,KAAK,SAAS,IAAI;AACtC,MAAI,SAAS;AAAW,WAAO;;AAC1B,WAAO,MAAM,QAAW,MAAM;AAEnC,QAAM,MAAM,IAAI,WAAW,SAAS,IAAI;AAExC,QAAM,OAAO,KAAK,OAAO,MAAM,GAAG;AAClC,QAAM,UAAU,KAAK,WAAU;AAC/B,QAAM,IAAI,IAAI,WAAW,KAAK,SAAS;AACvC,WAAS,UAAU,GAAG,UAAU,QAAQ,WAAW;AACjD,iBAAa,CAAC,IAAI,UAAU;AAG5B,YAAQ,OAAO,YAAY,IAAI,eAAe,CAAC,EAC5C,OAAO,IAAI,EACX,OAAO,YAAY,EACnB,WAAW,CAAC;AACf,QAAI,IAAI,GAAG,OAAO,OAAO;AACzB,SAAK,WAAW,OAAO;EACzB;AACA,OAAK,QAAO;AACZ,UAAQ,QAAO;AACf,QAAM,GAAG,YAAY;AACrB,SAAO,IAAI,MAAM,GAAG,MAAM;AAC5B;AA0BO,IAAM,OAAO,CAClB,MACA,KACA,MACA,MACA,WACqB,OAAO,MAAM,QAAQ,MAAM,KAAK,IAAI,GAAG,MAAM,MAAM;;;ACtGpE,SAAU,IAAI,GAAW,GAAW,GAAS;AACjD,SAAQ,IAAI,IAAM,CAAC,IAAI;AACzB;AAeM,SAAU,IAAI,GAAW,GAAW,GAAS;AACjD,SAAQ,IAAI,IAAM,IAAI,IAAM,IAAI;AAClC;AAoBM,IAAgB,SAAhB,MAAsB;EASjB;EACA;EACA,SAAS;EACT;EACA;;EAGC;EACA;EACA,WAAW;EACX,SAAS;EACT,MAAM;EACN,YAAY;EAEtB,YAAY,UAAkB,WAAmB,WAAmB,MAAa;AAC/E,SAAK,WAAW;AAChB,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,SAAK,OAAO;AACZ,SAAK,SAAS,IAAI,WAAW,QAAQ;AACrC,SAAK,OAAO,WAAW,KAAK,MAAM;EACpC;EACA,OAAO,MAAsB;AAC3B,YAAQ,IAAI;AACZ,WAAO,IAAI;AACX,UAAM,EAAE,MAAM,QAAQ,SAAQ,IAAK;AACnC,UAAM,MAAM,KAAK;AACjB,aAAS,MAAM,GAAG,MAAM,OAAO;AAC7B,YAAM,OAAO,KAAK,IAAI,WAAW,KAAK,KAAK,MAAM,GAAG;AAGpD,UAAI,SAAS,UAAU;AACrB,cAAM,WAAW,WAAW,IAAI;AAChC,eAAO,YAAY,MAAM,KAAK,OAAO;AAAU,eAAK,QAAQ,UAAU,GAAG;AACzE;MACF;AACA,aAAO,IAAI,KAAK,SAAS,KAAK,MAAM,IAAI,GAAG,KAAK,GAAG;AACnD,WAAK,OAAO;AACZ,aAAO;AACP,UAAI,KAAK,QAAQ,UAAU;AACzB,aAAK,QAAQ,MAAM,CAAC;AACpB,aAAK,MAAM;MACb;IACF;AACA,SAAK,UAAU,KAAK;AACpB,SAAK,WAAU;AACf,WAAO;EACT;EACA,WAAW,KAAqB;AAC9B,YAAQ,IAAI;AACZ,YAAQ,KAAK,IAAI;AACjB,SAAK,WAAW;AAIhB,UAAM,EAAE,QAAQ,MAAM,UAAU,KAAI,IAAK;AACzC,QAAI,EAAE,IAAG,IAAK;AAEd,WAAO,KAAK,IAAI;AAChB,UAAM,KAAK,OAAO,SAAS,GAAG,CAAC;AAG/B,QAAI,KAAK,YAAY,WAAW,KAAK;AACnC,WAAK,QAAQ,MAAM,CAAC;AACpB,YAAM;IACR;AAEA,aAAS,IAAI,KAAK,IAAI,UAAU;AAAK,aAAO,CAAC,IAAI;AAIjD,SAAK,aAAa,WAAW,GAAG,OAAO,KAAK,SAAS,CAAC,GAAG,IAAI;AAC7D,SAAK,QAAQ,MAAM,CAAC;AACpB,UAAM,QAAQ,WAAW,GAAG;AAC5B,UAAM,MAAM,KAAK;AAEjB,QAAI,MAAM;AAAG,YAAM,IAAI,MAAM,2CAA2C;AACxE,UAAM,SAAS,MAAM;AACrB,UAAM,QAAQ,KAAK,IAAG;AACtB,QAAI,SAAS,MAAM;AAAQ,YAAM,IAAI,MAAM,oCAAoC;AAC/E,aAAS,IAAI,GAAG,IAAI,QAAQ;AAAK,YAAM,UAAU,IAAI,GAAG,MAAM,CAAC,GAAG,IAAI;EACxE;EACA,SAAM;AACJ,UAAM,EAAE,QAAQ,UAAS,IAAK;AAC9B,SAAK,WAAW,MAAM;AAGtB,UAAM,MAAM,OAAO,MAAM,GAAG,SAAS;AACrC,SAAK,QAAO;AACZ,WAAO;EACT;EACA,WAAW,IAAM;AACf,WAAO,IAAK,KAAK,YAAmB;AACpC,OAAG,IAAI,GAAG,KAAK,IAAG,CAAE;AACpB,UAAM,EAAE,UAAU,QAAQ,QAAQ,UAAU,WAAW,IAAG,IAAK;AAC/D,OAAG,YAAY;AACf,OAAG,WAAW;AACd,OAAG,SAAS;AACZ,OAAG,MAAM;AAGT,QAAI,SAAS;AAAU,SAAG,OAAO,IAAI,MAAM;AAC3C,WAAO;EACT;EACA,QAAK;AACH,WAAO,KAAK,WAAU;EACxB;;AAWK,IAAM,YAA+C,4BAAY,KAAK;EAC3E;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;CACrF;;;ACrLD,IAAM,WAA2B,4BAAY,KAAK;EAChD;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EACpF;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EACpF;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EACpF;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EACpF;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EACpF;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EACpF;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EACpF;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;EAAY;CACrF;AAGD,IAAM,WAA2B,oBAAI,YAAY,EAAE;AAGnD,IAAe,WAAf,cAAuD,OAAS;EAY9D,YAAY,WAAiB;AAC3B,UAAM,IAAI,WAAW,GAAG,KAAK;EAC/B;EACU,MAAG;AACX,UAAM,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAC,IAAK;AACnC,WAAO,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;EAChC;;EAEU,IACR,GAAW,GAAW,GAAW,GAAW,GAAW,GAAW,GAAW,GAAS;AAEtF,SAAK,IAAI,IAAI;AACb,SAAK,IAAI,IAAI;AACb,SAAK,IAAI,IAAI;AACb,SAAK,IAAI,IAAI;AACb,SAAK,IAAI,IAAI;AACb,SAAK,IAAI,IAAI;AACb,SAAK,IAAI,IAAI;AACb,SAAK,IAAI,IAAI;EACf;EACU,QAAQ,MAAgB,QAAc;AAE9C,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK,UAAU;AAAG,eAAS,CAAC,IAAI,KAAK,UAAU,QAAQ,KAAK;AACpF,aAAS,IAAI,IAAI,IAAI,IAAI,KAAK;AAC5B,YAAM,MAAM,SAAS,IAAI,EAAE;AAC3B,YAAM,KAAK,SAAS,IAAI,CAAC;AACzB,YAAM,KAAK,KAAK,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,IAAK,QAAQ;AACnD,YAAM,KAAK,KAAK,IAAI,EAAE,IAAI,KAAK,IAAI,EAAE,IAAK,OAAO;AACjD,eAAS,CAAC,IAAK,KAAK,SAAS,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,EAAE,IAAK;IACjE;AAEA,QAAI,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAC,IAAK;AACjC,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,YAAM,SAAS,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE,IAAI,KAAK,GAAG,EAAE;AACpD,YAAM,KAAM,IAAI,SAAS,IAAI,GAAG,GAAG,CAAC,IAAI,SAAS,CAAC,IAAI,SAAS,CAAC,IAAK;AACrE,YAAM,SAAS,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE,IAAI,KAAK,GAAG,EAAE;AACpD,YAAM,KAAM,SAAS,IAAI,GAAG,GAAG,CAAC,IAAK;AACrC,UAAI;AACJ,UAAI;AACJ,UAAI;AACJ,UAAK,IAAI,KAAM;AACf,UAAI;AACJ,UAAI;AACJ,UAAI;AACJ,UAAK,KAAK,KAAM;IAClB;AAEA,QAAK,IAAI,KAAK,IAAK;AACnB,QAAK,IAAI,KAAK,IAAK;AACnB,QAAK,IAAI,KAAK,IAAK;AACnB,QAAK,IAAI,KAAK,IAAK;AACnB,QAAK,IAAI,KAAK,IAAK;AACnB,QAAK,IAAI,KAAK,IAAK;AACnB,QAAK,IAAI,KAAK,IAAK;AACnB,QAAK,IAAI,KAAK,IAAK;AACnB,SAAK,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;EACjC;EACU,aAAU;AAClB,UAAM,QAAQ;EAChB;EACA,UAAO;AAGL,SAAK,YAAY;AACjB,SAAK,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAC/B,UAAM,KAAK,MAAM;EACnB;;AAII,IAAO,UAAP,cAAuB,SAAiB;;;EAGlC,IAAY,UAAU,CAAC,IAAI;EAC3B,IAAY,UAAU,CAAC,IAAI;EAC3B,IAAY,UAAU,CAAC,IAAI;EAC3B,IAAY,UAAU,CAAC,IAAI;EAC3B,IAAY,UAAU,CAAC,IAAI;EAC3B,IAAY,UAAU,CAAC,IAAI;EAC3B,IAAY,UAAU,CAAC,IAAI;EAC3B,IAAY,UAAU,CAAC,IAAI;EACrC,cAAA;AACE,UAAM,EAAE;EACV;;AAsUK,IAAMA,UAA+C;EAC1D,MAAM,IAAI,QAAO;EACD,wBAAQ,CAAI;AAAC;;;AC1axB,IAAM,+BAA+B;AAoBrC,SAAS,kBACd,YACA,YACA,OACA,OACY;AACZ,QAAM,MAAM,aAAa,OAAO,UAAU;AAC1C,QAAM,OAAO,IAAI,YAAY,EAAE,OAAO,GAAG,4BAA4B,IAAI,UAAU,IAAI,KAAK,IAAI,KAAK,EAAE;AACvG,SAAO,KAAKC,SAAQ,KAAK,QAAW,MAAM,EAAE;AAC9C;;;ACjBA,IAAM,qBAAqB;AAK3B,IAAM,yBAAyB;AAUxB,SAAS,WAAW,GAAe,GAAwB;AAChE,MAAI,EAAE,WAAW,EAAE,OAAQ,QAAO;AAClC,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AACjC,QAAI,EAAE,CAAC,MAAM,EAAE,CAAC,EAAG,QAAO;AAAA,EAC5B;AACA,SAAO;AACT;AAEA,eAAeC,QAAO,OAAwC;AAC5D,UAAQ,MAAM,IAAI,WAAW,cAAc,MAAM,EAAE,OAAO,KAAK,EAAE,OAAO,GAAG;AAC7E;AAMA,eAAsB,iBACpB,QACA,WACA,YACqB;AACrB,SAAO,eAAe;AAAA,IACpB,eAAe,sBAAsB,kBAAkB;AAAA,IACvD,eAAe,iBAAiB,sBAAsB;AAAA,IACtD,eAAe,iBAAiB,OAAO,OAAO,CAAC;AAAA,IAC/C,eAAe,iBAAiB,UAAU,OAAO,CAAC;AAAA,IAClD,eAAe,iBAAiB,MAAMA,QAAO,WAAW,OAAO,CAAC,CAAC;AAAA,EACnE;AACF;AAeA,SAAS,iBAAiB,OAAsC;AAC9D,MAAI;AACF,UAAM,SAAS,iBAAiB,YAAY,OAAO,CAAC;AACpD,UAAM,UAAU,OAAO,iBAAiB,sBAAsB,OAAO,CAAC,CAAC,CAAC;AACxE,QAAI,YAAY,oBAAoB;AAClC,YAAM,IAAI,yBAAyB,4BAA4B,OAAO,OAAO,CAAC,mBAAmB;AAAA,IACnG;AACA,WAAO;AAAA,MACL,YAAY,iBAAiB,iBAAiB,OAAO,CAAC,CAAC;AAAA,MACvD,aAAa,iBAAiB,iBAAiB,OAAO,CAAC,CAAC;AAAA,MACxD,gBAAgB,iBAAiB,iBAAiB,OAAO,CAAC,CAAC;AAAA,MAC3D,gBAAgB,iBAAiB,iBAAiB,OAAO,CAAC,CAAC;AAAA,IAC7D;AAAA,EACF,SAAS,KAAK;AACZ,QAAI,eAAe,yBAA0B,OAAM;AACnD,UAAM,IAAI,yBAAyB,iDAAiD,GAAG;AAAA,EACzF;AACF;AAGA,SAAS,mBAAmB,KAAuB;AACjD,QAAM,SAAU,KAAuD,oBAAoB;AAC3F,SAAO,WAAW,iCAAiC;AACrD;AAWA,eAAsB,yBACpB,MACA,aACA,iBACA,aACgB;AAChB,QAAM,UAAU,iBAAiB,WAAW;AAC5C,MAAI,CAAC,WAAW,QAAQ,aAAa,gBAAgB,OAAO,CAAC,GAAG;AAC9D,UAAM,IAAI;AAAA,MACR,6EAA6E,QAAQ,UAAU;AAAA,IACjG;AAAA,EACF;AAGA,MAAI;AACJ,MAAI;AACF,gBAAY,eAAe,SAAS,QAAQ,cAAc;AAAA,EAC5D,SAAS,KAAK;AACZ,UAAM,IAAI,yBAAyB,uDAAuD,GAAG;AAAA,EAC/F;AACA,MAAI;AACJ,MAAI;AACF,oBAAgB,MAAM,gBAAgB,uBAAuB,KAAK,WAAW,KAAK,mBAAmB,KAAK,4BAA4B,SAAS;AAAA,EACjJ,SAAS,KAAK;AACZ,QAAI,mBAAmB,GAAG,GAAG;AAC3B,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,UAAM,IAAI,yBAAyB,qCAAqC,GAAG;AAAA,EAC7E;AAIA,MAAI;AACJ,MAAI;AACF,iBAAa,MAAM,YAAY,SAAS,eAAe,KAAK,mBAAmB;AAAA,EACjF,SAAS,KAAK;AACZ,UAAM,IAAI,yBAAyB,sDAAsD,GAAG;AAAA,EAC9F;AACA,MAAI,CAAC,WAAW,MAAMA,QAAO,WAAW,OAAO,CAAC,GAAG,QAAQ,cAAc,GAAG;AAC1E,UAAM,IAAI,yBAAyB,qEAAqE;AAAA,EAC1G;AACA,SAAO;AACT;;;AClDO,IAAM,iCAAiC;AAS9C,IAAM,uBAAuB;AAU7B,SAAS,qBAAqB,KAAuB;AACnD,SACE,eAAe,yBACf,eAAe,gCACf,eAAe,4BACf,eAAe;AAEnB;AAGA,IAAM,iBAAiB;AAevB,IAAM,wBAA6C,oBAAI,IAAI;AAAA,EACzD,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,oBAAoB;AACtB,CAAC;AAaM,IAAM,oBAAN,MAAgD;AAAA,EAS9C,YAA6B,MAAkB;AAAlB;AAClC,SAAK,gBAAgB,aAAa,OAAO,KAAK,UAAU;AAExD,SAAK,iBAAiB,sBAAsB,KAAK,cAAc;AAAA,EACjE;AAAA;AAAA,EAXgB,oBAAoB;AAAA;AAAA,EAGnB;AAAA,EAEA;AAAA;AAAA,EAUV,cAA8B;AACnC,WAAO,EAAE,aAAa,IAAI,WAAW,KAAK,KAAK,eAAe,SAAS,EAAE;AAAA,EAC3E;AAAA;AAAA,EAGO,sBAAsB,QAAsC;AACjE,WAAO,oBAAoB,UAAU,KAAK,KAAK,eAAe,SAAS;AAAA,EACzE;AAAA;AAAA,EAIO,UAAU,OAAwC;AACvD,WAAO,MAAM;AAAA,EACf;AAAA,EAEO,UAAU,OAAoB,QAAwB;AAC3D,QAAI,MAAM;AACV,eAAW,SAAS,MAAM,OAAO,UAAU,CAAC,GAAG;AAC7C,UAAI,MAAM,WAAW,OAAQ,QAAO,MAAM;AAAA,IAC5C;AACA,WAAO;AAAA,EACT;AAAA,EAEO,QAAQ,OAA4B;AACzC,WAAO,MAAM,KAAK;AAAA,EACpB;AAAA,EAEO,SAAS,OAAuC;AACrD,UAAM,WAAW,MAAM;AAEvB,QAAI,SAAS,aAAa,SAAS,GAAG;AACpC,aAAO,SAAS,kBAAkB;AAAA,IACpC;AAEA,UAAM,OAAO,SAAS,QAAQ;AAC9B,QAAI,QAAQ,KAAK,oBAAoB,IAAI,GAAG;AAC1C,aAAO,kBAAkB,SAAS,IAAI,EAAE;AAAA,IAC1C;AACA,WAAO;AAAA,EACT;AAAA,EAEO,cAAc,OAAuC;AAC1D,UAAM,OAAO,MAAM,SAAS,QAAQ;AACpC,WAAO,OAAO,IAAI,WAAW,IAAI,IAAI;AAAA,EACvC;AAAA;AAAA,EAIA,MAAa,KAAK,QAAoB,SAAiD;AACrF,UAAM,YAAY,mBAAmB,OAAO,OAAO,eAAe;AAClE,UAAM,OAAO,OAAO,QAAQ,MAAM,kBAAkB,UAAU,OAAO,KAAK,EAAE,OAAO,IAAI;AACvF,UAAM,aAAa,KAAK,kBAAkB,OAAO;AACjD,UAAM,UAAU,KAAK,eAAe,OAAO;AAO3C,UAAM,SAAS,MAAM,gBAAgB,OAAO,KAAK,KAAK,WAAW,WAAW;AAAA,MAC1E;AAAA,MACA,WAAW,IAAI,UAAU,kBAAkB,KAAK,eAAe,YAAY,SAAS,WAAW,CAAC;AAAA,MAChG,MAAM,UAAU,UAAU,kBAAkB,KAAK,eAAe,YAAY,SAAS,MAAM,CAAC;AAAA,IAC9F,CAAC;AACD,UAAM,oBAAoB,MAAM,kBAAkB,oBAAoB,MAAM;AAK5E,UAAM,QAAQ,MAAM,KAAK;AAAA,MACvB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,YAAY,MAAM,OAAO,uBAAuB,KAAK,KAAK,WAAW,KAAK,KAAK,mBAAmB,KAAK,KAAK,4BAA4B,KAAK;AACnJ,UAAM,QAAQ,MAAM,MAAM,KAAK,WAAW,KAAK,KAAK,mBAAmB;AACvE,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAa,cAAc,QAA6B,SAAiD;AACvG,UAAM,YAAY,mBAAmB,OAAO,OAAO,eAAe;AAClE,UAAM,YAAY,OAAO,YAAY,IAAI,UAAU,OAAO,SAAS,IAAI,UAAU,SAAS;AAE1F,UAAM,OAAO,OAAO,OAAO,UAAU,UAAU,OAAO,IAAI,IAAI,UAAU,SAAS;AAEjF,UAAM,SAAS,MAAM,gBAAgB,OAAO,KAAK,KAAK,WAAW,WAAW,EAAE,MAAM,OAAO,MAAM,WAAW,KAAK,CAAC;AAClH,UAAM,oBAAoB,MAAM,kBAAkB,oBAAoB,MAAM;AAI5E,UAAM,QAAQ,MAAM,KAAK;AAAA,MACvB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,YAAY,MAAM,OAAO,uBAAuB,KAAK,KAAK,WAAW,KAAK,KAAK,mBAAmB,KAAK,KAAK,4BAA4B,KAAK;AACnJ,UAAM,QAAQ,MAAM,MAAM,KAAK,WAAW,KAAK,KAAK,mBAAmB;AACvE,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAa,SAAS,QAAwB,SAAiD;AAC7F,SAAK,YAAY,OAAO,KAAK;AAC7B,UAAM,aAAa,KAAK,kBAAkB,OAAO;AACjD,UAAM,YAAY,mBAAmB,OAAO,OAAO,eAAe;AAGlE,UAAM,YAAY,UAAU;AAAA,MAC1B,kBAAkB,KAAK,eAAe,YAAY,KAAK,eAAe,OAAO,GAAG,WAAW;AAAA,IAC7F;AAEA,UAAM,aAAa,MAAM,oBAAoB,OAAO,OAAO,MAAM,UAAU,WAAW,WAAW;AAAA,MAC/F,MAAM,OAAO,QAAQ;AAAA,IACvB,CAAC;AACD,UAAM,eAAe,MAAM,+BAA+B,OAAO,YAAY,KAAK,KAAK,cAAc;AACrG,UAAM,oBAAoB,MAAM,kBAAkB,gBAAgB,YAAY,YAAY;AAE1F,UAAM,QAAQ,MAAM,KAAK;AAAA,MACvB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,YAAY,MAAM,WAAW,uBAAuB,KAAK,KAAK,WAAW,KAAK,KAAK,mBAAmB,KAAK,KAAK,4BAA4B,KAAK;AACvJ,UAAM,cAAc,MAAM,OAAO,MAAM,SAAS,SAAS,WAAW,KAAK,KAAK,mBAAmB;AACjG,WAAO,KAAK,UAAU,WAAW;AAAA,EACnC;AAAA,EAEA,MAAa,MAAM,QAAqB,SAAiD;AACvF,SAAK,YAAY,OAAO,KAAK;AAC7B,QAAI,OAAO,QAAQ,WAAW,GAAG;AAC/B,YAAM,IAAI,YAAY,sCAAsC,kBAAkB;AAAA,IAChF;AACA,UAAM,aAAa,KAAK,kBAAkB,OAAO;AAKjD,UAAM,WAAW,OAAO,QAAQ;AAAA,MAAI,CAAC,GAAG,MACtC,kBAAkB;AAAA,QAChB,mBAAmB,OAAO,EAAE,eAAe;AAAA,QAC3C,kBAAkB,OAAO,uBAAuB,OAAO,iBAAiB,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,EAAE,QAAQ,IAAI;AAAA,QAC5G,UAAU,UAAU,kBAAkB,KAAK,eAAe,YAAY,GAAG,MAAM,CAAC;AAAA,MAClF;AAAA,IACF;AAKA,UAAM,QAAQ,MAAM,WAAW,MAAM,OAAO,MAAM,UAAU,yBAAyB,UAAU;AAAA,MAC7F,eAAe,UAAU;AAAA,QACvB,kBAAkB,KAAK,eAAe,YAAY,KAAK,eAAe,OAAO,GAAG,MAAM;AAAA,MACxF;AAAA,IACF,CAAC;AAKD,UAAM,aAAa,MAAM,KAAK,kBAAkB,EAAE,QAAQ,OAAO,YAAY,QAAQ,CAAC;AAatF,UAAM,UAA+C,CAAC;AACtD,aAAS,QAAQ,GAAG,QAAQ,MAAM,OAAO,QAAQ,SAAS,sBAAsB;AAC9E,YAAM,QAAQ,MAAM,OAAO,MAAM,OAAO,QAAQ,oBAAoB;AACpE,cAAQ;AAAA,QACN,GAAI,MAAM,QAAQ;AAAA,UAChB,MAAM,IAAI,CAAC,UAAU,KAAK,gBAAgB,OAAO,YAAY,OAAO,CAAC;AAAA,QACvE;AAAA,MACF;AAAA,IACF;AAmBA,UAAM,oBAAoB,QAAQ;AAAA,MAChC,CAAC,MAAkC,EAAE,WAAW,cAAc,qBAAqB,EAAE,MAAM;AAAA,IAC7F;AACA,QAAI,sBAAsB,QAAW;AACnC,YAAM,kBAAkB;AAAA,IAC1B;AACA,UAAM,gBAAgB,QAAQ,UAAU,CAAC,MAAM,EAAE,WAAW,UAAU;AACtE,QAAI,kBAAkB,IAAI;AACxB,YAAM,cAAe,QAAQ,aAAa,EAA4B;AAStE,YAAM,IAAI;AAAA,QACR,QAAQ,KAAK,CAAC,MAAM,EAAE,WAAW,WAAW,IACxC,+KAEA;AAAA,QAEJ;AAAA,MACF;AAAA,IACF;AACA,UAAM,UAAU,QAAQ,IAAI,CAAC,MAAO,EAA0C,KAAK;AACnF,WAAO,EAAE,QAAQ;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,kBAAkB,KAAmC;AACjE,UAAM,QAAQ,IAAI,SAAS;AAC3B,UAAM,UAAU,KAAK,eAAe,IAAI,OAAO;AAC/C,UAAM,SAAS,IAAI,OAAO,MAAM;AAChC,QAAI,UAAU,QAAW;AACvB,cAAQ,MAAM,KAAK,WAAW,GAAG,GAAG;AAAA,IACtC;AACA,UAAM,SAAS,MAAM,MAAM,IAAI,IAAI,YAAY,OAAO;AACtD,QAAI,WAAW,MAAM;AACnB,aAAO,yBAAyB,KAAK,MAAM,QAAQ,IAAI,MAAM,KAAK,aAAa,MAAM;AAAA,IACvF;AACA,UAAM,KAAK,oBAAoB,GAAG;AAClC,UAAM,EAAE,YAAY,UAAU,IAAI,MAAM,KAAK,WAAW,GAAG;AAC3D,UAAM,WAAW,MAAM,iBAAiB,IAAI,MAAM,KAAK,aAAa,WAAW,UAAU;AAEzF,QAAI;AACJ,QAAI;AACF,sBAAgB,MAAM,MAAM,IAAI,IAAI,YAAY,SAAS,QAAQ;AAAA,IACnE,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAGA,WAAO,yBAAyB,KAAK,MAAM,eAAe,IAAI,MAAM,KAAK,aAAa,MAAM;AAAA,EAC9F;AAAA;AAAA,EAGA,MAAc,WAAW,KAA8E;AACrG,UAAM,SAAS,IAAI,MAAM,KAAK;AAC9B,UAAM,aAAa,MAAM,+BAA+B,OAAO,QAAQ,KAAK,KAAK,cAAc;AAC/F,UAAM,WAAW,MAAM,kBAAkB,gBAAgB,QAAQ,UAAU;AAC3E,UAAM,YAAY,MAAM,KAAK,oBAAoB,UAAU,QAAQ,qBAAqB,mBAAmB,IAAI,OAAO;AACtH,UAAM,gBAAgB,MAAM,OAAO,uBAAuB,KAAK,KAAK,WAAW,KAAK,KAAK,mBAAmB,KAAK,KAAK,4BAA4B,SAAS;AAC3J,UAAM,aAAa,MAAM,IAAI,OAAO,MAAM,SAAS,SAAS,eAAe,KAAK,KAAK,mBAAmB;AACxG,WAAO,EAAE,YAAY,UAAU;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,oBAAoB,KAAkC;AAIlE,UAAM,QAAQ;AAAA,MACZ,IAAI,MAAM,OAAO,IAAI,OAAO,QAAQ;AAClC,cAAM,OAAO,MAAM,IAAI,YAAY,OAAO;AAC1C,cAAM,QAAQ,MAAM,gBAAgB,OAAO,IAAI,WAAW,IAAI,WAAW;AAAA,UACvE;AAAA,UACA,WAAW,IAAI;AAAA,UACf,MAAM,IAAI;AAAA,UACV,eAAe;AAAA,QACjB,CAAC;AACD,cAAM,WAAW,MAAM,KAAK,KAAK,OAAO,kBAAkB,MAAM,QAAQ,gBAAgB,KAAK,CAAC;AAG9F,YAAI,SAAS,mBAAmB,MAAM;AACpC,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA,EAGA,MAAc,gBACZ,YACA,YACA,SACsB;AACtB,UAAM,OAAO,MAAM,WAAW,YAAY,OAAO;AACjD,UAAM,gBAAgB,uBAAuB,OAAO,YAAY,WAAW,MAAM,EAAE,OAAO;AAC1F,UAAM,SAAS,MAAM,gBAAgB,OAAO,WAAW,WAAW,WAAW,WAAW;AAAA,MACtF;AAAA,MACA,WAAW,WAAW;AAAA,MACtB,MAAM,WAAW;AAAA,MACjB;AAAA,IACF,CAAC;AACD,UAAM,WAAW,MAAM,kBAAkB,oBAAoB,MAAM;AACnE,UAAM,QAAQ,MAAM,KAAK,mBAAmB,UAAU,QAAQ,OAAO;AACrE,UAAM,YAAY,MAAM,OAAO,uBAAuB,KAAK,KAAK,WAAW,KAAK,KAAK,mBAAmB,KAAK,KAAK,4BAA4B,KAAK;AACnJ,UAAM,QAAQ,MAAM,MAAM,KAAK,WAAW,KAAK,KAAK,mBAAmB;AACvE,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,mBACZ,UACA,QACA,SACyB;AACzB,QAAI;AACF,aAAO,MAAM,KAAK,oBAAoB,UAAU,QAAQ,qBAAqB,oBAAoB,OAAO;AAAA,IAC1G,SAAS,KAAK;AACZ,UAAI,eAAe,uBAAuB;AACxC,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA,EAIA,MAAa,OAAO,OAAoB,UAAyD;AAG/F,UAAM,SAAS,KAAK,KAAK,gBACrB,MAAM,KAAK,KAAK,cAAc,OAAO,MAAM,UAAU,KAAK,KAAK,mBAAmB,IAClF,MAAM,MAAM,SAAS,OAAO,KAAK,KAAK,mBAAmB;AAC7D,WAAO,OAAO,WAAW,mBAAmB,KAAK,EAAE,IAAI,KAAK,IAAI,EAAE,IAAI,OAAO,QAAQ,OAAO,OAAO,MAAM,EAAE;AAAA,EAC7G;AAAA,EAEO,UAAU,OAAoB,QAA6B;AAChE,UAAM,QAAQ,MAAM,SAAS,kBAAkB;AAC/C,UAAM,UAAU,iBAAiB,cAAc,mBAAmB,OAAO,MAAM,CAAC;AAChF,WAAO,iBAAiB,OAAO,OAAO,OAAO;AAAA,EAC/C;AAAA,EAEA,MAAa,QAAQ,OAAoB,UAA8C;AAIrF,UAAM,QAAQ,MAAM,oBAAoB;AAAA,MACtC,MAAM;AAAA,MACN,mBAAmB,OAAO,KAAK,KAAK,eAAe,SAAS;AAAA,MAC5D,UAAU,UAAU,IAAI,WAAW,EAAE,CAAC;AAAA,IACxC;AACA,UAAM,UAAU,MAAM,QAAQ,gBAAgB,KAAK;AACnD,UAAM,WAAW,MAAM,KAAK,KAAK,OAAO,kBAAkB,OAAO;AAGjE,WAAO,SAAS,mBAAmB;AAAA,EACrC;AAAA;AAAA;AAAA,EAKO,aAAa,WAAwE;AAC1F,WAAO,mBAAmB,SAAS;AAAA,EACrC;AAAA,EAEO,YAAY,OAA+B;AAChD,WAAO,MAAM;AAAA,EACf;AAAA,EAEA,MAAa,YAAY,MAAuC;AAC9D,UAAM,WAAW,MAAM,MAAM,SAAS,KAAK,KAAK;AAChD,QAAI,SAAS,QAAQ,UAAU,OAAO,KAAK,KAAK,UAAU,IAAI;AAC5D,YAAM,IAAI;AAAA,QACR,+CAA+C,SAAS,QAAQ,UAAU,EAAE,eAC7D,KAAK,KAAK,UAAU,EAAE;AAAA,QACrC;AAAA,MACF;AAAA,IACF;AACA,WAAO,KAAK,UAAU,QAAQ;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYQ,eAAe,SAAmC;AACxD,UAAM,UAAU,SAAS,WAAW;AACpC,QAAI,CAAC,OAAO,UAAU,OAAO,KAAK,UAAU,GAAG;AAC7C,YAAM,IAAI,YAAY,+CAA+C,OAAO,OAAO,CAAC,IAAI,kBAAkB;AAAA,IAC5G;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,kBAAkB,SAAmC;AAC3D,UAAM,aAAa,SAAS,cAAc,WAAW;AACrD,QAAI,CAAC,eAAe,KAAK,UAAU,GAAG;AACpC,YAAM,IAAI;AAAA,QACR,8DAA8D,UAAU;AAAA,QACxE;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAc,oBACZ,mBACA,aACA,WACA,UACA,SACyB;AACzB,UAAM,WAAW;AAAA,MACf,KAAK;AAAA,MACL,SAAS;AAAA,MACT,GAAG,SAAS;AAAA,IACd;AACA,QAAI;AACF,aAAO,MAAM,KAAK,gBAAgB,mBAAmB,aAAa,WAAW,UAAU,SAAS,MAAM;AAAA,IACxG,UAAE;AACA,eAAS,QAAQ;AAAA,IACnB;AAAA,EACF;AAAA;AAAA;AAAA,EAIA,MAAc,gBACZ,mBACA,aACA,WACA,UACA,QACyB;AACzB,QAAI,cAAuB;AAK3B,QAAI,wBAAwB;AAC5B,QAAI;AACF,YAAM,EAAE,OAAO,UAAU,QAAQ,IAAI,MAAM;AAAA,QACzC,YAAY;AACV,gBAAM,SAAS,MAAM,KAAK,KAAK,OAAO,2BAA2B,iBAAiB;AAIlF,cAAI,OAAO,OAAO,MAAM,MAAM,OAAO,oBAAoB,iBAAiB,GAAG;AAC3E,kBAAM,IAAI,sBAAsB,OAAO,OAAO,MAAM,CAAC;AAAA,UACvD;AACA,iBAAO;AAAA,QACT;AAAA,QACA;AAAA,QACA,KAAK,KAAK,uBAAuB;AAAA,MACnC;AACA,UAAI,SAAS,WAAW,oBAAoB,SAAS;AACnD,sBAAc,IAAI,YAAY,GAAG,SAAS,KAAK,SAAS,MAAM,IAAI,QAAQ;AAC1E,gCAAwB,CAAC,WAAW,sBAAsB,IAAI,SAAS,MAAM;AAAA,MAC/E;AAAA,IACF,SAAS,KAAK;AACZ,oBAAc,OAAO,IAAI,YAAY,GAAG,SAAS,mBAAmB,QAAQ;AAAA,IAC9E;AAEA,QAAI;AACF,aAAO,MAAM;AAAA,QACX;AAAA,UACE,QAAQ,KAAK,KAAK;AAAA,UAClB,WAAW,KAAK,KAAK;AAAA,UACrB,mBAAmB,KAAK,KAAK;AAAA,UAC7B,4BAA4B,KAAK,KAAK;AAAA,UACtC,YAAY,KAAK,KAAK,uBAAuB;AAAA;AAAA,QAC/C;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,qBAAqB,KAAK,WAAW,aAAa,qBAAqB;AAAA,IAC/E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,YAAY,OAA0B;AAC5C,QAAI,CAAC,KAAK,UAAU,OAAO,KAAK,KAAK,eAAe,SAAS,GAAG;AAC9D,YAAM,IAAI,YAAY,6DAA6D,kBAAkB;AAAA,IACvG;AAAA,EACF;AAAA;AAAA,EAGQ,UAAU,UAA8B;AAC9C,UAAM,OAAO,SAAS,QAAQ;AAC9B,QAAI,QAA4B;AAGhC,QAAI,QAAQ,KAAK,oBAAoB,IAAI,GAAG;AAC1C,UAAI;AACF,gBAAQ,kBAAkB,SAAS,IAAI,EAAE,QAAQ;AAAA,MACnD,SAAS,KAAK;AACZ,cAAM,IAAI;AAAA,UACR,wCAAwC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,UACxF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,UAAM,OAAkB;AAAA,MACtB,SAAS,aAAa,OAAO,SAAS,GAAG,KAAK;AAAA,MAC9C,OAAO,SAAS,OAAO;AAAA,IACzB;AACA,WAAO,EAAE,UAAU,MAAM,MAAM;AAAA,EACjC;AAAA;AAAA,EAGQ,oBAAoB,MAA2B;AACrD,QAAI;AACF,aAAO,iBAAiB,UAAU,IAAI,EAAE,QAAQ,kBAAkB;AAAA,IACpE,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAKO,UAAgB;AACrB,SAAK,KAAK,eAAe,QAAQ;AAAA,EACnC;AAEF;;;ACvvBA,IAAM,iCAAiC;AAQvC,IAAM,gCAAN,cAA4C,oBAAoB;AAAA,EACvD,YACY,OACjB,UACA;AACA,UAAM,QAAQ;AAHG;AAAA,EAInB;AAAA,EAEU,eAAwB;AAChC,WAAO,KAAK,MAAM;AAAA,EACpB;AACF;AAGO,SAAS,0BAA0B,QAA2D;AACnG,QAAM,WAAW,OAAO,YAAY;AACpC,MAAI,CAAC,OAAO,UAAU,QAAQ,KAAK,WAAW,GAAG;AAC/C,UAAM,IAAI,UAAU,yDAAyD,OAAO,OAAO,QAAQ,CAAC,EAAE;AAAA,EACxG;AACA,SAAO,IAAI,8BAA8B,OAAO,cAAc,QAAQ;AACxE;AAEA,eAAsB,wBAAwB,QAA6C;AACzF,MAAI,OAAO,iBAAiB,MAAM;AAChC,UAAM,IAAI,YAAY,uDAAuD,gBAAgB;AAAA,EAC/F;AAEA,MAAI,CAAC,OAAO,QAAQ;AAClB,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,YAAY,cAAc,SAAS,OAAO,aAAa;AAC7D,QAAM,oBAAoB,yBAAyB,OAAO;AAI1D,QAAM,6BAA6B,IAAI;AAAA,IACrC,IAAI,4CAA4C,IAAI,2BAA2B,GAAG,IAAI,kBAAkB,GAAG,CAAC;AAAA,EAC9G;AACA,QAAM,4BAA4B,IAAI,iCAAiC;AACvE,4BAA0B;AAAA,IACtB,IAAI,+BAA+B,uBAAuB;AAAA,EAC9D;AAEA,QAAM,OAAmB;AAAA,IACvB,QAAQ,IAAI,sBAAsB,IAAI,iBAAiB,OAAO,eAAe,OAAO,UAAU,IAAI,CAAC;AAAA,IACnG;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,qBAAqB,IAAI;AAAA,MACvB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,IAAI,6BAA6B,KAAK;AAAA,IACxC;AAAA,IACA,gBAAgB,IAAI,eAAe,OAAO,UAAU;AAAA;AAAA;AAAA,IAGpD,YAAY,OAAO;AAAA;AAAA;AAAA,IAGnB,WAAW,UAAU;AAAA;AAAA,IAErB,qBAAqB,OAAO;AAAA,IAC5B,gBAAgB,OAAO;AAAA;AAAA;AAAA,IAEvB,GAAI,OAAO,eAAe,EAAE,eAAe,0BAA0B,OAAO,YAAY,EAAE,IAAI,CAAC;AAAA,EACjG;AAEA,SAAO,IAAI,kBAAkB,IAAI;AACnC;","names":["sha256","sha256","sha256"]}
|
|
1
|
+
{"version":3,"sources":["../../token-engine/sdk.ts","../../token-engine/identity.ts","../../core/errors.ts","../../core/logger.ts","../../token-engine/SpherePaymentData.ts","../../token-engine/proof-wait.ts","../../token-engine/errors.ts","../../token-engine/certification-outcome.ts","../../core/uuid.ts","../../token-engine/blob-keys.ts","../../node_modules/@noble/hashes/src/utils.ts","../../node_modules/@noble/hashes/src/hmac.ts","../../node_modules/@noble/hashes/src/hkdf.ts","../../node_modules/@noble/hashes/src/_md.ts","../../node_modules/@noble/hashes/src/sha2.ts","../../token-engine/realization.ts","../../token-engine/split-checkpoint.ts","../../token-engine/SphereTokenEngine.ts","../../token-engine/factory.ts"],"sourcesContent":["/**\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\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 * token-engine/identity.ts — legacy `DIRECT://` identity address (Path A, A6).\n *\n * Reproduces the wallet's stable L3 identity address EXACTLY as the v1\n * `UnmaskedPredicateReference` → `DirectAddress` path did, but VENDORED (no v1 SDK\n * import) so the v1 dependency can be removed at the final cut-over. Quest XP is\n * keyed on this address, so it MUST stay byte-identical — the multi-vector\n * golden test (identity.test.ts) locks it.\n *\n * The recipe (recovered from v1 `UnmaskedPredicateReference.create` + `DirectAddress.create`):\n * ref = SHA-256( CBOR[ bstr([UNMASKED]), bstr(tokenType.toCBOR()),\n * tstr(\"secp256k1\"), uint(SHA256), bstr(publicKey) ] )\n * imprint = 0x0000 ‖ ref (SHA-256 DataHash imprint)\n * address = \"DIRECT://\" ‖ hex(imprint) ‖ hex( SHA-256(imprint)[0:4] )\n *\n * The CBOR + SHA-256 are standard, so v2's CborSerializer/DataHasher produce\n * byte-identical output; the v1 enum values (UNMASKED=0, HashAlgorithm.SHA256=0)\n * and the SHA-256 imprint prefix (0x0000) are pinned as constants.\n */\n\nimport { CborSerializer, DataHasher, HashAlgorithm, HexConverter } from './sdk';\n\n/**\n * Unicity L3 token type used for identity-address derivation (immutable).\n * Also pinned as the fixed token type of self-issued Unicity ID tokens\n * (token-engine/unicity-id.ts) — the same constant the v1 nametag mint used,\n * keeping the mint deterministic per (name, wallet key).\n */\nexport const UNICITY_TOKEN_TYPE_HEX = 'f8aa13834268d29355ff12183066f0cb902003629bbc5eb9ef0efbe397867509';\n/** v1 `SigningService.algorithm` for secp256k1. */\nconst SIGNING_ALGORITHM = 'secp256k1';\n/** v1 `EmbeddedPredicateType.UNMASKED`. */\nconst EMBEDDED_PREDICATE_UNMASKED = 0;\n/** v1 `HashAlgorithm.SHA256` (as encoded in the reference CBOR). */\nconst HASH_ALGORITHM_SHA256 = 0n;\n/** v1 SHA-256 `DataHash` imprint algorithm tag (2-byte big-endian). */\nconst SHA256_IMPRINT_PREFIX = new Uint8Array([0x00, 0x00]);\n\nfunction hexToBytes(hex: string): Uint8Array {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\nfunction sha256(data: Uint8Array): Promise<Uint8Array> {\n return new DataHasher(HashAlgorithm.SHA256)\n .update(data)\n .digest()\n .then((h) => h.data);\n}\n\n/**\n * Derive the legacy `DIRECT://` identity address for a compressed (33-byte)\n * secp256k1 public key. Deterministic; byte-identical to the v1 path (Path A).\n */\nexport async function deriveDirectAddress(publicKey: Uint8Array): Promise<string> {\n const tokenTypeCbor = CborSerializer.encodeByteString(hexToBytes(UNICITY_TOKEN_TYPE_HEX)); // v1 TokenType.toCBOR()\n const reference = CborSerializer.encodeArray(\n CborSerializer.encodeByteString(new Uint8Array([EMBEDDED_PREDICATE_UNMASKED])),\n CborSerializer.encodeByteString(tokenTypeCbor),\n CborSerializer.encodeTextString(SIGNING_ALGORITHM),\n CborSerializer.encodeUnsignedInteger(HASH_ALGORITHM_SHA256),\n CborSerializer.encodeByteString(publicKey),\n );\n\n const refHash = await sha256(reference);\n const imprint = new Uint8Array([...SHA256_IMPRINT_PREFIX, ...refHash]);\n const checksum = (await sha256(imprint)).slice(0, 4);\n\n return `DIRECT://${HexConverter.encode(imprint)}${HexConverter.encode(checksum)}`;\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 * Centralized SDK Logger\n *\n * A lightweight singleton logger that works across all tsup bundles\n * by storing state on globalThis. Supports three log levels:\n * - debug: detailed messages (only shown when debug=true)\n * - warn: important warnings (ALWAYS shown regardless of debug flag)\n * - error: critical errors (ALWAYS shown regardless of debug flag)\n *\n * Global debug flag enables all logging. Per-tag overrides allow\n * granular control (e.g., only transport debug).\n *\n * @example\n * ```ts\n * import { logger } from '@unicitylabs/sphere-sdk';\n *\n * // Enable all debug logging\n * logger.configure({ debug: true });\n *\n * // Enable only specific tags\n * logger.setTagDebug('Nostr', true);\n *\n * // Usage in SDK classes\n * logger.debug('Payments', 'Transfer started', { amount, recipient });\n * logger.warn('Nostr', 'queryEvents timed out after 5s');\n * logger.error('Sphere', 'Critical failure', error);\n * ```\n */\n\nexport type LogLevel = 'debug' | 'warn' | 'error';\n\nexport type LogHandler = (level: LogLevel, tag: string, message: string, ...args: unknown[]) => void;\n\nexport interface LoggerConfig {\n /** Enable debug logging globally (default: false). When false, only warn and error messages are shown. */\n debug?: boolean;\n /** Custom log handler. If provided, replaces console output. Useful for tests or custom log sinks. */\n handler?: LogHandler | null;\n}\n\n// Use a unique symbol-like key on globalThis to share logger state across tsup bundles\nconst LOGGER_KEY = '__sphere_sdk_logger__';\n\ninterface LoggerState {\n debug: boolean;\n tags: Record<string, boolean>;\n handler: LogHandler | null;\n}\n\nfunction getState(): LoggerState {\n const g = globalThis as unknown as Record<string, unknown>;\n if (!g[LOGGER_KEY]) {\n g[LOGGER_KEY] = { debug: false, tags: {}, handler: null } satisfies LoggerState;\n }\n return g[LOGGER_KEY] as LoggerState;\n}\n\nfunction isEnabled(tag: string): boolean {\n const state = getState();\n // Per-tag override takes priority\n if (tag in state.tags) return state.tags[tag];\n // Fall back to global flag\n return state.debug;\n}\n\nexport const logger = {\n /**\n * Configure the logger. Can be called multiple times (last write wins).\n * Typically called by createBrowserProviders(), createNodeProviders(), or Sphere.init().\n */\n configure(config: LoggerConfig): void {\n const state = getState();\n if (config.debug !== undefined) state.debug = config.debug;\n if (config.handler !== undefined) state.handler = config.handler;\n },\n\n /**\n * Enable/disable debug logging for a specific tag.\n * Per-tag setting overrides the global debug flag.\n *\n * @example\n * ```ts\n * logger.setTagDebug('Nostr', true); // enable only Nostr logs\n * logger.setTagDebug('Nostr', false); // disable Nostr logs even if global debug=true\n * ```\n */\n setTagDebug(tag: string, enabled: boolean): void {\n getState().tags[tag] = enabled;\n },\n\n /**\n * Clear per-tag override, falling back to global debug flag.\n */\n clearTagDebug(tag: string): void {\n delete getState().tags[tag];\n },\n\n /** Returns true if debug mode is enabled for the given tag (or globally). */\n isDebugEnabled(tag?: string): boolean {\n if (tag) return isEnabled(tag);\n return getState().debug;\n },\n\n /**\n * Debug-level log. Only shown when debug is enabled (globally or for this tag).\n * Use for detailed operational information.\n */\n debug(tag: string, message: string, ...args: unknown[]): void {\n if (!isEnabled(tag)) return;\n const state = getState();\n if (state.handler) {\n state.handler('debug', tag, message, ...args);\n } else {\n console.log(`[${tag}]`, message, ...args);\n }\n },\n\n /**\n * Warning-level log. ALWAYS shown regardless of debug flag.\n * Use for important but non-critical issues (timeouts, retries, degraded state).\n */\n warn(tag: string, message: string, ...args: unknown[]): void {\n const state = getState();\n if (state.handler) {\n state.handler('warn', tag, message, ...args);\n } else {\n console.warn(`[${tag}]`, message, ...args);\n }\n },\n\n /**\n * Error-level log. ALWAYS shown regardless of debug flag.\n * Use for critical failures that should never be silenced.\n */\n error(tag: string, message: string, ...args: unknown[]): void {\n const state = getState();\n if (state.handler) {\n state.handler('error', tag, message, ...args);\n } else {\n console.error(`[${tag}]`, message, ...args);\n }\n },\n\n /** Reset all logger state (debug flag, tags, handler). Primarily for tests. */\n reset(): void {\n const g = globalThis as unknown as Record<string, unknown>;\n delete g[LOGGER_KEY];\n },\n};\n","/**\n * token-engine/SpherePaymentData.ts — the sphere value model.\n *\n * v2 `Token` carries no coins; value is app-defined and stored in\n * `MintTransaction.data`. `SpherePaymentData` is that payload: it implements the\n * SDK's `IPaymentData` (so `TokenSplit` can read it for value conservation) and\n * encodes a `PaymentAssetCollection` inside a versioned, tagged CBOR envelope.\n *\n * The SDK never inspects our raw bytes — it only calls `decodePaymentData(data)`\n * and reads `.assets` — so the envelope (tag + version) is ours, chosen for\n * forward-compatible storage. `fromValue`/`toValue` bridge sphere-domain values\n * (hex coin id + bigint amount) to/from the SDK asset collection.\n */\n\nimport {\n Asset,\n AssetId,\n CborDeserializer,\n CborError,\n CborSerializer,\n HexConverter,\n type IPaymentData,\n PaymentAssetCollection,\n} from './sdk';\nimport type { CoinId, SphereValue } from './types';\nimport { SphereError } from '../core/errors';\n\n/** Canonical coin id: non-empty, even-length lowercase hex (the form `toValue` emits). */\nconst COIN_ID_PATTERN = /^([0-9a-f]{2})+$/;\n\n/** Guard a sphere-domain asset before it crosses into the SDK value model. */\nfunction assertAsset(coinId: CoinId, amount: bigint): void {\n if (!COIN_ID_PATTERN.test(coinId)) {\n throw new SphereError(`Invalid coin id (expected even-length lowercase hex): \"${coinId}\"`, 'VALIDATION_ERROR');\n }\n if (amount <= 0n) {\n // The 2.0.0 SDK requires a strictly positive 256-bit asset value; reject\n // here with the typed sphere error before the raw SDK throw.\n throw new SphereError(`Asset amount must be positive: ${amount.toString()}`, 'VALIDATION_ERROR');\n }\n}\n\n/** Validate a sphere-domain asset and build the SDK Asset — the single validation point. */\nexport function sphereAssetToSdk(coinId: CoinId, amount: bigint): Asset {\n assertAsset(coinId, amount);\n return new Asset(new AssetId(HexConverter.decode(coinId)), amount);\n}\n\nexport class SpherePaymentData implements IPaymentData {\n /** Sphere-private CBOR tag (verified free in the v2 SDK tag space). */\n public static readonly CBOR_TAG = 39050n;\n /** Envelope version; bump when the structure changes. */\n public static readonly VERSION = 1n;\n\n private constructor(\n public readonly assets: PaymentAssetCollection,\n private readonly _memo: Uint8Array | null = null,\n ) {}\n\n /** Opaque, app-defined memo carried alongside the value (e.g. invoice attribution). */\n public get memo(): Uint8Array | null {\n return this._memo ? new Uint8Array(this._memo) : null;\n }\n\n /** Wrap an existing SDK asset collection (+ optional opaque memo). */\n public static create(assets: PaymentAssetCollection, memo: Uint8Array | null = null): SpherePaymentData {\n return new SpherePaymentData(assets, memo);\n }\n\n /** Build from a sphere-domain value (hex coin id → bigint amount) + optional opaque memo. */\n public static fromValue(value: SphereValue, memo: Uint8Array | null = null): SpherePaymentData {\n if (value.assets.length === 0) {\n throw new SphereError('SpherePaymentData requires at least one asset', 'VALIDATION_ERROR');\n }\n const assets = value.assets.map((a) => sphereAssetToSdk(a.coinId, a.amount));\n return new SpherePaymentData(PaymentAssetCollection.create(...assets), memo);\n }\n\n /** Decode from the CBOR envelope produced by {@link encode}. */\n public static fromCBOR(bytes: Uint8Array): SpherePaymentData {\n const tag = CborDeserializer.decodeTag(bytes);\n if (tag.tag !== SpherePaymentData.CBOR_TAG) {\n throw new CborError(`Invalid SpherePaymentData tag: ${tag.tag}`);\n }\n // Strict structure: exactly [version, assets, memo] (matches encode + the SDK's\n // fixed-shape decoders). Extra/missing fields are corruption, not tolerated.\n const fields = CborDeserializer.decodeArray(tag.data, 3);\n const version = CborDeserializer.decodeUnsignedInteger(fields[0]);\n if (version !== SpherePaymentData.VERSION) {\n throw new CborError(`Unsupported SpherePaymentData version: ${version}`);\n }\n const memo = CborDeserializer.decodeNullable(fields[2], CborDeserializer.decodeByteString);\n return new SpherePaymentData(PaymentAssetCollection.fromCBOR(fields[1]), memo);\n }\n\n /** Deterministic, versioned, tagged CBOR: `tag(39050)[ version, assets, memo? ]`. */\n public encode(): Promise<Uint8Array> {\n return Promise.resolve(\n CborSerializer.encodeTag(\n SpherePaymentData.CBOR_TAG,\n CborSerializer.encodeArray(\n CborSerializer.encodeUnsignedInteger(SpherePaymentData.VERSION),\n this.assets.toCBOR(),\n CborSerializer.encodeNullable(this._memo, CborSerializer.encodeByteString),\n ),\n ),\n );\n }\n\n /** Project to a sphere-domain value (hex coin id + bigint amount), preserving order. */\n public toValue(): SphereValue {\n return {\n assets: this.assets.toArray().map((a) => ({\n coinId: HexConverter.encode(a.id.bytes) as CoinId,\n amount: a.value,\n })),\n };\n }\n\n /** Balance of a single coin within this payload (0n when absent). */\n public balanceOf(coinId: CoinId): bigint {\n if (!COIN_ID_PATTERN.test(coinId)) {\n throw new SphereError(`Invalid coin id (expected even-length lowercase hex): \"${coinId}\"`, 'VALIDATION_ERROR');\n }\n const asset = this.assets.get(new AssetId(HexConverter.decode(coinId)));\n return asset ? asset.value : 0n;\n }\n}\n\n/**\n * Async payment-data decoder matching the SDK's `decodePaymentData` signature.\n * Used by `TokenSplit.split` (value conservation) and `SplitMintJustificationVerifier`.\n */\nexport function decodeSpherePaymentData(bytes: Uint8Array): Promise<IPaymentData> {\n return Promise.resolve(SpherePaymentData.fromCBOR(bytes));\n}\n","// One inclusion-proof wait: bounded by a deadline we own, and tolerant of a\n// gateway that blips (#739, #741). state-transition-sdk terminates its own poll\n// loop on abort since 2.0.3; proof-deadline.test.ts guards that it still does.\n\nimport {\n type InclusionProof,\n JsonRpcNetworkError,\n type PredicateVerifierService,\n type UnicityCertificateVerifier,\n type RootTrustBase,\n type StateTransitionClient,\n waitInclusionProof,\n} from './sdk';\nimport { SphereError } from '../core/errors';\n\nexport const DEFAULT_PROOF_TIMEOUT_MS = 10_000;\n\n/** Always bounded: an uncapped wait is the #739 hang, so there is no \"no cap\"\n * value — non-positive is refused, never read as forever or as zero delay. */\nexport function resolveProofTimeoutMs(configured: number | undefined): number {\n if (configured === undefined) return DEFAULT_PROOF_TIMEOUT_MS;\n if (!Number.isFinite(configured) || configured <= 0) {\n throw new SphereError(\n `proofTimeoutMs must be a positive number of milliseconds (got ${String(configured)}); ` +\n 'an unbounded inclusion-proof wait is not supported',\n 'INVALID_CONFIG'\n );\n }\n return configured;\n}\n\n/** \"Ask again\", not \"this certification failed\" — the loop itself tolerates only\n * 404, so without this one blip strands a certification that would land (#741). */\nconst TRANSIENT_HTTP_STATUSES = new Set([408, 425, 429, 500, 502, 503, 504]);\n\n/** A submit ANSWER meaning \"ask again\" — SERVICE_NOT_READY is a 503 in a 200 body. */\nexport class TransientSubmitAnswer extends Error {\n public constructor(public readonly status: string) {\n super(`gateway is not ready to certify yet (${status})`);\n this.name = 'TransientSubmitAnswer';\n }\n}\n\nfunction isTransientGatewayError(err: unknown): boolean {\n if (err instanceof TransientSubmitAnswer) return true;\n return err instanceof JsonRpcNetworkError && TRANSIENT_HTTP_STATUSES.has(err.status);\n}\n\n/** Resolves on elapse OR abort; the caller re-checks the signal. */\nfunction pause(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise<void>((resolve) => {\n const timer = setTimeout(resolve, ms);\n signal.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n resolve();\n },\n { once: true }\n );\n });\n}\n\n/**\n * Runs `attempt` until it succeeds, a non-transient error surfaces, or the\n * signal ends it. The metered call is the SUBMIT, so this policy has to be\n * reusable by both — a copy per call site is how the two drift.\n */\nexport async function retryTransient<T>(\n attempt: () => Promise<T>,\n signal: AbortSignal,\n intervalMs: number\n): Promise<{ value: T; retried: boolean }> {\n let retried = false;\n for (;;) {\n // `pause` resolves on abort too, so recheck before attempting (#747 review).\n if (signal.aborted) throw signal.reason as Error;\n try {\n return { value: await attempt(), retried };\n } catch (err) {\n // The deadline (or the caller) ended it: that outcome is final.\n if (signal.aborted) throw err;\n if (!isTransientGatewayError(err)) throw err;\n retried = true;\n await pause(intervalMs, signal);\n }\n }\n}\n\n/** A deadline for ONE certification attempt: submit retries and proof share it. */\nexport function certificationDeadline(\n timeoutMs: number,\n external: AbortSignal | undefined,\n label: string\n): { signal: AbortSignal; dispose: () => void } {\n const controller = new AbortController();\n const relayAbort = (): void => {\n controller.abort(external?.reason);\n };\n if (external !== undefined) {\n if (external.aborted) relayAbort();\n else external.addEventListener('abort', relayAbort, { once: true });\n }\n const timer = setTimeout(() => {\n controller.abort(new SphereError(`${label} within ${String(timeoutMs)} ms`, 'AGGREGATOR_ERROR'));\n }, timeoutMs);\n return {\n signal: controller.signal,\n dispose: () => {\n clearTimeout(timer);\n external?.removeEventListener('abort', relayAbort);\n },\n };\n}\n\nexport interface ProofWaitDeps {\n readonly client: StateTransitionClient;\n readonly trustBase: RootTrustBase;\n readonly predicateVerifier: PredicateVerifierService;\n readonly unicityCertificateVerifier: UnicityCertificateVerifier;\n readonly intervalMs: number;\n}\n\n/** Await one inclusion proof, always terminating; a deadline hit throws and the\n * caller maps it to ProofUnconfirmedError (keep-open — the spend may be on-chain). */\nexport async function awaitProofBounded(\n deps: ProofWaitDeps,\n transaction: Parameters<typeof waitInclusionProof>[4],\n signal: AbortSignal\n): Promise<InclusionProof> {\n const { value } = await retryTransient(\n () =>\n waitInclusionProof(\n deps.client,\n deps.trustBase,\n deps.predicateVerifier,\n deps.unicityCertificateVerifier,\n transaction,\n signal,\n deps.intervalMs\n ),\n signal,\n deps.intervalMs\n );\n return value;\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","import { InclusionProofVerificationStatus } from './sdk';\nimport { ProofUnconfirmedError, TransferConflictError } from './errors';\n\n/** What a failed certification means: lost race, proven-clean reject, or indeterminate. */\nexport function certificationFailure(\n err: unknown,\n failLabel: string,\n submitError: unknown,\n submitRejectedCleanly: boolean,\n): unknown {\n // The SDK reports a match-verify mismatch as a generic Error carrying the\n // status in its message; that fragile string is mapped HERE and nowhere else.\n if (\n err instanceof Error &&\n err.message === `Invalid inclusion proof status: ${InclusionProofVerificationStatus.TRANSACTION_HASH_MISMATCH}`\n ) {\n return new TransferConflictError(\n `${failLabel}: the source state was already consumed by a different transaction ` +\n '(lost race — abort this intent and re-plan under a new transferId)',\n err,\n );\n }\n if (submitRejectedCleanly) return submitError;\n return new ProofUnconfirmedError(\n `${failLabel}: certification unconfirmed — the source spend may be on-chain; ` +\n 'keep the intent open and resume under the same transferId',\n submitError ?? err,\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","/**\n * token-engine/blob-keys.ts — protocol-true delivery keys from TokenBlob bytes.\n *\n * The wallet-api backend keys mailbox entries on the SDK's PROTOCOL state hash\n * (`token.latestTransaction.calculateStateHash().imprint`, hex) — NOT a plain\n * sha256 over the token bytes (wallet-api src/validation/chain.ts; §8.2 step 4\n * validates a deposit's claimed stateHash against exactly this value, and\n * entry_id = SHA-256(tokenId ‖ stateHash) builds on it). Any client-side\n * delivery id or deposit claim MUST use this derivation; a bytes-hash variant\n * 422s on deposit and misses every entry on ack.\n *\n * Lives in token-engine because decoding requires the SDK (the one-import-point\n * rule, see ./sdk.ts).\n */\nimport { HexConverter, Token } from './sdk';\n\nexport interface DeliveryKeys {\n /** Genesis-stable 64-hex token id (TokenBlob.tokenId). */\n readonly tokenId: string;\n /** The SDK's per-state hash: hex of the DataHash imprint of the latest state. */\n readonly stateHash: string;\n}\n\n/**\n * Derive the backend-true (tokenId, stateHash) for a finished token blob.\n * The input is the raw wallet-api wire form — `Token.toCBOR()` bytes, what the\n * §16 API serves (§5.2/§8.2). Both keys come from the DECODED token, never\n * from a field alongside it, so they cannot disagree with the token itself.\n */\nexport async function deriveDeliveryKeys(blobBytes: Uint8Array): Promise<DeliveryKeys> {\n const token = await Token.fromCBOR(blobBytes);\n const stateHash = HexConverter.encode((await token.latestTransaction.calculateStateHash()).imprint);\n return { tokenId: HexConverter.encode(token.id.bytes), stateHash };\n}\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 * HMAC: RFC2104 message authentication code.\n * @module\n */\nimport {\n abytes,\n aexists,\n ahash,\n aoutput,\n clean,\n type CHash,\n type Hash,\n type TArg,\n type TRet,\n} from './utils.ts';\n\n/**\n * Internal class for HMAC.\n * Accepts any byte key, although RFC 2104 §3 recommends keys at least\n * `HashLen` bytes long.\n */\nexport class _HMAC<T extends Hash<T>> implements Hash<_HMAC<T>> {\n oHash: T;\n iHash: T;\n blockLen: number;\n outputLen: number;\n canXOF = false;\n private finished = false;\n private destroyed = false;\n\n constructor(hash: TArg<CHash>, key: TArg<Uint8Array>) {\n ahash(hash);\n abytes(key, undefined, 'key');\n this.iHash = hash.create() as T;\n if (typeof this.iHash.update !== 'function')\n throw new Error('Expected instance of class which extends utils.Hash');\n this.blockLen = this.iHash.blockLen;\n this.outputLen = this.iHash.outputLen;\n const blockLen = this.blockLen;\n const pad = new Uint8Array(blockLen);\n // blockLen can be bigger than outputLen\n pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);\n for (let i = 0; i < pad.length; i++) pad[i] ^= 0x36;\n this.iHash.update(pad);\n // By doing update (processing of the first block) of the outer hash here,\n // we can re-use it between multiple calls via clone.\n this.oHash = hash.create() as T;\n // Undo internal XOR && apply outer XOR\n for (let i = 0; i < pad.length; i++) pad[i] ^= 0x36 ^ 0x5c;\n this.oHash.update(pad);\n clean(pad);\n }\n update(buf: TArg<Uint8Array>): this {\n aexists(this);\n this.iHash.update(buf);\n return this;\n }\n digestInto(out: TArg<Uint8Array>): void {\n aexists(this);\n aoutput(out, this);\n this.finished = true;\n const buf = out.subarray(0, this.outputLen);\n // Reuse the first outputLen bytes for the inner digest; the outer hash consumes them before\n // overwriting that same prefix with the final tag, leaving any oversized tail untouched.\n this.iHash.digestInto(buf);\n this.oHash.update(buf);\n this.oHash.digestInto(buf);\n this.destroy();\n }\n digest(): TRet<Uint8Array> {\n const out = new Uint8Array(this.oHash.outputLen);\n this.digestInto(out);\n return out as TRet<Uint8Array>;\n }\n _cloneInto(to?: _HMAC<T>): _HMAC<T> {\n // Create new instance without calling constructor since the key\n // is already in state and we don't know it.\n to ||= Object.create(Object.getPrototypeOf(this), {});\n const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;\n to = to as this;\n to.finished = finished;\n to.destroyed = destroyed;\n to.blockLen = blockLen;\n to.outputLen = outputLen;\n to.oHash = oHash._cloneInto(to.oHash);\n to.iHash = iHash._cloneInto(to.iHash);\n return to;\n }\n clone(): _HMAC<T> {\n return this._cloneInto();\n }\n destroy(): void {\n this.destroyed = true;\n this.oHash.destroy();\n this.iHash.destroy();\n }\n}\n\n/**\n * HMAC: RFC2104 message authentication code.\n * @param hash - function that would be used e.g. sha256\n * @param key - authentication key bytes\n * @param message - message bytes to authenticate\n * @returns Authentication tag bytes.\n * @example\n * Compute an RFC 2104 HMAC.\n * ```ts\n * import { hmac } from '@noble/hashes/hmac.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * const mac = hmac(sha256, new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6]));\n * ```\n */\ntype HmacFn = {\n (hash: TArg<CHash>, key: TArg<Uint8Array>, message: TArg<Uint8Array>): TRet<Uint8Array>;\n create(hash: TArg<CHash>, key: TArg<Uint8Array>): TRet<_HMAC<any>>;\n};\nexport const hmac: TRet<HmacFn> = /* @__PURE__ */ (() => {\n const hmac_ = ((\n hash: TArg<CHash>,\n key: TArg<Uint8Array>,\n message: TArg<Uint8Array>\n ): TRet<Uint8Array> => new _HMAC<any>(hash, key).update(message).digest()) as TRet<HmacFn>;\n hmac_.create = (hash: TArg<CHash>, key: TArg<Uint8Array>): TRet<_HMAC<any>> =>\n new _HMAC<any>(hash, key) as TRet<_HMAC<any>>;\n return hmac_;\n})();\n","/**\n * HKDF (RFC 5869): extract + expand in one step.\n * See {@link https://soatok.blog/2021/11/17/understanding-hkdf/}.\n * @module\n */\nimport { hmac } from './hmac.ts';\nimport { abytes, ahash, anumber, type CHash, clean, type TArg, type TRet } from './utils.ts';\n\n/**\n * HKDF-extract from spec. Less important part. `HKDF-Extract(IKM, salt) -> PRK`\n * Arguments position differs from spec (IKM is first one, since it is not optional)\n * Local validation only checks `hash`; `ikm` / `salt` byte validation is delegated to `hmac()`.\n * @param hash - hash function that would be used (e.g. sha256)\n * @param ikm - input keying material, the initial key\n * @param salt - optional salt value (a non-secret random value)\n * @returns Pseudorandom key derived from input keying material.\n * @example\n * Run the HKDF extract step.\n * ```ts\n * import { extract } from '@noble/hashes/hkdf.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * extract(sha256, new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6]));\n * ```\n */\nexport function extract(\n hash: TArg<CHash>,\n ikm: TArg<Uint8Array>,\n salt?: TArg<Uint8Array>\n): TRet<Uint8Array> {\n ahash(hash);\n // NOTE: some libraries treat zero-length array as 'not provided';\n // we don't, since we have undefined as 'not provided'\n // https://github.com/RustCrypto/KDFs/issues/15\n if (salt === undefined) salt = new Uint8Array(hash.outputLen);\n return hmac(hash, salt, ikm);\n}\n\n// Shared mutable scratch byte for the RFC 5869 block counter `N`.\n// Safe to reuse because `expand()` is synchronous and resets it with `clean(...)` before returning.\nconst HKDF_COUNTER = /* @__PURE__ */ Uint8Array.of(0);\n// Shared RFC 5869 empty string for both `info === undefined` and the first-block `T(0)` input.\nconst EMPTY_BUFFER = /* @__PURE__ */ Uint8Array.of();\n\n/**\n * HKDF-expand from the spec. The most important part. `HKDF-Expand(PRK, info, L) -> OKM`\n * @param hash - hash function that would be used (e.g. sha256)\n * @param prk - a pseudorandom key of at least HashLen octets\n * (usually, the output from the extract step)\n * @param info - optional context and application specific information (can be a zero-length string)\n * @param length - length of output keying material in bytes.\n * RFC 5869 §2.3 allows `0..255*HashLen`, so `0` returns an empty OKM.\n * @returns Output keying material with the requested length.\n * @throws If the requested output length exceeds the HKDF limit\n * for the selected hash. {@link Error}\n * @example\n * Run the HKDF expand step.\n * ```ts\n * import { expand } from '@noble/hashes/hkdf.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * expand(sha256, new Uint8Array(32), new Uint8Array([1, 2, 3]), 16);\n * ```\n */\nexport function expand(\n hash: TArg<CHash>,\n prk: TArg<Uint8Array>,\n info?: TArg<Uint8Array>,\n length: number = 32\n): TRet<Uint8Array> {\n ahash(hash);\n anumber(length, 'length');\n abytes(prk, undefined, 'prk');\n const olen = hash.outputLen;\n // RFC 5869 §2.3: PRK is \"a pseudorandom key of at least HashLen octets\".\n if (prk.length < olen) throw new Error('\"prk\" must be at least HashLen octets');\n // RFC 5869 §2.3 only bounds `L` by `<= 255*HashLen`; `L=0` is valid and yields empty OKM.\n if (length > 255 * olen) throw new Error('Length must be <= 255*HashLen');\n const blocks = Math.ceil(length / olen);\n if (info === undefined) info = EMPTY_BUFFER;\n else abytes(info, undefined, 'info');\n // first L(ength) octets of T\n const okm = new Uint8Array(blocks * olen);\n // Re-use HMAC instance between blocks\n const HMAC = hmac.create(hash, prk);\n const HMACTmp = HMAC._cloneInto();\n const T = new Uint8Array(HMAC.outputLen);\n for (let counter = 0; counter < blocks; counter++) {\n HKDF_COUNTER[0] = counter + 1;\n // T(0) = empty string (zero length)\n // T(N) = HMAC-Hash(PRK, T(N-1) | info | N)\n HMACTmp.update(counter === 0 ? EMPTY_BUFFER : T)\n .update(info)\n .update(HKDF_COUNTER)\n .digestInto(T);\n okm.set(T, olen * counter);\n HMAC._cloneInto(HMACTmp);\n }\n HMAC.destroy();\n HMACTmp.destroy();\n clean(T, HKDF_COUNTER);\n return okm.slice(0, length) as TRet<Uint8Array>;\n}\n\n/**\n * HKDF (RFC 5869): derive keys from an initial input.\n * Combines hkdf_extract + hkdf_expand in one step\n * @param hash - hash function that would be used (e.g. sha256)\n * @param ikm - input keying material, the initial key\n * @param salt - optional salt value (a non-secret random value)\n * @param info - optional context and application specific information bytes\n * @param length - length of output keying material in bytes.\n * RFC 5869 §2.3 allows `0..255*HashLen`, so `0` returns an empty OKM.\n * @returns Output keying material derived from the input key.\n * @throws If the requested output length exceeds the HKDF limit\n * for the selected hash. {@link Error}\n * @example\n * HKDF (RFC 5869): derive keys from an initial input.\n * ```ts\n * import { hkdf } from '@noble/hashes/hkdf.js';\n * import { sha256 } from '@noble/hashes/sha2.js';\n * import { randomBytes, utf8ToBytes } from '@noble/hashes/utils.js';\n * const inputKey = randomBytes(32);\n * const salt = randomBytes(32);\n * const info = utf8ToBytes('application-key');\n * const okm = hkdf(sha256, inputKey, salt, info, 32);\n * ```\n */\nexport const hkdf = (\n hash: TArg<CHash>,\n ikm: TArg<Uint8Array>,\n salt: TArg<Uint8Array | undefined>,\n info: TArg<Uint8Array | undefined>,\n length: number\n): TRet<Uint8Array> => expand(hash, extract(hash, ikm, salt), info, length);\n","/**\n * Internal Merkle-Damgard hash utils.\n * @module\n */\nimport {\n abytes,\n aexists,\n aoutput,\n clean,\n createView,\n type Hash,\n type TArg,\n type TRet,\n} from './utils.ts';\n\n/**\n * Shared 32-bit conditional boolean primitive reused by SHA-256, SHA-1, and MD5 `F`.\n * Returns bits from `b` when `a` is set, otherwise from `c`.\n * The XOR form is equivalent to MD5's `F(X,Y,Z) = XY v not(X)Z` because the masked terms never\n * set the same bit.\n * @param a - selector word\n * @param b - word chosen when selector bit is set\n * @param c - word chosen when selector bit is clear\n * @returns Mixed 32-bit word.\n * @example\n * Combine three words with the shared 32-bit choice primitive.\n * ```ts\n * Chi(0xffffffff, 0x12345678, 0x87654321);\n * ```\n */\nexport function Chi(a: number, b: number, c: number): number {\n return (a & b) ^ (~a & c);\n}\n\n/**\n * Shared 32-bit majority primitive reused by SHA-256 and SHA-1.\n * Returns bits shared by at least two inputs.\n * @param a - first input word\n * @param b - second input word\n * @param c - third input word\n * @returns Mixed 32-bit word.\n * @example\n * Combine three words with the shared 32-bit majority primitive.\n * ```ts\n * Maj(0xffffffff, 0x12345678, 0x87654321);\n * ```\n */\nexport function Maj(a: number, b: number, c: number): number {\n return (a & b) ^ (a & c) ^ (b & c);\n}\n\n/**\n * Merkle-Damgard hash construction base class.\n * Could be used to create MD5, RIPEMD, SHA1, SHA2.\n * Accepts only byte-aligned `Uint8Array` input, even when the underlying spec describes bit\n * strings with partial-byte tails.\n * @param blockLen - internal block size in bytes\n * @param outputLen - digest size in bytes\n * @param padOffset - trailing length field size in bytes\n * @param isLE - whether length and state words are encoded in little-endian\n * @example\n * Use a concrete subclass to get the shared Merkle-Damgard update/digest flow.\n * ```ts\n * import { _SHA1 } from '@noble/hashes/legacy.js';\n * const hash = new _SHA1();\n * hash.update(new Uint8Array([97, 98, 99]));\n * hash.digest();\n * ```\n */\nexport abstract class HashMD<T extends HashMD<T>> implements Hash<T> {\n // Subclasses must treat `buf` as read-only: `update()` may pass a direct view over caller input\n // when it can process whole blocks without buffering first.\n protected abstract process(buf: DataView, offset: number): void;\n protected abstract get(): number[];\n protected abstract set(...args: number[]): void;\n abstract destroy(): void;\n protected abstract roundClean(): void;\n\n readonly blockLen: number;\n readonly outputLen: number;\n readonly canXOF = false;\n readonly padOffset: number;\n readonly isLE: boolean;\n\n // For partial updates less than block size\n protected buffer: Uint8Array;\n protected view: DataView;\n protected finished = false;\n protected length = 0;\n protected pos = 0;\n protected destroyed = false;\n\n constructor(blockLen: number, outputLen: number, padOffset: number, isLE: boolean) {\n this.blockLen = blockLen;\n this.outputLen = outputLen;\n this.padOffset = padOffset;\n this.isLE = isLE;\n this.buffer = new Uint8Array(blockLen);\n this.view = createView(this.buffer);\n }\n update(data: TArg<Uint8Array>): this {\n aexists(this);\n abytes(data);\n const { view, buffer, blockLen } = this;\n const len = data.length;\n for (let pos = 0; pos < len; ) {\n const take = Math.min(blockLen - this.pos, len - pos);\n // Fast path only when there is no buffered partial block: `take === blockLen` implies\n // `this.pos === 0`, so we can process full blocks directly from the input view.\n if (take === blockLen) {\n const dataView = createView(data);\n for (; blockLen <= len - pos; pos += blockLen) this.process(dataView, pos);\n continue;\n }\n buffer.set(data.subarray(pos, pos + take), this.pos);\n this.pos += take;\n pos += take;\n if (this.pos === blockLen) {\n this.process(view, 0);\n this.pos = 0;\n }\n }\n this.length += data.length;\n this.roundClean();\n return this;\n }\n digestInto(out: TArg<Uint8Array>): void {\n aexists(this);\n aoutput(out, this);\n this.finished = true;\n // Padding\n // We can avoid allocation of buffer for padding completely if it\n // was previously not allocated here. But it won't change performance.\n const { buffer, view, blockLen, isLE } = this;\n let { pos } = this;\n // append the bit '1' to the message\n buffer[pos++] = 0b10000000;\n clean(this.buffer.subarray(pos));\n // we have less than padOffset left in buffer, so we cannot put length in\n // current block, need process it and pad again\n if (this.padOffset > blockLen - pos) {\n this.process(view, 0);\n pos = 0;\n }\n // Pad until full block byte with zeros\n for (let i = pos; i < blockLen; i++) buffer[i] = 0;\n // `padOffset` reserves the whole length field. For SHA-384/512 the high 64 bits stay zero from\n // the padding fill above, and JS will overflow before user input can make that half non-zero.\n // So we only need to write the low 64 bits here.\n view.setBigUint64(blockLen - 8, BigInt(this.length * 8), isLE);\n this.process(view, 0);\n const oview = createView(out);\n const len = this.outputLen;\n // NOTE: we do division by 4 later, which must be fused in single op with modulo by JIT\n if (len % 4) throw new Error('_sha2: outputLen must be aligned to 32bit');\n const outLen = len / 4;\n const state = this.get();\n if (outLen > state.length) throw new Error('_sha2: outputLen bigger than state');\n for (let i = 0; i < outLen; i++) oview.setUint32(4 * i, state[i], isLE);\n }\n digest(): TRet<Uint8Array> {\n const { buffer, outputLen } = this;\n this.digestInto(buffer);\n // Copy before destroy(): subclasses wipe `buffer` during cleanup, but `digest()` must return\n // fresh bytes to the caller.\n const res = buffer.slice(0, outputLen);\n this.destroy();\n return res as TRet<Uint8Array>;\n }\n _cloneInto(to?: T): T {\n to ||= new (this.constructor as any)() as T;\n to.set(...this.get());\n const { blockLen, buffer, length, finished, destroyed, pos } = this;\n to.destroyed = destroyed;\n to.finished = finished;\n to.length = length;\n to.pos = pos;\n // Only partial-block bytes need copying: when `length % blockLen === 0`, `pos === 0` and\n // later `update()` / `digestInto()` overwrite `to.buffer` from the start before reading it.\n if (length % blockLen) to.buffer.set(buffer);\n return to as unknown as any;\n }\n clone(): T {\n return this._cloneInto();\n }\n}\n\n/**\n * Initial SHA-2 state: fractional parts of square roots of first 16 primes 2..53.\n * Check out `test/misc/sha2-gen-iv.js` for recomputation guide.\n */\n\n/** Initial SHA256 state from RFC 6234 §6.1: the first 32 bits of the fractional parts of the\n * square roots of the first eight prime numbers. Exported as a shared table; callers must treat\n * it as read-only because constructors copy words from it by index. */\nexport const SHA256_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n]);\n\n/** Initial SHA224 state `H(0)` from RFC 6234 §6.1. Exported as a shared table; callers must\n * treat it as read-only because constructors copy words from it by index. */\nexport const SHA224_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4,\n]);\n\n/** Initial SHA384 state from RFC 6234 §6.3: eight RFC 64-bit `H(0)` words stored as sixteen\n * big-endian 32-bit halves. Derived from the fractional parts of the square roots of the ninth\n * through sixteenth prime numbers. Exported as a shared table; callers must treat it as read-only\n * because constructors copy halves from it by index. */\nexport const SHA384_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0xcbbb9d5d, 0xc1059ed8, 0x629a292a, 0x367cd507, 0x9159015a, 0x3070dd17, 0x152fecd8, 0xf70e5939,\n 0x67332667, 0xffc00b31, 0x8eb44a87, 0x68581511, 0xdb0c2e0d, 0x64f98fa7, 0x47b5481d, 0xbefa4fa4,\n]);\n\n/** Initial SHA512 state from RFC 6234 §6.3: eight RFC 64-bit `H(0)` words stored as sixteen\n * big-endian 32-bit halves. Derived from the fractional parts of the square roots of the first\n * eight prime numbers. Exported as a shared table; callers must treat it as read-only because\n * constructors copy halves from it by index. */\nexport const SHA512_IV: TRet<Uint32Array> = /* @__PURE__ */ Uint32Array.from([\n 0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b, 0xa54ff53a, 0x5f1d36f1,\n 0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179,\n]);\n","/**\n * SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256.\n * SHA256 is the fastest hash implementable in JS, even faster than Blake3.\n * Check out {@link https://www.rfc-editor.org/rfc/rfc4634 | RFC 4634} and\n * {@link https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf | FIPS 180-4}.\n * @module\n */\nimport { Chi, HashMD, Maj, SHA224_IV, SHA256_IV, SHA384_IV, SHA512_IV } from './_md.ts';\nimport * as u64 from './_u64.ts';\nimport { type CHash, clean, createHasher, oidNist, rotr, type TRet } from './utils.ts';\n\n/**\n * SHA-224 / SHA-256 round constants from RFC 6234 §5.1: the first 32 bits\n * of the cube roots of the first 64 primes (2..311).\n */\n// prettier-ignore\nconst SHA256_K = /* @__PURE__ */ Uint32Array.from([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n]);\n\n/** Reusable SHA-224 / SHA-256 message schedule buffer `W_t` from RFC 6234 §6.2 step 1. */\nconst SHA256_W = /* @__PURE__ */ new Uint32Array(64);\n\n/** Internal SHA-224 / SHA-256 compression engine from RFC 6234 §6.2. */\nabstract class SHA2_32B<T extends SHA2_32B<T>> extends HashMD<T> {\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n protected abstract A: number;\n protected abstract B: number;\n protected abstract C: number;\n protected abstract D: number;\n protected abstract E: number;\n protected abstract F: number;\n protected abstract G: number;\n protected abstract H: number;\n\n constructor(outputLen: number) {\n super(64, outputLen, 8, false);\n }\n protected get(): [number, number, number, number, number, number, number, number] {\n const { A, B, C, D, E, F, G, H } = this;\n return [A, B, C, D, E, F, G, H];\n }\n // prettier-ignore\n protected set(\n A: number, B: number, C: number, D: number, E: number, F: number, G: number, H: number\n ): void {\n this.A = A | 0;\n this.B = B | 0;\n this.C = C | 0;\n this.D = D | 0;\n this.E = E | 0;\n this.F = F | 0;\n this.G = G | 0;\n this.H = H | 0;\n }\n protected process(view: DataView, offset: number): void {\n // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array\n for (let i = 0; i < 16; i++, offset += 4) SHA256_W[i] = view.getUint32(offset, false);\n for (let i = 16; i < 64; i++) {\n const W15 = SHA256_W[i - 15];\n const W2 = SHA256_W[i - 2];\n const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);\n const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);\n SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;\n }\n // Compression function main loop, 64 rounds\n let { A, B, C, D, E, F, G, H } = this;\n for (let i = 0; i < 64; i++) {\n const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);\n const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;\n const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);\n const T2 = (sigma0 + Maj(A, B, C)) | 0;\n H = G;\n G = F;\n F = E;\n E = (D + T1) | 0;\n D = C;\n C = B;\n B = A;\n A = (T1 + T2) | 0;\n }\n // Add the compressed chunk to the current hash value\n A = (A + this.A) | 0;\n B = (B + this.B) | 0;\n C = (C + this.C) | 0;\n D = (D + this.D) | 0;\n E = (E + this.E) | 0;\n F = (F + this.F) | 0;\n G = (G + this.G) | 0;\n H = (H + this.H) | 0;\n this.set(A, B, C, D, E, F, G, H);\n }\n protected roundClean(): void {\n clean(SHA256_W);\n }\n destroy(): void {\n // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves\n // update()/digest() callable on reused instances.\n this.destroyed = true;\n this.set(0, 0, 0, 0, 0, 0, 0, 0);\n clean(this.buffer);\n }\n}\n\n/** Internal SHA-256 hash class grounded in RFC 6234 §6.2. */\nexport class _SHA256 extends SHA2_32B<_SHA256> {\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n protected A: number = SHA256_IV[0] | 0;\n protected B: number = SHA256_IV[1] | 0;\n protected C: number = SHA256_IV[2] | 0;\n protected D: number = SHA256_IV[3] | 0;\n protected E: number = SHA256_IV[4] | 0;\n protected F: number = SHA256_IV[5] | 0;\n protected G: number = SHA256_IV[6] | 0;\n protected H: number = SHA256_IV[7] | 0;\n constructor() {\n super(32);\n }\n}\n\n/** Internal SHA-224 hash class grounded in RFC 6234 §6.2 and §8.5. */\nexport class _SHA224 extends SHA2_32B<_SHA224> {\n protected A: number = SHA224_IV[0] | 0;\n protected B: number = SHA224_IV[1] | 0;\n protected C: number = SHA224_IV[2] | 0;\n protected D: number = SHA224_IV[3] | 0;\n protected E: number = SHA224_IV[4] | 0;\n protected F: number = SHA224_IV[5] | 0;\n protected G: number = SHA224_IV[6] | 0;\n protected H: number = SHA224_IV[7] | 0;\n constructor() {\n super(28);\n }\n}\n\n// SHA2-512 is slower than sha256 in js because u64 operations are slow.\n\n// SHA-384 / SHA-512 round constants from RFC 6234 §5.2:\n// 80 full 64-bit words split into high/low halves.\n// prettier-ignore\nconst K512 = /* @__PURE__ */ (() => u64.split([\n '0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc',\n '0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118',\n '0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2',\n '0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694',\n '0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65',\n '0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5',\n '0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4',\n '0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70',\n '0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df',\n '0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b',\n '0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30',\n '0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8',\n '0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8',\n '0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3',\n '0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec',\n '0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b',\n '0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178',\n '0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b',\n '0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c',\n '0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817'\n].map(n => BigInt(n))))();\nconst SHA512_Kh = /* @__PURE__ */ (() => K512[0])();\nconst SHA512_Kl = /* @__PURE__ */ (() => K512[1])();\n\n// Reusable high-half schedule buffer for the RFC 6234 §6.4 64-bit `W_t` words.\nconst SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);\n// Reusable low-half schedule buffer for the RFC 6234 §6.4 64-bit `W_t` words.\nconst SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);\n\n/** Internal SHA-384 / SHA-512 compression engine from RFC 6234 §6.4. */\nabstract class SHA2_64B<T extends SHA2_64B<T>> extends HashMD<T> {\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n // h -- high 32 bits, l -- low 32 bits\n protected abstract Ah: number;\n protected abstract Al: number;\n protected abstract Bh: number;\n protected abstract Bl: number;\n protected abstract Ch: number;\n protected abstract Cl: number;\n protected abstract Dh: number;\n protected abstract Dl: number;\n protected abstract Eh: number;\n protected abstract El: number;\n protected abstract Fh: number;\n protected abstract Fl: number;\n protected abstract Gh: number;\n protected abstract Gl: number;\n protected abstract Hh: number;\n protected abstract Hl: number;\n\n constructor(outputLen: number) {\n super(128, outputLen, 16, false);\n }\n // prettier-ignore\n protected get(): [\n number, number, number, number, number, number, number, number,\n number, number, number, number, number, number, number, number\n ] {\n const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;\n return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];\n }\n // prettier-ignore\n protected set(\n Ah: number, Al: number, Bh: number, Bl: number, Ch: number, Cl: number, Dh: number, Dl: number,\n Eh: number, El: number, Fh: number, Fl: number, Gh: number, Gl: number, Hh: number, Hl: number\n ): void {\n this.Ah = Ah | 0;\n this.Al = Al | 0;\n this.Bh = Bh | 0;\n this.Bl = Bl | 0;\n this.Ch = Ch | 0;\n this.Cl = Cl | 0;\n this.Dh = Dh | 0;\n this.Dl = Dl | 0;\n this.Eh = Eh | 0;\n this.El = El | 0;\n this.Fh = Fh | 0;\n this.Fl = Fl | 0;\n this.Gh = Gh | 0;\n this.Gl = Gl | 0;\n this.Hh = Hh | 0;\n this.Hl = Hl | 0;\n }\n protected process(view: DataView, offset: number): void {\n // Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array\n for (let i = 0; i < 16; i++, offset += 4) {\n SHA512_W_H[i] = view.getUint32(offset);\n SHA512_W_L[i] = view.getUint32((offset += 4));\n }\n for (let i = 16; i < 80; i++) {\n // s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7)\n const W15h = SHA512_W_H[i - 15] | 0;\n const W15l = SHA512_W_L[i - 15] | 0;\n const s0h = u64.rotrSH(W15h, W15l, 1) ^ u64.rotrSH(W15h, W15l, 8) ^ u64.shrSH(W15h, W15l, 7);\n const s0l = u64.rotrSL(W15h, W15l, 1) ^ u64.rotrSL(W15h, W15l, 8) ^ u64.shrSL(W15h, W15l, 7);\n // s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6)\n const W2h = SHA512_W_H[i - 2] | 0;\n const W2l = SHA512_W_L[i - 2] | 0;\n const s1h = u64.rotrSH(W2h, W2l, 19) ^ u64.rotrBH(W2h, W2l, 61) ^ u64.shrSH(W2h, W2l, 6);\n const s1l = u64.rotrSL(W2h, W2l, 19) ^ u64.rotrBL(W2h, W2l, 61) ^ u64.shrSL(W2h, W2l, 6);\n // SHA512_W[i] = s0 + s1 + SHA512_W[i - 7] + SHA512_W[i - 16];\n const SUMl = u64.add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);\n const SUMh = u64.add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);\n SHA512_W_H[i] = SUMh | 0;\n SHA512_W_L[i] = SUMl | 0;\n }\n let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;\n // Compression function main loop, 80 rounds\n for (let i = 0; i < 80; i++) {\n // S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41)\n const sigma1h = u64.rotrSH(Eh, El, 14) ^ u64.rotrSH(Eh, El, 18) ^ u64.rotrBH(Eh, El, 41);\n const sigma1l = u64.rotrSL(Eh, El, 14) ^ u64.rotrSL(Eh, El, 18) ^ u64.rotrBL(Eh, El, 41);\n //const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;\n const CHIh = (Eh & Fh) ^ (~Eh & Gh);\n const CHIl = (El & Fl) ^ (~El & Gl);\n // T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i]\n // prettier-ignore\n const T1ll = u64.add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);\n const T1h = u64.add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);\n const T1l = T1ll | 0;\n // S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39)\n const sigma0h = u64.rotrSH(Ah, Al, 28) ^ u64.rotrBH(Ah, Al, 34) ^ u64.rotrBH(Ah, Al, 39);\n const sigma0l = u64.rotrSL(Ah, Al, 28) ^ u64.rotrBL(Ah, Al, 34) ^ u64.rotrBL(Ah, Al, 39);\n const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch);\n const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl);\n Hh = Gh | 0;\n Hl = Gl | 0;\n Gh = Fh | 0;\n Gl = Fl | 0;\n Fh = Eh | 0;\n Fl = El | 0;\n ({ h: Eh, l: El } = u64.add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));\n Dh = Ch | 0;\n Dl = Cl | 0;\n Ch = Bh | 0;\n Cl = Bl | 0;\n Bh = Ah | 0;\n Bl = Al | 0;\n const All = u64.add3L(T1l, sigma0l, MAJl);\n Ah = u64.add3H(All, T1h, sigma0h, MAJh);\n Al = All | 0;\n }\n // Add the compressed chunk to the current hash value\n ({ h: Ah, l: Al } = u64.add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));\n ({ h: Bh, l: Bl } = u64.add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));\n ({ h: Ch, l: Cl } = u64.add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));\n ({ h: Dh, l: Dl } = u64.add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));\n ({ h: Eh, l: El } = u64.add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));\n ({ h: Fh, l: Fl } = u64.add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));\n ({ h: Gh, l: Gl } = u64.add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));\n ({ h: Hh, l: Hl } = u64.add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));\n this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);\n }\n protected roundClean(): void {\n clean(SHA512_W_H, SHA512_W_L);\n }\n destroy(): void {\n // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves\n // update()/digest() callable on reused instances.\n this.destroyed = true;\n clean(this.buffer);\n this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);\n }\n}\n\n/** Internal SHA-512 hash class grounded in RFC 6234 §6.3 and §6.4. */\nexport class _SHA512 extends SHA2_64B<_SHA512> {\n protected Ah: number = SHA512_IV[0] | 0;\n protected Al: number = SHA512_IV[1] | 0;\n protected Bh: number = SHA512_IV[2] | 0;\n protected Bl: number = SHA512_IV[3] | 0;\n protected Ch: number = SHA512_IV[4] | 0;\n protected Cl: number = SHA512_IV[5] | 0;\n protected Dh: number = SHA512_IV[6] | 0;\n protected Dl: number = SHA512_IV[7] | 0;\n protected Eh: number = SHA512_IV[8] | 0;\n protected El: number = SHA512_IV[9] | 0;\n protected Fh: number = SHA512_IV[10] | 0;\n protected Fl: number = SHA512_IV[11] | 0;\n protected Gh: number = SHA512_IV[12] | 0;\n protected Gl: number = SHA512_IV[13] | 0;\n protected Hh: number = SHA512_IV[14] | 0;\n protected Hl: number = SHA512_IV[15] | 0;\n\n constructor() {\n super(64);\n }\n}\n\n/** Internal SHA-384 hash class grounded in RFC 6234 §6.3 and §6.4. */\nexport class _SHA384 extends SHA2_64B<_SHA384> {\n protected Ah: number = SHA384_IV[0] | 0;\n protected Al: number = SHA384_IV[1] | 0;\n protected Bh: number = SHA384_IV[2] | 0;\n protected Bl: number = SHA384_IV[3] | 0;\n protected Ch: number = SHA384_IV[4] | 0;\n protected Cl: number = SHA384_IV[5] | 0;\n protected Dh: number = SHA384_IV[6] | 0;\n protected Dl: number = SHA384_IV[7] | 0;\n protected Eh: number = SHA384_IV[8] | 0;\n protected El: number = SHA384_IV[9] | 0;\n protected Fh: number = SHA384_IV[10] | 0;\n protected Fl: number = SHA384_IV[11] | 0;\n protected Gh: number = SHA384_IV[12] | 0;\n protected Gl: number = SHA384_IV[13] | 0;\n protected Hh: number = SHA384_IV[14] | 0;\n protected Hl: number = SHA384_IV[15] | 0;\n\n constructor() {\n super(48);\n }\n}\n\n/**\n * Truncated SHA512/256 and SHA512/224.\n * SHA512_IV is XORed with 0xa5a5a5a5a5a5a5a5, then used as \"intermediary\" IV of SHA512/t.\n * Then t hashes string to produce result IV.\n * See the repo-side derivation recipe in `test/misc/sha2-gen-iv.js`.\n * These IV literals are checked against that script rather than a dedicated\n * local RFC section.\n */\n\n/** SHA-512/224 IV derived by the SHA-512/t recipe in `test/misc/sha2-gen-iv.js` and\n * stored as sixteen big-endian 32-bit halves. */\nconst T224_IV = /* @__PURE__ */ Uint32Array.from([\n 0x8c3d37c8, 0x19544da2, 0x73e19966, 0x89dcd4d6, 0x1dfab7ae, 0x32ff9c82, 0x679dd514, 0x582f9fcf,\n 0x0f6d2b69, 0x7bd44da8, 0x77e36f73, 0x04c48942, 0x3f9d85a8, 0x6a1d36c8, 0x1112e6ad, 0x91d692a1,\n]);\n\n/** SHA-512/256 IV derived by the SHA-512/t recipe in `test/misc/sha2-gen-iv.js` and\n * stored as sixteen big-endian 32-bit halves. */\nconst T256_IV = /* @__PURE__ */ Uint32Array.from([\n 0x22312194, 0xfc2bf72c, 0x9f555fa3, 0xc84c64c2, 0x2393b86b, 0x6f53b151, 0x96387719, 0x5940eabd,\n 0x96283ee2, 0xa88effe3, 0xbe5e1e25, 0x53863992, 0x2b0199fc, 0x2c85b8aa, 0x0eb72ddc, 0x81c52ca2,\n]);\n\n/** Internal SHA-512/224 hash class using the derived `T224_IV` and the shared\n * RFC 6234 §6.4 compression engine. */\nexport class _SHA512_224 extends SHA2_64B<_SHA512_224> {\n protected Ah: number = T224_IV[0] | 0;\n protected Al: number = T224_IV[1] | 0;\n protected Bh: number = T224_IV[2] | 0;\n protected Bl: number = T224_IV[3] | 0;\n protected Ch: number = T224_IV[4] | 0;\n protected Cl: number = T224_IV[5] | 0;\n protected Dh: number = T224_IV[6] | 0;\n protected Dl: number = T224_IV[7] | 0;\n protected Eh: number = T224_IV[8] | 0;\n protected El: number = T224_IV[9] | 0;\n protected Fh: number = T224_IV[10] | 0;\n protected Fl: number = T224_IV[11] | 0;\n protected Gh: number = T224_IV[12] | 0;\n protected Gl: number = T224_IV[13] | 0;\n protected Hh: number = T224_IV[14] | 0;\n protected Hl: number = T224_IV[15] | 0;\n\n constructor() {\n super(28);\n }\n}\n\n/** Internal SHA-512/256 hash class using the derived `T256_IV` and the shared\n * RFC 6234 §6.4 compression engine. */\nexport class _SHA512_256 extends SHA2_64B<_SHA512_256> {\n protected Ah: number = T256_IV[0] | 0;\n protected Al: number = T256_IV[1] | 0;\n protected Bh: number = T256_IV[2] | 0;\n protected Bl: number = T256_IV[3] | 0;\n protected Ch: number = T256_IV[4] | 0;\n protected Cl: number = T256_IV[5] | 0;\n protected Dh: number = T256_IV[6] | 0;\n protected Dl: number = T256_IV[7] | 0;\n protected Eh: number = T256_IV[8] | 0;\n protected El: number = T256_IV[9] | 0;\n protected Fh: number = T256_IV[10] | 0;\n protected Fl: number = T256_IV[11] | 0;\n protected Gh: number = T256_IV[12] | 0;\n protected Gl: number = T256_IV[13] | 0;\n protected Hh: number = T256_IV[14] | 0;\n protected Hl: number = T256_IV[15] | 0;\n\n constructor() {\n super(32);\n }\n}\n\n/**\n * SHA2-256 hash function from RFC 4634. In JS it's the fastest: even faster than Blake3. Some info:\n *\n * - Trying 2^128 hashes would get 50% chance of collision, using birthday attack.\n * - BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.\n * - Each sha256 hash is executing 2^18 bit operations.\n * - Good 2024 ASICs can do 200Th/sec with 3500 watts of power, corresponding to 2^36 hashes/joule.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-256.\n * ```ts\n * sha256(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha256: TRet<CHash<_SHA256>> = /* @__PURE__ */ createHasher(\n () => new _SHA256(),\n /* @__PURE__ */ oidNist(0x01)\n);\n/**\n * SHA2-224 hash function from RFC 4634.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-224.\n * ```ts\n * sha224(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha224: TRet<CHash<_SHA224>> = /* @__PURE__ */ createHasher(\n () => new _SHA224(),\n /* @__PURE__ */ oidNist(0x04)\n);\n\n/**\n * SHA2-512 hash function from RFC 4634.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-512.\n * ```ts\n * sha512(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha512: TRet<CHash<_SHA512>> = /* @__PURE__ */ createHasher(\n () => new _SHA512(),\n /* @__PURE__ */ oidNist(0x03)\n);\n/**\n * SHA2-384 hash function from RFC 4634.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-384.\n * ```ts\n * sha384(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha384: TRet<CHash<_SHA384>> = /* @__PURE__ */ createHasher(\n () => new _SHA384(),\n /* @__PURE__ */ oidNist(0x02)\n);\n\n/**\n * SHA2-512/256 \"truncated\" hash function, with improved resistance to length extension attacks.\n * See the paper on {@link https://eprint.iacr.org/2010/548.pdf | truncated SHA512}.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-512/256.\n * ```ts\n * sha512_256(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha512_256: TRet<CHash<_SHA512_256>> = /* @__PURE__ */ createHasher(\n () => new _SHA512_256(),\n /* @__PURE__ */ oidNist(0x06)\n);\n/**\n * SHA2-512/224 \"truncated\" hash function, with improved resistance to length extension attacks.\n * See the paper on {@link https://eprint.iacr.org/2010/548.pdf | truncated SHA512}.\n * @param msg - message bytes to hash\n * @returns Digest bytes.\n * @example\n * Hash a message with SHA2-512/224.\n * ```ts\n * sha512_224(new Uint8Array([97, 98, 99]));\n * ```\n */\nexport const sha512_224: TRet<CHash<_SHA512_224>> = /* @__PURE__ */ createHasher(\n () => new _SHA512_224(),\n /* @__PURE__ */ oidNist(0x05)\n);\n","/**\n * token-engine/realization.ts — deterministic realization values (Part E.1).\n *\n * Every \"random\" value a transfer/split binds to (stateMask, per-output salt,\n * tokenType where not fixed, the split burn mask) is derived from the wallet\n * key + a pre-persisted transferId instead of `crypto.getRandomValues`, so the\n * exact transaction can be rebuilt later — on any device holding the seed.\n * That is what makes an interrupted transfer resumable (sdk-changes Part E,\n * ARCHITECTURE §8.1): re-running with the same transferId reproduces the\n * byte-identical transaction, and the aggregator's existing proof applies.\n *\n * Derivation (mirrors impl/shared/ipfs/ipns-key-derivation.ts — same\n * @noble/hashes HKDF, no salt):\n *\n * HKDF-SHA256(ikm = privKey, info = \"sphere-realization-v1:\" + transferId\n * + \":\" + field + \":\" + index)[0..32)\n *\n * `field` is the domain separator between the values of one transfer;\n * `index` separates per-output values (split salts). The output is\n * per-transfer unique and unpredictable to outsiders (derived from the secret\n * key — no privacy/unlinkability regression), yet reproducible by the owner.\n */\n\nimport { hkdf } from '@noble/hashes/hkdf.js';\nimport { sha256 } from '@noble/hashes/sha2.js';\nimport { HexConverter } from './sdk';\n\n/** HKDF info prefix — versioned; the same formula appears in ARCHITECTURE §8.1. */\nexport const REALIZATION_HKDF_INFO_PREFIX = 'sphere-realization-v1';\n\n/**\n * Domain separator between the realization values of one transfer.\n * 'salt' is indexed by split-OUTPUT ordinal; a standalone mint's salt lives in\n * the separate 'mint' domain (indexed by opIndex) so the two never collide\n * under a shared transferId (#692 F13).\n */\nexport type RealizationField = 'stateMask' | 'salt' | 'tokenType' | 'burn' | 'mint';\n\n/**\n * Derive one 32-byte realization value.\n *\n * @param privKeyHex - wallet secp256k1 private key, hex (the HKDF ikm is its raw bytes)\n * @param transferId - client-generated UUIDv4 in canonical lowercase string form\n * (validated by the engine before any derivation)\n * @param index - per-output index within the transfer (0 for single-value fields)\n * @param field - which value of the transfer is being derived\n * @returns 32 deterministic bytes\n */\nexport function deriveRealization(\n privKeyHex: string,\n transferId: string,\n index: number,\n field: RealizationField,\n): Uint8Array {\n const ikm = HexConverter.decode(privKeyHex);\n const info = new TextEncoder().encode(`${REALIZATION_HKDF_INFO_PREFIX}:${transferId}:${field}:${index}`);\n return hkdf(sha256, ikm, undefined, info, 32);\n}\n","/**\n * token-engine/split-checkpoint.ts — the split burn checkpoint (sdk-changes E.4, sphere-sdk#501\n * option b). Encodes/decodes the one split-resume input the engine cannot re-derive — the burn's\n * aggregator-issued inclusion proof — and rebuilds the burnt token from STORED bytes so every\n * mint justification is byte-stable across a resume (the aggregator regenerates proofs per\n * request; only `CertificationData` is stable).\n *\n * Payload (strict-canonical CBOR array): `[v, sdkVersion, burnTx.toCBOR(), burnProof.toCBOR(),\n * sha256(burntToken.toCBOR())]`. Storing the burn-tx bytes turns any cross-version derivation\n * drift into a LOUD byte-inequality; the burnt-token hash catches a tolerant-decode wire migration\n * on resume. The engine passes PLAINTEXT through the `SplitCheckpointStore` port; AAD-encryption is\n * the transport adapter's concern.\n */\n\nimport { SplitCheckpointLostError, CheckpointTrustbaseMismatchError } from './errors';\nimport {\n CborDeserializer,\n CborSerializer,\n DataHasher,\n HashAlgorithm,\n InclusionProof,\n InclusionProofVerificationStatus,\n type PredicateVerifierService,\n type UnicityCertificateVerifier,\n type RootTrustBase,\n Token,\n type TransferTransaction,\n type VerificationContext,\n} from './sdk';\n\n/**\n * Checkpoint payload version (the CBOR array's first element).\n *\n * 2 since the state-transition-sdk 3.x bump: the burn transaction and its\n * inclusion proof are both stored as SDK CBOR, and every wire version under\n * them moved, so no v1 record can be replayed. Without this bump a stale record\n * still fails — the byte-comparison below catches it — but it fails blaming\n * \"derivation drift\", which sends the reader hunting a realization bug that\n * isn't there. The version check names the real cause.\n */\nconst CHECKPOINT_VERSION = 2;\n/**\n * The base-SDK pin whose CBOR wire form governs byte-stability — recorded for a LOUD drift\n * diagnosis only (byte-inequality of the stored burn tx is the actual guard). Bump with the pin.\n */\nconst CHECKPOINT_SDK_VERSION = '@unicitylabs/state-transition-sdk@3.0.1';\n\nexport interface CheckpointDeps {\n readonly trustBase: RootTrustBase;\n readonly predicateVerifier: PredicateVerifierService;\n readonly unicityCertificateVerifier: UnicityCertificateVerifier;\n readonly verificationContext: VerificationContext;\n}\n\n/** Constant-length-agnostic byte-equality (no early-exit timing concern — these are public bytes). */\nexport function bytesEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n}\n\nasync function sha256(bytes: Uint8Array): Promise<Uint8Array> {\n return (await new DataHasher(HashAlgorithm.SHA256).update(bytes).digest()).imprint;\n}\n\n/**\n * Encode the checkpoint for `store.put`. `burntToken` is the freshly-built burnt token whose hash\n * pins the resume-side re-encode equality check.\n */\nexport async function encodeCheckpoint(\n burnTx: TransferTransaction,\n burnProof: InclusionProof,\n burntToken: Token,\n): Promise<Uint8Array> {\n return CborSerializer.encodeArray(\n CborSerializer.encodeUnsignedInteger(CHECKPOINT_VERSION),\n CborSerializer.encodeTextString(CHECKPOINT_SDK_VERSION),\n CborSerializer.encodeByteString(burnTx.toCBOR()),\n CborSerializer.encodeByteString(burnProof.toCBOR()),\n CborSerializer.encodeByteString(await sha256(burntToken.toCBOR())),\n );\n}\n\ninterface DecodedCheckpoint {\n readonly sdkVersion: string;\n readonly burnTxBytes: Uint8Array;\n readonly burnProofBytes: Uint8Array;\n readonly burntTokenHash: Uint8Array;\n}\n\n/**\n * Decode a stored checkpoint; ANY malformed/unknown-version record is a lost checkpoint (never\n * mint). The FULL decode (array framing AND every inner field) is guarded — a well-framed 5-array\n * with a wrong-typed/non-canonical inner field throws a raw `CborError` from the per-field decoders,\n * which must still surface as the typed keep-open error, not escape `split()` untyped (AC-E6(c)).\n */\nfunction decodeCheckpoint(bytes: Uint8Array): DecodedCheckpoint {\n try {\n const fields = CborDeserializer.decodeArray(bytes, 5);\n const version = Number(CborDeserializer.decodeUnsignedInteger(fields[0]));\n if (version !== CHECKPOINT_VERSION) {\n throw new SplitCheckpointLostError(`split checkpoint version ${String(version)} is not supported`);\n }\n return {\n sdkVersion: CborDeserializer.decodeTextString(fields[1]),\n burnTxBytes: CborDeserializer.decodeByteString(fields[2]),\n burnProofBytes: CborDeserializer.decodeByteString(fields[3]),\n burntTokenHash: CborDeserializer.decodeByteString(fields[4]),\n };\n } catch (err) {\n if (err instanceof SplitCheckpointLostError) throw err;\n throw new SplitCheckpointLostError('split checkpoint is malformed (cannot decode)', err);\n }\n}\n\n/** Classify a `toCertifiedTransaction` failure: only INVALID_TRUSTBASE is a keep-open drain case. */\nfunction isTrustbaseFailure(err: unknown): boolean {\n const status = (err as { verificationResult?: { status?: unknown } })?.verificationResult?.status;\n return status === InclusionProofVerificationStatus.INVALID_TRUSTBASE;\n}\n\n/**\n * Rebuild the burnt token from a stored checkpoint (resume, or adopt-after-put). NEVER refetches\n * the burn proof — it applies the STORED proof to the re-derived burn tx, so the mint\n * justification is byte-stable. Throws (never returns a wrong burnt token):\n * - stored burn tx ≠ re-derived (cross-version drift) → SplitCheckpointLostError (names sdkVersion)\n * - stored proof fails ONLY the current trust base → CheckpointTrustbaseMismatchError\n * - stored proof otherwise invalid / corrupt → SplitCheckpointLostError\n * - rebuilt burnt token re-encodes to a different hash → SplitCheckpointLostError (wire migration)\n */\nexport async function burntTokenFromCheckpoint(\n deps: CheckpointDeps,\n storedBytes: Uint8Array,\n reDerivedBurnTx: TransferTransaction,\n sourceToken: Token,\n): Promise<Token> {\n const decoded = decodeCheckpoint(storedBytes);\n if (!bytesEqual(decoded.burnTxBytes, reDerivedBurnTx.toCBOR())) {\n throw new SplitCheckpointLostError(\n `split checkpoint burn tx does not match the re-derived burn (stored under ${decoded.sdkVersion}) — derivation drift`,\n );\n }\n // The burn-proof field is the most transit-exposed value; parsing corrupt bytes throws a raw\n // CborError, which must surface as the typed keep-open error (not escape split() untyped).\n let burnProof: InclusionProof;\n try {\n burnProof = InclusionProof.fromCBOR(decoded.burnProofBytes);\n } catch (err) {\n throw new SplitCheckpointLostError('split checkpoint proof is malformed (cannot decode)', err);\n }\n let burnCertified;\n try {\n burnCertified = await reDerivedBurnTx.toCertifiedTransaction(deps.trustBase, deps.predicateVerifier, deps.unicityCertificateVerifier, burnProof);\n } catch (err) {\n if (isTrustbaseFailure(err)) {\n throw new CheckpointTrustbaseMismatchError(\n 'split checkpoint proof no longer verifies against the current trust base (validator rotation)',\n err,\n );\n }\n throw new SplitCheckpointLostError('split checkpoint proof is invalid', err);\n }\n // Defense-in-depth: the inputs are pre-validated (byte-equal burn tx + trustbase-verified proof),\n // so this application is effectively unreachable-throwing — but keep the whole resume path free of\n // raw-error escapes (a future wire migration must still surface the typed keep-open error).\n let burntToken: Token;\n try {\n burntToken = await sourceToken.transfer(burnCertified, deps.verificationContext);\n } catch (err) {\n throw new SplitCheckpointLostError('split checkpoint could not rebuild the burnt token', err);\n }\n if (!bytesEqual(await sha256(burntToken.toCBOR()), decoded.burntTokenHash)) {\n throw new SplitCheckpointLostError('split checkpoint burnt-token hash mismatch (wire re-encoding drift)');\n }\n return burntToken;\n}\n","/**\n * token-engine/SphereTokenEngine.ts — the real ITokenEngine adapter (Track A).\n *\n * The full sender-driven engine over the v2 SDK: identity, value reads,\n * serialization, verification, mint, transfer, split and spent-status. All\n * crypto/value logic is the SDK's; this class orchestrates build → submit →\n * wait-proof → certify → realize, and maps SDK errors/states to the\n * sphere-domain ITokenEngine port.\n *\n * SDK objects are injected via `EngineDeps` (built by the factory in A4, or by\n * test wiring around TestAggregatorClient), keeping the engine logic independent\n * of how the aggregator/trust base are constructed.\n *\n * Advertises `deterministicMint` (F13): a same-seed `mint` re-call recovers an\n * existing certification instead of minting a second token.\n */\n\nimport { SphereError, type SphereErrorCode } from '../core/errors';\nimport {\n awaitProofBounded,\n certificationDeadline,\n resolveProofTimeoutMs,\n retryTransient,\n TransientSubmitAnswer,\n} from './proof-wait';\nimport { certificationFailure } from './certification-outcome';\nimport { randomUUID } from '../core/uuid';\nimport {\n CheckpointPersistFailedError,\n CheckpointTrustbaseMismatchError,\n ProofUnconfirmedError,\n SplitCheckpointLostError,\n TransferConflictError,\n} from './errors';\nimport { deriveDirectAddress } from './identity';\nimport { deriveDeliveryKeys } from './blob-keys';\nimport { deriveRealization } from './realization';\nimport { burntTokenFromCheckpoint, encodeCheckpoint } from './split-checkpoint';\nimport {\n CborDeserializer,\n CertificationData,\n CertificationStatus,\n EncodedPredicate,\n HexConverter,\n type InclusionProof,\n InclusionProofVerificationStatus,\n type ITransaction,\n type MintJustificationVerifierService,\n MintTransaction,\n type NetworkId,\n PaymentAssetCollection,\n type PredicateVerifierService,\n type UnicityCertificateVerifier,\n type RootTrustBase,\n SignaturePredicate,\n SignaturePredicateUnlockScript,\n type SigningService,\n SplitMintJustification,\n type SplitToken,\n SplitTokenRequest,\n StateId,\n StateMask,\n type StateTransitionClient,\n Token,\n TokenSalt,\n TokenSplit,\n TokenType,\n TransferTransaction,\n type VerificationContext,\n VerificationStatus,\n waitInclusionProof,\n type ITokenVerifier,\n} from './sdk';\nimport { decodeSpherePaymentData, SpherePaymentData, sphereAssetToSdk } from './SpherePaymentData';\nimport type { EngineOpOptions, ITokenEngine } from './engine';\nimport type {\n CoinId,\n EngineIdentity,\n EngineVerifyResult,\n MintDataTokenParams,\n MintParams,\n SphereToken,\n SphereValue,\n SplitParams,\n SplitResult,\n TokenBlob,\n TransferParams,\n} from './types';\n\n/** SDK objects the engine operates with; assembled by the factory (A4) or test wiring. */\n/** An `ITokenVerifier` that also owns terminable resources (a worker pool). */\nexport interface DisposableTokenVerifier extends ITokenVerifier {\n dispose(): void;\n}\n\nexport interface EngineDeps {\n readonly client: StateTransitionClient;\n readonly trustBase: RootTrustBase;\n readonly predicateVerifier: PredicateVerifierService;\n readonly unicityCertificateVerifier: UnicityCertificateVerifier;\n readonly mintJustificationVerifier: MintJustificationVerifierService;\n readonly verificationContext: VerificationContext;\n /**\n * Opt-in parallel verifier (EngineConfig.verification). Absent → tokens verify\n * sequentially via `Token.verify`, which is what every release before 2.0.2 did.\n */\n readonly tokenVerifier?: DisposableTokenVerifier;\n /** The wallet's signing key (its identity + the spender for transfers it owns). */\n readonly signingService: SigningService;\n /**\n * The same key as raw bytes — the HKDF ikm for deterministic realization\n * (Part E.1; SigningService does not expose it back).\n */\n readonly privateKey: Uint8Array;\n readonly networkId: NetworkId;\n /** Inclusion-proof poll cadence in ms (#683); undefined → the tuned default below. */\n readonly proofPollIntervalMs?: number;\n /** Deadline for one inclusion-proof wait; defaults to DEFAULT_PROOF_TIMEOUT_MS (#739). */\n readonly proofTimeoutMs?: number;\n}\n\n/**\n * #683: default inclusion-proof poll interval (ms). Finer than the sdk's 1000ms\n * default so a ~1.2s finalization is caught near ~1.2-1.5s instead of at the 2s\n * poll boundary. Bounded by waitInclusionProof's 10s abort; the extra polls are\n * cheap read-only getInclusionProof calls confined to the ~1.5s finalization window.\n */\nexport const DEFAULT_PROOF_POLL_INTERVAL_MS = 300;\n\n/**\n * #684: max split-mint legs minted concurrently. The mints are independent off the\n * one burn, but an UNBOUNDED fan-out would submit + proof-poll every leg at once\n * against the gateway (the prior sequential loop naturally paced it to one). This\n * cap keeps a typical split (K=2 — payment + change) fully parallel while bounding\n * gateway load on a large multi-output split.\n */\nconst MAX_MINT_CONCURRENCY = 8;\n\n/**\n * The keep-open engine errors a split leg can raise — mirrors PaymentsModule's `keepOpen` set.\n * When one of these settles a parallel mint fan-out, the leg's spend MAY already be certified\n * on-chain, so the intent MUST stay OPEN for checkpoint-based resume; the fan-out must surface a\n * keep-open outcome rather than an abortable clean failure that would strand a certified sibling\n * (#684). Only ProofUnconfirmedError / SplitCheckpointLostError are reachable from a mint leg\n * today; the checkpoint pair is included so the classifier stays faithful to the keep-open family.\n */\nfunction isKeepOpenSplitError(err: unknown): boolean {\n return (\n err instanceof ProofUnconfirmedError ||\n err instanceof CheckpointPersistFailedError ||\n err instanceof SplitCheckpointLostError ||\n err instanceof CheckpointTrustbaseMismatchError\n );\n}\n\n/** Canonical lowercase UUID — the spec's `transferId` wire form (sdk-changes E.1). */\nconst TRANSFER_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;\n\n/**\n * The KNOWN validation-reject submit statuses: a well-formed rejection that PROVES the\n * state was never certified (a byte-identical resume of a *valid* tx never later returns\n * a format/signature/state/shard-mismatch failure). E.2 is status-AGNOSTIC for everything\n * else: an UNKNOWN or transitional non-SUCCESS status (e.g. the gateway's transitional\n * `STATE_ID_EXISTS`) means \"a certification for this state MAY already exist\" — it must be\n * treated as possibly-certified (keep the intent OPEN — #631), NEVER a clean abort. Any\n * status outside this set therefore falls through to `ProofUnconfirmedError`.\n *\n * v3's REQUEST_EXPIRED and SERVICE_NOT_READY stay OUT despite their names: each\n * reports only that THIS submit was not admitted, never that no earlier attempt\n * certified. Pinned by expires-at.test.ts.\n */\nconst CLEAN_REJECT_STATUSES: ReadonlySet<string> = new Set([\n CertificationStatus.STATE_ID_MISMATCH,\n CertificationStatus.SIGNATURE_VERIFICATION_FAILED,\n CertificationStatus.INVALID_SIGNATURE_FORMAT,\n CertificationStatus.INVALID_PUBLIC_KEY_FORMAT,\n CertificationStatus.INVALID_SOURCE_STATE_HASH_FORMAT,\n CertificationStatus.INVALID_TRANSACTION_HASH_FORMAT,\n CertificationStatus.UNSUPPORTED_ALGORITHM,\n CertificationStatus.INVALID_SHARD,\n]);\n\n/** The deterministic split plan (burn leg + per-output mint requests) — `TokenSplit.split`'s result. */\ntype SplitPlan = Awaited<ReturnType<typeof TokenSplit.split>>;\n\n/** Threaded through the E.4 burnt-token resolution so its helpers stay within the max-params bound. */\ninterface SplitContext {\n readonly params: SplitParams;\n readonly split: SplitPlan;\n readonly transferId: string;\n readonly options?: EngineOpOptions | undefined;\n}\n\nexport class SphereTokenEngine implements ITokenEngine {\n /** F13 advertisement: mint under a (transferId, opIndex) seed is idempotent-recoverable — a same-seed re-call converges, never double-mints. */\n public readonly deterministicMint = true;\n\n /** Hex form of the wallet key — deriveRealization's ikm input (Part E.1). */\n private readonly privateKeyHex: string;\n\n private readonly proofTimeoutMs: number;\n\n public constructor(private readonly deps: EngineDeps) {\n this.privateKeyHex = HexConverter.encode(deps.privateKey);\n // Refused here, not per op: a bad deadline must not surface as a money error.\n this.proofTimeoutMs = resolveProofTimeoutMs(deps.proofTimeoutMs);\n }\n\n // ── identity ────────────────────────────────────────────────────────────────\n\n public getIdentity(): EngineIdentity {\n return { chainPubkey: new Uint8Array(this.deps.signingService.publicKey) };\n }\n\n /** Legacy DIRECT:// address (Path A). Async: the derivation hashes via the SDK. */\n public deriveIdentityAddress(pubkey?: Uint8Array): Promise<string> {\n return deriveDirectAddress(pubkey ?? this.deps.signingService.publicKey);\n }\n\n // ── value (read) ─────────────────────────────────────────────────────────────\n\n public readValue(token: SphereToken): SphereValue | null {\n return token.value;\n }\n\n public balanceOf(token: SphereToken, coinId: CoinId): bigint {\n let sum = 0n;\n for (const asset of token.value?.assets ?? []) {\n if (asset.coinId === coinId) sum += asset.amount;\n }\n return sum;\n }\n\n public tokenId(token: SphereToken): string {\n return token.blob.tokenId;\n }\n\n public readMemo(token: SphereToken): Uint8Array | null {\n const sdkToken = token.sdkToken;\n // A transferred token delivers its memo on the latest transfer.\n if (sdkToken.transactions.length > 0) {\n return sdkToken.latestTransaction.data;\n }\n // A minted output (e.g. a split output) carries the memo in its value envelope.\n const data = sdkToken.genesis.data;\n if (data && this.isSpherePaymentData(data)) {\n return SpherePaymentData.fromCBOR(data).memo;\n }\n return null;\n }\n\n public readTokenData(token: SphereToken): Uint8Array | null {\n const data = token.sdkToken.genesis.data;\n return data ? new Uint8Array(data) : null;\n }\n\n // ── lifecycle ────────────────────────────────────────────────────────────────\n\n public async mint(params: MintParams, options?: EngineOpOptions): Promise<SphereToken> {\n const recipient = SignaturePredicate.create(params.recipientPubkey);\n const data = params.value ? await SpherePaymentData.fromValue(params.value).encode() : null;\n const transferId = this.resolveTransferId(options);\n const opIndex = this.resolveOpIndex(options);\n\n // #692 F13 — E.1: HKDF-derived salt (→ tokenId → stateId) + tokenType make a\n // re-call with the same transferId rebuild the byte-identical mint. The salt\n // gets its own 'mint' field domain: 'salt' is indexed by split-OUTPUT ordinal\n // under the same transferId, so ('salt', opIndex) would collide with output\n // #opIndex of a sibling split (see RealizationField).\n const mintTx = await MintTransaction.create(this.deps.networkId, recipient, {\n data,\n tokenType: new TokenType(deriveRealization(this.privateKeyHex, transferId, opIndex, 'tokenType')),\n salt: TokenSalt.fromBytes(deriveRealization(this.privateKeyHex, transferId, opIndex, 'mint')),\n });\n const certificationData = await CertificationData.fromMintTransaction(mintTx);\n\n // The same idempotent submit-then-always-probe primitive as transfer/split (E.2):\n // OK-match = mine (resume), mismatch = typed conflict, clean reject = submit error,\n // inconclusive = ProofUnconfirmedError (keep-open) — never inferred from the status.\n const proof = await this.submitAndAwaitProof(\n certificationData,\n mintTx,\n 'Mint certification failed',\n 'AGGREGATOR_ERROR',\n options,\n );\n const certified = await mintTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);\n const token = await Token.mint(certified, this.deps.verificationContext);\n return this.wrapToken(token);\n }\n\n public async mintDataToken(params: MintDataTokenParams, options?: EngineOpOptions): Promise<SphereToken> {\n const recipient = SignaturePredicate.create(params.recipientPubkey);\n const tokenType = params.tokenType ? new TokenType(params.tokenType) : TokenType.generate();\n // A deterministic salt yields a stable, terms-derived tokenId (TokenId.fromSalt).\n const salt = params.salt ? TokenSalt.fromBytes(params.salt) : TokenSalt.generate();\n\n const mintTx = await MintTransaction.create(this.deps.networkId, recipient, { data: params.data, tokenType, salt });\n const certificationData = await CertificationData.fromMintTransaction(mintTx);\n\n // #692 F13: the caller's deterministic salt already makes the re-call byte-identical;\n // routing through the probe primitive makes the re-call actually RECOVER (E.2).\n const proof = await this.submitAndAwaitProof(\n certificationData,\n mintTx,\n 'Data-token mint failed',\n 'AGGREGATOR_ERROR',\n options,\n );\n const certified = await mintTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);\n const token = await Token.mint(certified, this.deps.verificationContext);\n return this.wrapToken(token);\n }\n\n public async transfer(params: TransferParams, options?: EngineOpOptions): Promise<SphereToken> {\n this.assertOwned(params.token);\n const transferId = this.resolveTransferId(options);\n const recipient = SignaturePredicate.create(params.recipientPubkey);\n // E.1 deterministic realization: same transferId + inputs ⇒ byte-identical\n // transaction, so an interrupted transfer can be rebuilt and resumed (AC-E1/E2).\n const stateMask = StateMask.fromBytes(\n deriveRealization(this.privateKeyHex, transferId, this.resolveOpIndex(options), 'stateMask'),\n );\n\n const transferTx = await TransferTransaction.create(params.token.sdkToken, recipient, stateMask, {\n data: params.data ?? null,\n });\n const unlockScript = await SignaturePredicateUnlockScript.create(transferTx, this.deps.signingService);\n const certificationData = await CertificationData.fromTransaction(transferTx, unlockScript);\n\n const proof = await this.submitAndAwaitProof(\n certificationData,\n transferTx,\n 'Transfer certification failed',\n 'TRANSFER_FAILED',\n options,\n );\n const certified = await transferTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);\n const transferred = await params.token.sdkToken.transfer(certified, this.deps.verificationContext);\n return this.wrapToken(transferred);\n }\n\n public async split(params: SplitParams, options?: EngineOpOptions): Promise<SplitResult> {\n this.assertOwned(params.token);\n if (params.outputs.length === 0) {\n throw new SphereError('Split requires at least one output', 'VALIDATION_ERROR');\n }\n const transferId = this.resolveTransferId(options);\n\n // E.1 deterministic realization: per-output HKDF salts make every output's\n // mint transaction (and its salt-derived tokenId) reproducible from the\n // wallet key + transferId.\n const requests = params.outputs.map((o, i) =>\n SplitTokenRequest.create(\n SignaturePredicate.create(o.recipientPubkey),\n SpherePaymentData.create(PaymentAssetCollection.create(sphereAssetToSdk(o.coinId, o.amount)), o.data ?? null),\n TokenSalt.fromBytes(deriveRealization(this.privateKeyHex, transferId, i, 'salt')),\n ),\n );\n\n // Value conservation is enforced inside the SDK split (root.value === source value).\n // E.1: the burn state mask is HKDF-derived, so the whole split — burn leg\n // included — is rebuildable from the wallet key + transferId (crash resume).\n const split = await TokenSplit.split(params.token.sdkToken, decodeSpherePaymentData, requests, {\n burnStateMask: StateMask.fromBytes(\n deriveRealization(this.privateKeyHex, transferId, this.resolveOpIndex(options), 'burn'),\n ),\n });\n\n // 1. Resolve the burnt token: from a durable checkpoint on resume, else burn now and persist\n // the checkpoint BEFORE any mint submit (E.4 — the burn proof is the one non-re-derivable\n // split input; a mint certified against proof bytes that were never stored strands #501).\n const burntToken = await this.resolveBurntToken({ params, split, transferId, options });\n\n // 2. Mint every output IN PARALLEL (#684), each justified by the burnt token + its\n // own split proofs. The mints are independent legs off the ONE already-certified,\n // already-checkpointed burn (step 1, outside this fan-out — E.4 burn-before-mint\n // is unchanged), so they carry no ordering constraint among themselves.\n //\n // MONEY-SAFETY, identical to the prior sequential loop: `allSettled` waits for\n // EVERY leg (no leg abandoned mid-submit) and rethrows the LOWEST-index rejection,\n // which is the error the sequential loop surfaced — so keep-open classification is\n // unchanged. On failure the intent stays OPEN and resume re-runs all legs from the\n // durable checkpoint; an already-certified leg is recovered idempotently (#631/E.2),\n // so legs this fan-out submitted early are never lost. MAX_MINT_CONCURRENCY paces it.\n const settled: PromiseSettledResult<SphereToken>[] = [];\n for (let start = 0; start < split.tokens.length; start += MAX_MINT_CONCURRENCY) {\n const batch = split.tokens.slice(start, start + MAX_MINT_CONCURRENCY);\n settled.push(\n ...(await Promise.allSettled(\n batch.map((token) => this.mintSplitOutput(token, burntToken, options)),\n )),\n );\n }\n // Every leg has settled. Aggregate with a KEEP-OPEN BIAS. The old sequential loop never\n // submitted a later leg once an earlier one failed, so surfacing the first failure could\n // never orphan a certified sibling. THIS fan-out submits every leg, so a lower-index CLEAN\n // failure can coexist with a higher-index leg that already CERTIFIED (fulfilled) or MAY have\n // (a keep-open rejection). Surfacing the lowest-index CLEAN error in that case would let\n // PaymentsModule abort the intent (its committed-source set is still empty here) and strand\n // the certified sibling with no checkpoint recovery (Codex P1 on #684). So, in order:\n // 1. If ANY leg rejected keep-open (ProofUnconfirmed / SplitCheckpointLost / the E.4 pair),\n // surface that verbatim (lowest-index) so its specific keep-open type drives\n // PaymentsModule's classification exactly as before.\n // 2. Else (ANY clean rejection, whether or not a sibling certified) the BURN is already\n // committed + checkpointed (resolveBurntToken, above), so the source is spent on-chain.\n // Convert to a keep-open ProofUnconfirmedError (cause = the clean failure): a plain\n // abortable error would let PaymentsModule abort the intent and STRAND the whole source\n // value (the burn cannot be undone; an aborted intent never re-runs). Keep-open so resume\n // re-runs ALL legs idempotently from the burn checkpoint (HKDF-deterministic stateId → the\n // aggregator returns the existing proof; #631/E.2/E.3). A clean mint reject after a valid,\n // value-conserving burn is transient (e.g. a shard reconfiguration), never permanent.\n const keepOpenRejection = settled.find(\n (r): r is PromiseRejectedResult => r.status === 'rejected' && isKeepOpenSplitError(r.reason),\n );\n if (keepOpenRejection !== undefined) {\n throw keepOpenRejection.reason;\n }\n const firstRejected = settled.findIndex((r) => r.status === 'rejected');\n if (firstRejected !== -1) {\n const cleanReason = (settled[firstRejected] as PromiseRejectedResult).reason;\n // 3. Else (every rejection is clean — none keep-open) the burn is STILL committed +\n // checkpointed (resolveBurntToken, above), whether or not a sibling certified. Surfacing\n // a plain abortable clean error would let PaymentsModule abort the intent and STRAND the\n // entire source value — the burn cannot be undone and an aborted intent never re-runs. So\n // EVERY post-burn mint failure is keep-open: resume re-runs all legs idempotently from the\n // burn checkpoint. (A clean mint reject after a valid, value-conserving burn is transient —\n // e.g. a shard reconfiguration — not a permanent validation failure; keep-open leaves the\n // funds RECOVERABLE, abort loses them.)\n throw new ProofUnconfirmedError(\n settled.some((r) => r.status === 'fulfilled')\n ? 'a split mint leg certified while a sibling leg failed — keep the intent open; resume ' +\n 'completes all legs idempotently from the burn checkpoint (#684 parallel fan-out)'\n : 'every split mint leg failed after the burn certified — keep the intent open; resume ' +\n 're-runs all legs idempotently from the burn checkpoint (post-burn must never abort)',\n cleanReason,\n );\n }\n const outputs = settled.map((r) => (r as PromiseFulfilledResult<SphereToken>).value);\n return { outputs };\n }\n\n /**\n * E.4 burnt-token resolution. With a checkpoint store: `get` → rebuild from the STORED proof on\n * resume; else a leg-0 pre-flight probe (a certified leaf with no checkpoint is unrecoverable),\n * then burn, persist the checkpoint (durable-ack gated), and adopt the authoritative stored\n * bytes. Without a store: burn as before (a documented residual for fully-local compositions).\n */\n private async resolveBurntToken(ctx: SplitContext): Promise<Token> {\n const store = ctx.options?.checkpointStore;\n const opIndex = this.resolveOpIndex(ctx.options);\n const source = ctx.params.token.sdkToken;\n if (store === undefined) {\n return (await this.burnSource(ctx)).burntToken;\n }\n const stored = await store.get(ctx.transferId, opIndex);\n if (stored !== null) {\n return burntTokenFromCheckpoint(this.deps, stored, ctx.split.burn.transaction, source);\n }\n await this.assertNoLegStranded(ctx);\n const { burntToken, burnProof } = await this.burnSource(ctx);\n const envelope = await encodeCheckpoint(ctx.split.burn.transaction, burnProof, burntToken);\n // The durable-ack gate: `put` resolving IS the ack, and NO mint has been submitted yet.\n let authoritative: Uint8Array;\n try {\n authoritative = await store.put(ctx.transferId, opIndex, envelope);\n } catch (err) {\n throw new CheckpointPersistFailedError(\n 'split burn certified but its checkpoint could not be persisted — keep the intent open and resume',\n err,\n );\n }\n // Decode-from-stored discipline: mint from the AUTHORITATIVE bytes (ours, or a racing resumer's\n // that won the slot), never the pre-store in-memory burnt token — so concurrent resumers agree.\n return burntTokenFromCheckpoint(this.deps, authoritative, ctx.split.burn.transaction, source);\n }\n\n /** Burn the source: certify the burn transfer and append it -> burntToken (+ its proof). */\n private async burnSource(ctx: SplitContext): Promise<{ burntToken: Token; burnProof: InclusionProof }> {\n const burnTx = ctx.split.burn.transaction;\n const burnUnlock = await SignaturePredicateUnlockScript.create(burnTx, this.deps.signingService);\n const burnCert = await CertificationData.fromTransaction(burnTx, burnUnlock);\n const burnProof = await this.submitAndAwaitProof(burnCert, burnTx, 'Split burn failed', 'TRANSFER_FAILED', ctx.options);\n const burnCertified = await burnTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, burnProof);\n const burntToken = await ctx.params.token.sdkToken.transfer(burnCertified, this.deps.verificationContext);\n return { burntToken, burnProof };\n }\n\n /**\n * Pre-flight (no-checkpoint path): if ANY mint leaf is already certified on-chain while the\n * checkpoint is missing, the burn proof is genuinely unrecoverable — fail BEFORE any re-burn. A\n * mint's stateId is justification-INDEPENDENT (only the source state hash + salt-derived mask),\n * so a probe mint with a null justification derives the true on-chain key. Every leg is probed,\n * so correctness does NOT depend on the mint loop certifying leg 0 first (E.4 step 3).\n */\n private async assertNoLegStranded(ctx: SplitContext): Promise<void> {\n // #684: probe every leg's stateId IN PARALLEL — read-only getInclusionProof calls,\n // order-independent (it throws if ANY leg is already certified). Promise.all rejects\n // on the first stranded leg, same as the prior sequential loop.\n await Promise.all(\n ctx.split.tokens.map(async (leg) => {\n const data = await leg.paymentData.encode();\n const probe = await MintTransaction.create(leg.networkId, leg.recipient, {\n data,\n tokenType: leg.tokenType,\n salt: leg.salt,\n justification: null,\n });\n const response = await this.deps.client.getInclusionProof(await StateId.fromTransaction(probe));\n // v3: a null `inclusionProof` IS \"not certified yet\"; a present one always\n // describes a real leaf, so there is no longer a field to misread here.\n if (response.inclusionProof !== null) {\n throw new SplitCheckpointLostError(\n 'a split mint leaf is certified on-chain but no burn checkpoint exists — outputs are unrecoverable',\n );\n }\n }),\n );\n }\n\n /** One split output: build the justification from the burnt token, submit, certify, wrap. */\n private async mintSplitOutput(\n splitToken: SplitToken,\n burntToken: Token,\n options?: EngineOpOptions,\n ): Promise<SphereToken> {\n const data = await splitToken.paymentData.encode();\n const justification = SplitMintJustification.create(burntToken, splitToken.proofs).toCBOR();\n const mintTx = await MintTransaction.create(splitToken.networkId, splitToken.recipient, {\n data,\n tokenType: splitToken.tokenType,\n salt: splitToken.salt,\n justification,\n });\n const certData = await CertificationData.fromMintTransaction(mintTx);\n const proof = await this.submitSplitMintLeg(certData, mintTx, options);\n const certified = await mintTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);\n const token = await Token.mint(certified, this.deps.verificationContext);\n return this.wrapToken(token);\n }\n\n /**\n * Submit one split-mint leg. A `TRANSACTION_HASH_MISMATCH` on a mint leg is NOT a foreign spend\n * (its stateId is HKDF-derived from `(seed, transferId)`, so only a seed-holder under THIS\n * transferId could have certified a different leaf): the stored checkpoint no longer reproduces\n * the certified leaf → keep-open `SplitCheckpointLostError`, never the abort-and-re-plan\n * `TransferConflictError` (E.2/E.4 split-mint arm).\n */\n private async submitSplitMintLeg(\n certData: CertificationData,\n mintTx: MintTransaction,\n options?: EngineOpOptions,\n ): Promise<InclusionProof> {\n try {\n return await this.submitAndAwaitProof(certData, mintTx, 'Split mint failed', 'AGGREGATOR_ERROR', options);\n } catch (err) {\n if (err instanceof TransferConflictError) {\n throw new SplitCheckpointLostError(\n 'a split mint leg no longer matches its certified leaf — the burn checkpoint is stale or lost',\n err,\n );\n }\n throw err;\n }\n }\n\n // ── verification ─────────────────────────────────────────────────────────────\n\n public async verify(token: SphereToken, _options?: EngineOpOptions): Promise<EngineVerifyResult> {\n // Both verifiers produce the same aggregated result; the worker one only\n // moves the independent per-transfer work off this thread.\n const result = this.deps.tokenVerifier\n ? await this.deps.tokenVerifier.verify(token.sdkToken, this.deps.verificationContext)\n : await token.sdkToken.verify(this.deps.verificationContext);\n return result.status === VerificationStatus.OK ? { ok: true } : { ok: false, reason: String(result.status) };\n }\n\n public isOwnedBy(token: SphereToken, pubkey: Uint8Array): boolean {\n const owner = token.sdkToken.latestTransaction.recipient;\n const claimed = EncodedPredicate.fromPredicate(SignaturePredicate.create(pubkey));\n return EncodedPredicate.equals(owner, claimed);\n }\n\n public async isSpent(token: SphereToken, _options?: EngineOpOptions): Promise<boolean> {\n // The token's current state id = what a future transfer would spend. Derive it via a\n // probe transfer (never submitted) — StateId depends only on the source's lock script\n // and state hash, not on the recipient or state mask.\n const probe = await TransferTransaction.create(\n token.sdkToken,\n SignaturePredicate.create(this.deps.signingService.publicKey),\n StateMask.fromBytes(new Uint8Array(32)),\n );\n const stateId = await StateId.fromTransaction(probe);\n const response = await this.deps.client.getInclusionProof(stateId);\n // Consumed iff the aggregator answers with a PROOF. Reporting an UNSPENT state\n // as spent destroys a live token via the fail-closed recovery gates.\n return response.inclusionProof !== null;\n }\n\n // ── serialization ────────────────────────────────────────────────────────────\n\n /** @inheritDoc — SDK-derived (Token.fromCBOR → latestTransaction.calculateStateHash().imprint). */\n public deliveryKeys(blobBytes: Uint8Array): Promise<{ tokenId: string; stateHash: string }> {\n return deriveDeliveryKeys(blobBytes);\n }\n\n public encodeToken(token: SphereToken): TokenBlob {\n return token.blob;\n }\n\n public async decodeToken(blob: TokenBlob): Promise<SphereToken> {\n const sdkToken = await Token.fromCBOR(blob.token);\n if (sdkToken.genesis.networkId.id !== this.deps.networkId.id) {\n throw new SphereError(\n `Token network mismatch: token is on network ${sdkToken.genesis.networkId.id}, ` +\n `engine on ${this.deps.networkId.id}`,\n 'VALIDATION_ERROR',\n );\n }\n return this.wrapToken(sdkToken);\n }\n\n // ── internals ────────────────────────────────────────────────────────────────\n\n /**\n * The effective realization seed for one transfer/split (Part E). A caller\n * that wants resumability supplies a pre-persisted UUIDv4 (sdk-changes E.3);\n * otherwise one is generated here — same derivation path, just non-resumable.\n * The canonical-lowercase-UUID check also keeps the HKDF info string\n * unambiguous (no ':' injection, no case-variant double derivations).\n */\n /** Validated op ordinal (§8.1 mask domain separation across ops of one send). */\n private resolveOpIndex(options?: EngineOpOptions): number {\n const opIndex = options?.opIndex ?? 0;\n if (!Number.isInteger(opIndex) || opIndex < 0) {\n throw new SphereError(`opIndex must be a non-negative integer, got ${String(opIndex)}`, 'VALIDATION_ERROR');\n }\n return opIndex;\n }\n\n private resolveTransferId(options?: EngineOpOptions): string {\n const transferId = options?.transferId ?? randomUUID();\n if (!TRANSFER_ID_RE.test(transferId)) {\n throw new SphereError(\n `transferId must be a canonical lowercase UUID string, got \"${transferId}\"`,\n 'VALIDATION_ERROR',\n );\n }\n return transferId;\n }\n\n /**\n * E.2 — status-agnostic idempotent submit with conflict detection\n * (sdk-changes E.2, ARCHITECTURE §8.1).\n *\n * Submit the certification request and treat ANY outcome — success status,\n * error status, or a response-parse throw (the live gateway may still emit\n * statuses this SDK no longer parses, e.g. the transitional STATE_ID_EXISTS)\n * — as \"a certification for this state may already exist\". Then ALWAYS fetch\n * the inclusion proof and match-verify it against the rebuilt transaction\n * (`waitInclusionProof` only returns an OK-verified proof):\n *\n * - match (OK) → proceed; this is how an interrupted\n * attempt with the same transferId resumes;\n * - mismatch (hash ≠ rebuilt tx) → `TransferConflictError`: the source was\n * consumed by a DIFFERENT transaction (lost\n * race) — never applied, never retried;\n * - no proof & the submit failed → the original submit error (a genuine\n * failure, not a resume case).\n */\n private async submitAndAwaitProof(\n certificationData: CertificationData,\n transaction: ITransaction,\n failLabel: string,\n failCode: SphereErrorCode,\n options?: EngineOpOptions,\n ): Promise<InclusionProof> {\n const deadline = certificationDeadline(\n this.proofTimeoutMs,\n options?.signal,\n `${failLabel}: not certified`\n );\n try {\n return await this.submitThenProve(certificationData, transaction, failLabel, failCode, deadline.signal);\n } finally {\n deadline.dispose();\n }\n }\n\n /** One certification attempt under one deadline: the metered submit retries\n * transient answers instead of falling through to a proof that cannot exist. */\n private async submitThenProve(\n certificationData: CertificationData,\n transaction: ITransaction,\n failLabel: string,\n failCode: SphereErrorCode,\n signal: AbortSignal,\n ): Promise<InclusionProof> {\n let submitError: unknown = null;\n // True ONLY for a KNOWN validation-reject status: a PROVEN clean pre-certification\n // reject. Everything else stays INDETERMINATE (keep-open, #631) — including any\n // submit that was RETRIED, since the earlier POST may already have been processed\n // server-side, which is what sawAmbiguousAttempt latches (#747 review).\n let submitRejectedCleanly = false;\n try {\n const { value: response, retried } = await retryTransient(\n async () => {\n const answer = await this.deps.client.submitCertificationRequest(certificationData);\n // A booting gateway is \"ask again\", not a certification failure — see\n // TransientSubmitAnswer. Everything else, known or unknown, keeps the\n // status-agnostic treatment below.\n if (String(answer.status) === String(CertificationStatus.SERVICE_NOT_READY)) {\n throw new TransientSubmitAnswer(String(answer.status));\n }\n return answer;\n },\n signal,\n this.deps.proofPollIntervalMs ?? DEFAULT_PROOF_POLL_INTERVAL_MS,\n );\n if (response.status !== CertificationStatus.SUCCESS) {\n submitError = new SphereError(`${failLabel}: ${response.status}`, failCode);\n submitRejectedCleanly = !retried && CLEAN_REJECT_STATUSES.has(response.status);\n }\n } catch (err) {\n submitError = err ?? new SphereError(`${failLabel}: submit failed`, failCode);\n }\n\n try {\n return await awaitProofBounded(\n {\n client: this.deps.client,\n trustBase: this.deps.trustBase,\n predicateVerifier: this.deps.predicateVerifier,\n unicityCertificateVerifier: this.deps.unicityCertificateVerifier,\n intervalMs: this.deps.proofPollIntervalMs ?? DEFAULT_PROOF_POLL_INTERVAL_MS, // #683\n },\n transaction,\n signal,\n );\n } catch (err) {\n throw certificationFailure(err, failLabel, submitError, submitRejectedCleanly);\n }\n }\n\n\n /**\n * One inclusion-proof wait, with the deadline OWNED here (#739) so it is bounded\n * and configurable rather than the SDK's fixed default. A hit throws, and the\n * caller maps it to ProofUnconfirmedError (keep-open) — the correct posture,\n * since the spend may be on-chain.\n */\n /** Fail fast if this engine's key does not own the token's current state. */\n private assertOwned(token: SphereToken): void {\n if (!this.isOwnedBy(token, this.deps.signingService.publicKey)) {\n throw new SphereError('Cannot transfer a token not owned by this engine identity', 'VALIDATION_ERROR');\n }\n }\n\n /** Wrap an SDK token into a SphereToken: cache its blob (incl. stable tokenId) + decoded value. */\n private wrapToken(sdkToken: Token): SphereToken {\n const data = sdkToken.genesis.data;\n let value: SphereValue | null = null;\n // Only value tokens carry a SpherePaymentData envelope; data tokens (e.g. invoices)\n // leave value === null. A corrupt value envelope still errors loudly.\n if (data && this.isSpherePaymentData(data)) {\n try {\n value = SpherePaymentData.fromCBOR(data).toValue();\n } catch (err) {\n throw new SphereError(\n `Failed to decode token payment data: ${err instanceof Error ? err.message : String(err)}`,\n 'VALIDATION_ERROR',\n );\n }\n }\n const blob: TokenBlob = {\n tokenId: HexConverter.encode(sdkToken.id.bytes),\n token: sdkToken.toCBOR(),\n };\n return { sdkToken, blob, value };\n }\n\n /** True if the bytes are a SpherePaymentData envelope (value token) vs a raw data token. */\n private isSpherePaymentData(data: Uint8Array): boolean {\n try {\n return CborDeserializer.decodeTag(data).tag === SpherePaymentData.CBOR_TAG;\n } catch {\n return false;\n }\n }\n /**\n * Terminate the verification worker pool, if this engine was configured with\n * one. Idempotent — the pool's dispose only touches workers it spawned.\n */\n public dispose(): void {\n this.deps.tokenVerifier?.dispose();\n }\n\n}\n","/**\n * token-engine/factory.ts — the real engine constructor (A4).\n *\n * `createSphereTokenEngine` is the public way to obtain an ITokenEngine. It maps\n * the sphere-domain EngineConfig to the SDK objects the engine needs: the\n * aggregator client (from `aggregatorUrl`), the trust base (parsed from\n * `trustBaseJson`), the wallet signing key (from `privateKey`), the network id,\n * and a mint-justification verifier with the split verifier registered (so\n * split-output tokens verify).\n *\n * Loading the trust base per environment (browser fetch / node file) stays with\n * the caller (impl/<env>/oracle, reusing the existing trust-base loaders); it\n * passes the parsed JSON in via `trustBaseJson`, keeping this factory env-agnostic.\n */\n\nimport { SphereError } from '../core/errors';\nimport { logger } from '../core/logger';\nimport {\n AggregatorClient,\n MintJustificationVerifierService,\n PredicateVerifierService,\n RootTrustBase,\n Secp256k1SignatureVerifier,\n SigningService,\n SplitMintJustificationVerifier,\n StateTransitionClient,\n TokenIssuanceVerifierService,\n UnicityCertificateVerifier,\n UnicitySealQuorumSignaturesVerificationRule,\n VerificationContext,\n VerifiedSealCache,\n WorkerTokenVerifier,\n type IWorker,\n} from './sdk';\nimport { decodeSpherePaymentData } from './SpherePaymentData';\nimport { type DisposableTokenVerifier, type EngineDeps, SphereTokenEngine } from './SphereTokenEngine';\nimport type { EngineConfig, ITokenEngine, VerificationWorker, VerificationWorkerConfig } from './engine';\n\nconst DEFAULT_VERIFICATION_POOL_SIZE = 4;\n\n/** #770(4): what a verification cancelled by `dispose()` rejects with. */\nfunction disposedError(): SphereError {\n return new SphereError(\n 'Verification worker pool disposed — the in-flight verification was cancelled',\n 'MODULE_DESTROYED',\n );\n}\n\n/**\n * The consumer's worker factory, bound to the base SDK's pool verifier. The SDK\n * leaves `createWorker()` abstract so the platform choice stays with the consumer;\n * the cast is the port boundary (same web-`Worker` subset, payloads `unknown` on\n * our side so no SDK wire type escapes).\n *\n * ── #770(4): dispose() must SETTLE the in-flight batch ──────────────────────────\n * The SDK's `WorkerPool.dispose()` (3.0.1) only calls `worker.terminate()` on\n * every worker it spawned. A dispatched task resolves ONLY from `worker.onmessage`,\n * which a terminated worker never posts, and queued tasks are never drained — so\n * `WorkerTokenVerifier.verify`, which awaits `Promise.all(pool.run(...))`, hangs\n * FOREVER. `pool` is `private readonly` upstream, so the settle has to live here.\n *\n * Reachable in production: `Sphere.setOracleApiKey` → `PaymentsFacade.setEngine`\n * disposes the engine it replaced while a receive drain may be mid-`verify`.\n *\n * The cancellation MUST REJECT — never resolve `{ ok: false }`. The only\n * `engine.verify` caller in the money path is `modules/payments-v2/receive/Receive.ts`\n * (`screen()`, the `const verdict = await engine.verify(token)` line): a falsy\n * verdict there is a PERMANENT `rejectAck(entry, 'invalid')`, i.e. a VALID\n * incoming token thrown away at the mailbox because an api-key change happened\n * to land mid-drain. A rejection instead propagates to the drain's catch, which\n * leaves the entry UNACKED so it re-lists on the next drain.\n *\n * ── Why the cancellation is PER CALL, not one shared promise ──────────────────\n * Racing every verify() against a single long-lived never-settling promise\n * LEAKS: `Promise.race` subscribes to every input and does not detach when\n * another input wins, so each finished verification pins a reaction record to\n * that promise until dispose() — retention growing with every token the wallet\n * has ever verified, inside the very class added to fix a teardown bug. So each\n * call registers its own rejector in `cancellations` and drops it the instant\n * the call settles: retention is bounded by CONCURRENT verifications, never by\n * lifetime count. No parked `.catch()` is needed to keep a cancellation from\n * becoming an unhandled rejection either — the only promise built per call is\n * the one RETURNED, so its rejection is the caller's to observe, as before, and\n * no promise this class creates outlives the call that created it.\n */\nclass ConfiguredWorkerTokenVerifier extends WorkerTokenVerifier {\n private disposed = false;\n /** One rejector per IN-FLIGHT verify(), dropped on settle; empty when idle. */\n private readonly cancellations = new Set<() => void>();\n\n public constructor(\n private readonly spawn: () => VerificationWorker,\n poolSize: number\n ) {\n super(poolSize);\n }\n\n /** Verifications awaiting a verdict — back to 0 whenever the verifier is idle. */\n public get pendingCancellations(): number {\n return this.cancellations.size;\n }\n\n /** Rejects (see the class note) if `dispose()` lands before the pool answers. */\n public override verify(\n ...args: Parameters<WorkerTokenVerifier['verify']>\n ): ReturnType<WorkerTokenVerifier['verify']> {\n if (this.disposed) return Promise.reject(disposedError());\n const verdict = super.verify(...args);\n return new Promise((resolve, reject) => {\n const cancel = (): void => reject(disposedError());\n this.cancellations.add(cancel);\n // Defensive, and currently UNREACHABLE — the SDK awaits the genesis rule before\n // fanning transfers out, so a reentrant dispose() (a worker's postMessage handler\n // runs on THIS thread) cannot land before this line. Kept because that ordering is\n // an internal detail of a pinned dependency: fan out first and dispose() would\n // clear the set BEFORE registration, hanging this promise on a dead worker.\n if (this.disposed) {\n this.cancellations.delete(cancel);\n cancel();\n }\n // Settling twice is a no-op, so a verdict landing after dispose() cancelled\n // the call can never downgrade that rejection into a falsy verdict.\n void verdict.then(\n (result) => {\n this.cancellations.delete(cancel);\n resolve(result);\n },\n (error: unknown) => {\n this.cancellations.delete(cancel);\n reject(error);\n }\n );\n });\n }\n\n /** Idempotent — Sphere.setOracleApiKey disposes the replaced engine twice (facade + caller). */\n public override dispose(): void {\n if (this.disposed) return;\n this.disposed = true;\n super.dispose(); // terminate() every spawned worker, as before\n // Only AFTER the pool is down: settle whatever the terminated workers will\n // now never answer. A no-op when nothing is in flight.\n const cancelling = [...this.cancellations];\n this.cancellations.clear();\n for (const cancel of cancelling) cancel();\n }\n\n protected createWorker(): IWorker {\n // The SDK's dispose() leaves its `workers` array populated, so a task that\n // slips in afterwards would call acquire() → createWorker() and RESURRECT\n // the pool it just tore down. Fail instead.\n if (this.disposed) throw disposedError();\n return this.spawn() as unknown as IWorker;\n }\n}\n\n/**\n * A verifier whose in-flight verifications `dispose()` cancels. `pendingCancellations`\n * is the observable that the bookkeeping behind that is per-call and short-lived\n * (see the class note): it must return to 0 as verifications settle, never grow\n * with the number of tokens verified.\n */\nexport interface CancellableTokenVerifier extends DisposableTokenVerifier {\n readonly pendingCancellations: number;\n}\n\n/** Workers spawn LAZILY on first verify and are reused, so this costs nothing to build. */\nexport function createWorkerTokenVerifier(config: VerificationWorkerConfig): CancellableTokenVerifier {\n const poolSize = config.poolSize ?? DEFAULT_VERIFICATION_POOL_SIZE;\n if (!Number.isInteger(poolSize) || poolSize < 1) {\n throw new TypeError(`verification.poolSize must be a positive integer, got ${String(config.poolSize)}`);\n }\n return new ConfiguredWorkerTokenVerifier(config.createWorker, poolSize);\n}\n\nexport async function createSphereTokenEngine(config: EngineConfig): Promise<ITokenEngine> {\n if (config.trustBaseJson == null) {\n throw new SphereError('Engine config requires a trust base (trustBaseJson)', 'INVALID_CONFIG');\n }\n\n if (!config.apiKey) {\n logger.warn(\n 'TokenEngine',\n 'No aggregator apiKey — pass config.oracle.apiKey (testnet2 value in .env.example; mainnet from a secret env var). Gateway requests will be unauthenticated.',\n );\n }\n\n const trustBase = RootTrustBase.fromJSON(config.trustBaseJson);\n const predicateVerifier = PredicateVerifierService.create();\n // st-sdk 2.1.0: seal verification is memoised per rule instance. Every leaf\n // certified in one aggregator round shares a seal, so a multi-token send's\n // proofs collapse onto a handful of seals instead of re-verifying each.\n const unicityCertificateVerifier = new UnicityCertificateVerifier(\n new UnicitySealQuorumSignaturesVerificationRule(new Secp256k1SignatureVerifier(), new VerifiedSealCache(256)),\n );\n const mintJustificationVerifier = new MintJustificationVerifierService();\n mintJustificationVerifier.register(\n new SplitMintJustificationVerifier(decodeSpherePaymentData),\n );\n\n const deps: EngineDeps = {\n client: new StateTransitionClient(new AggregatorClient(config.aggregatorUrl, config.apiKey ?? null)),\n trustBase,\n predicateVerifier,\n unicityCertificateVerifier,\n mintJustificationVerifier,\n verificationContext: new VerificationContext(\n trustBase,\n predicateVerifier,\n unicityCertificateVerifier,\n mintJustificationVerifier,\n new TokenIssuanceVerifierService(false),\n ),\n signingService: new SigningService(config.privateKey),\n // Also the HKDF ikm for deterministic realization (Part E.1) — the\n // SigningService wraps the key but does not expose it back.\n privateKey: config.privateKey,\n // The trust base is the single source of truth for the network id (it carries\n // NetworkId.fromId, so any id works — e.g. testnet2 = 4 — with no enum entry).\n networkId: trustBase.networkId,\n // #683: forward the (optional) proof-poll cadence; undefined → the engine default.\n proofPollIntervalMs: config.proofPollIntervalMs,\n proofTimeoutMs: config.proofTimeoutMs, // #739: was declared but never wired\n // Opt-in parallel verification (2.0.2). Absent → the sequential verifier.\n ...(config.verification ? { tokenVerifier: createWorkerTokenVerifier(config.verification) } : {}),\n };\n\n return new SphereTokenEngine(deps);\n}\n"],"mappings":"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","names":["sha256","sha256","sha256"]}
|