This is a submission for the Midnight Network "Privacy First" Challenge - Protect That Data prompt
What I Built
Midnight Whistleblower is a privacy-first DApp that reimagines secure reporting. Imagine needing to report something sensitive (corruption, safety violations, or misconduct) but fearing retaliation. Traditional systems force you to choose: stay silent or risk exposure. Midnight Whistleblower breaks this dilemma.
The Magic โจ
Our platform combines three powerful privacy technologies:
- Zero-Knowledge Proofs: Prove you're authorized to report without revealing who you are
- Rate-Limit Nullifiers (RLN): Prevent spam while maintaining complete anonymity
- End-to-End Encryption: Only the designated moderator can decrypt reports, not even our servers can read them
The Journey Through Every Page ๐บ๏ธ
๐  Home Page: Your gateway to anonymous truth

- Clean, minimalist design that doesn't intimidate
- Two clear paths: "I need to report something" or "I'm a moderator"
- Privacy promise front and center: "Your identity is mathematically protected"
๐ Submit Report (Reporter Page): Where courage meets cryptography

- Step 1: Trust Setup. Paste the moderator's public key (like choosing who gets to read your sealed letter)
- Step 2: Your Story. Write your report with confidence. Add evidence. Every keystroke stays local until encrypted
- 
Step 3: The Magic Moment. Click submit and watch as:
- Your browser generates a ZK proof (proving you can submit without saying who you are)
- Content gets encrypted with military-grade AES-GCM
- A unique nullifier prevents double-submission this epoch
- You get a mock transaction hash (no real money involved, per challenge rules)
 
๐ Moderator Dashboard: The trusted guardian's toolkit

- Key Vault: Generate, import, or export your cryptographic keys with password protection
- Encrypted Inbox: See reports as mysterious locked boxes until you decrypt them
- Proof Verification: Each report's ZK proof is verified before you can decrypt
- Workflow Management: Mark as reviewed or archive (stats update instantly)
- The Trust Model: Your private key never leaves your browser. Ever.
๐ Metrics Page: Understanding the flow of truth

- Real-time counts: pending, reviewed, archived
- Trend visualization over time
- Helps moderators manage workload and spot patterns
- All derived from encrypted data. no content exposure
๐ Public Stats: Transparency without compromise

- Shows aggregate numbers to build public trust
- "147 reports submitted, 89% reviewed"
- No identifying information, just accountability metrics
โ๏ธ Settings: Your control center

- 
Cloud Sync Toggle: One switch, no complexity
- OFF = Pure local mode, your data never leaves your device
- ON = Encrypted sync via Vercel KV for multi-device access
 
- Smart Contract Mode: Enabled by default (mocked for the challenge)
- Advanced Options: Hidden unless you need them. we respect your cognitive load
๐ก๏ธ Privacy Page: Our promises, explained

- Plain English explanation of our cryptography
- What we store (ciphertext), what we don't (your identity)
- How RLN works without a PhD in mathematics
- Your rights and our commitments
Demo
- ๐ GitHub Repository: https://github.com/depapp/midnight-whistleblower
- ๐ Live Demo: https://midnight-whistleblower.vercel.app
Architecture Overview
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ                    USER BROWSER                         โ
โ  โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ    โ
โ  โ   React App + MidnightJS + Web Crypto API       โ    โ
โ  โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ    โ
โ                           โ                             โ
โ        โโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโ          โ
โ        โผ                  โผ                  โผ          โ
โ  โโโโโโโโโโโโ      โโโโโโโโโโโโ      โโโโโโโโโโโโ       โ
โ  โZK Proofs โ      โEncryptionโ      โ   RLN    โ       โ
โ  โ(Groth16) โ      โ(AES-GCM) โ      โNullifiersโ       โ
โ  โโโโโโโโโโโโ      โโโโโโโโโโโโ      โโโโโโโโโโโโ       โ
โ                           โ                             โ
โ                    โโโโโโโโผโโโโโโโ                      โ
โ                    โ  IndexedDB  โ                      โ
โ                    โ(Local First)โ                      โ
โ                    โโโโโโโโฌโโโโโโโ                      โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
                            โ (Optional)
                    โโโโโโโโโผโโโโโโโโโ
                    โ  Vercel KV     โ
                    โ(Encrypted Only)โ
                    โโโโโโโโโโโโโโโโโโ
How I Used Midnight's Technology
  
  
  ๐ฎ The Compact Circuit (circuits/membership_rln.compact)
