OmniPriv
Prove you're verified on any blockchain without revealing your personal data using ZK proofs.
Problem Statement
OmniPriv lets users prove things about themselves - like being over 18 or from an allowed country - without putting personal information on-chain or sharing it with apps.Here's how it works: Users store encrypted credentials locally in their browser. When they need to verify something, a zero-knowledge proof circuit runs on their device to generate a proof that their credentials meet specific requirements, without revealing the actual data.The proof gets verified on Base Sepolia, then LayerZero propagates the verification status to other chains like Optimism. dApps on any supported chain can check "is this wallet verified?" and get a simple yes or no - but they never see birth dates, countries, or any personal information.This solves a real problem: right now, projects that need age verification or compliance either collect sensitive data (privacy risk) or trust centralized services (defeats the purpose of decentralization). OmniPriv gives you the best of both worlds - cryptographically proven compliance without sacrificing privacy.Once you verify on one chain, your verification works everywhere LayerZero connects. No need to re-submit documents to every new protocol.
Solution
The core architecture has three main pieces working together:First, we built a Noir circuit that takes private inputs (birth year, country code, secret salt) and proves they meet policy requirements (age >= 18, country allowed) without revealing the actual values. The circuit outputs only a commitment hash and policy ID as public signals. Getting the commitment formula to match exactly between JavaScript and Solidity took some trial and error - we had to carefully synchronize keccak256(abi.encodePacked()) on both sides, and one tiny type mismatch would make everything fail silently.For smart contracts, we deployed a VaultAnchor on Base Sepolia that stores commitment hashes (not actual data), and a ProofConsumer that verifies zero-knowledge proofs and marks wallets as verified. Then we extended LayerZero's OApp base contract to add identity-specific features: policy IDs so dApps can check specific verification types, expiry timestamps so verifications don't last forever, and replay-safe nonces. The LayerZero message payload is intentionally minimal - just wallet address, policy ID, commitment, and expiry - about 200 bytes total.For the frontend, we used Coinbase's Embedded Wallets throughout, which gives users email-based onboarding without seed phrases. The tricky part was that CDP injects window.ethereum just like MetaMask, but its transaction API doesn't quite match wagmi's expectations. We worked around this by using viem's custom transport with CDP's provider directly, bypassing wagmi entirely for transaction submissions. We also hardcoded the LayerZero fee at 0.005 ETH after discovering testnet fee quote APIs were unreliable.Credentials are encrypted using AES-GCM with keys derived from the user's wallet signature and stored in IndexedDB. The encryption happens entirely client-side - nothing ever touches our servers. For the hackathon, we generate deterministic mock proofs (real Noir WASM proving would require additional build setup), but the circuit logic is production-ready and the contract verification works with actual proof structures.We also built a demo mode that shows the full UX flow even if testnet RPCs are having issues - it attempts real transactions first, then gracefully falls back to simulation only if needed. This way judges can see the complete experience regardless of infrastructure hiccups.The biggest technical challenge was definitely the hash synchronization - making sure the commitment computed in JavaScript exactly matches what Solidity expects, down to byte-level encoding. We created a shared SDK that both frontend and contracts import to keep the logic consistent. Another fun challenge was encoding LayerZero messages efficiently while keeping them readable on the receiving side - we used careful abi.encodePacked patterns to minimize gas costs.