Skip to main content

Verifying proofs with zkVerifyJS

In this tutorial we will be verifying proofs using zkVerify JS package. zkVerify JS is a NPM package which makes it very easy to submit proofs, listen events and get attestation proofs. You can use this package with all the proof types we support.

Let's create a new project and install zkverify JS for our project. Run the following commands:

# Creating a new directory
mkdir proof-submission

# Navigating to the project directory
cd proof-submission

# Initializing an NPM project
npm init

# Installing zkVerify JS
npm i zkverifyjs

Create a new file named index.js to write the verification logic. Open index.js in your IDE and import the following components from zkVerify JS :

const {zkVerifySession, Library, CurveType, ZkVerifyEvents} = require("zkverifyjs");

We would also need to import the required files we have generated already in previous tutorials, which are proof, verification key and public inputs. Use the following code snippets :

const fs = require("fs");
const proof = require("./data/proof.json");
const public = require("./data/public.json");
const key = require("./data/main.groth16.vkey.json");

Once you have all the requirements imported, we will start by instantiating a session with our testnet with an account(This account should have $ACME to pay for transactions).

const session = await zkVerifySession.start().Testnet().withAccount("seed-phrase")

For Circom and Noir proofs, we need to register a verification key on our testnet which will be used in further steps while verifying proofs. This step is not required for Risc Zero because we already got a hash of the image id which can be used directly. You can execute the following code snippet to register a vkey:

const {events, regResult} = await session.registerVerificationKey().groth16(Library.snarkjs, CurveType.bn128).execute(key);

events.on(ZkVerifyEvents.Finalized, (eventData) => {
console.log('Registration finalized:', eventData);
fs.writeFileSync("vkey.json", JSON.stringify({"hash": eventData.statementHash}, null, 2));
return eventData.statementHash
});

Next we will send a proof verification request to the testnet, with all the details like which proving schema, proof, public signals and the key. We will also add a condition to wait till attestation is published. As we have already registered our vkey with zkVerify, we can import it and use it for our proof verification :-

const {events, txResults} = await session.verify()
.groth16(Library.snarkjs, CurveType.bn128).waitForPublishedAttestation().withRegisteredVk()
.execute({proofData: {
vk: vkey.hash,
proof: proof,
publicSignals: public
}});

We can listen to events to get the current status of our submitted proof, we have various options like if proof is included in block, proof is finalized or attestations for the proof have been published. You can listen to them using our events.on() function like :-

events.on(ZkVerifyEvents.IncludedInBlock, (eventData) => {
console.log('Transaction included in block:', eventData);
});

events.on(ZkVerifyEvents.Finalized, (eventData) => {
console.log('Transaction finalized:', eventData);
});

To proceed further, we would require attestation proofs which can be verified onchain on Ethereum that the proof was verified by zkVerify, these proofs can only be generated once the proofs attestation is published on Ethereum. To get the proof we implement :-

events.on(ZkVerifyEvents.AttestationConfirmed, async(eventData) => {
console.log('Attestation Confirmed', eventData);
const proofDetails = await session.poe(attestationId, leafDigest);
proofDetails.attestationId = eventData.id;
fs.writeFileSync("attestation.json", JSON.stringify(proofDetails, null, 2));
console.log("proofDetails", proofDetails);
})

You can check details about the verified proofs using our zkVerify explorer.

alt_text

By running the above code snippet, your attestation proof will be saved at attestation.json file. After completing this process, we have successfully verified our proof with zkVerify and the next steps will be to use this attestation proof for our business logic onchain. Next we will be verifying the proof reciepts through a smart contract. You can check this tutorial to understand more about the smart contract verification part.