This repo generates a notarized web proof of an Etherscan API call for a wallet's USDC balance, compresses it into a ZK proof, and verifies it on-chain with an EVM contract. It uses vlayer Web Prover (notary) + vlayer ZK Prover and a RISC Zero Groth16 verifier on Sepolia.
- Proven HTTP request to
https://api.etherscan.io/v2/api?...tokenbalance... - Compressed ZK proof (
proof.json) ready for on-chain verification - EtherscanVerifier contract you can deploy and call with the proof
- Node.js 18+ and npm
- Foundry (
forge) for compiling contracts - vlayer Web Prover credentials (client id + secret) and an Etherscan API key
- A funded Sepolia account for deployments/txs
npm i
cp .env.example .env
# fill WEB_PROVER_API_CLIENT_ID, WEB_PROVER_API_SECRET, ETHERSCAN_API_KEY
npm run prove- Makes the notarized request for the USDC contract and wallet address in
prove.ts. - Compresses the proof via ZK Prover, decodes the extracted balance, and saves
proof.json.
cd contracts
npm i
cp .env.example .env
# set PRIVATE_KEY (+ SEPOLIA_RPC_URL if you want a custom RPC)
# keep NOTARY_KEY_FINGERPRINT, QUERIES_HASH, EXPECTED_URL aligned with the proof you generated
# ensure ZK_PROVER_GUEST_ID is set
forge build
npm run deploy sepolia 0x2a098988600d87650Fb061FfAff08B97149Fa84D # RISC Zero Groth16 verifier on Sepolia
# or: npm run deploy sepolia # deploys a local mock verifier (testing only)- We instantiate
EtherscanVerifierwith the Sepolia RiscZeroGroth16Verifier at0x2a098988600d87650Fb061FfAff08B97149Fa84D(code, docs). That contract performs the Groth16 proof verification for the RISC Zero guest that produced your web proof. You should use the canonical verifier for real proofs; the mock option is only for local/testing.
cd contracts
npm run verify sepolia <your-contract-address>cd contracts
npm run submit sepolia ../proof.json # uses deployments/sepolia.json if present
# or: npm run submit sepolia ../proof.json 0xYourContract- Simulates first, then sends
submitBalance(journalData, seal). - Confirms the tx and reads back the stored balance.
- Deployed contract addresses are recorded in
contracts/deployments/<network>.json(e.g.,contracts/deployments/sepolia.json) when you deploy;npm run submitwill auto-use those.
- Web Prover notary performs the Etherscan request and returns a signed presentation.
- ZK Prover compresses the presentation, extracts
result(the balance), and returnszkProof+journalDataAbi. proof.jsonholds those values for on-chain use.- EtherscanVerifier checks the notary key, query hash, URL, and verifies the Groth16 proof before storing the balance.