Integrate Validator

The ZKAP Validator contract is the on-chain component responsible for verifying ZK proofs, enforcing replay protection, checking expiry windows, and emitting encrypted events for applications to consume. This file explains how to integrate the validator into your backend, smart contracts, or application infrastructure.


1. What the Validator Does

The ZKAP Validator performs three critical checks:

  1. Verifies the zero-knowledge proof

  2. Ensures the nullifier has not been used

  3. Confirms the request has not expired

If all checks pass, it emits:

AnonymousAction(commitment_root, encrypted_payload)

Applications listen to these events and decrypt payloads off-chain.

The validator never learns:

  • who sent the action

  • what the action contains

  • any metadata about the user or agent


2. Deploying the Validator Contract

You can install the validator contract package using:

npm install @zkap/contracts

The contract can be deployed via:

  • Hardhat

  • Foundry (Forge)

  • Remix

  • Any EVM deployment tool

Example (using Hardhat):

const Validator = await ethers.getContractFactory("ZKAPValidator"); const validator = await Validator.deploy(); await validator.waitForDeployment(); console.log("Validator deployed at:", validator.target);

Once deployed, you can interact with it via any RPC provider.


3. Validator ABI and Interface

The validator exposes the following core functions:

submitFrame(frame) verifyProof(proof, commitment_root) (internal)

And the key event:

event AnonymousAction(bytes32 commitment_root, bytes encrypted_payload);

The frame object contains:

{ zk_proof, commitment_root, payload_ciphertext, nullifier, session_hash, expiry_block }


4. Submitting a Frame On-Chain

After generating a frame using the SDK, developers submit it like this:

import { ethers } from "ethers";

const contract = new ethers.Contract(validatorAddress, ValidatorABI, signer); await contract.submitFrame(frame);

The validator:

  • verifies the proof

  • checks nullifier reuse

  • checks expiry

  • emits AnonymousAction

If something fails, it reverts with a descriptive error.


5. Listening for AnonymousAction Events

Applications must listen for the encrypted event emitted by the validator.

Example:

contract.on("AnonymousAction", async (root, encrypted) => { const payload = await decryptPayload(encrypted, appKey); handleAction(payload); });

This event is the entry point to application logic.

Important: No sender address is included in the event. The action comes through anonymously.


6. Integrating With Backend Services

Most applications integrate the validator with a backend listener:

  1. Subscribe to AnonymousAction

  2. Receive encrypted payload

  3. Decrypt payload

  4. Run application logic

  5. Execute internal or cross-chain actions

This pattern supports:

  • DEX swaps

  • RFQ matching

  • agent orchestration

  • bridge routing

  • governance actions

The backend acts as the “consumer” of private instructions.


7. Multi-Chain Integration

Each chain has its own validator contract instance. Applications can:

  • deploy multiple validators across chains

  • listen to events from all chains

  • decrypt and route actions appropriately

ZKAP maintains privacy even across L1/L2/L3 boundaries.


8. Common Integration Patterns

8.1 Private DEX

Listen → decrypt → execute swap internally.

8.2 Wallet backend

Listen → decrypt → execute user operation.

8.3 Agent runtime

Listen → decrypt → run task or instruction.

8.4 Cross-chain router

Listen → decrypt → forward encrypted intent to another chain.

Each integration only needs to consume decrypted payloads.


9. Error Handling

The validator throws clear errors when:

  • nullifier is reused

  • proof is invalid

  • expiry exceeded

  • malformed frame

Backend services should watch for revert reasons when submitting frames.


10. Security Considerations

  • Always check nullifier status before acting

  • Never decrypt payloads on-chain

  • Keep decryption keys private

  • Enforce rate limiting if needed

  • Validate payload structure after decryption

These ensure the system remains both private and secure.

Last updated