UNPKG

zkapp-cli

Version:

CLI to create zkApps (zero-knowledge apps) for Mina Protocol

137 lines (110 loc) 3.87 kB
export default `import { Mina, PublicKey, fetchAccount, Field, JsonProof, Cache } from 'o1js'; import * as Comlink from "comlink"; import { AddProgramProof } from "../../contracts/src/AddZkProgram"; import type { Add } from "../../contracts/src/Add"; import type { AddZkProgram } from "../../contracts/src/AddZkProgram"; import cacheJSONList from "./cache.json"; type Transaction = Awaited<ReturnType<typeof Mina.transaction>>; const state = { AddInstance: null as null | typeof Add, zkappInstance: null as null | Add, AddZkProgramInstance: null as null | typeof AddZkProgram, transaction: null as null | Transaction }; const fetchFiles = async () => { const cacheJson = cacheJSONList; const cacheListPromises = cacheJson.files.map(async (file) => { const [header, data] = await Promise.all([ fetch(\`/cache/\${file}.header\`).then((res) => res.text()), fetch(\`/cache/\${file}\`).then((res) => res.text()) ]); return { file, header, data }; }); const cacheList = await Promise.all(cacheListPromises); return cacheList.reduce((acc: any, { file, header, data }) => { acc[file] = { file, header, data }; return acc; }, {}); }; const FileSystem = (files: any): Cache => ({ read({ persistentId, uniqueId, dataType }: any) { if (!files[persistentId]) { return undefined; } const currentId = files[persistentId].header; if (currentId !== uniqueId) { return undefined; } if (dataType === "string") { console.log("found in cache:", { persistentId, uniqueId, dataType }); return new TextEncoder().encode(files[persistentId].data); } return undefined; }, write({ persistentId, uniqueId, dataType }: any, data: any) { console.log({ persistentId, uniqueId, dataType }); }, canWrite: false }); export const api = { async setActiveInstanceToDevnet() { const Network = Mina.Network( "https://api.minascan.io/node/devnet/v1/graphql" ); console.log("Devnet network instance configured"); Mina.setActiveInstance(Network); }, async loadContract() { const { Add } = await import("../../contracts/build/src/Add.js"); const { AddZkProgram } = await import( "../../contracts/build/src/AddZkProgram.js" ); state.AddInstance = Add; state.AddZkProgramInstance = AddZkProgram; }, async compileZkProgram() { await state.AddZkProgramInstance!.compile(); }, async compileContract() { const cacheFiles = await fetchFiles(); await state.AddInstance!.compile({ cache: FileSystem(cacheFiles) }); }, async fetchAccount(publicKey58: string) { const publicKey = PublicKey.fromBase58(publicKey58); return fetchAccount({ publicKey }); }, async initZkappInstance(publicKey58: string) { const publicKey = PublicKey.fromBase58(publicKey58); state.zkappInstance = new state.AddInstance!(publicKey); }, async initZkProgram(num: string) { const init = await state.AddZkProgramInstance!.init(Field(num)); return init.proof.toJSON(); }, async getNum() { const num = await state.zkappInstance!.num.get(); return JSON.stringify(num.toJSON()); }, async updateZkProgram(contractState: string, proof: JsonProof) { const previousProof = await AddProgramProof.fromJSON(proof); const update = await state.AddZkProgramInstance!.update( Field(contractState), previousProof ); return update.proof.toJSON(); }, async createSettleStateTransaction(proof: JsonProof) { const zkProgramProof = await AddProgramProof.fromJSON(proof); state.transaction = await Mina.transaction(async () => { await state.zkappInstance!.settleState(zkProgramProof); }); }, async proveSettleStateTransaction() { await state.transaction!.prove(); }, async getTransactionJSON() { return state.transaction!.toJSON(); } } // Expose the API to be used by the main thread Comlink.expose(api);`;