|
1 | 1 | # Semaphore Modular Smart Account Modules |
2 | 2 |
|
3 | | -## Project Artifacts |
| 3 | +**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. |
4 | 4 |
|
5 | | -- 🌐 [Project demo website](https://semaphore-msa-modules.jimmychu0807.hk/) (please connect to Base Sepolia) |
6 | | -- 🎥 [Project demo video](https://www.loom.com/share/0b800171a4f1491f9eedd4f555569e37?sid=0c2d3024-5652-499e-b374-218023da581b) |
7 | | -- 📜 [Project writeup](https://jimmychu0807.hk/semaphore-msa-modules) |
| 5 | +## Try it |
8 | 6 |
|
9 | | -## Overview |
| 7 | +- [Demo website](https://semaphore-msa-modules.jimmychu0807.hk/) (connect on **Base Sepolia**) |
| 8 | +- [Demo video](https://www.loom.com/share/0b800171a4f1491f9eedd4f555569e37?sid=0c2d3024-5652-499e-b374-218023da581b) |
| 9 | +- [Project write-up](https://jimmychu0807.hk/semaphore-msa-modules) |
10 | 10 |
|
11 | | -This project mainly consists of [a validator and an executor modules](https://eips.ethereum.org/EIPS/eip-7579#validators) adheres to [**ERC-7579**](https://eips.ethereum.org/EIPS/eip-7579) standard that uses [Semaphore](https://semaphore.pse.dev/) for proof validation. Smart accounts incorporate these modules gain the following benefits: |
| 11 | +## What this repo delivers |
12 | 12 |
|
13 | | -- The smart account behaves like an **anonymous multi-sig wallet** controlled by [Semaphore group members](https://docs.semaphore.pse.dev/guides/groups) of the smart account. Proofs sent by the members are regarded as signatures. |
| 13 | +Two complementary [ERC-7579](https://eips.ethereum.org/EIPS/eip-7579) modules (see [validators and executors](https://eips.ethereum.org/EIPS/eip-7579#validators)) backed by [Semaphore](https://semaphore.pse.dev/): |
14 | 14 |
|
15 | | -- The smart account gains Semaphore property guaranteeing a valid proof (seen as signature) must be from a member within the group and have not signed before, while preserving the member privacy and no one could trace who send the proof from the on-chain log. |
| 15 | +| Module | Role | |
| 16 | +|--------|------| |
| 17 | +| **SemaphoreValidator** | Validates `UserOperation` signatures (EdDSA + identity commitment in the account’s Semaphore [group](https://docs.semaphore.pse.dev/guides/groups)). Restricts calls so the account can only drive the paired executor’s API surface. | |
| 18 | +| **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. | |
16 | 19 |
|
17 | | -Development of this project is supported by [PSE Acceleration Program](https://github.com/privacy-scaling-explorations/acceleration-program) (see [thread discussion](https://github.com/privacy-scaling-explorations/acceleration-program/issues/72)). |
| 20 | +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. |
18 | 21 |
|
19 | | -Project Code: FY24-1847 |
| 22 | +**Project code:** FY24-1847 · Development supported by the [PSE Acceleration Program](https://github.com/privacy-scaling-explorations/acceleration-program) ([discussion](https://github.com/privacy-scaling-explorations/acceleration-program/issues/72)). |
20 | 23 |
|
21 | | -Please refer to the project packages READMEs: |
22 | | -- [packages/contracts](./packages/contracts): Smart contracts of the Semaphore validator and executor module. |
23 | | -- [packages/lib](./packages/lib): Javascript library for interacting with Semaphore modular smart account modules. |
24 | | -- [packages/web](./packages/web): Frontend demo to interact with a smart account and semaphore MSA modules. |
| 24 | +## Architecture |
25 | 25 |
|
26 | | -## Relevant Information |
| 26 | +High-level data flow from a developer-built client through account abstraction to Semaphore on-chain. |
27 | 27 |
|
28 | | - |
| 28 | +```mermaid |
| 29 | +sequenceDiagram |
29 | 30 |
|
30 | | -*Source: [ERC-4337 website](https://www.erc4337.io/docs/understanding-ERC-4337/architecture)* |
| 31 | + autonumber |
| 32 | + actor App as Wallet or demo dApp |
| 33 | + participant Lib as @semaphore-msa-modules/lib |
| 34 | + participant ZK as Off-chain ZK prover |
| 35 | + participant SA as Smart account |
| 36 | + participant Val as SemaphoreValidator |
| 37 | + participant Ex as SemaphoreExecutor |
| 38 | + participant Sem as Semaphore contracts |
31 | 39 |
|
32 | | -- [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337): [overview](https://www.erc4337.io/) |
33 | | -- [ERC-7579](https://eips.ethereum.org/EIPS/eip-7579): [overview](https://erc7579.com/) |
34 | | -- [ERC-7780](https://eips.ethereum.org/EIPS/eip-7780) |
| 40 | + App->>Lib: Install modules, encode calls, build user ops |
35 | 41 |
|
36 | | -## Acknowledgement |
| 42 | + Note over App,Sem: Anonymous threshold flow — each step is usually its own UserOperation |
37 | 43 |
|
38 | | -Thanks to the following folks on discussing about this project and helps along: |
| 44 | + App->>ZK: Identity + signal, proof for initiateTx |
| 45 | + ZK-->>App: Proof bytes |
| 46 | + App->>SA: initiateTx UserOperation (validate + execute) |
| 47 | + SA->>Val: validateUserOp |
| 48 | + Val->>Ex: Restrict to paired executor API |
| 49 | + SA->>Ex: initiateTx |
| 50 | + Ex->>Sem: Verify proof, nullifier, store pending tx (1st proof) |
39 | 51 |
|
40 | | -- [Saleel P](https://github.com/saleel) on initiating this idea with [Semaphore Wallet](https://github.com/saleel/semaphore-wallet), showing me that the idea is feasible. |
41 | | -- [Cedoor](https://github.com/cedoor) and [Vivian Plasencia](https://github.com/vplasencia) on Semaphore development and their opinions. |
42 | | -- [John Guilding](https://github.com/JohnGuilding) on the discussion, support, and review of the project. |
43 | | -- [Rhinestone team](https://rhinestone.wtf/) and [Konrad Kopp](https://github.com/kopy-kat) support on using [ModuleKit](https://docs.rhinestone.wtf/build-modules), [ModuleSDK](https://docs.rhinestone.wtf/build-modules) and their work on ERC-7579 that make this project possible, from which I have learned a lot. |
| 52 | + Note over App,Sem: signTx UserOperation |
| 53 | +
|
| 54 | + loop Until collected proofs >= M-of-N threshold |
| 55 | + App->>ZK: Proof for same txHash / signal |
| 56 | + ZK-->>App: Proof bytes |
| 57 | + App->>SA: signTx UserOperation (validate + execute) |
| 58 | + SA->>Val: validateUserOp |
| 59 | + Val->>Ex: Restrict to paired executor API |
| 60 | + SA->>Ex: signTx |
| 61 | + Ex->>Sem: Verify proof, nullifier, increment count |
| 62 | + end |
| 63 | +
|
| 64 | + Note over App,Sem: executeTx UserOperation |
| 65 | + App->>SA: executeTx UserOperation (validate + execute) |
| 66 | + SA->>Val: validateUserOp |
| 67 | + Val->>Ex: Restrict to paired executor API |
| 68 | + SA->>Ex: executeTx |
| 69 | + Ex->>Sem: Final checks, then run the pending external call |
| 70 | +``` |
| 71 | + |
| 72 | +**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). |
| 73 | + |
| 74 | +## Who should integrate this? |
| 75 | + |
| 76 | +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](https://eips.ethereum.org/EIPS/eip-7579). |
| 77 | + |
| 78 | +| If you are building… | Why integrate | |
| 79 | +|----------------------|----------------| |
| 80 | +| **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. | |
| 81 | +| **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. | |
| 82 | +| **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. | |
| 83 | +| **Research and education** | End-to-end reference: Foundry tests (FFI + proofs), a **Next.js** demo, and Dockerized **Alto** + paymaster for local experimentation. | |
| 84 | + |
| 85 | +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. |
| 86 | + |
| 87 | +## Monorepo layout |
| 88 | + |
| 89 | +| Package | Description | |
| 90 | +|---------|-------------| |
| 91 | +| [`packages/contracts`](./packages/contracts) | **Foundry** contracts: `SemaphoreValidator`, `SemaphoreExecutor`, tests, deployment scripts. Includes **Base Sepolia** deployment addresses in its README. | |
| 92 | +| [`packages/lib`](./packages/lib) | **`@semaphore-msa-modules/lib`**: module installation helpers, ABIs, and transaction helpers built on **viem** and **Rhinestone Module SDK**. | |
| 93 | +| [`packages/web`](./packages/web) | **Next.js** demo UI for installing modules, managing identities, and sending demo transactions. | |
| 94 | +| [`docker-containers`](./docker-containers) | **Docker Compose**: forked **Anvil**, **Alto** bundler, mock paymaster—used by `pnpm dev` at the workspace root. | |
| 95 | + |
| 96 | +**Requirements:** Node **≥ 22**, **pnpm** (see root `package.json` for the pinned version). |
| 97 | + |
| 98 | +**Common commands:** |
| 99 | + |
| 100 | +```bash |
| 101 | +pnpm install |
| 102 | +pnpm dev # Docker stack + package dev servers |
| 103 | +pnpm ci-check # build, test, lint across packages |
| 104 | +``` |
| 105 | + |
| 106 | +## Standards and further reading |
| 107 | + |
| 108 | + |
| 109 | + |
| 110 | +*Source: [ERC-4337 documentation](https://www.erc4337.io/docs/understanding-ERC-4337/architecture)* |
| 111 | + |
| 112 | +- [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) — [overview](https://www.erc4337.io/) |
| 113 | +- [ERC-7579](https://eips.ethereum.org/EIPS/eip-7579) — [overview](https://erc7579.com/) |
| 114 | +- [ERC-7780](https://eips.ethereum.org/EIPS/eip-7780) (stateless validator hooks used by the validator module—see contracts README) |
| 115 | + |
| 116 | +## Acknowledgements |
| 117 | + |
| 118 | +Thanks to everyone who shaped and supported this work: |
| 119 | + |
| 120 | +- [Saleel P](https://github.com/saleel) for the original impetus with [Semaphore Wallet](https://github.com/saleel/semaphore-wallet) and showing the approach was viable. |
| 121 | +- [Cedoor](https://github.com/cedoor) and [Vivian Plasencia](https://github.com/vplasencia) for Semaphore guidance. |
| 122 | +- [John Guilding](https://github.com/JohnGuilding) for discussion, support, and review. |
| 123 | +- The [Rhinestone](https://rhinestone.wtf/) team and [Konrad Kopp](https://github.com/kopy-kat) for [ModuleKit](https://docs.rhinestone.wtf/build-modules), [Module SDK](https://docs.rhinestone.wtf/build-modules), and ERC-7579 foundations this repo builds on. |
0 commit comments