@silvana-one/mina-prover
Version:
Silvana Mina Prover
1,162 lines (1,155 loc) • 36.8 kB
JavaScript
"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
});