npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

zkverifyjs

v0.2.0

Published

Submit proofs to zkVerify and query proof state with ease using our npm package.

Downloads

171

Readme

zkverifyjs Instructions

The zkverifyjs package is a TypeScript library designed to facilitate sending proofs to zkVerify for verification, listening for transaction events, and waiting for transaction finalization. The package is built with an intuitive API that allows developers to handle real-time transaction events and await final results.

Table of Contents

Installation

To install the package, use npm or yarn:

npm install zkverifyjs

Usage

Creating a Session

Before sending a proof, you need to start a session. A session establishes a connection to the zkVerify network and optionally sets up an account using a seed phrase (required for sending transactions).

  1. Read-Only Session with Supported Network:
const session = await zkVerifySession.start()
        .Testnet(); // Preconfigured network selection
// No full account session as .withAccount() has not been used.
  1. Read-Only Session with Custom WebSocket:
const session = await zkVerifySession.start()
        .Custom("wss://testnet-rpc.zkverify.io"); // Custom network
// No full account session as .withAccount() has not been used.
  1. Full Backend Session (send transactions) with Supported Network:
const session = await zkVerifySession.start()
        .Testnet() // Preconfigured network selection
        .withAccount(process.env.SEED_PHRASE!); // Full session with active account
  1. Full Backend Session (send transactions) with Custom WebSocket:
const session = await zkVerifySession.start()
        .Testnet() // Custom network
        .withAccount(); // Full session with active account
  1. Full Frontend Browser Session (send transactions) with Supported Network:
const session = await zkVerifySession.start()
        .Testnet()
        .withWallet(); // Uses browser session context "window"
  1. Full Frontend Browser Session (send transactions) with Custom WebSocket:
const session = await zkVerifySession.start()
        .Custom("wss://testnet-rpc.zkverify.io") // Custom network
        .withWallet(); // Uses browser session context "window"

Not specifying withAccount() or withWallet() will start a read-only session, transaction methods cannot be used, and only calls to read data are allowed:

import { zkVerifySession } from 'zkverifyjs';

const readOnlySession = await zkVerifySession.start().Testnet();

Verifying a Proof

The zkVerifySession.verify method allows you to configure and execute a verification process using a fluent syntax. This approach offers a more readable and flexible way to set up your verification options before executing the proof verification.

  1. Backend / server side after establishing a session with withAccount()
const { events, transactionResult } = await session
        .fflonk()                                  // Select the proof type (e.g., fflonk)
        .nonce(1)                                  // Set the nonce (optional)
        .waitForPublishedAttestation()             // Wait for the attestation to be published (optional)
        .withRegisteredVk()                        // Indicate that the verification key is already registered (optional)
        .execute(proof, publicSignals, vk);        // Execute the verification with the provided proof data
  1. Frontend after establishing a session with withWallet()
const { events, transactionResult } = await session.verify()
        .groth16()
        .execute(proofData, publicSignals, vkey);

events.on('ErrorEvent', (eventData) => {
  console.error(JSON.stringify(eventData));
});

let transactionInfo = null;
try {
  transactionInfo = await transactionResult;
} catch (error) {
  throw new Error(`Transaction failed: ${error.message}`);
}

Registering a Verification Key & Submitting a proof with the Statement Hash

Register your Verification Key on chain and use it in future proof submissions by specifying the registeredVk() option.

const { events, transactionResult } = await session.registerVerificationKey().fflonk().execute(vk);
const vkTransactionInfo: VKRegistrationTransactionInfo = await transactionResult;

const {events: verifyEvents, transactionResult: verifyTransactionResult} = await session.verify()
        .fflonk()
        .withRegisteredVk() // Option needs to be specified as we're using the registered statement hash.
        .execute(proof, publicSignals, vkTransactionInfo.statementHash);

const verifyTransactionInfo: VerifyTransactionInfo = await verifyTransactionResult;

Listening to Events

