IMPORTANT: This project is not production-ready. Mainnets are not supported. Testnets only (Sepolia, Base Sepolia, OP Sepolia, and local Anvil).
A Next.js application that uses web proofs / zkTLS to verify GitHub contributions through vlayer's Web Prover API.
This tool allows users to cryptographically prove and verify their contributions to GitHub repositories. It creates tamper-proof attestations of contributor data from GitHub's API.
- Node.js 20+
- npm or pnpm
- vlayer Web Prover API credentials
npm installCreate a .env.local file with your vlayer API credentials:
VLAYER_API_GATEWAY_KEY=your_api_key
# Optional: override the Web Prover / ZK Prover base URL
WEB_PROVER_API_URL=https://web-prover.vlayer.xyz/api/v2.0
ZK_PROVER_API_URL=https://zk-prover.vlayer.xyz/api/v2.0
- Start the development server:
npm run dev-
Enter a GitHub org + repo name (e.g.,
vlayer-xyz/vlayer) -
For private repositories, provide a GitHub Personal Access Token
-
Enter your GitHub username
-
Click "Prove Contributions" to generate a cryptographic proof
-
Click "Verify Proof" to verify your contributions with our backend
-
Click "Generate ZK Proof" to verify your contributions on-chain
The end-to-end suite exercises the full stack (Anvil chain, contract deployment, Next.js API routes, and the prover API proxy).
npm run test:e2eRequirements:
- Foundry's
anvilandforgemust be available on yourPATH contractsdependencies installed (npm installinsidecontracts/)- No other services bound to the random ports the test selects
- Real network access plus the following environment variables (the test fails fast if any are missing):
VLAYER_API_GATEWAY_KEY— API key for the vlayer dashboard (Web Prover + ZK Prover)GITHUB_TOKEN(orGITHUB_GRAPHQL_TOKEN) with GitHub GraphQL accessZK_PROVER_GUEST_ID— guest image ID for the ZK Prover (required for E2E runs)PRIVATE_KEY— Base Sepolia private key with testnet ETH (Boundless suite only)- Optional overrides:
WEB_PROVER_API_URL,ZK_PROVER_API_URL,DEV_ZK_PROVER_API_URL,GITHUB_LOGIN,GITHUB_REPO_OWNER,GITHUB_REPO_NAME
- The test calls
/api/prove,/api/compress, and finally submits the compressed proof to the locally deployed contract via viem/wagmi-compatible logic. - These env vars can be exported in your shell or placed in a
.env.testfile in the repo root, which the Vitest suite loads automatically before running. - Example
.env.test:GITHUB_TOKEN=ghp_xxx VLAYER_API_GATEWAY_KEY=your_api_key WEB_PROVER_API_URL=https://web-prover.vlayer.xyz/api/v2.0 ZK_PROVER_API_URL=https://zk-prover.vlayer.xyz/api/v2.0 DEV_ZK_PROVER_API_URL=https://zk-prover.vlayer.xyz/api/v2.0/fake ZK_PROVER_GUEST_ID=0x6a7e93daf523b54f3edb5fba6c6390983adc7fbf962cbd5c9cac738b006bd36c PRIVATE_KEY=0x<base_sepolia_private_key>
A simple script to test GitHub GraphQL API calls directly, useful for debugging and verifying GitHub token access.
Usage:
# Using environment variables
GITHUB_TOKEN=ghp_xxx OWNER=vlayer-xyz NAME=vouch LOGIN=Chmarusso node testScripts/test-graphql-prove.js
# Or using .env.local file (recommended)
# Add to .env.local:
# GITHUB_TOKEN=ghp_xxx
# OWNER=vlayer-xyz
# NAME=vouch
# LOGIN=Chmarusso
node testScripts/test-graphql-prove.jsEnvironment Variables:
GITHUB_TOKEN(required): GitHub Personal Access Token with appropriate permissionsOWNER(optional, default:vlayer-xyz): Repository owner/organizationNAME(optional, default:vouch): Repository nameLOGIN(optional, default:Chmarusso): GitHub username to queryGITHUB_URL(optional, default:https://api.github.com/graphql): GitHub API endpoint
Features:
- Automatically loads
.envand.env.localfiles (.env.localoverrides.env) - Tests direct GraphQL queries to GitHub API
- Useful for verifying token permissions and repository access
- Prints formatted JSON response for easy debugging
The project includes Solidity smart contracts for storing verified GitHub contributions on-chain.
- On-chain verification of ZK proofs using RISC Zero
- Store contribution records permanently on blockchain
- Supports testnets only: Sepolia, Base Sepolia, OP Sepolia, and local Anvil
cd contracts
# Install JS deps
npm install
# Install Foundry deps via Soldeer (forge-std, risc0-ethereum)
forge soldeer install
# Deploy to testnet
npm run deploy:sepoliaFor detailed documentation, see contracts/README.md.
- Dependencies are managed with Soldeer and specified in
contracts/foundry.tomlunder the[soldeer]section. forge-stdandrisc0-ethereumare installed intocontracts/lib/at build time.- Commit the lockfile generated by Soldeer (e.g.,
soldeer.lock) but do not commit thecontracts/lib/contents.
Commands:
cd contracts
# Add or update packages
forge soldeer add foundry-rs/forge-std@^1.9
forge soldeer add risc0/risc0-ethereum@^0.2
# Install per lockfile (CI-friendly)
forge soldeer install
# Regenerate remappings.txt if needed
forge soldeer remap- Sepolia (testnet)
- Base Sepolia (testnet)
- OP Sepolia (testnet)
- Anvil (local testing)
- Start Anvil in a terminal:
anvil- In a new terminal, export env vars (use one private key printed by Anvil):
export ANVIL_RPC_URL=http://127.0.0.1:8545
export PRIVATE_KEY=0x<one_of_anvil_accounts_private_keys>
# Fetch the ZK Prover guest ID from the dashboard
export ZK_PROVER_GUEST_ID=$(curl -s -H "Authorization: Bearer $VLAYER_API_GATEWAY_KEY" \
https:/zk-prover.vlayer.xyz/api/v2.0/evm/guest-id | jq -r '.data.guestId')
# Match these to your compressed proof (example from zk_proof_compress_*.json)
export NOTARY_KEY_FINGERPRINT=0xa7e62d7f17aa7a22c26bdb93b7ce9400e826ffb2c6f54e54d2ded015677499af
export QUERIES_HASH=0x85db70a06280c1096181df15a8c754a968a0eb669b34d686194ce1faceb5c6c6
export EXPECTED_URL=https://api.github.com/graphql- Build, install and deploy the contract to Anvil:
cd contracts
forge soldeer install
forge build
# Via npm script if available
npm run deploy:anvil
# Or directly
npx ts-node --transpile-only scripts/deploy.ts anvilNote the printed contract address and optionally export it:
export ANVIL_CONTRACT_ADDRESS=0x<deployed_address>- Submit your compressed zk proof to the contract:
cd ..
PROOF=./zk_proof_compress_YYYYMMDD_HHMMSS.json # your file path
# Via npm script if available
npm run submit-proof anvil "$PROOF" ${ANVIL_CONTRACT_ADDRESS:-}
# Or directly
npx ts-node --transpile-only contracts/scripts/submitProof.ts anvil "$PROOF" ${ANVIL_CONTRACT_ADDRESS:-}Expected output:
- Simulation success, transaction hash, receipt details
- Deploy contract
npm run deploy:sepolia- Verify contract
npm run verify sepolia <your-contract-address>- Add contract config to .env.local in root directory:
NEXT_PUBLIC_SEPOLIA_CONTRACT_ADDRESS=<your-contract-address>
NEXT_PUBLIC_DEFAULT_CHAIN_ID=11155111- Submit your compressed zk proof to the contract
Troubleshooting:
- If you see "Contract not compiled", run
forge buildincontracts. - If deployment fails with "
ZK_PROVER_GUEST_ID not set", ensure you've fetched it from the ZK prover server (see step 2 above). Note: In e2e tests, this is fetched automatically. - If simulation reverts, ensure env vars match the proof:
NOTARY_KEY_FINGERPRINTequalspublicOutputs.notaryKeyFingerprintQUERIES_HASHequalspublicOutputs.queriesHashEXPECTED_URLmatches the proof domain (e.g.,https://api.github.com/graphql)
- If not exporting
ANVIL_CONTRACT_ADDRESS, pass the deployed address as the 3rd arg in the submit command.
For more information about vlayer and the Web Prover API, visit the official documentation: