ERC-7579 modules that plug Semaphore’s anonymous group proofs into ERC-4337 modular smart accounts—so members can co-author transactions without revealing which member approved each action on-chain.
- Demo website (connect on Base Sepolia)
- Demo video
- Project write-up
Two complementary ERC-7579 modules (see validators and executors) backed by Semaphore:
| Module | Role |
|---|---|
| SemaphoreValidator | Validates UserOperation signatures (EdDSA + identity commitment in the account’s Semaphore group). Restricts calls so the account can only drive the paired executor’s API surface. |
| SemaphoreExecutor | Holds per-account state (group, threshold, pending txs, collected proofs). Exposes initiateTx → signTx → executeTx so proofs act like threshold “signatures” while preserving member privacy. |
Together they give a smart account anonymous threshold control: only group members can advance state, proofs are unique per signal (no replay as the same “vote”), and calldata does not deanonymize the prover.
Project code: FY24-1847 · Development supported by the PSE Acceleration Program (discussion).
High-level data flow from a developer-built client through account abstraction to Semaphore on-chain.
sequenceDiagram
autonumber
actor App as Wallet or demo dApp
participant Lib as @semaphore-msa-modules/lib
participant ZK as Off-chain ZK prover
participant SA as Smart account
participant Val as SemaphoreValidator
participant Ex as SemaphoreExecutor
participant Sem as Semaphore contracts
App->>Lib: Install modules, encode calls, build user ops
Note over App,Sem: Anonymous threshold flow — each step is usually its own UserOperation
App->>ZK: Identity + signal, proof for initiateTx
ZK-->>App: Proof bytes
App->>SA: initiateTx UserOperation (validate + execute)
SA->>Val: validateUserOp
Val->>Ex: Restrict to paired executor API
SA->>Ex: initiateTx
Ex->>Sem: Verify proof, nullifier, store pending tx (1st proof)
Note over App,Sem: signTx UserOperation
loop Until collected proofs >= M-of-N threshold
App->>ZK: Proof for same txHash / signal
ZK-->>App: Proof bytes
App->>SA: signTx UserOperation (validate + execute)
SA->>Val: validateUserOp
Val->>Ex: Restrict to paired executor API
SA->>Ex: signTx
Ex->>Sem: Verify proof, nullifier, increment count
end
Note over App,Sem: executeTx UserOperation
App->>SA: executeTx UserOperation (validate + execute)
SA->>Val: validateUserOp
Val->>Ex: Restrict to paired executor API
SA->>Ex: executeTx
Ex->>Sem: Final checks, then run the pending external call
How to read it: clients use the library (with Rhinestone Module SDK and viem under the hood) to install modules, encode calls, and assemble user ops; an off-chain prover produces Semaphore proofs; each UserOperation is validated and executed on the smart account (in a full ERC-4337 stack, EntryPoint orchestrates this via handleOps, often through a bundler, with an optional paymaster); the validator checks the user-op path and signature; the executor runs initiateTx (first proof, pending tx), then signTx in a loop until the account’s M-of-N threshold is met, then executeTx when proofs are sufficient (or earlier if execute is set so the contract auto-runs executeTx once the threshold is reached).
Pick this stack when you are not satisfied with a plain on-chain multisig that reveals approvers, but you still want account abstraction (gas sponsorship, batched ops, smart accounts) and modular validation per ERC-7579.
| If you are building… | Why integrate |
|---|---|
| Modular smart account products (wallets, DAO tooling, team treasuries) | Add a privacy-preserving threshold policy: M-of-N control without exposing which key approved each transaction. |
| dApps that already use Semaphore | Reuse groups and proofs as the authorization layer for a 4337 smart account instead of only for app-specific claims. |
| Rhinestone / Module SDK workflows | The published package exposes getSemaphoreExecutor and getSemaphoreValidator module descriptors compatible with @rhinestone/module-sdk, so you can treat these modules like other installable validators and executors. |
| Research and education | End-to-end reference: Foundry tests (FFI + proofs), a Next.js demo, and Dockerized Alto + paymaster for local experimentation. |
You will touch Solidity if you fork or redeploy the modules, TypeScript for proofs and user-ops (viem, Semaphore protocol packages), and 4337 infrastructure (bundler RPC, optional paymaster) for production UX.
| Package | Description |
|---|---|
packages/contracts |
Foundry contracts: SemaphoreValidator, SemaphoreExecutor, tests, deployment scripts. Includes Base Sepolia deployment addresses in its README. |
packages/lib |
@semaphore-msa-modules/lib: module installation helpers, ABIs, and transaction helpers built on viem and Rhinestone Module SDK. |
packages/web |
Next.js demo UI for installing modules, managing identities, and sending demo transactions. |
docker-containers |
Docker Compose: forked Anvil, Alto bundler, mock paymaster—used by pnpm dev at the workspace root. |
Requirements: Node ≥ 22, pnpm (see root package.json for the pinned version).
Common commands:
pnpm install
pnpm dev # Docker stack + package dev servers
pnpm ci-check # build, test, lint across packagesSource: ERC-4337 documentation
- ERC-4337 — overview
- ERC-7579 — overview
- ERC-7780 (stateless validator hooks used by the validator module—see contracts README)
Thanks to everyone who shaped and supported this work:
- Saleel P for the original impetus with Semaphore Wallet and showing the approach was viable.
- Cedoor and Vivian Plasencia for Semaphore guidance.
- John Guilding for discussion, support, and review.
- The Rhinestone team and Konrad Kopp for ModuleKit, Module SDK, and ERC-7579 foundations this repo builds on.