You can listen for transaction events using the events emitter. Common events include:

  • includedInBlock: Triggered when the transaction is included in a block.
  • finalized: Triggered when the transaction is finalized.
  • attestationConfirmed: Triggered when the NewElement event is raised by the zkVerify chain.
  • error: Triggered if an error occurs during the transaction process.
const { events, transactionResult } = await session.verify().risc0().execute(
  proof,
  publicSignals,
  vk
);

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

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

events.on('attestationConfirmed', (eventData) => {
    console.log('Attestation Event Raised:', eventData);
});

events.on('error', (error) => {
    console.error('An error occurred during the transaction:', error);
});

Awaiting the Final Transaction Result

To await the final result of the transaction, use the transactionResult promise. This resolves with the final transaction details after the transaction is finalized in a block.

const {events, transactionResult} = await session.verify()
  .groth16()
  .execute(proof, publicSignals, vk)

const result = await transactionResult;
console.log('Final transaction result:', result);

Wait for the Attestation to be published

Wait for the NewElement event to be published before the transaction info is returned back by the promise. Occurs around every ~60s.

const {events, transactionResult} = await session.verify().risc0()
    .waitForPublishedAttestation()
    .execute(
    proof,
    publicSignals,
    vk
);

const transactionInfo: VerifyTransactionInfo = await transactionResult;

console.log(transactionInfo.attestationConfirmed); // Expect 'true'
console.log(JSON.stringify(transactionInfo.attestationEvent)) // Attestation Event details.

Example Usage

import { zkVerifySession, ZkVerifyEvents, TransactionStatus, VerifyTransactionInfo } from 'zkverifyjs';

async function executeVerificationTransaction(proof: unknown, publicSignals: unknown, vk: unknown) {
  // Start a new zkVerifySession on our testnet (replace 'your-seed-phrase' with actual value)
  const session = await zkVerifySession.start()
          .Testnet()
          .withAccount('your-seed-phrase');

  // Execute the verification transaction
  const { events, transactionResult } = await session.verify().risc0()
          .waitForPublishedAttestation()
          .execute(proof, publicSignals, vk);

  // Listen for the 'includedInBlock' event
  events.on(ZkVerifyEvents.IncludedInBlock, (eventData) => {
    console.log('Transaction included in block:', eventData);
    // Handle the event data as needed
  });

  // Listen for the 'finalized' event
  events.on(ZkVerifyEvents.Finalized, (eventData) => {
    console.log('Transaction finalized:', eventData);
    // Handle the event data as needed
  });

  // Handle errors during the transaction process
  events.on('error', (error) => {
    console.error('An error occurred during the transaction:', error);
  });

  try {
    // Await the final transaction result
    const transactionInfo: VerifyTransactionInfo = await transactionResult;

    // Log the final transaction result
    console.log('Transaction completed successfully:', transactionInfo);
  } catch (error) {
    // Handle any errors that occurred during the transaction
    console.error('Transaction failed:', error);
  } finally {
    // Close the session when done
    await session.close();
  }
}

// Replace these variables with actual proof data
const proof = /* Your proof data */;
const publicSignals = /* Your public signals */;
const vk = /* Your verification key */;

// Execute the transaction
executeVerificationTransaction(proof, publicSignals, vk);

API Reference

zkVerifySession.start

