TypeScript/Node.js/Linux

Quick start tutorial for the TypeScript/Node.js binding of the zkPass SDK

To install the zkpass-client-ts lib separately, please refer to this section Installing the zkpass-client-ts lib

System Requirements

  1. Ubuntu version 20 or higher, WSL (Windows Subsystem for Linux) is also supported.

  2. Node.js 18.17.0 or later.

Make sure the VPN is off

Installing WSL for Windows users

This command will enable the necessary features to run WSL and install the Ubuntu distribution of Linux.

If your underlying system, like Ubuntu, is already Linux-based, you can skip this step.

If your Windows version is below Windows 10 2004, please refer to this documentation instead.

  1. Open PowerShell or Windows Command Prompt in administrator mode by right-clicking and selecting "Run as administrator"

  2. Run the command below

wsl --install
  1. Restart your machine

  2. Once you have installed WSL, you will need to create a user account and password for your newly installed Linux distribution.

The above command only works if WSL is not installed at all, if you run wsl --install and see the WSL help text, please try running wsl --list --online to see a list of available distros and run wsl --install -d <DistroName> to install a distro. To uninstall WSL, see Uninstall legacy version of WSL or unregister or uninstall a Linux distribution.

If you have installed WSL before, you can login using the command wsl

For a complete WSL installation guide, refer to this documentation.

Installing Node.js 18.17.0 via NVM

Installing NVM

nvm allows you to quickly install and use different versions of node via the command line.

  1. Run the command below

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash
  1. Restart your terminal session

Installing Node 18.17.0 and NPM via NVM

nvm install 18.17.0

To check whether Node has been installed properly, run the commands below:

node -v
npm -v

Complete NVM documentation can be found here.

Installing Git

sudo apt update
sudo apt install git

To check whether Node has been installed properly, run the commands below:

git --version

Complete Git documentation can be found here.

Installing the SDK

If you wish to explore our demo application, feel free to skip this installation step, as it has already been completed in the demo application.

If you want to use our zkpass-client-ts library on your own project / outside the demo application, you can follow this step

  1. Set the npm registry configuration to gdp-labs registry.

npm config set @didpass:registry=https://us-west1-npm.pkg.dev/gdp-labs/gdplabs-npm-public/
  1. Install the zkpass-client library for typescript

npm install @didpass/zkpass-client-ts

For NextJS projects with App Routing, several configurations have to be made in next.config.js file:

next.config.js

const nextConfig = {
  ...,
  experimental: {
    ...,
    esmExternals: "loose", // Enable ESM imports
    serverComponentsExternalPackages: ["@didpass/zkpass-client-ts"], // Exclude SDK from bundling, to enable reading binary file
  },
};

module.exports = nextConfig;

The serverComponentsExternalPackages configuration ensures that the package @didpass/zkpass-client-ts is excluded from NextJS' bundling and compilation process, allowing it to be imported directly from node_modules. As a result, remember to include the node_modules directory in your production build. See NextJS Deployment Guide.

Running CLI Demo

The demo application will run in a CLI and requires 2 parameters: DVR and user data. Please review zkPass key concepts to have better understanding of the use case.

Cloning Demo

To try our Typescript CLI demo, you can follow these steps

  1. Clone demo repository

