Prerequisites
- Node.js 18.0.0 or later
- An application ID and secret from Reclaim Protocol. Obtain these from the Reclaim Developer Protocol (opens in a new tab).
you can find more examples/starter packs here
- React Example (opens in a new tab)
- Express Example (opens in a new tab)
- Ethers.js Example (opens in a new tab)
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)
}
}