name: groth16-submit description: Submit zero-knowledge proofs to zkVerify using the Kurier REST API. Use when the user wants to submit proofs, verify on zkVerify, register verification keys, or interact with the zkVerify network. argument-hint: [network]
Submit Proofs to zkVerify via Kurier API
Help the user submit their generated proofs to zkVerify for on-chain verification using the Kurier REST API.
Arguments
If invoked with an argument (e.g., /groth16-submit testnet), use it as the network.
| Argument | Network | API Base URL |
|---|---|---|
testnet |
Volta Testnet | https://api-testnet.kurier.xyz |
mainnet |
zkVerify Mainnet | https://api.kurier.xyz |
If no argument provided, ask the user which network they want to use.
Pre-flight Check (MANDATORY)
Before doing anything else, verify the .env file exists:
ls -la .env 2>/dev/null && echo "Found .env" || echo "ERROR: .env not found"
| Check | If Missing |
|---|---|
.env file |
STOP - User must create it with API key (see Setup below) |
proofs/proof.json |
Run /groth16-prove first |
proofs/public.json |
Run /groth16-prove first |
build/verification_key.json |
Run /groth16-compile first |
IMPORTANT: Do NOT read the contents of .env - it contains sensitive credentials.
If .env does not exist, tell the user to create it and do not proceed.
Scope
This skill submits Groth16 proofs to zkVerify blockchain using the Kurier REST API.
What this covers:
- Register verification key (returns vkHash for efficient submissions)
- Submit proofs with optimistic verification
- Poll for finalization status
- Support for aggregation via chainId
Prerequisites:
- Proof files from
/groth16-prove(proofs/proof.json,proofs/public.json) - Verification key (
build/verification_key.json) - Kurier API key from kurier.xyz (mainnet) or testnet.kurier.xyz (testnet)
Setup
Install Dependencies
npm install axios dotenv
If using TypeScript:
npm install axios dotenv typescript ts-node @types/node
Environment Configuration
The user must create a .env file:
# Your Kurier API key
API_KEY="your-api-key-here"
Important: Ensure .env is in .gitignore to avoid committing credentials.
Getting an API Key
| Network | Sign Up URL |
|---|---|
| Testnet | https://testnet.kurier.xyz |
| Mainnet | https://kurier.xyz |
Quick Start
1. Register Verification Key (One-time)
npx ts-node src/submit.ts testnet register-vk
# Save the vkHash for future submissions
2. Submit Proof
# To testnet
npx ts-node src/submit.ts testnet submit
# To mainnet
npx ts-node src/submit.ts mainnet submit
3. View Transaction
After submission, you'll receive a job ID and can track status through the API. Once finalized, view on explorer:
- Testnet:
https://zkverify-testnet.subscan.io/ - Mainnet:
https://zkverify.subscan.io/
Workflow Options
Option A: Simple Submission (Full VK each time)
Submit proof with full verification key:
npx ts-node src/submit.ts testnet submit
Option B: Register VK First (Recommended)
Register VK once:
npx ts-node src/submit.ts testnet register-vk # Save the vkHash from the responseSubmit with registered VK (more efficient):
npx ts-node src/submit.ts testnet submit --vk-hash=0x123abc...
Option C: Submit with Aggregation (Cross-chain)
For aggregation to settlement layers, include a chainId:
# Sepolia (chainId: 11155111)
npx ts-node src/submit.ts testnet submit --chain-id=11155111
# Base Sepolia (chainId: 84532)
npx ts-node src/submit.ts testnet submit --chain-id=84532
Kurier API Endpoints
IMPORTANT: All endpoints require the /api/v1/ prefix (not shown in some older docs).
| Endpoint | Method | Purpose |
|---|---|---|
/api/v1/register-vk/{API_KEY} |
POST | Register verification key |
/api/v1/submit-proof/{API_KEY} |
POST | Submit proof for verification |
/api/v1/job-status/{API_KEY}/{jobId} |
GET | Check proof status |
Correct Request Payload Format
Register VK:
{
proofType: "groth16",
proofOptions: {
library: "snarkjs",
curve: "bn128"
},
vk: verificationKeyObject
}
Submit Proof (with full VK):
{
proofType: "groth16",
vkRegistered: false,
proofOptions: {
library: "snarkjs",
curve: "bn128"
},
proofData: {
proof: proofObject,
publicSignals: publicSignalsArray,
vk: verificationKeyObject
}
}
Submit Proof (with registered vkHash):
{
proofType: "groth16",
vkRegistered: true,
proofOptions: {
library: "snarkjs",
curve: "bn128"
},
proofData: {
proof: proofObject,
publicSignals: publicSignalsArray,
vk: "0xvkHash..." // The vkHash string, not the full VK
}
}
Job Status States
| Status | Description |
|---|---|
Queued |
Proof is queued for processing |
Valid |
Proof passed optimistic verification |
Submitted |
Transaction submitted to zkVerify |
IncludedInBlock |
Transaction included in a block |
Finalized |
Transaction finalized on chain |
Failed |
Verification failed |
AggregationPending |
Waiting for aggregation (with chainId) |
Aggregated |
Proof aggregated (with chainId) |
AggregationPublished |
Aggregation published to settlement layer |
After Submission
- Check optimistic verification - Immediate pass/fail response
- Poll for finalization - Use job-status endpoint
- For aggregation - Track through aggregation states
- Check explorer - View finalized transaction on Subscan
Checklist
-
.envfile exists with valid API_KEY - Proof files exist (
proofs/proof.json,proofs/public.json) - Verification key exists (
build/verification_key.json) - Network selected (testnet or mainnet)
- VK registered (optional but recommended)
- Proof submitted and job ID received
- Status polled until Finalized
Additional Resources
- examples.md - CLI usage examples, aggregation, batch workflows
- reference.md - TypeScript code, API request/response formats
- troubleshooting.md - Common errors and solutions
- Kurier API Docs - Swagger documentation