@provablehq/sdk 0.11.3 → 0.11.4

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.
@@ -439,6 +439,7 @@ exports.defaultTransport = browser.defaultTransport;
439
439
  exports.encryptAuthorization = browser.encryptAuthorization;
440
440
  exports.encryptProvingRequest = browser.encryptProvingRequest;
441
441
  exports.encryptRegistrationRequest = browser.encryptRegistrationRequest;
442
+ exports.encryptSerializedProvingRequest = browser.encryptSerializedProvingRequest;
442
443
  exports.encryptViewKey = browser.encryptViewKey;
443
444
  exports.generateHookData = browser.generateHookData;
444
445
  exports.getLogLevel = browser.getLogLevel;
@@ -452,6 +453,7 @@ exports.isViewKeyStrategy = browser.isViewKeyStrategy;
452
453
  exports.logAndThrow = browser.logAndThrow;
453
454
  exports.programChecksum = browser.programChecksum;
454
455
  exports.provingKeyLocator = browser.provingKeyLocator;
456
+ exports.serializeProvingRequest = browser.serializeProvingRequest;
455
457
  exports.setLogLevel = browser.setLogLevel;
456
458
  exports.sha256Hex = browser.sha256Hex;
457
459
  exports.toAddress = browser.toAddress;
@@ -1 +1 @@
1
- {"version":3,"file":"node.cjs","sources":["../../src/keys/keystore/file.ts"],"sourcesContent":["import * as fs from \"node:fs/promises\";\nimport * as fsSync from \"node:fs\";\nimport * as path from \"path\";\n\nimport { FunctionKeyPair } from \"../../models/keyPair.js\";\nimport { KeyFingerprint } from \"../verifier/interface.js\";\nimport { InvalidLocatorError } from \"./error.js\";\nimport { KeyLocator, KeyStore, ProvingKeyLocator, VerifyingKeyLocator } from \"./interface.js\";\nimport { MemKeyVerifier } from \"../verifier/memory.js\";\nimport { ProvingKey, VerifyingKey } from \"../../wasm.js\";\n\nexport class LocalFileKeyStore implements KeyStore {\n private directory: string;\n private readonly keyVerifier = new MemKeyVerifier();\n\n /**\n * Creates a new directory at the given path or CURRENTDIR/.aleo if none is provided to store keys.\n * If a custom directory is passed and its last path segment is not \".aleo\", \".aleo\" is appended\n * so keys are stored under that subdirectory (e.g. /home/project → /home/project/.aleo).\n *\n * @param {string} [directory] - Optional custom directory path for key storage. Defaults to \".aleo\" in current working directory.\n * @throws {Error} If directory creation fails.\n */\n constructor(directory?: string) {\n this.directory = directory ?? path.join(process.cwd(), \".aleo\");\n if (directory !== undefined && path.basename(this.directory) !== \".aleo\") {\n this.directory = path.join(this.directory, \".aleo\");\n }\n fsSync.mkdirSync(this.directory, { recursive: true });\n }\n\n /**\n * Validates a single locator component for unsafe filesystem characters.\n *\n * @private\n * @param {string} value - The component value to validate.\n * @param {string} label - Label for error messages (e.g. \"program\", \"functionName\").\n * @throws {InvalidLocatorError} If the value is empty, contains traversal sequences, path separators, or null bytes.\n */\n private validateComponent(value: string, label: string): void {\n if (value === \"\" || value === \".\") {\n throw new InvalidLocatorError(\n `KeyLocator ${label} must not be empty or \".\" (got \"${value}\")`,\n value,\n \"reserved_name\"\n );\n }\n if (value.includes(\"..\")) {\n throw new InvalidLocatorError(\n `KeyLocator ${label} must not contain \"..\" (got \"${value}\")`,\n value,\n \"path_traversal\"\n );\n }\n if (value.includes(\"/\") || value.includes(\"\\\\\") || value.includes(\"\\0\")) {\n throw new InvalidLocatorError(\n `KeyLocator ${label} must not contain path separators or null bytes (got \"${value}\")`,\n value,\n \"path_separator\"\n );\n }\n }\n\n /**\n * Validates that a numeric locator field is not negative.\n *\n * @private\n * @param {number} value - The numeric value to validate.\n * @param {string} label - Label for error messages (e.g. \"edition\", \"amendment\").\n * @throws {InvalidLocatorError} If the value is negative.\n */\n private validateNonNegative(value: number, label: string): void {\n if (!Number.isInteger(value) || value < 0) {\n throw new InvalidLocatorError(\n `KeyLocator ${label} must be a non-negative integer (got ${value})`,\n String(value),\n \"negative_value\"\n );\n }\n }\n\n /**\n * Serializes a {@link KeyLocator} to a filesystem-safe flat string, validating components first.\n *\n * For prover/verifier keys: `{program}.{functionName}.e{edition}.a{amendment}.{network}.{keyType}`\n * For translation keys: `{program}.{functionName}.e{edition}.a{amendment}.{network}.translation.{recordName}.{recordInputPosition}`\n *\n * Note: The optional `checksum` field is excluded — it is used for integrity verification only\n * (via {@link checksumToFingerprint}) and is not part of the key identity.\n *\n * @private\n * @param {KeyLocator} locator - The key locator.\n * @returns {string} A dot-delimited string safe for use as a filename.\n * @throws {InvalidLocatorError} If any component contains unsafe characters.\n */\n private serializeLocator(locator: KeyLocator): string {\n this.validateComponent(locator.program, \"program\");\n this.validateComponent(locator.functionName, \"functionName\");\n this.validateComponent(locator.network, \"network\");\n this.validateNonNegative(locator.edition, \"edition\");\n this.validateNonNegative(locator.amendment, \"amendment\");\n const base = `${locator.program}.${locator.functionName}.e${locator.edition}.a${locator.amendment}.${locator.network}.${locator.keyType}`;\n if (locator.keyType === \"translation\") {\n this.validateComponent(locator.recordName, \"recordName\");\n this.validateNonNegative(locator.recordInputPosition, \"recordInputPosition\");\n return `${base}.${locator.recordName}.${locator.recordInputPosition}`;\n }\n return base;\n }\n\n /**\n * Converts an optional checksum string from a locator into a KeyFingerprint\n * suitable for the key verifier, using the actual key byte length for size.\n *\n * @private\n */\n private checksumToFingerprint(checksum: string | undefined, keyBytes: Uint8Array): KeyFingerprint | undefined {\n if (!checksum) return undefined;\n return { checksum, size: keyBytes.length };\n }\n\n /**\n * Generates the path for a key metadata file based on the locator.\n *\n * @private\n * @param {string} locator - Unique identifier for the key.\n * @returns {string} Full filesystem path to the metadata file.\n */\n private metadataPath(locator: string): string {\n return path.join(this.directory, `${locator}.metadata`);\n }\n\n /**\n * Reads and parses the key fingerprint metadata from storage.\n *\n * @private\n * @param {string} locator - Unique identifier for the key.\n * @returns {Promise<KeyFingerprint | null>} The key fingerprint if found, null if file doesn't exist.\n * @throws {Error} If file read fails for any reason other than not found.\n */\n private async readKeyMetadata(\n locator: string,\n ): Promise<KeyFingerprint | null> {\n try {\n const data = await fs.readFile(this.metadataPath(locator), \"utf-8\");\n return JSON.parse(data) as KeyFingerprint;\n } catch (err: unknown) {\n if (\n err &&\n typeof err === \"object\" &&\n \"code\" in err &&\n err.code === \"ENOENT\"\n )\n return null;\n throw err;\n }\n }\n\n /**\n * Writes key fingerprint metadata to storage.\n *\n * @private\n * @param {string} locator - Unique identifier for the key.\n * @param {KeyFingerprint} metadata - Key fingerprint metadata to store.\n * @returns {Promise<void>}\n * @throws {Error} If directory creation or file write fails.\n */\n private async writeKeyMetadata(\n locator: string,\n metadata: KeyFingerprint,\n ): Promise<void> {\n await fs.mkdir(path.dirname(this.metadataPath(locator)), {\n recursive: true,\n });\n await fs.writeFile(\n this.metadataPath(locator),\n JSON.stringify(metadata, null, 0),\n \"utf-8\",\n );\n }\n\n private async readFileOptional(\n filepath: string,\n ): Promise<Uint8Array | null> {\n try {\n const data = await fs.readFile(filepath);\n return new Uint8Array(data);\n } catch (err: any) {\n if (err.code === \"ENOENT\") return null;\n throw err;\n }\n }\n\n /**\n * Atomically writes data to a file, ensuring the parent directories exist.\n *\n * @private\n * @param {string} filepath - Full path to the file to write\n * @param {Uint8Array} data - Binary data to write to the file\n * @returns {Promise<void>} Resolves when write is complete\n * @throws {Error} If directory creation or file write fails\n */\n private async writeFileAtomic(\n filepath: string,\n data: Uint8Array,\n ): Promise<void> {\n const dir = path.dirname(filepath);\n await fs.mkdir(dir, { recursive: true });\n const tempPath = path.join(\n dir,\n `.${path.basename(filepath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`\n );\n await fs.writeFile(tempPath, data);\n try {\n await fs.rename(tempPath, filepath);\n } catch (err: unknown) {\n const code = err && typeof err === \"object\" && \"code\" in err ? (err as NodeJS.ErrnoException).code : undefined;\n // Windows often throws EEXIST when target exists; EPERM/EACCES happen with locks/AV.\n if (code === \"EEXIST\" || code === \"EPERM\" || code === \"EACCES\") {\n await fs.unlink(filepath).catch(() => {});\n try {\n await fs.rename(tempPath, filepath);\n } catch (err2) {\n await fs.unlink(tempPath).catch(() => {});\n throw err2;\n }\n } else {\n await fs.unlink(tempPath).catch(() => {});\n throw err;\n }\n }\n }\n\n /**\n * Recursively removes all files and subdirectories under the given directory, then removes the directory itself.\n * Uses fs.rm with recursive: true and force: true so that symbolic links are removed without following them,\n * avoiding deletion of content outside the keystore.\n *\n * @private\n * @param {string} dir - Directory path to clear\n * @returns {Promise<void>} Resolves when clearing is complete\n * @throws {Error} If directory removal fails for reasons other than non-existence\n */\n private async clearDirectory(dir: string): Promise<void> {\n try {\n await fs.rm(dir, { recursive: true, force: true });\n } catch (err: unknown) {\n const code = err && typeof err === \"object\" && \"code\" in err ? (err as NodeJS.ErrnoException).code : undefined;\n if (code === \"ENOENT\") {\n return;\n }\n throw err;\n }\n }\n\n // -------------------------------------------------------\n // KEYSTORE INTERFACE\n // -------------------------------------------------------\n\n /**\n * Retrieves the key bytes from storage and optionally verifies them.\n *\n * @param {KeyLocator} locator - The key locator with optional checksum for verification.\n * @returns {Promise<Uint8Array | null>} The key bytes if found and verified, null if not found.\n * @throws {KeyVerificationError} If verification fails.\n */\n async getKeyBytes(locator: KeyLocator): Promise<Uint8Array | null> {\n const fileKey = this.serializeLocator(locator);\n\n // Attempt to read key bytes from storage (under this.directory).\n const keyBytes = await this.readFileOptional(path.join(this.directory, fileKey));\n\n // If no key bytes were found, return null.\n if (!keyBytes) return null;\n\n // Use caller-provided checksum or metadata stored on disk for verification.\n const fingerprint =\n this.checksumToFingerprint(locator.checksum, keyBytes) ?? (await this.getKeyMetadata(locator));\n if (fingerprint) {\n await this.keyVerifier.verifyKeyBytes({\n keyBytes,\n locator: fileKey,\n fingerprint,\n });\n }\n\n // Return the verified key bytes.\n return keyBytes;\n }\n\n /**\n * Retrieves and verifies a proving key from storage.\n *\n * @param {ProvingKeyLocator} locator - The proving key locator.\n * @returns {Promise<ProvingKey | null>} The proving key if found and verified, null if not found.\n * @throws {KeyVerificationError} If verification fails.\n * @throws {Error} If key bytes cannot be parsed into a valid ProvingKey.\n */\n async getProvingKey(locator: ProvingKeyLocator): Promise<ProvingKey | null> {\n const proverBytes = await this.getKeyBytes(locator);\n if (!proverBytes) return null;\n return ProvingKey.fromBytes(proverBytes);\n }\n\n /**\n * Retrieves and verifies a verifying key from storage.\n *\n * @param {VerifyingKeyLocator} locator - The verifying key locator.\n * @returns {Promise<VerifyingKey | null>} The verifying key if found and verified, null if not found.\n * @throws {KeyVerificationError} If verification fails.\n * @throws {Error} If key bytes cannot be parsed into a valid VerifyingKey.\n */\n async getVerifyingKey(locator: VerifyingKeyLocator): Promise<VerifyingKey | null> {\n const verifierBytes = await this.getKeyBytes(locator);\n if (!verifierBytes) return null;\n return VerifyingKey.fromBytes(verifierBytes);\n }\n\n /**\n * Stores proving and verifying keys in key storage.\n *\n * @param {ProvingKeyLocator} proverLocator The locator for the proving key.\n * @param {VerifyingKeyLocator} verifierLocator The locator for the verifying key.\n * @param {FunctionKeyPair} keys The proving and verifying keys.\n */\n async setKeys(\n proverLocator: ProvingKeyLocator,\n verifierLocator: VerifyingKeyLocator,\n keys: FunctionKeyPair,\n ): Promise<void> {\n const proverKey = this.serializeLocator(proverLocator);\n const verifierKey = this.serializeLocator(verifierLocator);\n\n // Convert the WASM keys to raw bytes.\n const [provingKey, verifyingKey] = keys;\n const [provingKeyBytes, verifyingKeyBytes] = [\n provingKey.toBytes(),\n verifyingKey.toBytes(),\n ];\n\n // Compute the fingerprints for the proving and verifying keys, verify against expected checksums if provided.\n const [proverFingerPrint, verifierFingerPrint] = await Promise.all([\n this.keyVerifier.computeKeyMetadata({\n keyBytes: provingKeyBytes,\n locator: proverKey,\n fingerprint: this.checksumToFingerprint(proverLocator.checksum, provingKeyBytes),\n }),\n this.keyVerifier.computeKeyMetadata({\n keyBytes: verifyingKeyBytes,\n locator: verifierKey,\n fingerprint: this.checksumToFingerprint(verifierLocator.checksum, verifyingKeyBytes),\n }),\n ]);\n\n // Write the proving and verifying key bytes and their metadata to storage (under this.directory).\n await this.writeFileAtomic(path.join(this.directory, proverKey), provingKeyBytes);\n await this.writeFileAtomic(path.join(this.directory, verifierKey), verifyingKeyBytes);\n await this.writeKeyMetadata(proverKey, proverFingerPrint);\n await this.writeKeyMetadata(verifierKey, verifierFingerPrint);\n }\n\n /**\n * Store a raw key in storage along with its fingerprint metadata for future verification.\n *\n * @param {Uint8Array} keyBytes The raw key bytes.\n * @param {KeyLocator} locator The unique locator for the key.\n * @returns {Promise<void>}\n * @throws {Error} If computing key metadata or writing to storage fails\n */\n async setKeyBytes(keyBytes: Uint8Array, locator: KeyLocator): Promise<void> {\n const fileKey = this.serializeLocator(locator);\n\n // Compute the key metadata including fingerprint\n const computedMetadata = await this.keyVerifier.computeKeyMetadata({\n keyBytes: keyBytes,\n locator: fileKey,\n fingerprint: this.checksumToFingerprint(locator.checksum, keyBytes),\n });\n\n // Write the key bytes and metadata atomically (key file under this.directory).\n await this.writeFileAtomic(path.join(this.directory, fileKey), keyBytes);\n await this.writeKeyMetadata(fileKey, computedMetadata);\n }\n\n /**\n * Returns stored metadata for a key, if any.\n *\n * @param {KeyLocator} locator The unique locator for the key.\n * @returns {Promise<KeyFingerprint | null>} The stored fingerprint metadata, or null if none exists.\n */\n async getKeyMetadata(locator: KeyLocator): Promise<KeyFingerprint | null> {\n const fileKey = this.serializeLocator(locator);\n return this.readKeyMetadata(fileKey);\n }\n\n /**\n * Checks if a key exists for the given locator.\n *\n * @param {KeyLocator} locator - The unique key locator.\n * @returns {Promise<boolean>} True if key exists, false otherwise.\n */\n async has(locator: KeyLocator): Promise<boolean> {\n const fileKey = this.serializeLocator(locator);\n const keyPath = path.join(this.directory, fileKey);\n return await fs\n .access(keyPath)\n .then(() => true)\n .catch(() => false);\n }\n\n /**\n * Deletes a key and its associated metadata from storage. Silently ignores errors if files don't exist.\n *\n * @param {KeyLocator} locator - The unique key locator.\n * @returns {Promise<void>}\n */\n async delete(locator: KeyLocator): Promise<void> {\n const fileKey = this.serializeLocator(locator);\n const p = path.join(this.directory, fileKey);\n const m = this.metadataPath(fileKey);\n\n await fs.unlink(p).catch(() => {});\n await fs.unlink(m).catch(() => {});\n }\n\n /**\n * Clears the key storage directory by recursively removing all files and subdirectories under it, then removes the keystore directory itself.\n *\n * @returns {Promise<void>}\n * @throws {Error} If directory listing fails for reasons other than non-existence.\n */\n async clear(): Promise<void> {\n await this.clearDirectory(this.directory);\n }\n}\n"],"names":["MemKeyVerifier","path","fsSync","InvalidLocatorError","fs","ProvingKey","VerifyingKey"],"mappings":"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"}
1
+ {"version":3,"file":"node.cjs","sources":["../../src/keys/keystore/file.ts"],"sourcesContent":["import * as fs from \"node:fs/promises\";\nimport * as fsSync from \"node:fs\";\nimport * as path from \"path\";\n\nimport { FunctionKeyPair } from \"../../models/keyPair.js\";\nimport { KeyFingerprint } from \"../verifier/interface.js\";\nimport { InvalidLocatorError } from \"./error.js\";\nimport { KeyLocator, KeyStore, ProvingKeyLocator, VerifyingKeyLocator } from \"./interface.js\";\nimport { MemKeyVerifier } from \"../verifier/memory.js\";\nimport { ProvingKey, VerifyingKey } from \"../../wasm.js\";\n\nexport class LocalFileKeyStore implements KeyStore {\n private directory: string;\n private readonly keyVerifier = new MemKeyVerifier();\n\n /**\n * Creates a new directory at the given path or CURRENTDIR/.aleo if none is provided to store keys.\n * If a custom directory is passed and its last path segment is not \".aleo\", \".aleo\" is appended\n * so keys are stored under that subdirectory (e.g. /home/project → /home/project/.aleo).\n *\n * @param {string} [directory] - Optional custom directory path for key storage. Defaults to \".aleo\" in current working directory.\n * @throws {Error} If directory creation fails.\n */\n constructor(directory?: string) {\n this.directory = directory ?? path.join(process.cwd(), \".aleo\");\n if (directory !== undefined && path.basename(this.directory) !== \".aleo\") {\n this.directory = path.join(this.directory, \".aleo\");\n }\n fsSync.mkdirSync(this.directory, { recursive: true });\n }\n\n /**\n * Validates a single locator component for unsafe filesystem characters.\n *\n * @private\n * @param {string} value - The component value to validate.\n * @param {string} label - Label for error messages (e.g. \"program\", \"functionName\").\n * @throws {InvalidLocatorError} If the value is empty, contains traversal sequences, path separators, or null bytes.\n */\n private validateComponent(value: string, label: string): void {\n if (value === \"\" || value === \".\") {\n throw new InvalidLocatorError(\n `KeyLocator ${label} must not be empty or \".\" (got \"${value}\")`,\n value,\n \"reserved_name\"\n );\n }\n if (value.includes(\"..\")) {\n throw new InvalidLocatorError(\n `KeyLocator ${label} must not contain \"..\" (got \"${value}\")`,\n value,\n \"path_traversal\"\n );\n }\n if (value.includes(\"/\") || value.includes(\"\\\\\") || value.includes(\"\\0\")) {\n throw new InvalidLocatorError(\n `KeyLocator ${label} must not contain path separators or null bytes (got \"${value}\")`,\n value,\n \"path_separator\"\n );\n }\n }\n\n /**\n * Validates that a numeric locator field is not negative.\n *\n * @private\n * @param {number} value - The numeric value to validate.\n * @param {string} label - Label for error messages (e.g. \"edition\", \"amendment\").\n * @throws {InvalidLocatorError} If the value is negative.\n */\n private validateNonNegative(value: number, label: string): void {\n if (!Number.isInteger(value) || value < 0) {\n throw new InvalidLocatorError(\n `KeyLocator ${label} must be a non-negative integer (got ${value})`,\n String(value),\n \"negative_value\"\n );\n }\n }\n\n /**\n * Serializes a {@link KeyLocator} to a filesystem-safe flat string, validating components first.\n *\n * For prover/verifier keys: `{program}.{functionName}.e{edition}.a{amendment}.{network}.{keyType}`\n * For translation keys: `{program}.{functionName}.e{edition}.a{amendment}.{network}.translation.{recordName}.{recordInputPosition}`\n *\n * Note: The optional `checksum` field is excluded — it is used for integrity verification only\n * (via {@link checksumToFingerprint}) and is not part of the key identity.\n *\n * @private\n * @param {KeyLocator} locator - The key locator.\n * @returns {string} A dot-delimited string safe for use as a filename.\n * @throws {InvalidLocatorError} If any component contains unsafe characters.\n */\n private serializeLocator(locator: KeyLocator): string {\n this.validateComponent(locator.program, \"program\");\n this.validateComponent(locator.functionName, \"functionName\");\n this.validateComponent(locator.network, \"network\");\n this.validateNonNegative(locator.edition, \"edition\");\n this.validateNonNegative(locator.amendment, \"amendment\");\n const base = `${locator.program}.${locator.functionName}.e${locator.edition}.a${locator.amendment}.${locator.network}.${locator.keyType}`;\n if (locator.keyType === \"translation\") {\n this.validateComponent(locator.recordName, \"recordName\");\n this.validateNonNegative(locator.recordInputPosition, \"recordInputPosition\");\n return `${base}.${locator.recordName}.${locator.recordInputPosition}`;\n }\n return base;\n }\n\n /**\n * Converts an optional checksum string from a locator into a KeyFingerprint\n * suitable for the key verifier, using the actual key byte length for size.\n *\n * @private\n */\n private checksumToFingerprint(checksum: string | undefined, keyBytes: Uint8Array): KeyFingerprint | undefined {\n if (!checksum) return undefined;\n return { checksum, size: keyBytes.length };\n }\n\n /**\n * Generates the path for a key metadata file based on the locator.\n *\n * @private\n * @param {string} locator - Unique identifier for the key.\n * @returns {string} Full filesystem path to the metadata file.\n */\n private metadataPath(locator: string): string {\n return path.join(this.directory, `${locator}.metadata`);\n }\n\n /**\n * Reads and parses the key fingerprint metadata from storage.\n *\n * @private\n * @param {string} locator - Unique identifier for the key.\n * @returns {Promise<KeyFingerprint | null>} The key fingerprint if found, null if file doesn't exist.\n * @throws {Error} If file read fails for any reason other than not found.\n */\n private async readKeyMetadata(\n locator: string,\n ): Promise<KeyFingerprint | null> {\n try {\n const data = await fs.readFile(this.metadataPath(locator), \"utf-8\");\n return JSON.parse(data) as KeyFingerprint;\n } catch (err: unknown) {\n if (\n err &&\n typeof err === \"object\" &&\n \"code\" in err &&\n err.code === \"ENOENT\"\n )\n return null;\n throw err;\n }\n }\n\n /**\n * Writes key fingerprint metadata to storage.\n *\n * @private\n * @param {string} locator - Unique identifier for the key.\n * @param {KeyFingerprint} metadata - Key fingerprint metadata to store.\n * @returns {Promise<void>}\n * @throws {Error} If directory creation or file write fails.\n */\n private async writeKeyMetadata(\n locator: string,\n metadata: KeyFingerprint,\n ): Promise<void> {\n await fs.mkdir(path.dirname(this.metadataPath(locator)), {\n recursive: true,\n });\n await fs.writeFile(\n this.metadataPath(locator),\n JSON.stringify(metadata, null, 0),\n \"utf-8\",\n );\n }\n\n private async readFileOptional(\n filepath: string,\n ): Promise<Uint8Array | null> {\n try {\n const data = await fs.readFile(filepath);\n return new Uint8Array(data);\n } catch (err: any) {\n if (err.code === \"ENOENT\") return null;\n throw err;\n }\n }\n\n /**\n * Atomically writes data to a file, ensuring the parent directories exist.\n *\n * @private\n * @param {string} filepath - Full path to the file to write\n * @param {Uint8Array} data - Binary data to write to the file\n * @returns {Promise<void>} Resolves when write is complete\n * @throws {Error} If directory creation or file write fails\n */\n private async writeFileAtomic(\n filepath: string,\n data: Uint8Array,\n ): Promise<void> {\n const dir = path.dirname(filepath);\n await fs.mkdir(dir, { recursive: true });\n const tempPath = path.join(\n dir,\n `.${path.basename(filepath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`\n );\n await fs.writeFile(tempPath, data);\n try {\n await fs.rename(tempPath, filepath);\n } catch (err: unknown) {\n const code = err && typeof err === \"object\" && \"code\" in err ? (err as NodeJS.ErrnoException).code : undefined;\n // Windows often throws EEXIST when target exists; EPERM/EACCES happen with locks/AV.\n if (code === \"EEXIST\" || code === \"EPERM\" || code === \"EACCES\") {\n await fs.unlink(filepath).catch(() => {});\n try {\n await fs.rename(tempPath, filepath);\n } catch (err2) {\n await fs.unlink(tempPath).catch(() => {});\n throw err2;\n }\n } else {\n await fs.unlink(tempPath).catch(() => {});\n throw err;\n }\n }\n }\n\n /**\n * Recursively removes all files and subdirectories under the given directory, then removes the directory itself.\n * Uses fs.rm with recursive: true and force: true so that symbolic links are removed without following them,\n * avoiding deletion of content outside the keystore.\n *\n * @private\n * @param {string} dir - Directory path to clear\n * @returns {Promise<void>} Resolves when clearing is complete\n * @throws {Error} If directory removal fails for reasons other than non-existence\n */\n private async clearDirectory(dir: string): Promise<void> {\n try {\n await fs.rm(dir, { recursive: true, force: true });\n } catch (err: unknown) {\n const code = err && typeof err === \"object\" && \"code\" in err ? (err as NodeJS.ErrnoException).code : undefined;\n if (code === \"ENOENT\") {\n return;\n }\n throw err;\n }\n }\n\n // -------------------------------------------------------\n // KEYSTORE INTERFACE\n // -------------------------------------------------------\n\n /**\n * Retrieves the key bytes from storage and optionally verifies them.\n *\n * @param {KeyLocator} locator - The key locator with optional checksum for verification.\n * @returns {Promise<Uint8Array | null>} The key bytes if found and verified, null if not found.\n * @throws {KeyVerificationError} If verification fails.\n */\n async getKeyBytes(locator: KeyLocator): Promise<Uint8Array | null> {\n const fileKey = this.serializeLocator(locator);\n\n // Attempt to read key bytes from storage (under this.directory).\n const keyBytes = await this.readFileOptional(path.join(this.directory, fileKey));\n\n // If no key bytes were found, return null.\n if (!keyBytes) return null;\n\n // Use caller-provided checksum or metadata stored on disk for verification.\n const fingerprint =\n this.checksumToFingerprint(locator.checksum, keyBytes) ?? (await this.getKeyMetadata(locator));\n if (fingerprint) {\n await this.keyVerifier.verifyKeyBytes({\n keyBytes,\n locator: fileKey,\n fingerprint,\n });\n }\n\n // Return the verified key bytes.\n return keyBytes;\n }\n\n /**\n * Retrieves and verifies a proving key from storage.\n *\n * @param {ProvingKeyLocator} locator - The proving key locator.\n * @returns {Promise<ProvingKey | null>} The proving key if found and verified, null if not found.\n * @throws {KeyVerificationError} If verification fails.\n * @throws {Error} If key bytes cannot be parsed into a valid ProvingKey.\n */\n async getProvingKey(locator: ProvingKeyLocator): Promise<ProvingKey | null> {\n const proverBytes = await this.getKeyBytes(locator);\n if (!proverBytes) return null;\n return ProvingKey.fromBytes(proverBytes);\n }\n\n /**\n * Retrieves and verifies a verifying key from storage.\n *\n * @param {VerifyingKeyLocator} locator - The verifying key locator.\n * @returns {Promise<VerifyingKey | null>} The verifying key if found and verified, null if not found.\n * @throws {KeyVerificationError} If verification fails.\n * @throws {Error} If key bytes cannot be parsed into a valid VerifyingKey.\n */\n async getVerifyingKey(locator: VerifyingKeyLocator): Promise<VerifyingKey | null> {\n const verifierBytes = await this.getKeyBytes(locator);\n if (!verifierBytes) return null;\n return VerifyingKey.fromBytes(verifierBytes);\n }\n\n /**\n * Stores proving and verifying keys in key storage.\n *\n * @param {ProvingKeyLocator} proverLocator The locator for the proving key.\n * @param {VerifyingKeyLocator} verifierLocator The locator for the verifying key.\n * @param {FunctionKeyPair} keys The proving and verifying keys.\n */\n async setKeys(\n proverLocator: ProvingKeyLocator,\n verifierLocator: VerifyingKeyLocator,\n keys: FunctionKeyPair,\n ): Promise<void> {\n const proverKey = this.serializeLocator(proverLocator);\n const verifierKey = this.serializeLocator(verifierLocator);\n\n // Convert the WASM keys to raw bytes.\n const [provingKey, verifyingKey] = keys;\n const [provingKeyBytes, verifyingKeyBytes] = [\n provingKey.toBytes(),\n verifyingKey.toBytes(),\n ];\n\n // Compute the fingerprints for the proving and verifying keys, verify against expected checksums if provided.\n const [proverFingerPrint, verifierFingerPrint] = await Promise.all([\n this.keyVerifier.computeKeyMetadata({\n keyBytes: provingKeyBytes,\n locator: proverKey,\n fingerprint: this.checksumToFingerprint(proverLocator.checksum, provingKeyBytes),\n }),\n this.keyVerifier.computeKeyMetadata({\n keyBytes: verifyingKeyBytes,\n locator: verifierKey,\n fingerprint: this.checksumToFingerprint(verifierLocator.checksum, verifyingKeyBytes),\n }),\n ]);\n\n // Write the proving and verifying key bytes and their metadata to storage (under this.directory).\n await this.writeFileAtomic(path.join(this.directory, proverKey), provingKeyBytes);\n await this.writeFileAtomic(path.join(this.directory, verifierKey), verifyingKeyBytes);\n await this.writeKeyMetadata(proverKey, proverFingerPrint);\n await this.writeKeyMetadata(verifierKey, verifierFingerPrint);\n }\n\n /**\n * Store a raw key in storage along with its fingerprint metadata for future verification.\n *\n * @param {Uint8Array} keyBytes The raw key bytes.\n * @param {KeyLocator} locator The unique locator for the key.\n * @returns {Promise<void>}\n * @throws {Error} If computing key metadata or writing to storage fails\n */\n async setKeyBytes(keyBytes: Uint8Array, locator: KeyLocator): Promise<void> {\n const fileKey = this.serializeLocator(locator);\n\n // Compute the key metadata including fingerprint\n const computedMetadata = await this.keyVerifier.computeKeyMetadata({\n keyBytes: keyBytes,\n locator: fileKey,\n fingerprint: this.checksumToFingerprint(locator.checksum, keyBytes),\n });\n\n // Write the key bytes and metadata atomically (key file under this.directory).\n await this.writeFileAtomic(path.join(this.directory, fileKey), keyBytes);\n await this.writeKeyMetadata(fileKey, computedMetadata);\n }\n\n /**\n * Returns stored metadata for a key, if any.\n *\n * @param {KeyLocator} locator The unique locator for the key.\n * @returns {Promise<KeyFingerprint | null>} The stored fingerprint metadata, or null if none exists.\n */\n async getKeyMetadata(locator: KeyLocator): Promise<KeyFingerprint | null> {\n const fileKey = this.serializeLocator(locator);\n return this.readKeyMetadata(fileKey);\n }\n\n /**\n * Checks if a key exists for the given locator.\n *\n * @param {KeyLocator} locator - The unique key locator.\n * @returns {Promise<boolean>} True if key exists, false otherwise.\n */\n async has(locator: KeyLocator): Promise<boolean> {\n const fileKey = this.serializeLocator(locator);\n const keyPath = path.join(this.directory, fileKey);\n return await fs\n .access(keyPath)\n .then(() => true)\n .catch(() => false);\n }\n\n /**\n * Deletes a key and its associated metadata from storage. Silently ignores errors if files don't exist.\n *\n * @param {KeyLocator} locator - The unique key locator.\n * @returns {Promise<void>}\n */\n async delete(locator: KeyLocator): Promise<void> {\n const fileKey = this.serializeLocator(locator);\n const p = path.join(this.directory, fileKey);\n const m = this.metadataPath(fileKey);\n\n await fs.unlink(p).catch(() => {});\n await fs.unlink(m).catch(() => {});\n }\n\n /**\n * Clears the key storage directory by recursively removing all files and subdirectories under it, then removes the keystore directory itself.\n *\n * @returns {Promise<void>}\n * @throws {Error} If directory listing fails for reasons other than non-existence.\n */\n async clear(): Promise<void> {\n await this.clearDirectory(this.directory);\n }\n}\n"],"names":["MemKeyVerifier","path","fsSync","InvalidLocatorError","fs","ProvingKey","VerifyingKey"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAWa,iBAAiB,CAAA;AAClB,IAAA,SAAS;AACA,IAAA,WAAW,GAAG,IAAIA,sBAAc,EAAE;AAEnD;;;;;;;AAOG;AACH,IAAA,WAAA,CAAY,SAAkB,EAAA;AAC1B,QAAA,IAAI,CAAC,SAAS,GAAG,SAAS,IAAIC,eAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC;AAC/D,QAAA,IAAI,SAAS,KAAK,SAAS,IAAIA,eAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,OAAO,EAAE;AACtE,YAAA,IAAI,CAAC,SAAS,GAAGA,eAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC;QACvD;AACA,QAAAC,cAAM,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACzD;AAEA;;;;;;;AAOG;IACK,iBAAiB,CAAC,KAAa,EAAE,KAAa,EAAA;QAClD,IAAI,KAAK,KAAK,EAAE,IAAI,KAAK,KAAK,GAAG,EAAE;AAC/B,YAAA,MAAM,IAAIC,2BAAmB,CACzB,CAAA,WAAA,EAAc,KAAK,CAAA,gCAAA,EAAmC,KAAK,CAAA,EAAA,CAAI,EAC/D,KAAK,EACL,eAAe,CAClB;QACL;AACA,QAAA,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;AACtB,YAAA,MAAM,IAAIA,2BAAmB,CACzB,CAAA,WAAA,EAAc,KAAK,CAAA,6BAAA,EAAgC,KAAK,CAAA,EAAA,CAAI,EAC5D,KAAK,EACL,gBAAgB,CACnB;QACL;QACA,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;AACrE,YAAA,MAAM,IAAIA,2BAAmB,CACzB,CAAA,WAAA,EAAc,KAAK,CAAA,sDAAA,EAAyD,KAAK,CAAA,EAAA,CAAI,EACrF,KAAK,EACL,gBAAgB,CACnB;QACL;IACJ;AAEA;;;;;;;AAOG;IACK,mBAAmB,CAAC,KAAa,EAAE,KAAa,EAAA;AACpD,QAAA,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE;AACvC,YAAA,MAAM,IAAIA,2BAAmB,CACzB,CAAA,WAAA,EAAc,KAAK,wCAAwC,KAAK,CAAA,CAAA,CAAG,EACnE,MAAM,CAAC,KAAK,CAAC,EACb,gBAAgB,CACnB;QACL;IACJ;AAEA;;;;;;;;;;;;;AAaG;AACK,IAAA,gBAAgB,CAAC,OAAmB,EAAA;QACxC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC;QAClD,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,YAAY,EAAE,cAAc,CAAC;QAC5D,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC;QAClD,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC;QACpD,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC;QACxD,MAAM,IAAI,GAAG,CAAA,EAAG,OAAO,CAAC,OAAO,CAAA,CAAA,EAAI,OAAO,CAAC,YAAY,CAAA,EAAA,EAAK,OAAO,CAAC,OAAO,CAAA,EAAA,EAAK,OAAO,CAAC,SAAS,CAAA,CAAA,EAAI,OAAO,CAAC,OAAO,CAAA,CAAA,EAAI,OAAO,CAAC,OAAO,CAAA,CAAE;AACzI,QAAA,IAAI,OAAO,CAAC,OAAO,KAAK,aAAa,EAAE;YACnC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,UAAU,EAAE,YAAY,CAAC;YACxD,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,mBAAmB,EAAE,qBAAqB,CAAC;YAC5E,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,OAAO,CAAC,UAAU,CAAA,CAAA,EAAI,OAAO,CAAC,mBAAmB,CAAA,CAAE;QACzE;AACA,QAAA,OAAO,IAAI;IACf;AAEA;;;;;AAKG;IACK,qBAAqB,CAAC,QAA4B,EAAE,QAAoB,EAAA;AAC5E,QAAA,IAAI,CAAC,QAAQ;AAAE,YAAA,OAAO,SAAS;QAC/B,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE;IAC9C;AAEA;;;;;;AAMG;AACK,IAAA,YAAY,CAAC,OAAe,EAAA;AAChC,QAAA,OAAOF,eAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAA,EAAG,OAAO,CAAA,SAAA,CAAW,CAAC;IAC3D;AAEA;;;;;;;AAOG;IACK,MAAM,eAAe,CACzB,OAAe,EAAA;AAEf,QAAA,IAAI;AACA,YAAA,MAAM,IAAI,GAAG,MAAMG,aAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;AACnE,YAAA,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAmB;QAC7C;QAAE,OAAO,GAAY,EAAE;AACnB,YAAA,IACI,GAAG;gBACH,OAAO,GAAG,KAAK,QAAQ;AACvB,gBAAA,MAAM,IAAI,GAAG;gBACb,GAAG,CAAC,IAAI,KAAK,QAAQ;AAErB,gBAAA,OAAO,IAAI;AACf,YAAA,MAAM,GAAG;QACb;IACJ;AAEA;;;;;;;;AAQG;AACK,IAAA,MAAM,gBAAgB,CAC1B,OAAe,EACf,QAAwB,EAAA;AAExB,QAAA,MAAMA,aAAE,CAAC,KAAK,CAACH,eAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,EAAE;AACrD,YAAA,SAAS,EAAE,IAAI;AAClB,SAAA,CAAC;QACF,MAAMG,aAAE,CAAC,SAAS,CACd,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAC1B,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EACjC,OAAO,CACV;IACL;IAEQ,MAAM,gBAAgB,CAC1B,QAAgB,EAAA;AAEhB,QAAA,IAAI;YACA,MAAM,IAAI,GAAG,MAAMA,aAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;AACxC,YAAA,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC;QAC/B;QAAE,OAAO,GAAQ,EAAE;AACf,YAAA,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;AAAE,gBAAA,OAAO,IAAI;AACtC,YAAA,MAAM,GAAG;QACb;IACJ;AAEA;;;;;;;;AAQG;AACK,IAAA,MAAM,eAAe,CACzB,QAAgB,EAChB,IAAgB,EAAA;QAEhB,MAAM,GAAG,GAAGH,eAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;AAClC,QAAA,MAAMG,aAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AACxC,QAAA,MAAM,QAAQ,GAAGH,eAAI,CAAC,IAAI,CACtB,GAAG,EACH,CAAA,CAAA,EAAIA,eAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA,CAAA,EAAI,OAAO,CAAC,GAAG,CAAA,CAAA,EAAI,IAAI,CAAC,GAAG,EAAE,CAAA,CAAA,EAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA,IAAA,CAAM,CACxG;QACD,MAAMG,aAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC;AAClC,QAAA,IAAI;YACA,MAAMA,aAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC;QACvC;QAAE,OAAO,GAAY,EAAE;YACnB,MAAM,IAAI,GAAG,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,IAAI,GAAG,GAAI,GAA6B,CAAC,IAAI,GAAG,SAAS;;AAE9G,YAAA,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,QAAQ,EAAE;AAC5D,gBAAA,MAAMA,aAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,MAAK,EAAE,CAAC,CAAC;AACzC,gBAAA,IAAI;oBACA,MAAMA,aAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC;gBACvC;gBAAE,OAAO,IAAI,EAAE;AACX,oBAAA,MAAMA,aAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,MAAK,EAAE,CAAC,CAAC;AACzC,oBAAA,MAAM,IAAI;gBACd;YACJ;iBAAO;AACH,gBAAA,MAAMA,aAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,MAAK,EAAE,CAAC,CAAC;AACzC,gBAAA,MAAM,GAAG;YACb;QACJ;IACJ;AAEA;;;;;;;;;AASG;IACK,MAAM,cAAc,CAAC,GAAW,EAAA;AACpC,QAAA,IAAI;AACA,YAAA,MAAMA,aAAE,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACtD;QAAE,OAAO,GAAY,EAAE;YACnB,MAAM,IAAI,GAAG,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,IAAI,GAAG,GAAI,GAA6B,CAAC,IAAI,GAAG,SAAS;AAC9G,YAAA,IAAI,IAAI,KAAK,QAAQ,EAAE;gBACnB;YACJ;AACA,YAAA,MAAM,GAAG;QACb;IACJ;;;;AAMA;;;;;;AAMG;IACH,MAAM,WAAW,CAAC,OAAmB,EAAA;QACjC,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;;AAG9C,QAAA,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAACH,eAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;;AAGhF,QAAA,IAAI,CAAC,QAAQ;AAAE,YAAA,OAAO,IAAI;;QAG1B,MAAM,WAAW,GACb,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,KAAK,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAClG,IAAI,WAAW,EAAE;AACb,YAAA,MAAM,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC;gBAClC,QAAQ;AACR,gBAAA,OAAO,EAAE,OAAO;gBAChB,WAAW;AACd,aAAA,CAAC;QACN;;AAGA,QAAA,OAAO,QAAQ;IACnB;AAEA;;;;;;;AAOG;IACH,MAAM,aAAa,CAAC,OAA0B,EAAA;QAC1C,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC;AACnD,QAAA,IAAI,CAAC,WAAW;AAAE,YAAA,OAAO,IAAI;AAC7B,QAAA,OAAOI,qBAAU,CAAC,SAAS,CAAC,WAAW,CAAC;IAC5C;AAEA;;;;;;;AAOG;IACH,MAAM,eAAe,CAAC,OAA4B,EAAA;QAC9C,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC;AACrD,QAAA,IAAI,CAAC,aAAa;AAAE,YAAA,OAAO,IAAI;AAC/B,QAAA,OAAOC,uBAAY,CAAC,SAAS,CAAC,aAAa,CAAC;IAChD;AAEA;;;;;;AAMG;AACH,IAAA,MAAM,OAAO,CACT,aAAgC,EAChC,eAAoC,EACpC,IAAqB,EAAA;QAErB,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC;QACtD,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC;;AAG1D,QAAA,MAAM,CAAC,UAAU,EAAE,YAAY,CAAC,GAAG,IAAI;AACvC,QAAA,MAAM,CAAC,eAAe,EAAE,iBAAiB,CAAC,GAAG;YACzC,UAAU,CAAC,OAAO,EAAE;YACpB,YAAY,CAAC,OAAO,EAAE;SACzB;;QAGD,MAAM,CAAC,iBAAiB,EAAE,mBAAmB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;AAC/D,YAAA,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC;AAChC,gBAAA,QAAQ,EAAE,eAAe;AACzB,gBAAA,OAAO,EAAE,SAAS;gBAClB,WAAW,EAAE,IAAI,CAAC,qBAAqB,CAAC,aAAa,CAAC,QAAQ,EAAE,eAAe,CAAC;aACnF,CAAC;AACF,YAAA,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC;AAChC,gBAAA,QAAQ,EAAE,iBAAiB;AAC3B,gBAAA,OAAO,EAAE,WAAW;gBACpB,WAAW,EAAE,IAAI,CAAC,qBAAqB,CAAC,eAAe,CAAC,QAAQ,EAAE,iBAAiB,CAAC;aACvF,CAAC;AACL,SAAA,CAAC;;AAGF,QAAA,MAAM,IAAI,CAAC,eAAe,CAACL,eAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,eAAe,CAAC;AACjF,QAAA,MAAM,IAAI,CAAC,eAAe,CAACA,eAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,iBAAiB,CAAC;QACrF,MAAM,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,iBAAiB,CAAC;QACzD,MAAM,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,mBAAmB,CAAC;IACjE;AAEA;;;;;;;AAOG;AACH,IAAA,MAAM,WAAW,CAAC,QAAoB,EAAE,OAAmB,EAAA;QACvD,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;;QAG9C,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC;AAC/D,YAAA,QAAQ,EAAE,QAAQ;AAClB,YAAA,OAAO,EAAE,OAAO;YAChB,WAAW,EAAE,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC;AACtE,SAAA,CAAC;;AAGF,QAAA,MAAM,IAAI,CAAC,eAAe,CAACA,eAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC;QACxE,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,CAAC;IAC1D;AAEA;;;;;AAKG;IACH,MAAM,cAAc,CAAC,OAAmB,EAAA;QACpC,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;AAC9C,QAAA,OAAO,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC;IACxC;AAEA;;;;;AAKG;IACH,MAAM,GAAG,CAAC,OAAmB,EAAA;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;AAC9C,QAAA,MAAM,OAAO,GAAGA,eAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC;AAClD,QAAA,OAAO,MAAMG;aACR,MAAM,CAAC,OAAO;AACd,aAAA,IAAI,CAAC,MAAM,IAAI;AACf,aAAA,KAAK,CAAC,MAAM,KAAK,CAAC;IAC3B;AAEA;;;;;AAKG;IACH,MAAM,MAAM,CAAC,OAAmB,EAAA;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;AAC9C,QAAA,MAAM,CAAC,GAAGH,eAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC;QAC5C,MAAM,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC;AAEpC,QAAA,MAAMG,aAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAK,EAAE,CAAC,CAAC;AAClC,QAAA,MAAMA,aAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAK,EAAE,CAAC,CAAC;IACtC;AAEA;;;;;AAKG;AACH,IAAA,MAAM,KAAK,GAAA;QACP,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC;IAC7C;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -3,7 +3,7 @@ import * as fs from 'node:fs/promises';
3
3
  import * as $fs from 'node:fs';
4
4
  import * as path from 'path';
5
5
  import { MemKeyVerifier, InvalidLocatorError } from './browser.js';
6
- export { Account, AleoKeyProvider, AleoKeyProviderParams, AleoNetworkClient, BlockHeightSearch, CREDITS_PROGRAM_KEYS, ChecksumMismatchError, DecryptionNotEnabledError, IndexedDBKeyStore, KEY_STORE, ChecksumMismatchError as KeyVerificationError, NetworkRecordProvider, OfflineKeyProvider, OfflineSearchParams, PRIVATE_TO_PUBLIC_TRANSFER, PRIVATE_TRANSFER, PRIVATE_TRANSFER_TYPES, PUBLIC_TO_PRIVATE_TRANSFER, PUBLIC_TRANSFER, PUBLIC_TRANSFER_AS_SIGNER, ProgramManager, RECORD_DOMAIN, RecordNotFoundError, RecordScanner, RecordScannerRequestError, SealanceMerkleTree, UUIDError, VALID_TRANSFER_TYPES, ViewKeyNotStoredError, buildExecutionRequestFromExternallySignedData, computeExternalSigningInputs, cookieAffinityTransport, defaultTransport, encryptAuthorization, encryptProvingRequest, encryptRegistrationRequest, encryptViewKey, generateHookData, getLogLevel, initializeWasm, inputsToFields, isInputIdStrategy, isProveApiErrorBody, isProvingResponse, isRecordViewKeyStrategy, isViewKeyStrategy, logAndThrow, programChecksum, provingKeyLocator, setLogLevel, sha256Hex, toAddress, toField, toGroup, toSignature, toViewKey, translationKeyLocator, verifyBatchProof, verifyProof, verifyingKeyLocator, zeroizeBytes } from './browser.js';
6
+ export { Account, AleoKeyProvider, AleoKeyProviderParams, AleoNetworkClient, BlockHeightSearch, CREDITS_PROGRAM_KEYS, ChecksumMismatchError, DecryptionNotEnabledError, IndexedDBKeyStore, KEY_STORE, ChecksumMismatchError as KeyVerificationError, NetworkRecordProvider, OfflineKeyProvider, OfflineSearchParams, PRIVATE_TO_PUBLIC_TRANSFER, PRIVATE_TRANSFER, PRIVATE_TRANSFER_TYPES, PUBLIC_TO_PRIVATE_TRANSFER, PUBLIC_TRANSFER, PUBLIC_TRANSFER_AS_SIGNER, ProgramManager, RECORD_DOMAIN, RecordNotFoundError, RecordScanner, RecordScannerRequestError, SealanceMerkleTree, UUIDError, VALID_TRANSFER_TYPES, ViewKeyNotStoredError, buildExecutionRequestFromExternallySignedData, computeExternalSigningInputs, cookieAffinityTransport, defaultTransport, encryptAuthorization, encryptProvingRequest, encryptRegistrationRequest, encryptSerializedProvingRequest, encryptViewKey, generateHookData, getLogLevel, initializeWasm, inputsToFields, isInputIdStrategy, isProveApiErrorBody, isProvingResponse, isRecordViewKeyStrategy, isViewKeyStrategy, logAndThrow, programChecksum, provingKeyLocator, serializeProvingRequest, setLogLevel, sha256Hex, toAddress, toField, toGroup, toSignature, toViewKey, translationKeyLocator, verifyBatchProof, verifyProof, verifyingKeyLocator, zeroizeBytes } from './browser.js';
7
7
  import { ProvingKey, VerifyingKey } from '@provablehq/wasm/mainnet.js';
8
8
  export { Address, Authorization, BHP1024, BHP256, BHP512, BHP768, Boolean, Ciphertext, ComputeKey, DynamicRecord, EncryptionToolkit, ExecutionRequest, ExecutionResponse, Field, Execution as FunctionExecution, GraphKey, Group, I128, I16, I32, I64, I8, OfflineQuery, Pedersen128, Pedersen64, Plaintext, Poseidon2, Poseidon4, Poseidon8, PrivateKey, PrivateKeyCiphertext, Program, ProgramImports as ProgramImportsBuilder, ProgramManager as ProgramManagerBase, Proof, ProvingKey, ProvingRequest, QueryOption, RecordCiphertext, RecordPlaintext, Scalar, Signature, Transaction, Transition, U128, U16, U32, U64, U8, Value, VerifyingKey, ViewKey, getOrInitConsensusVersionTestHeights, initThreadPool, setWasmLogLevel, snarkVerify, snarkVerifyBatch, stringToField, verifyFunctionExecution } from '@provablehq/wasm/mainnet.js';
9
9
  import 'core-js/proposals/json-parse-with-source.js';
@@ -271,9 +271,15 @@ declare class ProgramManager {
271
271
  * @param {KeyStore} keyStore
272
272
  */
273
273
  setKeyStore(keyStore: KeyStore): void;
274
+ /**
275
+ * Collect static imports declared by the entry program together with any
276
+ * caller-provided imports, then resolve missing transitive dependencies.
277
+ * Caller-provided program sources take precedence over network sources.
278
+ */
279
+ private collectProgramImports;
274
280
  /**
275
281
  * Build a ProgramImportsBuilder from a program and its imports.
276
- * Fetches imports from the network if not provided, resolves transitive
282
+ * Fetches missing imports from the network, resolves transitive
277
283
  * dependencies, and optionally pre-loads cached keys from the KeyStore.
278
284
  *
279
285
  * @param loadKeys When true (default), loads cached proving/verifying keys
@@ -271,9 +271,15 @@ declare class ProgramManager {
271
271
  * @param {KeyStore} keyStore
272
272
  */
273
273
  setKeyStore(keyStore: KeyStore): void;
274
+ /**
275
+ * Collect static imports declared by the entry program together with any
276
+ * caller-provided imports, then resolve missing transitive dependencies.
277
+ * Caller-provided program sources take precedence over network sources.
278
+ */
279
+ private collectProgramImports;
274
280
  /**
275
281
  * Build a ProgramImportsBuilder from a program and its imports.
276
- * Fetches imports from the network if not provided, resolves transitive
282
+ * Fetches missing imports from the network, resolves transitive
277
283
  * dependencies, and optionally pre-loads cached keys from the KeyStore.
278
284
  *
279
285
  * @param loadKeys When true (default), loads cached proving/verifying keys
@@ -17,6 +17,49 @@ export declare function encryptAuthorization(publicKey: string, authorization: A
17
17
  * @returns {string} the encrypted ProvingRequest in RFC 4648 standard Base64.
18
18
  */
19
19
  export declare function encryptProvingRequest(publicKey: string, provingRequest: ProvingRequest): string;
20
+ /**
21
+ * Serialize a ProvingRequest for later encryption with
22
+ * `encryptSerializedProvingRequest`.
23
+ *
24
+ * Useful when the request may have to be encrypted more than once: the
25
+ * delegated proving service's one-time keys are single-use, so a client that
26
+ * needs to resend a request (e.g. after the service rejected a spent or
27
+ * unknown `key_id`) can keep the serialized form and re-encrypt it for a
28
+ * fresh key instead of rebuilding and re-signing the request.
29
+ *
30
+ * The returned buffer contains the plaintext request (including the signed
31
+ * authorization and its inputs) and is owned by the caller: keep it only as
32
+ * long as a resend may still be needed, then overwrite it with
33
+ * `zeroizeBytes(serialized)`. Zeroization in JavaScript is best-effort (see
34
+ * `zeroizeBytes`), and transient copies made inside the wasm boundary by
35
+ * `toBytesLe` are outside its reach.
36
+ *
37
+ * @param {ProvingRequest} provingRequest the ProvingRequest to serialize.
38
+ *
39
+ * @returns {Uint8Array} the serialized ProvingRequest bytes.
40
+ */
41
+ export declare function serializeProvingRequest(provingRequest: ProvingRequest): Uint8Array;
42
+ /**
43
+ * Encrypt an already-serialized ProvingRequest (as produced by
44
+ * `serializeProvingRequest`) with a cryptobox X25519 public key
45
+ * (libsodium-compatible wire format).
46
+ *
47
+ * Produces exactly the same ciphertext format as `encryptProvingRequest` —
48
+ * `encryptSerializedProvingRequest(pk, serializeProvingRequest(req))` and
49
+ * `encryptProvingRequest(pk, req)` are interchangeable from the proving
50
+ * service's point of view.
51
+ *
52
+ * The input buffer is not mutated and deliberately not zeroized here: the
53
+ * caller keeps ownership so the same bytes can be re-encrypted for another
54
+ * one-time key (retry). Call `zeroizeBytes(serializedProvingRequest)` once
55
+ * no resend can be needed anymore.
56
+ *
57
+ * @param {string} publicKey The cryptobox X25519 public key to encrypt with (encoded in RFC 4648 standard Base64).
58
+ * @param {Uint8Array} serializedProvingRequest the serialized ProvingRequest bytes.
59
+ *
60
+ * @returns {string} the encrypted ProvingRequest in RFC 4648 standard Base64.
61
+ */
62
+ export declare function encryptSerializedProvingRequest(publicKey: string, serializedProvingRequest: Uint8Array): string;
20
63
  /**
21
64
  * Encrypt a view key with a cryptobox X25519 public key (libsodium-compatible wire format).
22
65
  *
@@ -17,6 +17,49 @@ export declare function encryptAuthorization(publicKey: string, authorization: A
17
17
  * @returns {string} the encrypted ProvingRequest in RFC 4648 standard Base64.
18
18
  */
19
19
  export declare function encryptProvingRequest(publicKey: string, provingRequest: ProvingRequest): string;
20
+ /**
21
+ * Serialize a ProvingRequest for later encryption with
22
+ * `encryptSerializedProvingRequest`.
23
+ *
24
+ * Useful when the request may have to be encrypted more than once: the
25
+ * delegated proving service's one-time keys are single-use, so a client that
26
+ * needs to resend a request (e.g. after the service rejected a spent or
27
+ * unknown `key_id`) can keep the serialized form and re-encrypt it for a
28
+ * fresh key instead of rebuilding and re-signing the request.
29
+ *
30
+ * The returned buffer contains the plaintext request (including the signed
31
+ * authorization and its inputs) and is owned by the caller: keep it only as
32
+ * long as a resend may still be needed, then overwrite it with
33
+ * `zeroizeBytes(serialized)`. Zeroization in JavaScript is best-effort (see
34
+ * `zeroizeBytes`), and transient copies made inside the wasm boundary by
35
+ * `toBytesLe` are outside its reach.
36
+ *
37
+ * @param {ProvingRequest} provingRequest the ProvingRequest to serialize.
38
+ *
39
+ * @returns {Uint8Array} the serialized ProvingRequest bytes.
40
+ */
41
+ export declare function serializeProvingRequest(provingRequest: ProvingRequest): Uint8Array;
42
+ /**
43
+ * Encrypt an already-serialized ProvingRequest (as produced by
44
+ * `serializeProvingRequest`) with a cryptobox X25519 public key
45
+ * (libsodium-compatible wire format).
46
+ *
47
+ * Produces exactly the same ciphertext format as `encryptProvingRequest` —
48
+ * `encryptSerializedProvingRequest(pk, serializeProvingRequest(req))` and
49
+ * `encryptProvingRequest(pk, req)` are interchangeable from the proving
50
+ * service's point of view.
51
+ *
52
+ * The input buffer is not mutated and deliberately not zeroized here: the
53
+ * caller keeps ownership so the same bytes can be re-encrypted for another
54
+ * one-time key (retry). Call `zeroizeBytes(serializedProvingRequest)` once
55
+ * no resend can be needed anymore.
56
+ *
57
+ * @param {string} publicKey The cryptobox X25519 public key to encrypt with (encoded in RFC 4648 standard Base64).
58
+ * @param {Uint8Array} serializedProvingRequest the serialized ProvingRequest bytes.
59
+ *
60
+ * @returns {string} the encrypted ProvingRequest in RFC 4648 standard Base64.
61
+ */
62
+ export declare function encryptSerializedProvingRequest(publicKey: string, serializedProvingRequest: Uint8Array): string;
20
63
  /**
21
64
  * Encrypt a view key with a cryptobox X25519 public key (libsodium-compatible wire format).
22
65
  *
@@ -439,7 +439,15 @@ class IndexedDBKeyStore {
439
439
  * @returns {string} the encrypted authorization in RFC 4648 standard Base64.
440
440
  */
441
441
  function encryptAuthorization(publicKey, authorization) {
442
- return encryptMessage(publicKey, authorization.toBytesLe());
442
+ // Zeroize the intermediate plaintext bytes regardless of success or
443
+ // failure — same pattern as encryptRegistrationRequest.
444
+ const bytes = authorization.toBytesLe();
445
+ try {
446
+ return encryptMessage(publicKey, bytes);
447
+ }
448
+ finally {
449
+ zeroizeBytes(bytes);
450
+ }
443
451
  }
444
452
  /**
445
453
  * Encrypt a ProvingRequest with a cryptobox X25519 public key (libsodium-compatible wire format).
@@ -450,7 +458,62 @@ function encryptAuthorization(publicKey, authorization) {
450
458
  * @returns {string} the encrypted ProvingRequest in RFC 4648 standard Base64.
451
459
  */
452
460
  function encryptProvingRequest(publicKey, provingRequest) {
453
- return encryptMessage(publicKey, provingRequest.toBytesLe());
461
+ // Zeroize the intermediate plaintext bytes regardless of success or
462
+ // failure — same pattern as encryptRegistrationRequest.
463
+ const bytes = provingRequest.toBytesLe();
464
+ try {
465
+ return encryptMessage(publicKey, bytes);
466
+ }
467
+ finally {
468
+ zeroizeBytes(bytes);
469
+ }
470
+ }
471
+ /**
472
+ * Serialize a ProvingRequest for later encryption with
473
+ * `encryptSerializedProvingRequest`.
474
+ *
475
+ * Useful when the request may have to be encrypted more than once: the
476
+ * delegated proving service's one-time keys are single-use, so a client that
477
+ * needs to resend a request (e.g. after the service rejected a spent or
478
+ * unknown `key_id`) can keep the serialized form and re-encrypt it for a
479
+ * fresh key instead of rebuilding and re-signing the request.
480
+ *
481
+ * The returned buffer contains the plaintext request (including the signed
482
+ * authorization and its inputs) and is owned by the caller: keep it only as
483
+ * long as a resend may still be needed, then overwrite it with
484
+ * `zeroizeBytes(serialized)`. Zeroization in JavaScript is best-effort (see
485
+ * `zeroizeBytes`), and transient copies made inside the wasm boundary by
486
+ * `toBytesLe` are outside its reach.
487
+ *
488
+ * @param {ProvingRequest} provingRequest the ProvingRequest to serialize.
489
+ *
490
+ * @returns {Uint8Array} the serialized ProvingRequest bytes.
491
+ */
492
+ function serializeProvingRequest(provingRequest) {
493
+ return provingRequest.toBytesLe();
494
+ }
495
+ /**
496
+ * Encrypt an already-serialized ProvingRequest (as produced by
497
+ * `serializeProvingRequest`) with a cryptobox X25519 public key
498
+ * (libsodium-compatible wire format).
499
+ *
500
+ * Produces exactly the same ciphertext format as `encryptProvingRequest` —
501
+ * `encryptSerializedProvingRequest(pk, serializeProvingRequest(req))` and
502
+ * `encryptProvingRequest(pk, req)` are interchangeable from the proving
503
+ * service's point of view.
504
+ *
505
+ * The input buffer is not mutated and deliberately not zeroized here: the
506
+ * caller keeps ownership so the same bytes can be re-encrypted for another
507
+ * one-time key (retry). Call `zeroizeBytes(serializedProvingRequest)` once
508
+ * no resend can be needed anymore.
509
+ *
510
+ * @param {string} publicKey The cryptobox X25519 public key to encrypt with (encoded in RFC 4648 standard Base64).
511
+ * @param {Uint8Array} serializedProvingRequest the serialized ProvingRequest bytes.
512
+ *
513
+ * @returns {string} the encrypted ProvingRequest in RFC 4648 standard Base64.
514
+ */
515
+ function encryptSerializedProvingRequest(publicKey, serializedProvingRequest) {
516
+ return encryptMessage(publicKey, serializedProvingRequest);
454
517
  }
455
518
  /**
456
519
  * Encrypt a view key with a cryptobox X25519 public key (libsodium-compatible wire format).
@@ -461,7 +524,15 @@ function encryptProvingRequest(publicKey, provingRequest) {
461
524
  * @returns {string} the encrypted view key in RFC 4648 standard Base64.
462
525
  */
463
526
  function encryptViewKey(publicKey, viewKey) {
464
- return encryptMessage(publicKey, viewKey.toBytesLe());
527
+ // Zeroize the intermediate plaintext bytes regardless of success or
528
+ // failure — same pattern as encryptRegistrationRequest.
529
+ const bytes = viewKey.toBytesLe();
530
+ try {
531
+ return encryptMessage(publicKey, bytes);
532
+ }
533
+ finally {
534
+ zeroizeBytes(bytes);
535
+ }
465
536
  }
466
537
  /**
467
538
  * Encrypt a record scanner registration request.
@@ -1532,7 +1603,7 @@ class AleoNetworkClient {
1532
1603
  else {
1533
1604
  this.headers = {
1534
1605
  // This is replaced by the actual version by a Rollup plugin
1535
- "X-Aleo-SDK-Version": "0.11.3",
1606
+ "X-Aleo-SDK-Version": "0.11.4",
1536
1607
  "X-Aleo-environment": environment(),
1537
1608
  };
1538
1609
  }
@@ -1548,7 +1619,7 @@ class AleoNetworkClient {
1548
1619
  else {
1549
1620
  this.headers = {
1550
1621
  // This is replaced by the actual version by a Rollup plugin
1551
- "X-Aleo-SDK-Version": "0.11.3",
1622
+ "X-Aleo-SDK-Version": "0.11.4",
1552
1623
  "X-Aleo-environment": environment(),
1553
1624
  };
1554
1625
  }
@@ -5837,83 +5908,84 @@ class ProgramManager {
5837
5908
  this._keyStore = keyStore;
5838
5909
  }
5839
5910
  /**
5840
- * Build a ProgramImportsBuilder from a program and its imports.
5841
- * Fetches imports from the network if not provided, resolves transitive
5842
- * dependencies, and optionally pre-loads cached keys from the KeyStore.
5843
- *
5844
- * @param loadKeys When true (default), loads cached proving/verifying keys
5845
- * from the KeyStore into the builder. Set to false for authorization and
5846
- * proving request paths where keys are not synthesized.
5911
+ * Collect static imports declared by the entry program together with any
5912
+ * caller-provided imports, then resolve missing transitive dependencies.
5913
+ * Caller-provided program sources take precedence over network sources.
5847
5914
  */
5848
- async buildProgramImports(program, imports, loadKeys, entryFunction) {
5849
- const builder = new testnet_js.ProgramImports();
5915
+ async collectProgramImports(program, imports, tolerateNetworkErrors) {
5850
5916
  const programSource = typeof program === "string" ? program : program.toString();
5851
- const programObj = testnet_js.Program.fromString(programSource);
5852
- const importNames = programObj.getImports();
5853
- if (importNames.length === 0 && (!imports || Object.keys(imports).length === 0)) {
5854
- return { builder, importEditions: new Map() };
5855
- }
5856
- let resolvedImports = {};
5857
- if (imports) {
5858
- resolvedImports = { ...imports };
5859
- }
5860
- if (importNames.length > 0 && !imports) {
5917
+ const providedImports = { ...(imports ?? {}) };
5918
+ let resolvedImports = { ...providedImports };
5919
+ if (ProgramManager.getImportNames(programSource).length > 0) {
5861
5920
  try {
5862
- resolvedImports = await this.networkClient.getProgramImports(programSource);
5921
+ const networkImports = await this.networkClient.getProgramImports(programSource, { ...resolvedImports });
5922
+ resolvedImports = { ...networkImports, ...providedImports };
5863
5923
  }
5864
5924
  catch (e) {
5925
+ if (!tolerateNetworkErrors)
5926
+ throw e;
5865
5927
  logger.warn(`Failed to resolve program imports from network: ${e}.`);
5866
5928
  }
5867
5929
  }
5868
- // Build a map of which functions each import actually calls,
5869
- // so we only load keys for functions in the call chain.
5870
- const calledFunctions = ProgramManager.callGraphToMap(programObj.getCallGraph(entryFunction));
5871
- // Phase 1: Collect all programs via BFS, discovering transitive imports.
5872
- // The initial getProgramImports call above already resolves the full
5873
- // transitive closure via recursive DFS. The BFS loop here only needs
5874
- // to handle user-provided imports whose transitive deps may not yet be
5875
- // known. For each unknown import we issue a single getProgram() call
5876
- // (not a full recursive getProgramImports) and fetch siblings in
5877
- // parallel to minimize round-trips.
5878
5930
  const collected = new Map();
5879
- const collectQueue = Object.entries(resolvedImports).map(([name, src]) => [name, typeof src === "string" ? src : src.toString()]);
5931
+ const collectQueue = Object.entries(resolvedImports).map(([name, source]) => [name, typeof source === "string" ? source : source.toString()]);
5880
5932
  while (collectQueue.length > 0) {
5881
5933
  const [name, source] = collectQueue.shift();
5882
5934
  if (collected.has(name))
5883
5935
  continue;
5884
5936
  collected.set(name, source);
5885
- // Discover transitive imports for collection (call-graph tracing
5886
- // happens in a separate pass after topological sorting).
5887
5937
  try {
5888
5938
  const subImports = ProgramManager.getImportNames(source);
5889
- if (subImports.length > 0) {
5890
- // Fetch only unknown transitive imports — the source for
5891
- // programs already in collected/resolvedImports is known, so
5892
- // we skip them. Fetches within a BFS level run in parallel.
5893
- const unknownImports = subImports.filter((id) => !collected.has(id) && !(id in resolvedImports));
5894
- if (unknownImports.length > 0) {
5895
- const fetched = await Promise.all(unknownImports.map(async (id) => {
5896
- try {
5897
- const src = await this.networkClient.getProgram(id);
5898
- return [id, src];
5899
- }
5900
- catch {
5901
- return null;
5902
- }
5903
- }));
5904
- for (const entry of fetched) {
5905
- if (entry && !collected.has(entry[0])) {
5906
- collectQueue.push(entry);
5907
- }
5939
+ const unknownImports = subImports.filter((id) => !collected.has(id) && !(id in resolvedImports));
5940
+ if (unknownImports.length > 0) {
5941
+ const fetched = await Promise.all(unknownImports.map(async (id) => {
5942
+ try {
5943
+ const importedSource = await this.networkClient.getProgram(id);
5944
+ return [id, importedSource];
5945
+ }
5946
+ catch (e) {
5947
+ if (!tolerateNetworkErrors)
5948
+ throw e;
5949
+ return null;
5950
+ }
5951
+ }));
5952
+ for (const entry of fetched) {
5953
+ if (entry && !collected.has(entry[0])) {
5954
+ collectQueue.push(entry);
5908
5955
  }
5909
5956
  }
5910
5957
  }
5911
5958
  }
5912
5959
  catch (e) {
5960
+ if (!tolerateNetworkErrors)
5961
+ throw e;
5913
5962
  logger.warn(`Failed to resolve transitive imports for ${name}: ${e}`);
5914
5963
  }
5915
5964
  }
5916
- // Phase 2: Add programs in topological order (leaves first).
5965
+ return collected;
5966
+ }
5967
+ /**
5968
+ * Build a ProgramImportsBuilder from a program and its imports.
5969
+ * Fetches missing imports from the network, resolves transitive
5970
+ * dependencies, and optionally pre-loads cached keys from the KeyStore.
5971
+ *
5972
+ * @param loadKeys When true (default), loads cached proving/verifying keys
5973
+ * from the KeyStore into the builder. Set to false for authorization and
5974
+ * proving request paths where keys are not synthesized.
5975
+ */
5976
+ async buildProgramImports(program, imports, loadKeys, entryFunction) {
5977
+ const builder = new testnet_js.ProgramImports();
5978
+ const programSource = typeof program === "string" ? program : program.toString();
5979
+ const programObj = testnet_js.Program.fromString(programSource);
5980
+ const importNames = programObj.getImports();
5981
+ if (importNames.length === 0 && (!imports || Object.keys(imports).length === 0)) {
5982
+ return { builder, importEditions: new Map() };
5983
+ }
5984
+ const collected = await this.collectProgramImports(programSource, imports, true);
5985
+ // Build a map of which functions each import actually calls,
5986
+ // so we only load keys for functions in the call chain.
5987
+ const calledFunctions = ProgramManager.callGraphToMap(programObj.getCallGraph(entryFunction));
5988
+ // Add programs in topological order (leaves first).
5917
5989
  // A simple DFS post-order ensures dependencies are added before
5918
5990
  // dependents, regardless of the order collected entries arrived.
5919
5991
  const sorted = [];
@@ -8386,7 +8458,7 @@ class ProgramManager {
8386
8458
  throw new Error("Authorization must be provided if estimating fee for Authorization.");
8387
8459
  }
8388
8460
  const programSource = program ? program.toString() : await this.networkClient.getProgram(programName, edition);
8389
- const programImports = imports ?? await this.networkClient.getProgramImports(programSource);
8461
+ const programImports = Object.fromEntries(await this.collectProgramImports(programSource, imports, false));
8390
8462
  return testnet_js.ProgramManager.estimateFeeForAuthorization(authorization, programSource, programImports, edition);
8391
8463
  }
8392
8464
  /**
@@ -8421,7 +8493,7 @@ class ProgramManager {
8421
8493
  throw new Error("Function name must be specified when estimating fee.");
8422
8494
  }
8423
8495
  const programSource = program ? program.toString() : await this.networkClient.getProgram(programName, edition);
8424
- const programImports = imports ? imports : await this.networkClient.getProgramImports(programSource);
8496
+ const programImports = Object.fromEntries(await this.collectProgramImports(programSource, imports, false));
8425
8497
  return testnet_js.ProgramManager.estimateExecutionFee(programSource, functionName, programImports, edition);
8426
8498
  }
8427
8499
  // Internal utility function for getting a credits.aleo record
@@ -9412,6 +9484,7 @@ exports.defaultTransport = defaultTransport;
9412
9484
  exports.encryptAuthorization = encryptAuthorization;
9413
9485
  exports.encryptProvingRequest = encryptProvingRequest;
9414
9486
  exports.encryptRegistrationRequest = encryptRegistrationRequest;
9487
+ exports.encryptSerializedProvingRequest = encryptSerializedProvingRequest;
9415
9488
  exports.encryptViewKey = encryptViewKey;
9416
9489
  exports.generateHookData = generateHookData;
9417
9490
  exports.getLogLevel = getLogLevel;
@@ -9425,6 +9498,7 @@ exports.isViewKeyStrategy = isViewKeyStrategy;
9425
9498
  exports.logAndThrow = logAndThrow;
9426
9499
  exports.programChecksum = programChecksum;
9427
9500
  exports.provingKeyLocator = provingKeyLocator;
9501
+ exports.serializeProvingRequest = serializeProvingRequest;
9428
9502
  exports.setLogLevel = setLogLevel;
9429
9503
  exports.sha256Hex = sha256Hex;
9430
9504
  exports.toAddress = toAddress;