UNPKG

@provablehq/sdk

Version:

A Software Development Kit (SDK) for Zero-Knowledge Transactions

1 lines 27.5 kB
{"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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"}