From 34f4824a7df2b3414c64f4d5a4d9ea6bc22bf6c8 Mon Sep 17 00:00:00 2001 From: rhaoio Date: Wed, 12 Jun 2024 12:22:54 +1000 Subject: [PATCH 1/4] try with blob --- dist/cjs/helper/util.d.ts | 1 + dist/cjs/helper/util.js | 6 ++++++ dist/mjs/helper/util.d.ts | 1 + dist/mjs/helper/util.js | 6 ++++++ src/helper/util.ts | 7 +++++++ 5 files changed, 21 insertions(+) diff --git a/dist/cjs/helper/util.d.ts b/dist/cjs/helper/util.d.ts index 8ef320a5..e5afa24c 100644 --- a/dist/cjs/helper/util.d.ts +++ b/dist/cjs/helper/util.d.ts @@ -98,6 +98,7 @@ export declare class ZkWasmUtil { static loadContextFileFromPath(filePath: string): Promise; static loadContexFileAsBytes(filePath: string): Promise; static browserLoadContextFileAsBytes(file: File): Promise; + static bytesToTempFile(data: Uint8Array): Blob; static MAX_CONTEXT_SIZE: number; static validateContextBytes(data: Uint8Array): boolean; } diff --git a/dist/cjs/helper/util.js b/dist/cjs/helper/util.js index 2e92e340..31ff86a6 100644 --- a/dist/cjs/helper/util.js +++ b/dist/cjs/helper/util.js @@ -353,6 +353,12 @@ class ZkWasmUtil { }); }); } + // Convert Bytes into a temporary file, as it will be submitted through multipart to a server, file does not need to be saved + static bytesToTempFile(data) { + this.validateContextBytes(data); + let blob = new Blob([data]); + return blob; + } // Validate bytes are a multiple of 8 bytes (64 bits) and length less than 4KB static validateContextBytes(data) { if (data.length > this.MAX_CONTEXT_SIZE) { diff --git a/dist/mjs/helper/util.d.ts b/dist/mjs/helper/util.d.ts index 8ef320a5..e5afa24c 100644 --- a/dist/mjs/helper/util.d.ts +++ b/dist/mjs/helper/util.d.ts @@ -98,6 +98,7 @@ export declare class ZkWasmUtil { static loadContextFileFromPath(filePath: string): Promise; static loadContexFileAsBytes(filePath: string): Promise; static browserLoadContextFileAsBytes(file: File): Promise; + static bytesToTempFile(data: Uint8Array): Blob; static MAX_CONTEXT_SIZE: number; static validateContextBytes(data: Uint8Array): boolean; } diff --git a/dist/mjs/helper/util.js b/dist/mjs/helper/util.js index ec132978..a21665dd 100644 --- a/dist/mjs/helper/util.js +++ b/dist/mjs/helper/util.js @@ -447,6 +447,12 @@ export class ZkWasmUtil { reader.readAsArrayBuffer(file); }); } + // Convert Bytes into a temporary file, as it will be submitted through multipart to a server, file does not need to be saved + static bytesToTempFile(data) { + this.validateContextBytes(data); + let blob = new Blob([data]); + return blob; + } static MAX_CONTEXT_SIZE = 4096; // Validate bytes are a multiple of 8 bytes (64 bits) and length less than 4KB static validateContextBytes(data) { diff --git a/src/helper/util.ts b/src/helper/util.ts index d598bb17..eef0870d 100644 --- a/src/helper/util.ts +++ b/src/helper/util.ts @@ -567,6 +567,13 @@ export class ZkWasmUtil { }); } + // Convert Bytes into a temporary file, as it will be submitted through multipart to a server, file does not need to be saved + static bytesToTempFile(data: Uint8Array): Blob { + this.validateContextBytes(data); + let blob = new Blob([data]); + return blob; + } + static MAX_CONTEXT_SIZE = 4096; // Validate bytes are a multiple of 8 bytes (64 bits) and length less than 4KB From 0f0205d0b70e8bcd624ca8559fe192298fe98f0a Mon Sep 17 00:00:00 2001 From: rhaoio Date: Wed, 12 Jun 2024 12:30:07 +1000 Subject: [PATCH 2/4] try import blob for nodejs --- dist/cjs/helper/util.js | 12 +++++++++++- dist/mjs/helper/util.js | 12 +++++++++++- src/helper/util.ts | 13 ++++++++++++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/dist/cjs/helper/util.js b/dist/cjs/helper/util.js index 31ff86a6..b57e8b0f 100644 --- a/dist/cjs/helper/util.js +++ b/dist/cjs/helper/util.js @@ -356,7 +356,17 @@ class ZkWasmUtil { // Convert Bytes into a temporary file, as it will be submitted through multipart to a server, file does not need to be saved static bytesToTempFile(data) { this.validateContextBytes(data); - let blob = new Blob([data]); + let blob; + if (typeof Blob === "undefined") { + // Node.js environment + const { Blob } = require("buffer"); + const buffer = Buffer.from(data); + blob = new Blob([buffer]); + } + else { + // Browser environment + blob = new Blob([data]); + } return blob; } // Validate bytes are a multiple of 8 bytes (64 bits) and length less than 4KB diff --git a/dist/mjs/helper/util.js b/dist/mjs/helper/util.js index a21665dd..b492a1a3 100644 --- a/dist/mjs/helper/util.js +++ b/dist/mjs/helper/util.js @@ -450,7 +450,17 @@ export class ZkWasmUtil { // Convert Bytes into a temporary file, as it will be submitted through multipart to a server, file does not need to be saved static bytesToTempFile(data) { this.validateContextBytes(data); - let blob = new Blob([data]); + let blob; + if (typeof Blob === "undefined") { + // Node.js environment + const { Blob } = require("buffer"); + const buffer = Buffer.from(data); + blob = new Blob([buffer]); + } + else { + // Browser environment + blob = new Blob([data]); + } return blob; } static MAX_CONTEXT_SIZE = 4096; diff --git a/src/helper/util.ts b/src/helper/util.ts index eef0870d..98685bb3 100644 --- a/src/helper/util.ts +++ b/src/helper/util.ts @@ -570,7 +570,18 @@ export class ZkWasmUtil { // Convert Bytes into a temporary file, as it will be submitted through multipart to a server, file does not need to be saved static bytesToTempFile(data: Uint8Array): Blob { this.validateContextBytes(data); - let blob = new Blob([data]); + let blob: Blob; + + if (typeof Blob === "undefined") { + // Node.js environment + const { Blob } = require("buffer"); + const buffer = Buffer.from(data); + blob = new Blob([buffer]); + } else { + // Browser environment + blob = new Blob([data]); + } + return blob; } From b3c3ae0fe9c5fb4e035f6692e1d617272f7fcf0d Mon Sep 17 00:00:00 2001 From: rhaoio Date: Wed, 12 Jun 2024 12:39:04 +1000 Subject: [PATCH 3/4] try as buffer --- dist/cjs/helper/util.d.ts | 3 ++- dist/cjs/helper/util.js | 49 ++++++++++++++++++++++++++++----------- dist/mjs/helper/util.d.ts | 3 ++- dist/mjs/helper/util.js | 12 ++++------ src/helper/util.ts | 15 ++++++------ 5 files changed, 52 insertions(+), 30 deletions(-) diff --git a/dist/cjs/helper/util.d.ts b/dist/cjs/helper/util.d.ts index e5afa24c..10ab7954 100644 --- a/dist/cjs/helper/util.d.ts +++ b/dist/cjs/helper/util.d.ts @@ -1,3 +1,4 @@ +/// import BN from "bn.js"; import { AddImageParams, ProvingParams, DeployParams, ResetImageParams, ModifyImageParams, VerifyProofParams, LogQuery, ContextHexString, VerifyBatchProofParams } from "../interface/interface.js"; import { Contract, Signer } from "ethers"; @@ -98,7 +99,7 @@ export declare class ZkWasmUtil { static loadContextFileFromPath(filePath: string): Promise; static loadContexFileAsBytes(filePath: string): Promise; static browserLoadContextFileAsBytes(file: File): Promise; - static bytesToTempFile(data: Uint8Array): Blob; + static bytesToTempFile(data: Uint8Array): Promise; static MAX_CONTEXT_SIZE: number; static validateContextBytes(data: Uint8Array): boolean; } diff --git a/dist/cjs/helper/util.js b/dist/cjs/helper/util.js index b57e8b0f..c80362a5 100644 --- a/dist/cjs/helper/util.js +++ b/dist/cjs/helper/util.js @@ -1,4 +1,27 @@ "use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -355,19 +378,19 @@ class ZkWasmUtil { } // Convert Bytes into a temporary file, as it will be submitted through multipart to a server, file does not need to be saved static bytesToTempFile(data) { - this.validateContextBytes(data); - let blob; - if (typeof Blob === "undefined") { - // Node.js environment - const { Blob } = require("buffer"); - const buffer = Buffer.from(data); - blob = new Blob([buffer]); - } - else { - // Browser environment - blob = new Blob([data]); - } - return blob; + return __awaiter(this, void 0, void 0, function* () { + this.validateContextBytes(data); + if (typeof window === "undefined") { + // Node.js environment + const { Buffer } = yield Promise.resolve().then(() => __importStar(require("buffer"))); + const buffer = Buffer.from(data); + return buffer; + } + else { + // Browser environment + throw new Error("File creation in the browser is not supported by this function."); + } + }); } // Validate bytes are a multiple of 8 bytes (64 bits) and length less than 4KB static validateContextBytes(data) { diff --git a/dist/mjs/helper/util.d.ts b/dist/mjs/helper/util.d.ts index e5afa24c..10ab7954 100644 --- a/dist/mjs/helper/util.d.ts +++ b/dist/mjs/helper/util.d.ts @@ -1,3 +1,4 @@ +/// import BN from "bn.js"; import { AddImageParams, ProvingParams, DeployParams, ResetImageParams, ModifyImageParams, VerifyProofParams, LogQuery, ContextHexString, VerifyBatchProofParams } from "../interface/interface.js"; import { Contract, Signer } from "ethers"; @@ -98,7 +99,7 @@ export declare class ZkWasmUtil { static loadContextFileFromPath(filePath: string): Promise; static loadContexFileAsBytes(filePath: string): Promise; static browserLoadContextFileAsBytes(file: File): Promise; - static bytesToTempFile(data: Uint8Array): Blob; + static bytesToTempFile(data: Uint8Array): Promise; static MAX_CONTEXT_SIZE: number; static validateContextBytes(data: Uint8Array): boolean; } diff --git a/dist/mjs/helper/util.js b/dist/mjs/helper/util.js index b492a1a3..c39edf0a 100644 --- a/dist/mjs/helper/util.js +++ b/dist/mjs/helper/util.js @@ -448,20 +448,18 @@ export class ZkWasmUtil { }); } // Convert Bytes into a temporary file, as it will be submitted through multipart to a server, file does not need to be saved - static bytesToTempFile(data) { + static async bytesToTempFile(data) { this.validateContextBytes(data); - let blob; - if (typeof Blob === "undefined") { + if (typeof window === "undefined") { // Node.js environment - const { Blob } = require("buffer"); + const { Buffer } = await import("buffer"); const buffer = Buffer.from(data); - blob = new Blob([buffer]); + return buffer; } else { // Browser environment - blob = new Blob([data]); + throw new Error("File creation in the browser is not supported by this function."); } - return blob; } static MAX_CONTEXT_SIZE = 4096; // Validate bytes are a multiple of 8 bytes (64 bits) and length less than 4KB diff --git a/src/helper/util.ts b/src/helper/util.ts index 98685bb3..fca1c4c4 100644 --- a/src/helper/util.ts +++ b/src/helper/util.ts @@ -568,21 +568,20 @@ export class ZkWasmUtil { } // Convert Bytes into a temporary file, as it will be submitted through multipart to a server, file does not need to be saved - static bytesToTempFile(data: Uint8Array): Blob { + static async bytesToTempFile(data: Uint8Array): Promise { this.validateContextBytes(data); - let blob: Blob; - if (typeof Blob === "undefined") { + if (typeof window === "undefined") { // Node.js environment - const { Blob } = require("buffer"); + const { Buffer } = await import("buffer"); const buffer = Buffer.from(data); - blob = new Blob([buffer]); + return buffer; } else { // Browser environment - blob = new Blob([data]); + throw new Error( + "File creation in the browser is not supported by this function." + ); } - - return blob; } static MAX_CONTEXT_SIZE = 4096; From 9bdddaad2f3c5e409311fa4e3b0e85633999c160 Mon Sep 17 00:00:00 2001 From: rhaoio Date: Wed, 12 Jun 2024 12:51:20 +1000 Subject: [PATCH 4/4] readme + extra fn --- README.md | 126 ++++++++++++++++++++++---------------- dist/cjs/helper/util.d.ts | 1 + dist/cjs/helper/util.js | 15 ++++- dist/mjs/helper/util.d.ts | 1 + dist/mjs/helper/util.js | 13 +++- src/helper/util.ts | 16 ++++- 6 files changed, 116 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index 2fc6d212..bbd7019f 100644 --- a/README.md +++ b/README.md @@ -89,65 +89,85 @@ import { ProvingParams, WithSignature, ZkWasmUtil, - ZkWasmServiceHelper + ZkWasmServiceHelper, + ProofSubmitMode, + InputContextType, + WithCustomInputContextType, } from "zkwasm-service-helper"; -const endpoint = ""https://rpc.zkwasmhub.com:8090"; -const image_md5 = "xxxx"; -const public_inputs = "0x22:i64 0x21:i64"; -const private_inputs = ""; -const user_addr = "0xaaaaaa"; - -let helper = new ZkWasmServiceHelper(endpoint, "", ""); -let pb_inputs: Array = helper.parseProvingTaskInput(public_inputs); -let priv_inputs: Array = helper.parseProvingTaskInput(private_inputs); - -// Use the helper Enum type to determine the proof submit mode -let proofSubmitMode = ProofSubmitMode.Auto ? ProofSubmitMode.Auto : ProofSubmitMode.Manual; - -let info: ProvingParams = { - user_address: user_addr.toLowerCase(), - md5: image_md5, - public_inputs: pb_inputs, - private_inputs: priv_inputs, - // Whether the proof will be batched and verified through the auto submit service or manually submitted. - // If the field is not specified, the default value will be ProofSubmitMode.Manual and the proof will not be batched. - proof_submit_mode: proofSubmitMode, -}; - -// Context type for proof task. If none provided, will default to InputContextType.ImageCurrent in the server and use the image's current context -let selectedInputContextType = InputContextType.ImageCurrent; - -// For Custom Context, upload a binary file first containing the context. -if (selectedInputContextType === InputContextType.Custom) { +async function AddNewProofTask() { + const endpoint = "https://rpc.zkwasmhub.com:8090"; + const image_md5 = "xxxxx"; + const public_inputs = "0x22:i64 0x21:i64"; + const private_inputs = ""; + const user_addr = ""; + const privateKey = ""; + + let helper = new ZkWasmServiceHelper(endpoint, "", ""); + let pb_inputs: Array = ZkWasmUtil.validateInputs(public_inputs); + let priv_inputs: Array = ZkWasmUtil.validateInputs(private_inputs); + + // Use the helper Enum type to determine the proof submit mode + let proofSubmitMode = ProofSubmitMode.Auto + ? ProofSubmitMode.Auto + : ProofSubmitMode.Manual; + + let info: ProvingParams = { + user_address: user_addr.toLowerCase(), + md5: image_md5, + public_inputs: pb_inputs, + private_inputs: priv_inputs, + // Whether the proof will be batched and verified through the auto submit service or manually submitted. + // If the field is not specified, the default value will be ProofSubmitMode.Manual and the proof will not be batched. + proof_submit_mode: proofSubmitMode, + }; - let contextFile = await ZkWasmUtil.loadContexFileAsBytes(""); + // Context type for proof task. If none provided, will default to InputContextType.ImageCurrent in the server and use the image's current context + let selectedInputContextType = InputContextType.Custom; + + // For Custom Context, upload a binary file first containing the context. + if (selectedInputContextType === InputContextType.Custom) { + // Load bytes into Tempfile/Buffer type - Server side example with NodeJS + const contextBytes = new Uint8Array(64); + contextBytes.fill(1); + ZkWasmUtil.validateContextBytes(contextBytes); + let bytesFile = await ZkWasmUtil.bytesToTempFile(contextBytes); + let context_info: WithCustomInputContextType = { + input_context: bytesFile, + input_context_md5: ZkWasmUtil.convertToMd5(contextBytes), + input_context_type: selectedInputContextType, + }; - let context_info: WithCustomInputContextType = { - input_context: contextFile, - input_context_md5: ZkWasmUtil.convertToMd5(contextFile), - input_context_type: selectedInputContextType, + // // LOADING AS FILE DIRECTLY - Browser side example + // let contextFile = await ZkWasmUtil.loadContexFileAsBytes(""); + + // let context_info: WithCustomInputContextType = { + // input_context: contextFile, + // input_context_md5: ZkWasmUtil.convertToMd5(contextFile), + // input_context_type: selectedInputContextType, + // }; + info = { ...info, ...context_info }; + } else { + info = { ...info, input_context_type: selectedInputContextType }; + } + let msgString = ZkWasmUtil.createProvingSignMessage(info); + + let signature: string; + try { + signature = await ZkWasmUtil.signMessage(msgString, privateKey); + } catch (e: unknown) { + console.log("error signing message", e); + return; + } + + let task: WithSignature = { + ...info, + signature: signature, }; - info = { ...info, ...context_info }; -} else { - info = { ...info, input_context_type: selectedInputContextType }; -} -let msgString = ZkWasmUtil.createProvingSignMessage(info); - -let signature: string; -try { - signature = await ZkWasmUtil.signMessage(msgString, priv); -} catch (e: unknown) { - console.log("error signing message", e); - return; -} -let task: WithSignature = { - ...info, - signature: signature, -}; - -let response = await helper.addProvingTask(task); + let response = await helper.addProvingTask(task); + console.log(response); +} ``` ### Verifying a proof diff --git a/dist/cjs/helper/util.d.ts b/dist/cjs/helper/util.d.ts index 10ab7954..62bf7baa 100644 --- a/dist/cjs/helper/util.d.ts +++ b/dist/cjs/helper/util.d.ts @@ -100,6 +100,7 @@ export declare class ZkWasmUtil { static loadContexFileAsBytes(filePath: string): Promise; static browserLoadContextFileAsBytes(file: File): Promise; static bytesToTempFile(data: Uint8Array): Promise; + static bytesToFile(data: Uint8Array): Promise; static MAX_CONTEXT_SIZE: number; static validateContextBytes(data: Uint8Array): boolean; } diff --git a/dist/cjs/helper/util.js b/dist/cjs/helper/util.js index c80362a5..da66854c 100644 --- a/dist/cjs/helper/util.js +++ b/dist/cjs/helper/util.js @@ -376,7 +376,7 @@ class ZkWasmUtil { }); }); } - // Convert Bytes into a temporary file, as it will be submitted through multipart to a server, file does not need to be saved + // Convert Bytes into a temporary file (Buffer for nodejs), as it will be submitted through multipart to a server, file does not need to be saved static bytesToTempFile(data) { return __awaiter(this, void 0, void 0, function* () { this.validateContextBytes(data); @@ -392,6 +392,19 @@ class ZkWasmUtil { } }); } + static bytesToFile(data) { + return __awaiter(this, void 0, void 0, function* () { + this.validateContextBytes(data); + if (typeof window === "undefined") { + throw new Error("File creation in NodeJS env is not supported by this function."); + } + else { + // Browser environment + const blob = new Blob([data]); + return new File([blob], "context.bin"); + } + }); + } // Validate bytes are a multiple of 8 bytes (64 bits) and length less than 4KB static validateContextBytes(data) { if (data.length > this.MAX_CONTEXT_SIZE) { diff --git a/dist/mjs/helper/util.d.ts b/dist/mjs/helper/util.d.ts index 10ab7954..62bf7baa 100644 --- a/dist/mjs/helper/util.d.ts +++ b/dist/mjs/helper/util.d.ts @@ -100,6 +100,7 @@ export declare class ZkWasmUtil { static loadContexFileAsBytes(filePath: string): Promise; static browserLoadContextFileAsBytes(file: File): Promise; static bytesToTempFile(data: Uint8Array): Promise; + static bytesToFile(data: Uint8Array): Promise; static MAX_CONTEXT_SIZE: number; static validateContextBytes(data: Uint8Array): boolean; } diff --git a/dist/mjs/helper/util.js b/dist/mjs/helper/util.js index c39edf0a..ed354422 100644 --- a/dist/mjs/helper/util.js +++ b/dist/mjs/helper/util.js @@ -447,7 +447,7 @@ export class ZkWasmUtil { reader.readAsArrayBuffer(file); }); } - // Convert Bytes into a temporary file, as it will be submitted through multipart to a server, file does not need to be saved + // Convert Bytes into a temporary file (Buffer for nodejs), as it will be submitted through multipart to a server, file does not need to be saved static async bytesToTempFile(data) { this.validateContextBytes(data); if (typeof window === "undefined") { @@ -461,6 +461,17 @@ export class ZkWasmUtil { throw new Error("File creation in the browser is not supported by this function."); } } + static async bytesToFile(data) { + this.validateContextBytes(data); + if (typeof window === "undefined") { + throw new Error("File creation in NodeJS env is not supported by this function."); + } + else { + // Browser environment + const blob = new Blob([data]); + return new File([blob], "context.bin"); + } + } static MAX_CONTEXT_SIZE = 4096; // Validate bytes are a multiple of 8 bytes (64 bits) and length less than 4KB static validateContextBytes(data) { diff --git a/src/helper/util.ts b/src/helper/util.ts index fca1c4c4..33455b99 100644 --- a/src/helper/util.ts +++ b/src/helper/util.ts @@ -567,7 +567,7 @@ export class ZkWasmUtil { }); } - // Convert Bytes into a temporary file, as it will be submitted through multipart to a server, file does not need to be saved + // Convert Bytes into a temporary file (Buffer for nodejs), as it will be submitted through multipart to a server, file does not need to be saved static async bytesToTempFile(data: Uint8Array): Promise { this.validateContextBytes(data); @@ -584,6 +584,20 @@ export class ZkWasmUtil { } } + static async bytesToFile(data: Uint8Array): Promise { + this.validateContextBytes(data); + + if (typeof window === "undefined") { + throw new Error( + "File creation in NodeJS env is not supported by this function." + ); + } else { + // Browser environment + const blob = new Blob([data]); + return new File([blob], "context.bin"); + } + } + static MAX_CONTEXT_SIZE = 4096; // Validate bytes are a multiple of 8 bytes (64 bits) and length less than 4KB