// Simplified view of our RLN circuit
circuit MembershipRLN {
    // Public inputs
    merkleRoot: Field
    epoch: Field
    nullifier: Field
    signalHash: Field
    // Private inputs (never revealed!)
    identitySecret: Field
    merklePath: Field[20]
    // The magic: prove membership without revealing identity
    assert(verifyMerkleProof(identitySecret, merklePath) == merkleRoot)
    assert(hash(identitySecret, epoch) == nullifier)
}
๐ฏ MidnightJS Integration
Our src/lib/midnightjs.ts orchestrates the privacy symphony:
// Load compiled artifacts (proving key, verification key, WASM)
const artifacts = await ArtifactLoader.loadArtifacts('membership_rln');
// Generate proof (happens in reporter's browser)
const proof = await midnightJS.generateProof('membership_rln', {
    merkleRoot: organizationRoot,
    epoch: currentEpoch,
    identitySecret: userSecret,  // Never leaves the browser!
    merklePath: membershipPath
});
// Verify proof (happens in moderator's browser)
const isValid = await midnightJS.verifyProof('membership_rln', proof);
๐ The Development Experience
We built a two-speed system:
- Production Mode: Real ZK proofs using compiled Midnight artifacts
- 
Dev Mode: Lightning-fast stubs for rapid iteration (VITE_USE_REAL_MIDNIGHT=false)
This means you can develop the UX at full speed, then switch to real proofs for testing.
Data Protection as a Core Feature
๐ The Privacy Stack
Layer 1: Anonymous Identity
- ZK membership proofs let you prove "I'm allowed to submit" without revealing who you are
- Like showing you have a valid ticket without showing your name
Layer 2: Anti-Spam Without Tracking
- RLN nullifiers prevent multiple submissions per day
- The clever part: we can detect duplicates without knowing who submitted them
- Nullifier = Hash(YourSecret + Today'sDate)
Layer 3: End-to-End Encryption
// In the reporter's browser
const encrypted = await encryptMessage(reportContent, moderatorPublicKey);
// Now it's gibberish to everyone except the moderator
// In the moderator's browser (and nowhere else!)
const decrypted = await decryptMessage(encrypted, moderatorPrivateKey);
// The report is revealed, but the identity remains hidden
Layer 4: Local-First Architecture
- Your data lives in IndexedDB by default
- Cloud sync is optional and only moves ciphertext
- You own your data, we just help move it
๐ก๏ธ What Makes This Different
Traditional whistleblower systems:
- โ "Trust us, we'll protect your identity" (trust-based)
- โ "Use Tor and hope for the best" (network-based)
- โ "Create a throwaway email" (weak pseudonymity)
Midnight Whistleblower:
- โ Mathematical proof of anonymity (ZK-based)
- โ Encryption at rest and in transit (cryptography-based)
- โ No correlation possible across submissions (nullifier-based)
- โ Works even if our servers are compromised (client-based)
Set Up Instructions / Tutorial
๐ฏ Quick Start (5 minutes)
Prerequisites: Node.js 18+, Git
# 1. Clone the repository
git clone https://github.com/depapp/midnight-whistleblower.git
cd midnight-whistleblower
# 2. Install dependencies
npm install
# 3. Compile the Midnight circuits (this is the magic!)
npm run compile-circuits
# 4. Start the development server
npm run dev
# 5. Open http://localhost:5173
๐ญ Playing Both Roles (Tutorial Mode)
Act 1: Become the Moderator
- Navigate to /moderator
- Click "Generate New Key Pair"
- Copy your public key (this is what reporters need)
- Optional: Export your keys with a password for backup
Act 2: Submit a Report
- Open a new incognito window (for the full experience)
- Go to /submit
- Paste the moderator's public key
- Write your report: "The coffee machine is plotting against us"
- Attach evidence (optional): photo_of_suspicious_coffee_machine.jpg
- Click Submit and watch the magic:
- Console shows: [MidnightJS] Generating proof...
- Progress bar indicates encryption
- You get a transaction hash (mock)
 
- Console shows: 
Act 3: Moderate the Report
- Return to the moderator dashboard
- See your encrypted report (looks like gibberish)
- Click to decrypt (proof is verified first)
- Read the shocking coffee machine revelation
- Mark as "Reviewed" and watch the stats update
๐ Production Deployment (10 minutes)
Deploy to Vercel with Cloud Sync:
# 1. Install Vercel CLI
npm i -g vercel
# 2. Deploy (follow prompts)
vercel
# 3. Add KV Storage in Vercel Dashboard
# Project Settings โ Storage โ Create Database โ KV
# 4. Environment variables are auto-configured!
In your deployed app:
- Go to Settings
- Toggle "Cloud Sync" ON
- That's it! Multi-device sync with zero configuration
๐ง Advanced Configuration
Development Modes:
# Fast iteration mode (stub proofs)
VITE_USE_REAL_MIDNIGHT=false npm run dev
# Disable mock contract
VITE_USE_CONTRACT=false npm run dev
# Custom sync endpoint (for self-hosting)
VITE_SYNC_BASE_URL=https://your-api.com npm run dev
Circuit Customization:
// Modify circuits/membership_rln.compact
// Recompile with: npm run compile-circuits
// New artifacts are auto-loaded!
๐ Troubleshooting Guide
| Problem | Solution | 
|---|---|
| "Artifacts not found" | Run npm run compile-circuits | 
| "Proof generation failed" | Check browser console for [MidnightJS]logs | 
| "Can't decrypt report" | Verify you're using the correct private key | 
| "Stats not updating" | Wait 500ms for cloud sync, then refresh | 
| "CORS errors in dev" | Use VITE_SYNC_BASE_URLfor cross-origin | 
๐ Learning Resources
Understand the Code:
- 
src/lib/midnightjs.ts- See how ZK proofs work
- 
src/lib/encryption.ts- Learn Web Crypto API patterns
- 
src/pages/ReporterPage.tsx- Follow the submission flow
- ARCHITECTURE.md - Deep dive into system design
The Vision ๐
Imagine a world where:
- Employees can report harassment without fear
- Citizens can expose corruption safely
- Students can report bullying anonymously
- Journalists' sources are mathematically protected
Midnight Whistleblower isn't just a demo, it's a blueprint for privacy-respecting applications that can change the world.
 
 
              

 
    
Top comments (1)
Great job!! congrats..