Privacy-first hiring powered by Zero Knowledge Proofs on the Midnight Network.
Prove your credentials without exposing your data. Hire on proof, not paper.
Open ProofHire Website for Demo
contract: mn_d859b6887d635fd543f1134bc669c136051910eaf66ec2827c91740bce
ProofHire is a decentralized hiring platform built on the Midnight Network. Candidates submit their CV details, generate Zero Knowledge Proofs for each section (education, skills, experience, certifications), and deploy a smart contract to the Midnight Preview testnet. Recruiters can verify any credential claim on-chain without ever seeing the raw data.
Each section of a talent's CV gets its own ZK proof commitment:
| CV Section | Proof | What Recruiter Sees |
|---|---|---|
| Education | proofOfSchool |
Verified / Not Verified |
| Skills | proofOfSkills |
Verified / Not Verified |
| Experience | proofOfExperience |
Verified / Not Verified |
| Certifications | proofOfCertifications |
Verified / Not Verified |
The Compact smart contract uses persistentHash to create commitments. Credentials go through witness functions and never touch the public ledger. Only the commitment hash (the mathematical proof) is stored on-chain via disclose().
Recruiters call verifySchoolProof(commitment) etc. on the deployed contract. The circuit returns true or false — the raw data is never exposed.
- Frontend: Next.js 15, Tailwind CSS, TypeScript
- Blockchain: Midnight Network (Preview Testnet)
- Smart Contract: Compact language (
proof-hire.compact) - Wallet: Midnight Lace Wallet (DApp Connector API v4.0.1)
- Deployment: Vercel
git clone https://github.com/yourusername/proofhire
cd proofhire
npm installcp .env.example .env.local
npm run devOpen http://localhost:6300
- Install Midnight Lace Wallet
- Open Lace → Settings → Midnight
- Set Network to
Preview - Set Proof Server to
Remote - Click Save
- Refresh the ProofHire page
- Visit Preview Faucet to get tNIGHT
- Open Lace → Tokens → Click Generate tDUST for transaction fees
- Compact Compiler installed
- Lace Wallet configured for Preview network
cd contracts
compact compile proof-hire.compact managed/proof-hirecp -r contracts/dist/managed/proof-hire/keys ./public/keys
cp -r contracts/dist/managed/proof-hire/zkir ./public/zkirThe frontend deploys the contract automatically when a talent saves their CV. The contract address is shown in a modal and saved to localStorage.
- Push to GitHub
- Go to vercel.com → New Project → Import repo
- Add environment variables from
.env.example - Deploy
- Go to
/talent/authand connect Lace Wallet - Complete the onboarding form
- On the Education step, click Generate School Proof — watch the ZK animation
- Do the same for Experience and Skills steps
- On the final step, click Save CV & Go Live
- A modal shows your deployed contract address
- Copy and save it
- Go to
/recruiter/authand connect a different Lace Wallet (or same for demo) - Complete recruiter onboarding
- Go to Talent Marketplace
- Find a talent with Open for Work status
- Click Expand CV
- Click Verify next to any section (School, Skills, Experience)
- Watch the on-chain verification run
- See green checkmark ✓ with "Verified on Midnight Network"
- Open
/talent/auth→ Connect Lace Wallet - Fill in personal info → Click Next
- Fill in education → Click Generate School Proof → watch ZK animation → Next
- Fill in experience → Click Generate Experience Proof → Next
- Add skills → Click Generate Skills Proof → Next
- Skip certifications → Next
- Add hobbies → Next
- Review summary → Click Save CV & Go Live
- Copy the contract address from the modal
- Toggle Open for Work to ON → Save
- Open new browser tab or incognito →
/recruiter/auth→ Connect Lace Wallet - Fill in company onboarding form
- Go to Talent Marketplace
- See the talent you just created (filtered by Open for Work)
- Click Expand CV
- Click Verify on School → see "Verified on Midnight Network" ✓
- Click I Want to Hire This Person
- Go to Saved Candidates → Send interview link
- Mark as Hired → Check Hired Talent page
- Go to
/talent/interviews→ see the company and Calendly link - Go to
/talent/hired→ see hired status
File: contracts/proof-hire.compact
| Circuit | Description |
|---|---|
submitSchoolProof() |
Generates and stores education commitment |
submitSkillsProof() |
Generates and stores skills commitment |
submitExperienceProof() |
Generates and stores experience commitment |
submitCertificationsProof() |
Generates and stores certifications commitment |
saveCV() |
Sets CV status to LIVE (requires all proofs) |
verifySchoolProof(commitment) |
Returns Boolean — on-chain verification |
verifySkillsProof(commitment) |
Returns Boolean — on-chain verification |
verifyExperienceProof(commitment) |
Returns Boolean — on-chain verification |
verifyCertificationsProof(commitment) |
Returns Boolean — on-chain verification |
clearProfile() |
Resets all proof state |
| Service | Endpoint |
|---|---|
| Node RPC | https://rpc.preview.midnight.network |
| Indexer | https://indexer.preview.midnight.network/api/v3/graphql |
| Proof Server | https://proof-server.preview.midnight.network |
| Faucet | https://faucet.preview.midnight.network |
proofhire/
├── app/
│ ├── page.tsx # Landing page
│ ├── talent/
│ │ ├── auth/page.tsx # Talent login
│ │ ├── onboarding/page.tsx # Multi-step CV form + ZKP
│ │ ├── dashboard/page.tsx # Talent dashboard
│ │ ├── profile/page.tsx # Edit CV
│ │ ├── proofs/page.tsx # View ZK proofs
│ │ ├── contracts/page.tsx # Deployed contracts
│ │ ├── interviews/page.tsx # Interview requests
│ │ ├── hired/page.tsx # Hired status
│ │ └── settings/page.tsx # Wallet + account
│ └── recruiter/
│ ├── auth/page.tsx # Recruiter login
│ ├── onboarding/page.tsx # Company setup
│ ├── dashboard/page.tsx # Recruiter dashboard
│ ├── marketplace/page.tsx # Talent marketplace + verify
│ ├── candidates/page.tsx # Saved candidates
│ ├── hired/page.tsx # Hired talent
│ ├── team/page.tsx # Team access
│ └── settings/page.tsx # Company settings
├── components/
│ ├── WalletConnect.tsx # Lace wallet integration
│ ├── TalentSidebar.tsx
│ ├── RecruiterSidebar.tsx
│ ├── ContractModal.tsx # Contract address modal
│ └── RecruiterPages.tsx # Shared recruiter pages
├── lib/
│ ├── types.ts # TypeScript types
│ ├── storage.ts # localStorage utilities
│ └── midnight-utils.ts # ZKP + wallet utilities
└── contracts/
└── proof-hire.compact # Midnight smart contract
Talent fills CV form
↓
Data stays in browser memory only
↓
ZK proof generated locally per section
↓
Only commitment hash goes to Midnight chain via disclose()
↓
Contract deployed → address shared with recruiter
↓
Recruiter calls verifyXProof(commitment) on chain
↓
Circuit returns true/false — zero raw data exposed