UNPKG

@provablehq/sdk

Version:

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

707 lines (701 loc) 28.9 kB
'use strict'; require('./node-polyfill.cjs'); var fs = require('node:fs/promises'); var $fs = require('node:fs'); var path = require('path'); var browser = require('./browser.cjs'); var testnet_js = require('@provablehq/wasm/testnet.js'); require('core-js/proposals/json-parse-with-source.js'); require('node:crypto'); require('mime/lite'); require('xmlhttprequest-ssl'); require('node:worker_threads'); require('node:os'); require('@serenity-kit/noble-sodium'); require('@scure/base'); function _interopNamespaceDefault(e) { var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs); var $fs__namespace = /*#__PURE__*/_interopNamespaceDefault($fs); var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path); class LocalFileKeyStore { directory; keyVerifier = new browser.MemKeyVerifier(); /** * Creates a new directory at the given path or CURRENTDIR/.aleo if none is provided to store keys. * If a custom directory is passed and its last path segment is not ".aleo", ".aleo" is appended * so keys are stored under that subdirectory (e.g. /home/project → /home/project/.aleo). * * @param {string} [directory] - Optional custom directory path for key storage. Defaults to ".aleo" in current working directory. * @throws {Error} If directory creation fails. */ constructor(directory) { this.directory = directory ?? path__namespace.join(process.cwd(), ".aleo"); if (directory !== undefined && path__namespace.basename(this.directory) !== ".aleo") { this.directory = path__namespace.join(this.directory, ".aleo"); } $fs__namespace.mkdirSync(this.directory, { recursive: true }); } /** * Validates a single locator component for unsafe filesystem characters. * * @private * @param {string} value - The component value to validate. * @param {string} label - Label for error messages (e.g. "program", "functionName"). * @throws {InvalidLocatorError} If the value is empty, contains traversal sequences, path separators, or null bytes. */ validateComponent(value, label) { if (value === "" || value === ".") { throw new browser.InvalidLocatorError(`KeyLocator ${label} must not be empty or "." (got "${value}")`, value, "reserved_name"); } if (value.includes("..")) { throw new browser.InvalidLocatorError(`KeyLocator ${label} must not contain ".." (got "${value}")`, value, "path_traversal"); } if (value.includes("/") || value.includes("\\") || value.includes("\0")) { throw new browser.InvalidLocatorError(`KeyLocator ${label} must not contain path separators or null bytes (got "${value}")`, value, "path_separator"); } } /** * Validates that a numeric locator field is not negative. * * @private * @param {number} value - The numeric value to validate. * @param {string} label - Label for error messages (e.g. "edition", "amendment"). * @throws {InvalidLocatorError} If the value is negative. */ validateNonNegative(value, label) { if (!Number.isInteger(value) || value < 0) { throw new browser.InvalidLocatorError(`KeyLocator ${label} must be a non-negative integer (got ${value})`, String(value), "negative_value"); } } /** * Serializes a {@link KeyLocator} to a filesystem-safe flat string, validating components first. * * For prover/verifier keys: `{program}.{functionName}.e{edition}.a{amendment}.{network}.{keyType}` * For translation keys: `{program}.{functionName}.e{edition}.a{amendment}.{network}.translation.{recordName}.{recordInputPosition}` * * Note: The optional `checksum` field is excluded — it is used for integrity verification only * (via {@link checksumToFingerprint}) and is not part of the key identity. * * @private * @param {KeyLocator} locator - The key locator. * @returns {string} A dot-delimited string safe for use as a filename. * @throws {InvalidLocatorError} If any component contains unsafe characters. */ serializeLocator(locator) { this.validateComponent(locator.program, "program"); this.validateComponent(locator.functionName, "functionName"); this.validateComponent(locator.network, "network"); this.validateNonNegative(locator.edition, "edition"); this.validateNonNegative(locator.amendment, "amendment"); const base = `${locator.program}.${locator.functionName}.e${locator.edition}.a${locator.amendment}.${locator.network}.${locator.keyType}`; if (locator.keyType === "translation") { this.validateComponent(locator.recordName, "recordName"); this.validateNonNegative(locator.recordInputPosition, "recordInputPosition"); return `${base}.${locator.recordName}.${locator.recordInputPosition}`; } return base; } /** * Converts an optional checksum string from a locator into a KeyFingerprint * suitable for the key verifier, using the actual key byte length for size. * * @private */ checksumToFingerprint(checksum, keyBytes) { if (!checksum) return undefined; return { checksum, size: keyBytes.length }; } /** * Generates the path for a key metadata file based on the locator. * * @private * @param {string} locator - Unique identifier for the key. * @returns {string} Full filesystem path to the metadata file. */ metadataPath(locator) { return path__namespace.join(this.directory, `${locator}.metadata`); } /** * Reads and parses the key fingerprint metadata from storage. * * @private * @param {string} locator - Unique identifier for the key. * @returns {Promise<KeyFingerprint | null>} The key fingerprint if found, null if file doesn't exist. * @throws {Error} If file read fails for any reason other than not found. */ async readKeyMetadata(locator) { try { const data = await fs__namespace.readFile(this.metadataPath(locator), "utf-8"); return JSON.parse(data); } catch (err) { if (err && typeof err === "object" && "code" in err && err.code === "ENOENT") return null; throw err; } } /** * Writes key fingerprint metadata to storage. * * @private * @param {string} locator - Unique identifier for the key. * @param {KeyFingerprint} metadata - Key fingerprint metadata to store. * @returns {Promise<void>} * @throws {Error} If directory creation or file write fails. */ async writeKeyMetadata(locator, metadata) { await fs__namespace.mkdir(path__namespace.dirname(this.metadataPath(locator)), { recursive: true, }); await fs__namespace.writeFile(this.metadataPath(locator), JSON.stringify(metadata, null, 0), "utf-8"); } async readFileOptional(filepath) { try { const data = await fs__namespace.readFile(filepath); return new Uint8Array(data); } catch (err) { if (err.code === "ENOENT") return null; throw err; } } /** * Atomically writes data to a file, ensuring the parent directories exist. * * @private * @param {string} filepath - Full path to the file to write * @param {Uint8Array} data - Binary data to write to the file * @returns {Promise<void>} Resolves when write is complete * @throws {Error} If directory creation or file write fails */ async writeFileAtomic(filepath, data) { const dir = path__namespace.dirname(filepath); await fs__namespace.mkdir(dir, { recursive: true }); const tempPath = path__namespace.join(dir, `.${path__namespace.basename(filepath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`); await fs__namespace.writeFile(tempPath, data); try { await fs__namespace.rename(tempPath, filepath); } catch (err) { const code = err && typeof err === "object" && "code" in err ? err.code : undefined; // Windows often throws EEXIST when target exists; EPERM/EACCES happen with locks/AV. if (code === "EEXIST" || code === "EPERM" || code === "EACCES") { await fs__namespace.unlink(filepath).catch(() => { }); try { await fs__namespace.rename(tempPath, filepath); } catch (err2) { await fs__namespace.unlink(tempPath).catch(() => { }); throw err2; } } else { await fs__namespace.unlink(tempPath).catch(() => { }); throw err; } } } /** * Recursively removes all files and subdirectories under the given directory, then removes the directory itself. * Uses fs.rm with recursive: true and force: true so that symbolic links are removed without following them, * avoiding deletion of content outside the keystore. * * @private * @param {string} dir - Directory path to clear * @returns {Promise<void>} Resolves when clearing is complete * @throws {Error} If directory removal fails for reasons other than non-existence */ async clearDirectory(dir) { try { await fs__namespace.rm(dir, { recursive: true, force: true }); } catch (err) { const code = err && typeof err === "object" && "code" in err ? err.code : undefined; if (code === "ENOENT") { return; } throw err; } } // ------------------------------------------------------- // KEYSTORE INTERFACE // ------------------------------------------------------- /** * Retrieves the key bytes from storage and optionally verifies them. * * @param {KeyLocator} locator - The key locator with optional checksum for verification. * @returns {Promise<Uint8Array | null>} The key bytes if found and verified, null if not found. * @throws {KeyVerificationError} If verification fails. */ async getKeyBytes(locator) { const fileKey = this.serializeLocator(locator); // Attempt to read key bytes from storage (under this.directory). const keyBytes = await this.readFileOptional(path__namespace.join(this.directory, fileKey)); // If no key bytes were found, return null. if (!keyBytes) return null; // Use caller-provided checksum or metadata stored on disk for verification. const fingerprint = this.checksumToFingerprint(locator.checksum, keyBytes) ?? (await this.getKeyMetadata(locator)); if (fingerprint) { await this.keyVerifier.verifyKeyBytes({ keyBytes, locator: fileKey, fingerprint, }); } // Return the verified key bytes. return keyBytes; } /** * Retrieves and verifies a proving key from storage. * * @param {ProvingKeyLocator} locator - The proving key locator. * @returns {Promise<ProvingKey | null>} The proving key if found and verified, null if not found. * @throws {KeyVerificationError} If verification fails. * @throws {Error} If key bytes cannot be parsed into a valid ProvingKey. */ async getProvingKey(locator) { const proverBytes = await this.getKeyBytes(locator); if (!proverBytes) return null; return testnet_js.ProvingKey.fromBytes(proverBytes); } /** * Retrieves and verifies a verifying key from storage. * * @param {VerifyingKeyLocator} locator - The verifying key locator. * @returns {Promise<VerifyingKey | null>} The verifying key if found and verified, null if not found. * @throws {KeyVerificationError} If verification fails. * @throws {Error} If key bytes cannot be parsed into a valid VerifyingKey. */ async getVerifyingKey(locator) { const verifierBytes = await this.getKeyBytes(locator); if (!verifierBytes) return null; return testnet_js.VerifyingKey.fromBytes(verifierBytes); } /** * Stores proving and verifying keys in key storage. * * @param {ProvingKeyLocator} proverLocator The locator for the proving key. * @param {VerifyingKeyLocator} verifierLocator The locator for the verifying key. * @param {FunctionKeyPair} keys The proving and verifying keys. */ async setKeys(proverLocator, verifierLocator, keys) { const proverKey = this.serializeLocator(proverLocator); const verifierKey = this.serializeLocator(verifierLocator); // Convert the WASM keys to raw bytes. const [provingKey, verifyingKey] = keys; const [provingKeyBytes, verifyingKeyBytes] = [ provingKey.toBytes(), verifyingKey.toBytes(), ]; // Compute the fingerprints for the proving and verifying keys, verify against expected checksums if provided. const [proverFingerPrint, verifierFingerPrint] = await Promise.all([ this.keyVerifier.computeKeyMetadata({ keyBytes: provingKeyBytes, locator: proverKey, fingerprint: this.checksumToFingerprint(proverLocator.checksum, provingKeyBytes), }), this.keyVerifier.computeKeyMetadata({ keyBytes: verifyingKeyBytes, locator: verifierKey, fingerprint: this.checksumToFingerprint(verifierLocator.checksum, verifyingKeyBytes), }), ]); // Write the proving and verifying key bytes and their metadata to storage (under this.directory). await this.writeFileAtomic(path__namespace.join(this.directory, proverKey), provingKeyBytes); await this.writeFileAtomic(path__namespace.join(this.directory, verifierKey), verifyingKeyBytes); await this.writeKeyMetadata(proverKey, proverFingerPrint); await this.writeKeyMetadata(verifierKey, verifierFingerPrint); } /** * Store a raw key in storage along with its fingerprint metadata for future verification. * * @param {Uint8Array} keyBytes The raw key bytes. * @param {KeyLocator} locator The unique locator for the key. * @returns {Promise<void>} * @throws {Error} If computing key metadata or writing to storage fails */ async setKeyBytes(keyBytes, locator) { const fileKey = this.serializeLocator(locator); // Compute the key metadata including fingerprint const computedMetadata = await this.keyVerifier.computeKeyMetadata({ keyBytes: keyBytes, locator: fileKey, fingerprint: this.checksumToFingerprint(locator.checksum, keyBytes), }); // Write the key bytes and metadata atomically (key file under this.directory). await this.writeFileAtomic(path__namespace.join(this.directory, fileKey), keyBytes); await this.writeKeyMetadata(fileKey, computedMetadata); } /** * Returns stored metadata for a key, if any. * * @param {KeyLocator} locator The unique locator for the key. * @returns {Promise<KeyFingerprint | null>} The stored fingerprint metadata, or null if none exists. */ async getKeyMetadata(locator) { const fileKey = this.serializeLocator(locator); return this.readKeyMetadata(fileKey); } /** * Checks if a key exists for the given locator. * * @param {KeyLocator} locator - The unique key locator. * @returns {Promise<boolean>} True if key exists, false otherwise. */ async has(locator) { const fileKey = this.serializeLocator(locator); const keyPath = path__namespace.join(this.directory, fileKey); return await fs__namespace .access(keyPath) .then(() => true) .catch(() => false); } /** * Deletes a key and its associated metadata from storage. Silently ignores errors if files don't exist. * * @param {KeyLocator} locator - The unique key locator. * @returns {Promise<void>} */ async delete(locator) { const fileKey = this.serializeLocator(locator); const p = path__namespace.join(this.directory, fileKey); const m = this.metadataPath(fileKey); await fs__namespace.unlink(p).catch(() => { }); await fs__namespace.unlink(m).catch(() => { }); } /** * Clears the key storage directory by recursively removing all files and subdirectories under it, then removes the keystore directory itself. * * @returns {Promise<void>} * @throws {Error} If directory listing fails for reasons other than non-existence. */ async clear() { await this.clearDirectory(this.directory); } } exports.Account = browser.Account; exports.AleoKeyProvider = browser.AleoKeyProvider; exports.AleoKeyProviderParams = browser.AleoKeyProviderParams; exports.AleoNetworkClient = browser.AleoNetworkClient; exports.BlockHeightSearch = browser.BlockHeightSearch; exports.CREDITS_PROGRAM_KEYS = browser.CREDITS_PROGRAM_KEYS; exports.ChecksumMismatchError = browser.ChecksumMismatchError; exports.DecryptionNotEnabledError = browser.DecryptionNotEnabledError; exports.IndexedDBKeyStore = browser.IndexedDBKeyStore; exports.InvalidLocatorError = browser.InvalidLocatorError; exports.KEY_STORE = browser.KEY_STORE; exports.KeyVerificationError = browser.ChecksumMismatchError; exports.MemKeyVerifier = browser.MemKeyVerifier; exports.NetworkRecordProvider = browser.NetworkRecordProvider; exports.OfflineKeyProvider = browser.OfflineKeyProvider; exports.OfflineSearchParams = browser.OfflineSearchParams; exports.PRIVATE_TO_PUBLIC_TRANSFER = browser.PRIVATE_TO_PUBLIC_TRANSFER; exports.PRIVATE_TRANSFER = browser.PRIVATE_TRANSFER; exports.PRIVATE_TRANSFER_TYPES = browser.PRIVATE_TRANSFER_TYPES; exports.PUBLIC_TO_PRIVATE_TRANSFER = browser.PUBLIC_TO_PRIVATE_TRANSFER; exports.PUBLIC_TRANSFER = browser.PUBLIC_TRANSFER; exports.PUBLIC_TRANSFER_AS_SIGNER = browser.PUBLIC_TRANSFER_AS_SIGNER; exports.ProgramManager = browser.ProgramManager; exports.RECORD_DOMAIN = browser.RECORD_DOMAIN; exports.RecordNotFoundError = browser.RecordNotFoundError; exports.RecordScanner = browser.RecordScanner; exports.RecordScannerRequestError = browser.RecordScannerRequestError; exports.SealanceMerkleTree = browser.SealanceMerkleTree; exports.UUIDError = browser.UUIDError; exports.VALID_TRANSFER_TYPES = browser.VALID_TRANSFER_TYPES; exports.ViewKeyNotStoredError = browser.ViewKeyNotStoredError; exports.buildExecutionRequestFromExternallySignedData = browser.buildExecutionRequestFromExternallySignedData; exports.computeExternalSigningInputs = browser.computeExternalSigningInputs; exports.cookieAffinityTransport = browser.cookieAffinityTransport; exports.defaultTransport = browser.defaultTransport; exports.encryptAuthorization = browser.encryptAuthorization; exports.encryptProvingRequest = browser.encryptProvingRequest; exports.encryptRegistrationRequest = browser.encryptRegistrationRequest; exports.encryptSerializedProvingRequest = browser.encryptSerializedProvingRequest; exports.encryptViewKey = browser.encryptViewKey; exports.generateHookData = browser.generateHookData; exports.getLogLevel = browser.getLogLevel; exports.initializeWasm = browser.initializeWasm; exports.inputsToFields = browser.inputsToFields; exports.isInputIdStrategy = browser.isInputIdStrategy; exports.isProveApiErrorBody = browser.isProveApiErrorBody; exports.isProvingResponse = browser.isProvingResponse; exports.isRecordViewKeyStrategy = browser.isRecordViewKeyStrategy; exports.isViewKeyStrategy = browser.isViewKeyStrategy; exports.logAndThrow = browser.logAndThrow; exports.programChecksum = browser.programChecksum; exports.provingKeyLocator = browser.provingKeyLocator; exports.serializeProvingRequest = browser.serializeProvingRequest; exports.setLogLevel = browser.setLogLevel; exports.sha256Hex = browser.sha256Hex; exports.toAddress = browser.toAddress; exports.toField = browser.toField; exports.toGroup = browser.toGroup; exports.toSignature = browser.toSignature; exports.toViewKey = browser.toViewKey; exports.translationKeyLocator = browser.translationKeyLocator; exports.verifyBatchProof = browser.verifyBatchProof; exports.verifyProof = browser.verifyProof; exports.verifyingKeyLocator = browser.verifyingKeyLocator; exports.zeroizeBytes = browser.zeroizeBytes; Object.defineProperty(exports, "Address", { enumerable: true, get: function () { return testnet_js.Address; } }); Object.defineProperty(exports, "Authorization", { enumerable: true, get: function () { return testnet_js.Authorization; } }); Object.defineProperty(exports, "BHP1024", { enumerable: true, get: function () { return testnet_js.BHP1024; } }); Object.defineProperty(exports, "BHP256", { enumerable: true, get: function () { return testnet_js.BHP256; } }); Object.defineProperty(exports, "BHP512", { enumerable: true, get: function () { return testnet_js.BHP512; } }); Object.defineProperty(exports, "BHP768", { enumerable: true, get: function () { return testnet_js.BHP768; } }); Object.defineProperty(exports, "Boolean", { enumerable: true, get: function () { return testnet_js.Boolean; } }); Object.defineProperty(exports, "Ciphertext", { enumerable: true, get: function () { return testnet_js.Ciphertext; } }); Object.defineProperty(exports, "ComputeKey", { enumerable: true, get: function () { return testnet_js.ComputeKey; } }); Object.defineProperty(exports, "DynamicRecord", { enumerable: true, get: function () { return testnet_js.DynamicRecord; } }); Object.defineProperty(exports, "EncryptionToolkit", { enumerable: true, get: function () { return testnet_js.EncryptionToolkit; } }); Object.defineProperty(exports, "ExecutionRequest", { enumerable: true, get: function () { return testnet_js.ExecutionRequest; } }); Object.defineProperty(exports, "ExecutionResponse", { enumerable: true, get: function () { return testnet_js.ExecutionResponse; } }); Object.defineProperty(exports, "Field", { enumerable: true, get: function () { return testnet_js.Field; } }); Object.defineProperty(exports, "FunctionExecution", { enumerable: true, get: function () { return testnet_js.Execution; } }); Object.defineProperty(exports, "GraphKey", { enumerable: true, get: function () { return testnet_js.GraphKey; } }); Object.defineProperty(exports, "Group", { enumerable: true, get: function () { return testnet_js.Group; } }); Object.defineProperty(exports, "I128", { enumerable: true, get: function () { return testnet_js.I128; } }); Object.defineProperty(exports, "I16", { enumerable: true, get: function () { return testnet_js.I16; } }); Object.defineProperty(exports, "I32", { enumerable: true, get: function () { return testnet_js.I32; } }); Object.defineProperty(exports, "I64", { enumerable: true, get: function () { return testnet_js.I64; } }); Object.defineProperty(exports, "I8", { enumerable: true, get: function () { return testnet_js.I8; } }); Object.defineProperty(exports, "OfflineQuery", { enumerable: true, get: function () { return testnet_js.OfflineQuery; } }); Object.defineProperty(exports, "Pedersen128", { enumerable: true, get: function () { return testnet_js.Pedersen128; } }); Object.defineProperty(exports, "Pedersen64", { enumerable: true, get: function () { return testnet_js.Pedersen64; } }); Object.defineProperty(exports, "Plaintext", { enumerable: true, get: function () { return testnet_js.Plaintext; } }); Object.defineProperty(exports, "Poseidon2", { enumerable: true, get: function () { return testnet_js.Poseidon2; } }); Object.defineProperty(exports, "Poseidon4", { enumerable: true, get: function () { return testnet_js.Poseidon4; } }); Object.defineProperty(exports, "Poseidon8", { enumerable: true, get: function () { return testnet_js.Poseidon8; } }); Object.defineProperty(exports, "PrivateKey", { enumerable: true, get: function () { return testnet_js.PrivateKey; } }); Object.defineProperty(exports, "PrivateKeyCiphertext", { enumerable: true, get: function () { return testnet_js.PrivateKeyCiphertext; } }); Object.defineProperty(exports, "Program", { enumerable: true, get: function () { return testnet_js.Program; } }); Object.defineProperty(exports, "ProgramImportsBuilder", { enumerable: true, get: function () { return testnet_js.ProgramImports; } }); Object.defineProperty(exports, "ProgramManagerBase", { enumerable: true, get: function () { return testnet_js.ProgramManager; } }); Object.defineProperty(exports, "Proof", { enumerable: true, get: function () { return testnet_js.Proof; } }); Object.defineProperty(exports, "ProvingKey", { enumerable: true, get: function () { return testnet_js.ProvingKey; } }); Object.defineProperty(exports, "ProvingRequest", { enumerable: true, get: function () { return testnet_js.ProvingRequest; } }); Object.defineProperty(exports, "QueryOption", { enumerable: true, get: function () { return testnet_js.QueryOption; } }); Object.defineProperty(exports, "RecordCiphertext", { enumerable: true, get: function () { return testnet_js.RecordCiphertext; } }); Object.defineProperty(exports, "RecordPlaintext", { enumerable: true, get: function () { return testnet_js.RecordPlaintext; } }); Object.defineProperty(exports, "Scalar", { enumerable: true, get: function () { return testnet_js.Scalar; } }); Object.defineProperty(exports, "Signature", { enumerable: true, get: function () { return testnet_js.Signature; } }); Object.defineProperty(exports, "Transaction", { enumerable: true, get: function () { return testnet_js.Transaction; } }); Object.defineProperty(exports, "Transition", { enumerable: true, get: function () { return testnet_js.Transition; } }); Object.defineProperty(exports, "U128", { enumerable: true, get: function () { return testnet_js.U128; } }); Object.defineProperty(exports, "U16", { enumerable: true, get: function () { return testnet_js.U16; } }); Object.defineProperty(exports, "U32", { enumerable: true, get: function () { return testnet_js.U32; } }); Object.defineProperty(exports, "U64", { enumerable: true, get: function () { return testnet_js.U64; } }); Object.defineProperty(exports, "U8", { enumerable: true, get: function () { return testnet_js.U8; } }); Object.defineProperty(exports, "Value", { enumerable: true, get: function () { return testnet_js.Value; } }); Object.defineProperty(exports, "VerifyingKey", { enumerable: true, get: function () { return testnet_js.VerifyingKey; } }); Object.defineProperty(exports, "ViewKey", { enumerable: true, get: function () { return testnet_js.ViewKey; } }); Object.defineProperty(exports, "getOrInitConsensusVersionTestHeights", { enumerable: true, get: function () { return testnet_js.getOrInitConsensusVersionTestHeights; } }); Object.defineProperty(exports, "initThreadPool", { enumerable: true, get: function () { return testnet_js.initThreadPool; } }); Object.defineProperty(exports, "setWasmLogLevel", { enumerable: true, get: function () { return testnet_js.setWasmLogLevel; } }); Object.defineProperty(exports, "snarkVerify", { enumerable: true, get: function () { return testnet_js.snarkVerify; } }); Object.defineProperty(exports, "snarkVerifyBatch", { enumerable: true, get: function () { return testnet_js.snarkVerifyBatch; } }); Object.defineProperty(exports, "stringToField", { enumerable: true, get: function () { return testnet_js.stringToField; } }); Object.defineProperty(exports, "verifyFunctionExecution", { enumerable: true, get: function () { return testnet_js.verifyFunctionExecution; } }); exports.LocalFileKeyStore = LocalFileKeyStore; //# sourceMappingURL=node.cjs.map