Inspiration We got the idea for OneKYC from the hassle of repeating KYC for every Web3 dApp—sharing selfies and IDs over and over sucks for privacy. Seeing hackathon projects like Crescent and Brick Towers use Midnight’s ZK proofs for slick, private KYC inspired us to build a one-time KYC system that spits out a reusable zkID for easy logins.
What it does OneKYC lets you do KYC once (upload selfie/doc), verifies it privately off-chain, and creates a zkID—a zero-knowledge proof proving you’re legit (18+, verified, not sanctioned) without leaking your data. You can use this zkID to log into any dApp on Midnight’s testnet without redoing KYC. Admins can revoke it if needed.
How we built it
- Frontend : Vite/React/TS with Canvas for capturing selfie/doc, sent to backend via FormData with Lace wallet’s userAddress.
- Backend : Node.js/Express with Multer for uploads, Tesseract.js for OCR (reads country/DOB), face-api.js for face matching, and simple checks for age/sanctions.
- ZK Magic: Used Midnight’s Compact circuit (
kyc_eligibility.compact) to generate a ZK proof, hashed into an on-chain commitment via Lace. Stored zkID in localStorage for logins.
Challenges we ran into
- Compact CLI setup was a pain—v0.2.0 installer missed
compactc, needed v0.25.0 for Arch Linux. - SDK imports (
@midnight-ntwrk/wallet) were tricky; API methods changed (e.g.,generateProof). - Proof generation took 5-30s; needed Docker proof server to speed up.
Accomplishments we’re proud of
- Got a working zkID system in ~100 LOC that’s actually private and reusable.
- Hooked up Lace wallet and backend KYC without leaks.
- Deployed a verifier contract on testnet-02 in one shot.
What we learned
- Midnight’s ZK tech is dope but needs better CLI docs (v0.25.0 fixed our install woes).
- ZK proofs are slow on low-end machines—Docker server is a lifesaver.
- Lace + Compact makes Web3 UX way smoother than Ethereum’s gas hell.
What’s next for OneKYC
- Add multi-country support (extend circuit for EU, etc.).
- Encrypt zkID storage (Lace secure storage, not just localStorage).
- Integrate with more dApps when mainnet drops (Q4 2025).
Built With
- lace
- midnight
Log in or sign up for Devpost to join the conversation.