All projects

Proof of Presence — Bot-proof, privacy-preserving attendance for Web3 events

Bot-proof, privacy-preserving event attendance tracking using World ID ZK proofs and Chainlink CRE.

Privacy Risk & Compliance World

What it is

What it is:
Proof of Presence (PoP) is a privacy-preserving event attendance registry that leverages zero-knowledge proofs to verify that attendees are unique humans without revealing their identity. Attendees check in via World ID (Tier 1: Orb-verified) or Privy (Tier 2: email/phone), and their attendance is recorded anonymously on-chain using only a nullifierHash — never their wallet address or identity.
How it works:

  1. Attendee submits check-in → proves uniqueness via World ID ZK proof or Privy email
  2. Chainlink CRE Workflow (running in a secure enclave) receives the proof → verifies it against World ID API inside the enclave → calls recordAttendance() on the Sepolia contract via Keystone Forwarder
  3. ProofOfPresence contract stores the record indexed by anonymous nullifierHash → mints a non-transferable ERC-721 Soulbound Badge(POPB)
  4. CCIP automatically bridges the attendance record to Base Sepolia and Optimism Sepolia cross-chain
    Problem it solves:

How it Works

How is it built?
Tech Stack:

  • Identity: World ID (ZK Orb proof) + Privy (email/phone fallback)
  • Automation: Chainlink CRE (Confidential Runtime Environment) with Keystone Forwarder for secure off-chain→on-chain bridge
  • Cross-chain: Chainlink CCIP for automatic message bridging
  • Smart Contracts: Solidity 0.8.20 (ProofOfPresence + PoP_CCIP_Receiver)
  • Frontend: Next.js 15, Tailwind CSS, MiniKit SDK
  • Test Network: Ethereum Sepolia (primary), Base Sepolia, Optimism Sepolia
    User Flow
    Browser/World App → World ID ZK Proof
      ↓
    Next.js Frontend (/checkin, /processing, /credential, /vault)
      ↓
    Chainlink CRE Workflow (4 nodes)
     • HTTP Trigger (receives nullifierHash + proof)
     • Confidential HTTP (verifies against World ID API in TEE enclave)
     • ABI encoding (prepares attestation)
     • EVMClient.writeReport() → Keystone Forwarder
      ↓
    ProofOfPresence.sol (Sepolia)
     • onReport() (via IReceiver interface)
     • Records registry[nullifierHash][eventId]
     • Mints ERC-721 SBT badge
     • Sends CCIP messages
      ↓
    PoP_CCIP_Receiver.sol (Base + Optimism)
     • _ccipReceive() mirrors records

Key Contracts Deployed:

  • ProofOfPresence (Sepolia): 0xbA985984B1319451968f42281b1a92Ca709cF820
  • PoP_CCIP_Receiver (Base Sepolia): 0x508eC020139E6fcdA3878B18898F0E372D906b1a
  • PoP_CCIP_Receiver (Optimism Sepolia): 0xd01fac0953530D7833bA8eB0cc3CcCa2433BCD0b

Links

Created by

  • Shane Joans V