Pseudonymous, NFT-gated Discord discussions using Semaphore proofs
Disphorea is a privacy-preserving feedback board that lets NFT holders post anonymously while still proving they belong to a group. It integrates Semaphore for zero-knowledge membership proofs and uses an epoch-scoped external nullifier so each identity can post at most once per epoch (with a brief boundary grace).
The monorepo includes: • Next.js web app for wallet connect, proof generation, and posting. • Solidity contracts (Hardhat): a minimal Feedback contract wired to Semaphore and a Basic ERC-721 used for membership gating. • Express server that verifies join signatures, checks on-chain NFT ownership, relays transactions, stores posts in SQLite, and can broadcast to Discord.
The result is a gas-friendly, NFT-gated, pseudonymous board with on-chain verification and a clean developer flow: client proof → server relay → on-chain validation → optional Discord notification.
•	Contracts: Hardhat workspace with a Feedback contract that calls Semaphore. Posts are rate-limited by an epoch-derived external nullifier (keccak256(boardSalt, epoch)), preventing double posts without revealing identity. A BasicNFT gates membership; holders can self-join, and an owner key can relayer-join for gasless UX.
•	Server: Express + viem talks to a local Hardhat node, verifies signed join challenges and on-chain NFT balances, relays sendFeedback, persists posts in better-sqlite3, and optionally notifies a channel via discord.js.
•	Frontend: Next.js (Semaphore boilerplate foundation) loads copied proving artifacts from @zk-kit/semaphore-artifacts, builds proofs client-side, and hits the API for relay.
•	Testing: E2E flows run against a live Hardhat node; tests hop epochs with evm_increaseTime to assert nullifier reuse fails and next-epoch posts succeed.
•	What’s hacky/cool: Epoch-scoped ENs give “once per window” posting without user accounts; the relayer path enables gasless joins while keeping membership private and verifiable.

