✨Works out of the box guarantee. If you face any issue at all, hit us up on Telegram and we will write the integration for you.

zkFetch
Quickstart

Prerequisites

you can find more examples/starter packs here

Quickstart

The following tutorial is based on a Node.js

Create an application on Dev Tool

Head to https://dev.reclaimprotocol.org (opens in a new tab) and create a new zkFetch application. Once you create the application, you'll be given an application ID and an application secret. Please take note of these. These will be used in the next steps.

Install zkFetch SDK

npm i @reclaimprotocol/zk-fetch

Import Reclaim Client

import { ReclaimClient } from '@reclaimprotocol/zk-fetch

Initialize Reclaim Client

Boiler plate stuff.

const client = new ReclaimClient('YOUR_APP_ID', 'YOUR_APP_SECRET')

Add Public/Private headers, optional but recommended

For public endpoints

If the endpoint you want to fetch and generate a proof of the response. This endpoint is public, and doesn't need any private data like auth headers/api keys.

This is useful when

  • Verifier needs to verify without re-doing the api call
  • The API doesn't need any private headers or auth
  • The proof or response needs to be generated for a particular endpoint now, and verified later
  const publicOptions = {
    method: 'GET', // or POST
    headers : {
        accept: 'application/json, text/plain, */*' 
    }
  }
  const proof = await client.zkFetch(
    'https://your.url.org',
    publicOptions
  )

Note : all the data in the publicOptions will be visible to them who you share the proof with (aka, verifier).

For private endpoint

If you want to fetch and generate a proof of the response, but the fetch involves some private data like auth headers or api keys

This is useful when

  • Using API keys
  • Using Auth headers
  const publicOptions = {
    method: 'GET', // or POST
    headers : {
      accept: 'application/json, text/plain, */*' 
    }
  }
 
  const privateOptions = {
    headers {
        apiKey: "123...456",
        someOtherHeader: "someOtherValue",
    }
  }
 
  const proof = await client.zkFetch(
    'https://your.url.org',
    publicOptions,
    privateOptions
  )
 

All the data in the privateOptions will stay hidden to the verifier.

Fetch using zkFetch

const proof = await client.zkFetch('https://your.url.org')

Additonal Features

Retries and Retry Interval

Add retries and set a retry interval for fetch requests:

const proof = await client.zkFetch('https://your.url.org', publicOptions, privateOptions, 5, 10000);

Add Geolocation

Specify a geolocation (optional) using a two-letter ISO country code:

const publicOptions = {
  method: 'GET',
  headers: { accept: 'application/json' },
  geoLocation: 'US' // Example: 'US' for the United States
};
const proof = await client.zkFetch('https://your.url.org', publicOptions);

Using Response Match and Redactions

ou can also use responseMatches and responseRedactions to match and redact the response. This is useful when you want to verify the response against a particular value or redact some part of the response.

 const publicOptions = {
    method: 'GET', // or POST
    headers : {
      accept: 'application/json, text/plain, */*' 
    }
  }
 
  const privateOptions = {
    responseMatches: [
      {
        type: 'contains' | 'regex', // type of match 
        value: '<HTTP RESPONSE TEXT>' | '<REGEX>', // value to match or regex to match 
      }
    ],
    responseRedactions: [
      {
        jsonPath: '$.data', // JSON path to redact 
        xPath: '/data', // Xpath to redact  
        regex: '<REGEX>', // Regex to redact
      }
    ]
  }

Note: The responseMatches and responseRedactions are optional and can be used as per the requirement.

Verify the proofs and transform proof for onchain

Verify the proofs

Install @reclaimprotocol/js-sdk

npm install @reclaimprotocol/js-sdk

Import the Reclaim class from the js-sdk

const { Reclaim } = require('@reclaimprotocol/js-sdk');

Use Reclaim.verifySignedProof(proof)

You must send the proofObject and not the verifiedResponse to the verifier for them to be able to verify.

const isProofVerified = await Reclaim.verifySignedProof(proof);

it verifies the authenticity and completeness of a given proof. It checks if the proof contains signatures, recalculates the proof identifier, and verifies it against the provided signatures. If the verification fails, it will log the error and return false.

More information about the verifySignedProof method can be found here (opens in a new tab)

Transform proof for onchain

Transforms proof data into a format suitable for on-chain transactions, you need to use it before sending the proof to the blockchain.

Use Reclaim.transformForOnchain(proof) from the js-sdk to transform the proof for onchain.

const onchainProof = Reclaim.transformForOnchain(proof);

Summarizing

import { ReclaimClient } from '@reclaimprotocol/zk-fetch';
import { Reclaim } from '@reclaimprotocol/js-sdk'
 
const client = new ReclaimClient(YOUR_APP_ID, YOUR_APP_SECRET);
 
const generateProof = async() => {
    try{
        // URL to fetch the data from - in this case, the price of Ethereum in USD from the CoinGecko API
        const url = 'https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd';
        /* 
        * Fetch the data from the API and generate a proof for the response. 
        * The proof will contain the USD price of Ethereum. 
        */ 
        const proof = await client.zkFetch(url, {
          // public options for the fetch request 
          method: 'GET',
        }, {
          // options for the proof generation
          responseMatches: [
            /* 
            * The proof will match the response body with the regex pattern (search for the price of ethereum in the response body 
            the regex will capture the price in the named group 'price').
            * to extract the price of Ethereum in USD. (e.g. {"ethereum":{"usd":3000}}) 
            */ 
            {
                "type": "regex",
                "value": "\\{\"ethereum\":\\{\"usd\":(?<price>[\\d\\.]+)\\}\\}"
            }
          ],
        });
      
         // Verify Proof 
        const isVerified = await Reclaim.verifySignedProof(proof)
 
        // Transform the proof data to be used on-chain 
         const proofData = await Reclaim.transformForOnchain(proof);        
 
    } catch(error){
        console.log(error)
    }
}