UNPKG

@silvana-one/mina-prover

Version:
1,162 lines (1,155 loc) 36.8 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // dist/node/index.js var index_exports = {}; __export(index_exports, { LocalCloud: () => LocalCloud, LocalStorage: () => LocalStorage, NftAPI: () => NftAPI, TokenAPI: () => TokenAPI, zkCloudWorkerClient: () => zkCloudWorkerClient }); module.exports = __toCommonJS(index_exports); // dist/node/api/api.js var import_chalk = __toESM(require("chalk"), 1); var import_mina_utils2 = require("@silvana-one/mina-utils"); // dist/node/local/local.js var import_prover = require("@silvana-one/prover"); var import_mina_utils = require("@silvana-one/mina-utils"); var LocalCloud = class _LocalCloud extends import_prover.Cloud { /** * Constructor for LocalCloud * @param params the parameters to create the LocalCloud * @param params.job the job data * @param params.chain the blockchain to execute the job on, can be any blockchain, not only local * @param params.cache the cache folder * @param params.stepId the step id * @param params.localWorker the worker to execute the tasks */ constructor(params) { const { job, chain, cache, stepId, localWorker } = params; const { id, jobId, developer, repo, task, userId, args, metadata, taskId } = job; super({ id, jobId, stepId: stepId ?? "stepId", taskId: taskId ?? "taskId", cache: cache ?? "./cache", developer, repo, task, userId, args, metadata, isLocalCloud: true, chain }); this.localWorker = localWorker; } /** * Provides the deployer key pair for testing and development * @returns the deployer key pair */ async getDeployer() { const privateKey = process.env.DEPLOYER_PRIVATE_KEY; const publicKey = process.env.DEPLOYER_PUBLIC_KEY; try { return privateKey === void 0 || publicKey === void 0 ? void 0 : { privateKey, publicKey }; } catch (error) { console.error(`getDeployer: error getting deployer key pair: ${error}`, error); return void 0; } } /** * Releases the deployer key pair */ async releaseDeployer(params) { console.log("LocalCloud: releaseDeployer", params); } /** * Gets the data by key * @param key the key to get the data * @returns the data */ async getDataByKey(key) { const value = LocalStorage.data[key]; return value; } /** * Saves the data by key * @param key the key to save the data * @param value the value to save */ async saveDataByKey(key, value) { if (value !== void 0) LocalStorage.data[key] = value; else delete LocalStorage.data[key]; } /** * Saves the file * @param filename the filename to save * @param value the value to save */ async saveFile(filename, value) { LocalStorage.files[filename] = value; } /** * Loads the file * @param filename * @returns the file data */ async loadFile(filename) { return LocalStorage.files[filename]; } /** * Encrypts the data * @param params * @param params.data the data * @param params.context the context * @param params.keyId the key id, optional * @returns encrypted data */ async encrypt(params) { return JSON.stringify(params); } /** * Decrypts the data * @param params * @param params.data the data * @param params.context the context * @param params.keyId the key id, optional * @returns */ async decrypt(params) { const { data, context, keyId } = JSON.parse(params.data); if (context !== params.context) { console.error("decrypt: context mismatch"); return void 0; } if (keyId !== params.keyId) { console.error("decrypt: keyId mismatch"); return void 0; } return data; } /** * Generates an id for local cloud * @returns generated unique id */ static generateId(tx = void 0) { return Date.now() + "." + (0, import_mina_utils.makeString)(32); } /** * Send transactions to the local cloud * @param transactions the transactions to add * @returns the transaction ids */ async sendTransactions(transactions) { return await _LocalCloud.addTransactions(transactions); } /** * Adds transactions to the local cloud * @param transactions the transactions to add * @returns the transaction ids */ static async addTransactions(transactions) { const timeReceived = Date.now(); const txs = []; transactions.forEach((tx) => { if (typeof tx === "string") { const txId = _LocalCloud.generateId(JSON.stringify({ tx, time: timeReceived })); const transaction = { txId, transaction: tx, timeReceived, status: "accepted" }; LocalStorage.transactions[txId] = transaction; txs.push(transaction); } else { LocalStorage.transactions[tx.txId] = tx; txs.push(tx); } }); return txs; } /** * Deletes a transaction from the local cloud * @param txId the transaction id to delete */ async deleteTransaction(txId) { if (LocalStorage.transactions[txId] === void 0) throw new Error(`deleteTransaction: Transaction ${txId} not found`); delete LocalStorage.transactions[txId]; } async getTransactions() { const txs = Object.keys(LocalStorage.transactions).map((txId) => { return LocalStorage.transactions[txId]; }); return txs; } /** * Publish the transaction metadata in human-readable format * @param params * @param params.txId the transaction id * @param params.metadata the metadata */ async publishTransactionMetadata(params) { console.log("publishTransactionMetadata:", params); } /** * Runs the worker in the local cloud * @param params the parameters to run the worker * @param params.command the command to run * @param params.data the data to use * @param params.chain the blockchain to execute the job on * @param params.localWorker the worker to execute the tasks * @returns the job id */ static async run(params) { const { command, data, chain, localWorker } = params; const { developer, repo, transactions, task, userId, args, metadata } = data; const timeCreated = Date.now(); const jobId = _LocalCloud.generateId(); const job = { id: "local", jobId, developer, repo, task, userId, args, metadata, txNumber: command === "recursiveProof" ? transactions.length : 1, timeCreated, timeStarted: timeCreated, chain }; const cloud = new _LocalCloud({ job, chain, localWorker }); const worker = await localWorker(cloud); if (worker === void 0) throw new Error("worker is undefined"); const result = command === "recursiveProof" ? await _LocalCloud.sequencer({ worker, data }) : command === "execute" ? await worker.execute(transactions) : void 0; const timeFinished = Date.now(); if (result !== void 0) { LocalStorage.jobEvents[jobId] = { jobId, jobStatus: "finished", eventTime: timeFinished, result }; job.timeFinished = timeFinished; job.jobStatus = "finished"; job.result = result; } else { LocalStorage.jobEvents[jobId] = { jobId, jobStatus: "failed", eventTime: timeFinished }; job.timeFailed = timeFinished; job.jobStatus = "failed"; } job.billedDuration = timeFinished - timeCreated; LocalStorage.jobs[jobId] = job; return jobId; } /** * Runs the recursive proof in the local cloud * @param data the data to use * @param data.transactions the transactions to process * @param data.task the task to execute * @param data.userId the user id * @param data.args the arguments for the job * @param data.metadata the metadata for the job * @returns the job id */ async recursiveProof(data) { return await _LocalCloud.run({ command: "recursiveProof", data: { developer: this.developer, repo: this.repo, transactions: data.transactions, task: data.task ?? "recursiveProof", userId: data.userId, args: data.args, metadata: data.metadata }, chain: this.chain, localWorker: this.localWorker }); } /** * Executes the task in the local cloud * @param data the data to use * @param data.transactions the transactions to process * @param data.task the task to execute * @param data.userId the user id * @param data.args the arguments for the job * @param data.metadata the metadata for the job * @returns the job id */ async execute(data) { return await _LocalCloud.run({ command: "execute", data: { developer: this.developer, repo: this.repo, transactions: data.transactions, task: data.task, userId: data.userId, args: data.args, metadata: data.metadata }, chain: this.chain, localWorker: this.localWorker }); } /** * Gets the job result * @param jobId the job id * @returns the job data */ async jobResult(jobId) { return LocalStorage.jobs[jobId]; } /** * Adds a task to the local cloud * @param data the data to use * @param data.task the task to execute * @param data.startTime the start time for the task * @param data.userId the user id * @param data.args the arguments for the job * @param data.metadata the metadata for the job * @returns the task id */ async addTask(data) { const taskId = _LocalCloud.generateId(); LocalStorage.tasks[taskId] = { ...data, id: "local", taskId, timeCreated: Date.now(), developer: this.developer, repo: this.repo, chain: this.chain }; return taskId; } /** * Deletes a task from the local cloud * @param taskId the task id to delete */ async deleteTask(taskId) { if (LocalStorage.tasks[taskId] === void 0) throw new Error(`deleteTask: Task ${taskId} not found`); delete LocalStorage.tasks[taskId]; } /** * Processes the tasks in the local cloud */ async processTasks() { await _LocalCloud.processLocalTasks({ developer: this.developer, repo: this.repo, localWorker: this.localWorker, chain: this.chain }); } /** * Processes the local tasks * @param params the parameters to process the local tasks * @param params.developer the developer of the repo * @param params.repo the repo * @param params.localWorker the worker to execute the tasks * @param params.chain the blockchain to execute the job on */ static async processLocalTasks(params) { const { developer, repo, localWorker, chain } = params; for (const taskId in LocalStorage.tasks) { const data = LocalStorage.tasks[taskId]; const jobId = _LocalCloud.generateId(); const timeCreated = Date.now(); if (data.startTime !== void 0 && data.startTime < timeCreated) continue; const job = { id: "local", jobId, taskId, developer, repo, task: data.task, userId: data.userId, args: data.args, metadata: data.metadata, txNumber: 1, timeCreated }; const cloud = new _LocalCloud({ job, chain, localWorker }); const worker = await localWorker(cloud); const result = await worker.task(); const timeFinished = Date.now(); if (result !== void 0) { LocalStorage.jobEvents[jobId] = { jobId, jobStatus: "finished", eventTime: timeFinished, result }; job.timeFinished = timeFinished; } else { LocalStorage.jobEvents[jobId] = { jobId, jobStatus: "failed", eventTime: timeFinished }; job.timeFailed = timeFinished; } job.billedDuration = timeFinished - timeCreated; LocalStorage.jobs[jobId] = job; } let count = 0; for (const task in LocalStorage.tasks) count++; return count; } /** * Runs the sequencer in the local cloud * @param params the parameters to run the sequencer * @param params.worker the worker to execute the tasks * @param params.data the data to use * @returns the proof */ static async sequencer(params) { const { worker, data } = params; const { transactions } = data; if (transactions.length === 0) throw new Error("No transactions to process"); const proofs = []; for (const transaction of transactions) { const result = await worker.create(transaction); if (result === void 0) throw new Error("Failed to create proof"); proofs.push(result); } let proof = proofs[0]; for (let i = 1; i < proofs.length; i++) { const result = await worker.merge(proof, proofs[i]); if (result === void 0) throw new Error("Failed to merge proofs"); proof = result; } return proof; } /** * forces the worker to restart */ async forceWorkerRestart() { throw new Error("forceWorkerRestart called in LocalCloud"); } }; var _LocalStorage = class _LocalStorage { /** * Saves the data. * @param name The name to save the data under. * @throws Error Method not implemented to keep web compatibility. */ static async saveData(name) { throw new Error("Method not implemented to keep web compatibility."); const data = { jobs: _LocalStorage.jobs, data: _LocalStorage.data, transactions: _LocalStorage.transactions, tasks: _LocalStorage.tasks }; const filename = name + ".cloud"; } /** * Loads the data. * @param name The name to load the data from. * @throws Error Method not implemented to keep web compatibility. */ static async loadData(name) { throw new Error("Method not implemented to keep web compatibility."); const filename = name + ".cloud"; } }; _LocalStorage.jobs = {}; _LocalStorage.jobEvents = {}; _LocalStorage.data = {}; _LocalStorage.files = {}; _LocalStorage.transactions = {}; _LocalStorage.tasks = {}; var LocalStorage = _LocalStorage; // dist/node/api/api.js var import_prover2 = require("@silvana-one/prover"); var { ZKCLOUDWORKER_AUTH, ZKCLOUDWORKER_API } = import_prover2.config; var zkCloudWorkerClient = class { /** * Constructor for the API class * @param params the parameters for the API class * @param params.jwt The jwt token for authentication, get it at https://t.me/minanft_bot?start=auth * @param params.zkcloudworker The local worker for the serverless api to test the code locally * @param params.chain The blockchain network to use * @param params.webhook The webhook for the serverless api to get the results */ constructor(params) { const { jwt, zkcloudworker, webhook } = params; this.jwt = jwt; const chain = params.chain ?? "mina:devnet"; this.chain = chain; this.endpoint = chain === "mina:devnet" ? ZKCLOUDWORKER_API + "devnet" : chain === "zeko:testnet" ? ZKCLOUDWORKER_API + "zeko" : chain === "mina:mainnet" ? ZKCLOUDWORKER_API + "mainnet" : void 0; this.webhook = webhook; if (jwt === "local") { if (zkcloudworker === void 0) throw new Error("worker is required for local mode"); this.localWorker = zkcloudworker; } } /** * Starts a new job for the proof calculation using serverless api call * @param data the data for the proof call * @param data.developer the developer * @param data.repo the repo to use * @param data.transactions the transactions * @param data.task the task of the job * @param data.userId the userId of the job * @param data.args the arguments of the job, should be serialized JSON or string * @param data.metadata the metadata of the job, should be serialized JSON or string * @param data.webhook the webhook for the job * @returns { success: boolean, error?: string, jobId?: string } * where jonId is the jobId of the job * * The developers repo should provide a zkcloudworker function * that can be called with the given parameters, see the examples */ async recursiveProof(data) { const result = await this.apiHub("recursiveProof", data); if (result.data === "error" || typeof result.data === "string" && result.data.startsWith("error")) return { success: false, error: result.error }; else if (result.success === false || result.data?.success === false) return { success: false, error: result.error ?? result.data?.error ?? "recursiveProof call failed" }; else if (result.success === true && result.data?.success === true && result.data?.jobId !== void 0) return { success: result.success, jobId: result.data.jobId, error: result.error }; else return { success: false, error: "recursiveProof call error" }; } /** * Starts a new job for the function call using serverless api call * @param data the data for the proof call * @param data.developer the developer * @param data.repo the repo to use * @param data.transactions the transactions * @param data.task the task of the job * @param data.userId the userId of the job * @param data.args the arguments of the job * @param data.metadata the metadata of the job * @param data.mode the mode of the job execution: "sync" will not create a job, it will execute the function synchronously within 30 seconds and with the memory limit of 256 MB * @returns { success: boolean, error?: string, jobId?: string, result?: any } * where jonId is the jobId of the job (for async calls), result is the result of the job (for sync calls) */ async execute(data) { const result = await this.apiHub("execute", data); if (result.data === "error" || typeof result.data === "string" && result.data.startsWith("error")) return { success: false, error: result.error }; else if (result.success === false || result.data?.success === false) return { success: false, error: result.error ?? result.data?.error ?? "execute call failed" }; else if (result.success === true && data.mode === "sync" && result.data !== void 0) return { success: result.success, jobId: void 0, result: result.data, error: result.error }; else if (result.success === true && data.mode !== "sync" && result.data?.success === true && result.data?.jobId !== void 0) return { success: result.success, jobId: result.data.jobId, result: void 0, error: result.error }; else return { success: false, error: "execute call error" }; } /** * Sends transactions to the blockchain using serverless api call * @param data the data for the proof call * @param data.developer the developer * @param data.repo the repo to use * @param data.transactions the transactions * @returns { success: boolean, error?: string, txId?: string[] } * where txId is the transaction id of the transaction, in the sequence of the input transactions */ async sendTransactions(data) { const result = await this.apiHub("sendTransactions", data); if (result.data === "error") return { success: false, error: result.error }; else return { success: result.success, txId: result.data, error: result.error }; } /** * Gets the result of the job using serverless api call * @param data the data for the jobResult call * @param data.jobId the jobId of the job * @param data.includeLogs include logs in the result, default is false * @returns { success: boolean, error?: string, result?: any } * where result is the result of the job * if the job is not finished yet, the result will be undefined * if the job failed, the result will be undefined and error will be set * if the job is finished, the result will be set and error will be undefined * if the job is not found, the result will be undefined and error will be set */ async jobResult(data) { const result = await this.apiHub("jobResult", data); if (this.isError(result.data)) return { success: false, error: result.error, result: result.data }; else return { success: result.success, error: result.error, result: result.success ? result.data : result.data }; } /** * Deploys the code to the cloud using serverless api call * @param data the data for the deploy call * @param data.repo the repo to use * @param data.developer the developer * @param data.packageManager the package manager to use * @returns { success: boolean, error?: string, jobId?: string} * where jobId is the jobId of the job */ async deploy(data) { const { repo, developer, packageManager } = data; const result = await this.apiHub("deploy", { developer, repo, args: packageManager }); if (result.data === "error" || typeof result.data === "string" && result.data.startsWith("error")) return { success: false, error: result.error }; else return { success: result.success && result.data?.success, jobId: result.data?.jobId, error: result.error }; } /** * Gets the billing report for the jobs sent using JWT * @returns { success: boolean, error?: string, result?: any } * where result is the billing report */ async queryBilling() { const result = await this.apiHub("queryBilling", {}); if (this.isError(result.data)) return { success: false, error: result.error, result: result.data }; else return { success: result.success, error: result.error, result: result.data }; } /** * Gets the remaining balance * @returns { success: boolean, error?: string, result?: any } * where result is the balance */ async getBalance() { const result = await this.apiHub("getBalance", {}); if (this.isError(result.data)) return { success: false, error: result.error, result: result.data }; else return { success: result.success, error: result.error, result: result.data }; } /** * Waits for the job to finish * @param data the data for the waitForJobResult call * @param data.jobId the jobId of the job * @param data.maxAttempts the maximum number of attempts, default is 360 (2 hours) * @param data.interval the interval between attempts, default is 20000 (20 seconds) * @param data.maxErrors the maximum number of network errors, default is 10 * @param data.printLogs print logs, default is true * @returns { success: boolean, error?: string, result?: any } * where result is the result of the job */ async waitForJobResult(data) { if (this.jwt === "local") return this.jobResult({ jobId: data.jobId }); const maxAttempts = data?.maxAttempts ?? 360; const interval = data?.interval ?? 1e4; const maxErrors = data?.maxErrors ?? 10; const errorDelay = 3e4; const printedLogs = []; const printLogs = data.printLogs ?? true; function print(logs) { logs.forEach((log) => { if (printedLogs.includes(log) === false) { printedLogs.push(log); if (printLogs) { const text = log.replace(/error/gi, (matched) => import_chalk.default.red(matched)); console.log(text); } } }); } let attempts = 0; let errors = 0; while (attempts < maxAttempts) { const result = await this.apiHub("jobResult", { jobId: data.jobId, includeLogs: printLogs }); const isAllLogsFetched = result?.data?.isFullLog === true || printLogs === false; if (printLogs === true && result?.data?.logs !== void 0 && result?.data?.logs !== null && Array.isArray(result.data.logs) === true) print(result.data.logs); if (result.success === false) { errors++; if (errors > maxErrors) { return { success: false, error: "Too many network errors", result: void 0 }; } await (0, import_mina_utils2.sleep)(errorDelay * errors); } else { if (this.isError(result.data) && isAllLogsFetched) return { success: false, error: result.error, result: result.data }; else if (result.data?.result !== void 0 && isAllLogsFetched) { return { success: result.success, error: result.error, result: result.data }; } else if (result.data?.jobStatus === "failed" && isAllLogsFetched) { return { success: false, error: "Job failed", result: result.data }; } await (0, import_mina_utils2.sleep)(interval); } attempts++; } return { success: false, error: "Timeout", result: void 0 }; } /** * Calls the serverless API * @param command the command of the API * @param data the data of the API * */ async apiHub(command, data) { if (this.jwt === "local") { if (this.localWorker === void 0) throw new Error("localWorker is undefined"); switch (command) { case "recursiveProof": { const jobId = await LocalCloud.run({ command: "recursiveProof", data, chain: this.chain, localWorker: this.localWorker }); return { success: true, data: { success: true, jobId } }; } case "execute": { const jobId = await LocalCloud.run({ command: "execute", data, chain: this.chain, localWorker: this.localWorker }); if (data.mode === "sync") return { success: true, data: LocalStorage.jobEvents[jobId].result }; else return { success: true, data: { success: true, jobId } }; } case "jobResult": { const job = LocalStorage.jobs[data.jobId]; if (job === void 0) { return { success: false, error: "local job not found" }; } else { return { success: true, data: job }; } } case "sendTransactions": { return { success: true, data: await LocalCloud.addTransactions(data.transactions) }; } case "deploy": return { success: true, data: "local_deploy" }; case "queryBilling": return { success: true, data: "local_queryBilling" }; default: return { success: false, error: "local_error" }; } } else { if (this.endpoint === void 0) throw new Error("zkCloudWorker supports only mainnet, devnet and zeko chains in the cloud."); const apiData = { auth: ZKCLOUDWORKER_AUTH, command, jwtToken: this.jwt, data, chain: this.chain, webhook: this.webhook // TODO: implement webhook code on AWS }; try { const response = await fetch(this.endpoint, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(apiData) }); if (!response.ok) { return { success: false, error: `fetch error: ${response.statusText} status: ${response.status}` }; } const data2 = await response.json(); return { success: true, data: data2 }; } catch (error) { console.error("apiHub error:", error.message ?? error); return { success: false, error }; } } } // eslint-disable-next-line @typescript-eslint/no-explicit-any isError(data) { if (data === "error") return true; if (data?.jobStatus === "failed") return true; if (typeof data === "string" && data.toLowerCase().startsWith("error")) return true; if (data !== void 0 && data.error !== void 0) return true; return false; } }; // dist/node/tokens/token.js var TokenAPI = class { constructor(params) { const { jwt, zkcloudworker, chain } = params; if (jwt === void 0) throw new Error("jwt is undefined"); this.client = new zkCloudWorkerClient({ jwt, chain, zkcloudworker }); } async proveTransaction(params) { return this.proveTransactions([params]); } async proveTransactions(params) { const transactions = []; for (const tx of params) { const transaction = JSON.stringify(tx, null, 2); transactions.push(transaction); } const { request, symbol } = params[0]; const { txType } = request; const answer = await this.client.execute({ developer: "DFST", repo: "token-agent", transactions, task: "prove", args: JSON.stringify({ tokenAddress: params[0].request.tokenAddress }), metadata: `${params.length > 1 ? "airdrop" : txType.replace(/^token:/, "")} token${symbol ? ` ${symbol}` : ""}${params.length > 1 ? ` (${params.length} txs)` : ""}` }); const jobId = answer.jobId; if (jobId === void 0) console.error("Job ID is undefined", { answer, txType, symbol }); return jobId; } // Warning: this function will block the thread until the job is done and will print logs to the console // Do not use it in "use server" functions, use getResults instead async waitForJobResults(params) { const deployResult = await this.client.waitForJobResult(params); console.log("waitForJobResult result:", deployResult?.result?.result?.slice(0, 50)); return deployResult?.result?.result ?? "error"; } async getResults(jobId) { try { const callResult = await this.client.jobResult({ jobId }); const jobStatus = typeof callResult?.result === "string" ? void 0 : callResult?.result?.jobStatus; if (!callResult.success) { return { success: false, error: callResult?.error, jobStatus }; } const jobResult = callResult.result?.result; if (callResult.error) return { success: false, error: callResult.error, jobStatus }; if (!jobResult) return { success: true, jobStatus }; if (jobResult.toLowerCase().startsWith("error")) return { success: false, error: jobResult, jobStatus }; try { const { proofs } = JSON.parse(jobResult); const results = []; for (const proof of proofs) { const { success, tx, hash, error } = JSON.parse(proof); results.push({ success, tx, hash, error }); } return { success: true, results, jobStatus }; } catch (e) { return { success: false, error: `Error parsing job result: ${jobResult} ${e?.message ?? ""}`, jobStatus }; } } catch (e) { return { success: false, error: `Error getting job result: ${e?.message ?? ""}`, jobStatus: void 0 }; } } }; // dist/node/tokens/nft.js var NftAPI = class { constructor(params) { const { jwt, zkcloudworker, chain } = params; if (jwt === void 0) throw new Error("jwt is undefined"); this.client = new zkCloudWorkerClient({ jwt, chain, zkcloudworker }); } async proveTransaction(params) { return this.proveTransactions([params]); } async proveTransactions(params, name) { const transactions = []; for (const tx of params) { const transaction = JSON.stringify(tx, null, 2); transactions.push(transaction); } const { request, symbol, nftName } = params[0]; const { txType } = request; const answer = await this.client.execute({ developer: "DFST", repo: "nft-agent", transactions, task: "prove", args: JSON.stringify({ collectionAddress: params[0].request.collectionAddress }), metadata: `${params.length > 1 ? "mint" : txType.replace(/^nft:/, "")} ${symbol ? ` ${symbol ?? ""} ${params.length === 1 ? nftName ?? "" : ""}` : ""} ${params.length > 1 ? `(${params.length} txs)` : txType === "nft:launch" ? "Collection " + request.collectionName : txType === "nft:mint" ? request.nftMintParams.name : name ?? ""}` }); const jobId = answer.jobId; if (jobId === void 0) console.error("Job ID is undefined", { answer, txType, symbol }); return jobId; } // Warning: this function will block the thread until the job is done and will print logs to the console // Do not use it in "use server" functions, use getResults instead async waitForJobResults(params) { const deployResult = await this.client.waitForJobResult(params); console.log("waitForJobResult result:", deployResult?.result?.result?.slice(0, 50)); return deployResult?.result?.result ?? "error"; } async getResults(jobId) { try { const callResult = await this.client.jobResult({ jobId }); const jobStatus = typeof callResult?.result === "string" ? void 0 : callResult?.result?.jobStatus; if (!callResult.success) { return { success: false, error: callResult?.error, jobStatus }; } const jobResult = callResult.result?.result; if (callResult.error) return { success: false, error: callResult.error, jobStatus }; if (!jobResult) return { success: true, jobStatus }; if (jobResult.toLowerCase().startsWith("error")) return { success: false, error: jobResult, jobStatus }; try { const { proofs } = JSON.parse(jobResult); const results = []; for (const proof of proofs) { const { success, tx, hash, error } = JSON.parse(proof); results.push({ success, tx, hash, error }); } return { success: true, results, jobStatus }; } catch (e) { return { success: false, error: `Error parsing job result: ${jobResult} ${e?.message ?? ""}`, jobStatus }; } } catch (e) { return { success: false, error: `Error getting job result: ${e?.message ?? ""}`, jobStatus: void 0 }; } } }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { LocalCloud, LocalStorage, NftAPI, TokenAPI, zkCloudWorkerClient });