await zkVerifySession.start()
        .Testnet() // 1. Either preconfigured network selection
        .Custom('wss://custom') // 2. Or specify a custom network selection
        .withAccount(process.env.SEED_PHRASE!) // Optional
        .withWallet() // Optional
        .readOnly() // Optional
  • Network Selection: Preconfigured options such as .Testnet() or provide your own websocket url using .Custom('wss://custom'').
  • withAccount : Create a full session with ability send transactions get account info by using .withAccount('seed-phrase') and specifying your own seed phrase.
  • withWallet : Establish connection to a browser based substrate wallet, cannot be used with withAccount;
  • readOnly: Start the session in read-only mode, unable to send transactions or retrieve account info.

zkVerifySession.close

await session.close();
  • Closes the zkVerifySession.

zkVerifySession.verify

const { events, transactionResult } = await session.verify()
        .fflonk()
        .nonce(1)
        .waitForPublishedAttestation()
        .withRegisteredVk()
        .execute(proof, publicSignals, vk);
  • Proof Type: .fflonk() specifies the type of proof to be used. Options available for all supported proof types.
  • Nonce: .nonce(1) sets the nonce for the transaction. This is optional and can be omitted if not required.
  • Attestation Option: .waitForPublishedAttestation() specifies that the transaction should wait for the attestation to be published before completing. This is optional. Registered Verification Key: .withRegisteredVk() indicates that the verification key being used is registered on the chain. This option is optional and defaults to false.
  • Returns: An object containing an EventEmitter for real-time events and a Promise that resolves with the final transaction result, including waiting for the poe.NewElement attestation confirmation if waitForPublishedAttestation is specified.

zkVerifySession.registerVerificationKey

const { events, transactionResult } = await session.registerVerificationKey().fflonk().execute(vk);
  • Proof Type: .fflonk() specifies the type of proof to be used. Options available for all supported proof types.
  • Returns: A TransactionInfo object containing a statementHash string.

zkVerifySession.poe (Proof of Existence)

const proofDetails = await session.poe(attestationId, leafDigest, blockHash);
  • attestationId: A number representing the published attestation ID from which the proof path is to be retrieved.
  • leafDigest: A string representing the leaf digest to be used in the proof path retrieval.
  • blockHash: (Optional) A string representing the block hash at which the proof should be retrieved.
  • Returns: A Promise that resolves to a MerkleProof object containing the proof path details.

zkVerifySession.accountInfo

const accountInfo: AccountInfo = await session.accountInfo();
console.log(accountInfo.address);
console.log(accountInfo.nonce);
console.log(accountInfo.freeBalance);
console.log(accountInfo.reservedBalance);
  • Returns account information: address, nonce, freeBalance and reservedBalance. Full session only, will not work in readOnly mode.

zkVerifySession.addAccount

session.addAccount(seedPhrase);
  • seedPhrase: Your seed phrase as a string "my seed phrase"
  • Adds the account to the current session

zkVerifySession.removeAccount

session.removeAccount();
  • Removes the active account from the current session, does nothing if no account is currently active.

zkVerifySession.subscribeToNewAttestations

session.subscribeToNewAttestations(callback, attestationId);
  • callback: A Function to be called whenever a NewAttestation event occurs. The function receives an AttestationEvent object as its argument.
  • attestationId: (Optional) A string representing the attestation ID to filter events by. If provided, the subscription will automatically unsubscribe after receiving the specified attestation event.

zkVerifySession.unsubscribe

session.unsubscribe();
  • This method unsubscribes from any active NewAttestation event subscriptions. It is used to stop listening for NewAttestation events when they are no longer needed.

zkVerifySession.api

const api = session.api;
  • Uses PolkadotJS 12.4.2
  • Returns: The ApiPromise instance connected to the Polkadot.js API.
  • This is the main API object used to interact with the blockchain. It provides methods for querying the chain state, submitting extrinsics, subscribing to events, and more.

zkVerifySession.provider

const provider = session.provider;
  • Returns: The WsProvider instance connected to the WebSocket endpoint.
  • The provider manages the connection to the blockchain node. It handles WebSocket communication and can be used to interact with the node directly, such as for subscribing to updates or making RPC calls.

zkVerifySession.account

const account = session.account;
  • Returns: The KeyringPair object representing the active account in the session, or undefined if the session is in read-only mode.
  • The account is used for signing transactions and interacting with the blockchain on behalf of the user. If no account is associated with the session (i.e., the session is in read-only mode), this will return undefined.

Testing

To run the tests, use the following command:

npm test