git clone https://github.com/gl-zkPass/zkpass-sdk.git
  1. Go to Typescript CLI demo directory (Let's assume this is our root directory for steps below)

cd zkpass-sdk/typescript/node-js/cli

Running Demo

  1. Install packages

npm install
  1. Run Dewi demo

It will run the demo using predefined user data and DVR for Dewi. The expected query result is "false".

npm run demo-dewi

Expected result :

...
...
#### starting zkpass proof verification...
#### verification completed [time=118ms]
the query result is false
  1. Run Ramana demo

It will run the demo using predefined user data and DVR for Ramana. The expected query result is "true".

npm run demo-ramana

Expected result :

...
...
#### starting zkpass proof verification...
#### verification completed [time=60ms]
the query result is true
  1. Run Jane demo

It will run the demo using predefined user data and DVR for Jane. The expected query result is "true".

npm run demo-jane

Expected result :

...
...
#### starting zkpass proof verification...
#### verification completed [time=46ms]
the query result is true
  1. Run demo with custom data

You can run the demo using custom data. Examples for user data and DVR can be found in typescript/node-js/cli/test-data.

Example running demo using custom data :

npm run demo ./test-data/ramana-profile.json ./test-data/bca-finance-ramana-dvr.json

Expected result :

...
...
#### starting zkpass proof verification...
#### verification completed [time=51ms]
the query result is true
  1. Run demo with multiple user data

You can also run the demo using multiple user data. Examples for multiple user data and DVR can be found in typescript/node-js/cli/test-data/multiple.

Example running demo using multiple data:

npm run demo-multi

Running Tests

Integration Test

The integration test will run all available demo in package.json script using CLI.

  1. Go to Typescript CLI demo directory

    cd zkpass-sdk/typescript/node-js/cli
  2. Install packages

    npm install
  3. Run the tests

    npm run test

The test will run all demo tests one by one and expect every test result is passed. List of Tests:

  • demo.test.ts

  • demo-basic.test.ts

  • demo-basic-false.test.ts

  • demo-dewi.test.ts

  • demo-ramana.test.ts

  • demo-jane.test.ts

  • demo-multi.test.ts

Code Snippets

This section describes how we use the zkPass SDK in our demo code

Generate Proof

import {
  ZkPassApiKey,
  ZkPassClient,
} from "@didpass/zkpass-client-ts";

async function generateProof(): string {
  ...
  
  /**
    * Step 1: Instantiate the ZkPassApiKey and ZkPassClient object.
   */
  const zkPassApiKey = new ZkPassApiKey(
    YOUR_API_KEY,
    YOUR_API_SECRET
  );
  const zkPassZkvm = "r0"; 
  const zkPassClient = new ZkPassClient({
      zkPassServiceUrl: ZKPASS_SERVICE_URL,
      zkPassApiKey: zkPassApiKey,
      zkVm: zkPassZkvm 
  })
  /**
   * Step 2: Call the zkpassClient.generateZkpassProof
   *         to get the zkpassProofToken.
   */
  const zkpassProofToken = await zkPassClient.generateZkpassProof(
     userDataToken,
     dvrToken
   ); 
  
  ...
}

This code snippet generates a zkPass proof. It requires 3 parameters:

  1. zkPassServiceURL : you can use https://playground-zkpass.ssi.id/proof , or use your own endpoint if you deploy zkPass on your own server.

  2. userDataToken : check Generate User Data Token section for more details.

  3. dvrToken : check Generate DVR Token section for more details.

Verify Proof

import {
  ZkPassApiKey,
  ZkPassClient
} from "@didpass/zkpass-client-ts";

function verifyZkpassProof(zkpassProofToken: string) {
  ...
  
  /**
    * Step 1: Instantiate the ZkPassApiKey and ZkPassClient object.
   */
  const zkPassApiKey = new ZkPassApiKey(
    YOUR_API_KEY,
    YOUR_API_SECRET
  );
  const zkPassZkvm = "r0"; 
  const zkPassClient = new ZkPassClient({
      zkPassServiceUrl: ZKPASS_SERVICE_URL,
      zkPassApiKey: zkPassApiKey,
      zkVm: zkPassZkvm 
  })
  
  /**
    * Step 2: Call zkpassClient.verifyZkpassProof to verify the proof.
   */
  const proofResult = await zkPassClient.verifyZkpassProof(
    zkPassProofToken,
    proofMetadataValidator
  );
  
  ...
}

This code snippet verifies a zkPass proof token. It requires 2 parameters:

  1. zkPassProofToken : check Generate Proof section for more details.

  2. proofMetadataValidator : this is a Class that implements ZkPassProofMetadataValidator, it's up to verifier to verify metadata of zkpassProofToken.

Generate User Data Token

import {
  ZkPassApiKey,
  ZkPassClient
} from "@didpass/zkpass-client-ts";

async function getUserDataToken() {
  ...
  
  /**
    * Step 1: Instantiate the ZkPassApiKey and ZkPassClient object.
   */
  const zkPassApiKey = new ZkPassApiKey(
    YOUR_API_KEY,
    YOUR_API_SECRET
  );
  const zkPassZkvm = "r0"; 
  const zkPassClient = new ZkPassClient({
      zkPassServiceUrl: ZKPASS_SERVICE_URL,
      zkPassApiKey: zkPassApiKey,
      zkVm: zkPassZkvm 
  })

  /**
   * Step 2: Call the zkPassClient.signDataToJwsToken.
   *         This is to digitally-sign the user data.
   */
  const userDataToken = await zkPassClient.signDataToJwsToken(
    PRIVATE_KEY,
    userData,
    PUBLIC_KEY_JWKS
  );
  
  ...
}

This code snippet generate user data token. It requires 3 parameters:

  1. PRIVATE_KEY : a private key used to sign user data.

  2. userData : user data in JSON format.

  3. PUBLIC_KEY_JWKS : a public key JWKS used by zkPass to verify that user data token is not tampered during transport.

Generate DVR Token

import {
  ZkPassApiKey,
  ZkPassClient,
  DataVerificationRequest,
} from "@didpass/zkpass-client-ts";

async function getDvrToken() {
  ...
  
  /**
    * Step 1: Instantiate the ZkPassApiKey and ZkPassClient object.
   */
  const zkPassApiKey = new ZkPassApiKey(
    YOUR_API_KEY,
    YOUR_API_SECRET
  );
  const zkPassZkvm = "r0"; 
  const zkPassClient = new ZkPassClient({
      zkPassServiceUrl: ZKPASS_SERVICE_URL,
      zkPassApiKey: zkPassApiKey,
      zkVm: zkPassZkvm 
  })
  
  /**
   * Step 2: Call zkPassClient.getQueryEngineVersionInfo.
   *         The version info is needed for DVR object creation.
   */
   const { queryEngineVersion, queryMethodVersion } =
      await zkPassClient.getQueryEngineVersionInfo();

  /**
   * Step 4: Create the DVR object.
   */
  const dvr = DataVerificationRequest.fromJSON({
    dvr_title: "My DVR",
    dvr_id: uuidv4(),
    query_engine_ver: queryEngineVersion,
    query_method_ver: queryMethodVersion,
    query: JSON.stringify(queryObj),
    user_data_requests: {
      "": {
        user_data_url: "https://hostname/api/user_data/",
        user_data_verifying_key: {
          KeysetEndpoint: issuerPubkey,
        },
      },
    },
    dvr_verifying_key: {
      KeysetEndpoint: verifierPubkey
    },
    zkvm: zkPassZkvm
  });

  /**
   * Step 5: Call zkPassClient.signToJwsToken.
   *         This is to digitally-sign the dvr data.
   */
  const dvrToken = await dvr.signToJwsToken(
    PRIVATE_KEY,
    publicKey
  );
  
  ...
}

This code snippet generate DVR token. It has 2 steps, generate DVR and sign DVR.

Generate DVR requires 7 parameters:

  1. zkvm : Your choice of zkvm (currently available zkvm = r0)

  2. dvr_title : title of your DVR.

  3. dvr_id : ID of your DVR. When the verifier issues a DVR, they will save it. When the verifier verifies the zkPassProofToken, they will check whether the zkPassProofToken was generated using the DVR issued by them.

  4. query_engine_ver : query engine version of the SDK you currently use.

  5. query_method_ver : query method version of the SDK you currently use.

  6. query : queryObject is a zkPass query, you need to make them into a string

  7. user_data_url : this parameter is not used by zkPass when generating proof. However, it can be utilized by the holder in scenarios where they obtain the DVR but do not have user data yet. The holder can retrieve user data from this URL.

  8. user_data_verifying_key : a public key JWKS used by zkPass to verify that user data token is not tampered during transport.

  9. dvr_verifying_key : a public key JWKS used by zkPass to verify that data verification request is not tampered during transport.

Sign DVR requires 2 parameters:

  1. PRIVATE_KEY : a private key used to sign user data.

  2. PUBLIC_KEY_JWKS : a public key JWKS used by zkPass to verify that dvr token is not tampered during transport.

Last updated