Compare commits
147 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d99c5644c9 | ||
|
|
1dc597a175 | ||
|
|
b55bf7fd4d | ||
|
|
496e18ecab | ||
|
|
d4fb23a7af | ||
|
|
411667f5c7 | ||
|
|
87709224a3 | ||
|
|
0e20c6884f | ||
|
|
e1e893004d | ||
|
|
2e6bef51d4 | ||
|
|
9e7b2900cf | ||
|
|
cd02f49173 | ||
|
|
a8787bd1fc | ||
|
|
2c6f7846d7 | ||
|
|
8c359ad594 | ||
|
|
7ccb14d362 | ||
|
|
7e60446268 | ||
|
|
5dcba7fb2e | ||
|
|
0394caf2f7 | ||
|
|
820f34ac90 | ||
|
|
81dbf8631c | ||
|
|
4e084b0589 | ||
|
|
210fed4a50 | ||
|
|
53f41879d1 | ||
|
|
4089bbedc7 | ||
|
|
6a2b28c34e | ||
|
|
dce9813c8e | ||
|
|
aba32d83b1 | ||
|
|
520a02698f | ||
|
|
128cbcee13 | ||
|
|
a224f95d77 | ||
|
|
bb089c5544 | ||
|
|
88004d9092 | ||
|
|
e7ca1d9487 | ||
|
|
1b82dcdded | ||
|
|
cd04b0c5c7 | ||
|
|
b6a7a9883b | ||
|
|
fc1fe4d086 | ||
|
|
feb8c9c97d | ||
|
|
b56e9690a8 | ||
|
|
c973bab503 | ||
|
|
27aee4bf43 | ||
|
|
ea62310df6 | ||
|
|
6bc415f4d5 | ||
|
|
18f77ac0bb | ||
|
|
f3c4cf27e2 | ||
|
|
57132a38df | ||
|
|
6ef16976f7 | ||
|
|
2849ca1d24 | ||
|
|
d05d783852 | ||
|
|
993e46a427 | ||
|
|
f984c1e864 | ||
|
|
5c9d1737d3 | ||
|
|
1318b0e74b | ||
|
|
c0fcc94e82 | ||
|
|
e70ae1151b | ||
|
|
fd38539908 | ||
|
|
8bd45d8c46 | ||
|
|
534e69683a | ||
|
|
a0a3b9380b | ||
|
|
bc9f7df1da | ||
|
|
571ffdab0e | ||
|
|
773696f40c | ||
|
|
f679583498 | ||
|
|
05926d0ef7 | ||
|
|
eef277281d | ||
|
|
b96467f3d4 | ||
|
|
e530412f27 | ||
|
|
4df7693367 | ||
|
|
0ca80ca716 | ||
|
|
ed8141e873 | ||
|
|
0f4aca3ded | ||
|
|
6e2ef756bc | ||
|
|
c2dce437b4 | ||
|
|
8b91d75c6f | ||
|
|
abfcf9f006 | ||
|
|
a2e8f5a15c | ||
|
|
f77df8d98f | ||
|
|
2b9fde2676 | ||
|
|
ac4ddfc6eb | ||
|
|
afae06e8e1 | ||
|
|
4cc6980b55 | ||
|
|
6b04ec0eca | ||
|
|
13a9480165 | ||
|
|
53967a9a3c | ||
|
|
5b92c0a2bc | ||
|
|
31c776ea68 | ||
|
|
8d83d59220 | ||
|
|
9e4fb5376c | ||
|
|
745edb8e92 | ||
|
|
e732992952 | ||
|
|
3fcce15375 | ||
|
|
ebb6731d89 | ||
|
|
0c23acf9cf | ||
|
|
3e7db08eeb | ||
|
|
8adfc30da8 | ||
|
|
42639662c3 | ||
|
|
64025516c0 | ||
|
|
91f8a4be2a | ||
|
|
ebd9a27c1b | ||
|
|
bada8b8792 | ||
|
|
e93b19c566 | ||
|
|
862f715d05 | ||
|
|
3ed6c38587 | ||
|
|
7e183f3d2c | ||
|
|
901d0954c0 | ||
|
|
caebc1a4ab | ||
|
|
9b419f0c78 | ||
|
|
c67b888eb6 | ||
|
|
376cd11808 | ||
|
|
58132a9478 | ||
|
|
fadcf19206 | ||
|
|
3be17268ab | ||
|
|
82cdc60af6 | ||
|
|
6c9ede6931 | ||
|
|
e6576cdc47 | ||
|
|
c07dc88490 | ||
|
|
67060dd412 | ||
|
|
a4e540d8f4 | ||
|
|
79976f33cb | ||
|
|
822530f2cf | ||
|
|
b3f862979d | ||
|
|
06e11d5c34 | ||
|
|
88d4470b11 | ||
|
|
bb1c6984b2 | ||
|
|
5841327477 | ||
|
|
eab3ab30c6 | ||
|
|
cd6dc38f9e | ||
|
|
3cb1b5757d | ||
|
|
a8db8393c1 | ||
|
|
391b571c31 | ||
|
|
4c2769099f | ||
|
|
29cabb49d6 | ||
|
|
48b0694586 | ||
|
|
28684fdb1a | ||
|
|
49a16635d8 | ||
|
|
4bfe6d8791 | ||
|
|
a3d97795fe | ||
|
|
4c8d297902 | ||
|
|
fdbadf5b71 | ||
|
|
4496eee137 | ||
|
|
215a12e25c | ||
|
|
87331114c1 | ||
|
|
0d41562dad | ||
|
|
c435712656 | ||
|
|
7d48311474 | ||
|
|
5ef73e2819 |
@@ -26,5 +26,13 @@
|
||||
"no-console": ["warn", { "allow": ["info", "warn", "error"] }],
|
||||
"@typescript-eslint/lines-between-class-members": "off",
|
||||
"no-param-reassign": "off"
|
||||
}
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["./scripts/*"],
|
||||
"rules": {
|
||||
"no-console": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
4
.github/pull_request_template.md
vendored
@@ -29,10 +29,12 @@
|
||||
|
||||
<!-- Please check if the PR fulfills these requirements. -->
|
||||
|
||||
- [ ] My code follows the style guidelines of this project
|
||||
- [ ] I have performed a self-review of my code
|
||||
- [ ] I have commented my code, particularly in hard-to-understand areas
|
||||
- [ ] My changes generate no new warnings
|
||||
- [ ] I have run `yarn format` and `yarn lint` without getting any errors
|
||||
- [ ] I have added tests that prove my fix is effective or that my feature works
|
||||
- [ ] New and existing unit tests pass locally with my changes
|
||||
|
||||
> [!IMPORTANT]
|
||||
> We do not accept pull requests for minor grammatical fixes (e.g., correcting typos, rewording sentences) or for fixing broken links, unless they significantly improve clarity or functionality. These contributions, while appreciated, are not a priority for merging. If you notice any of these issues, please create a [GitHub Issue](https://github.com/semaphore-protocol/semaphore/issues/new?template=BLANK_ISSUE) to report them so they can be properly tracked and addressed.
|
||||
|
||||
4
.github/workflows/production.yml
vendored
@@ -34,7 +34,7 @@ jobs:
|
||||
run: yarn lint
|
||||
|
||||
test-subgraph:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04 # Context: https://github.com/graphprotocol/graph-tooling/issues/1546#issuecomment-2589680195
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -83,7 +83,7 @@ jobs:
|
||||
sudo apt-get update && sudo apt-get install -y wget nlohmann-json3-dev libgmp-dev nasm g++ build-essential
|
||||
|
||||
- name: Setup Circom
|
||||
run: wget https://github.com/iden3/circom/releases/latest/download/circom-linux-amd64 && sudo mv ./circom-linux-amd64 /usr/bin/circom && sudo chmod +x /usr/bin/circom
|
||||
run: sudo wget https://github.com/iden3/circom/releases/download/v2.1.9/circom-linux-amd64 -O /usr/bin/circom && sudo chmod +x /usr/bin/circom
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn
|
||||
|
||||
4
.github/workflows/pull-requests.yml
vendored
@@ -75,7 +75,7 @@ jobs:
|
||||
run: yarn run eslint ${{ steps.changed-files.outputs.to_lint_all_changed_files }} --ext .cjs,.js,.jsx,.ts,.tsx
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04 # Context: https://github.com/graphprotocol/graph-tooling/issues/1546#issuecomment-2589680195
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -111,7 +111,7 @@ jobs:
|
||||
run: |
|
||||
sudo rm /etc/apt/sources.list.d/microsoft-prod.list
|
||||
sudo apt-get update && sudo apt-get install -y wget nlohmann-json3-dev libgmp-dev nasm g++ build-essential
|
||||
wget https://github.com/iden3/circom/releases/latest/download/circom-linux-amd64 && sudo mv ./circom-linux-amd64 /usr/bin/circom && sudo chmod +x /usr/bin/circom
|
||||
sudo wget https://github.com/iden3/circom/releases/download/v2.1.9/circom-linux-amd64 -O /usr/bin/circom && sudo chmod +x /usr/bin/circom
|
||||
yarn workspace @semaphore-protocol/group build
|
||||
yarn workspace @semaphore-protocol/identity build
|
||||
yarn workspace @semaphore-protocol/proof build
|
||||
|
||||
12
.github/workflows/release.yml
vendored
@@ -4,6 +4,7 @@ permissions:
|
||||
contents: write
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
@@ -17,6 +18,16 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install soldeer
|
||||
uses: taiki-e/install-action@v2
|
||||
with:
|
||||
tool: soldeer
|
||||
- name: Store soldeer login credential
|
||||
env:
|
||||
SOLDEER_TOKEN: ${{ secrets.SOLDEER_TOKEN }}
|
||||
run: |
|
||||
echo "$SOLDEER_TOKEN" > "$GITHUB_WORKSPACE"/soldeer_login
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
@@ -37,6 +48,7 @@ jobs:
|
||||
run: yarn version:publish
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
SOLDEER_LOGIN_FILE: ${{ github.workspace }}/soldeer_login
|
||||
|
||||
- run: yarn version:release
|
||||
env:
|
||||
|
||||
2
.gitignore
vendored
@@ -94,3 +94,5 @@ typechain-types
|
||||
|
||||
# Other
|
||||
snark-artifacts
|
||||
|
||||
*.zip
|
||||
|
||||
1
.soldeerignore
Normal file
@@ -0,0 +1 @@
|
||||
package.json
|
||||
@@ -22,7 +22,7 @@ Pull requests are great if you want to add a feature or fix a bug. Here's a quic
|
||||
|
||||
3. Add a test for your change. Only refactoring and documentation changes require no new tests.
|
||||
|
||||
4. Make sure to check out the [Style Guide](/CONTRIBUTING#style-guide) and ensure that your code complies with the rules.
|
||||
4. Make sure to check out the [Style Guide](/CONTRIBUTING.md#style-guide) and ensure that your code complies with the rules.
|
||||
|
||||
5. Make the test pass.
|
||||
|
||||
@@ -30,6 +30,9 @@ Pull requests are great if you want to add a feature or fix a bug. Here's a quic
|
||||
|
||||
7. Push to your fork and submit a pull request on our `main` branch. Please provide us with some explanation of why you made the changes you made. For new features make sure to explain a standard use case to us.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> We do not accept pull requests for minor grammatical fixes (e.g., correcting typos, rewording sentences) or for fixing broken links, unless they significantly improve clarity or functionality. These contributions, while appreciated, are not a priority for merging. If you notice any of these issues, please create a [GitHub Issue](https://github.com/semaphore-protocol/semaphore/issues/new?template=BLANK_ISSUE) to report them so they can be properly tracked and addressed.
|
||||
|
||||
## CI (Github Actions) Tests
|
||||
|
||||
We use GitHub Actions to test each PR before it is merged.
|
||||
@@ -42,7 +45,7 @@ When you submit your PR (or later change that code), a CI build will automatical
|
||||
|
||||
We always use ESLint and Prettier. To check that your code follows the rules, simply run the npm script `yarn lint`.
|
||||
|
||||
### Commits rules
|
||||
### Commit rules
|
||||
|
||||
For commits it is recommended to use [Conventional Commits](https://www.conventionalcommits.org).
|
||||
|
||||
|
||||
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 Ethereum Foundation
|
||||
Copyright (c) 2025 Ethereum Foundation
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
34
README.md
@@ -53,7 +53,7 @@
|
||||
🔎 Issues
|
||||
</a>
|
||||
<span> | </span>
|
||||
<a href="https://semaphore.pse.dev/discord">
|
||||
<a href="https://semaphore.pse.dev/telegram">
|
||||
🗣️ Chat & Support
|
||||
</a>
|
||||
<span> | </span>
|
||||
@@ -264,7 +264,7 @@ The core of the Semaphore protocol is in the [circuit logic](/packages/circuits/
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## 🛠 Install
|
||||
@@ -275,12 +275,18 @@ Clone this repository:
|
||||
git clone https://github.com/semaphore-protocol/semaphore.git
|
||||
```
|
||||
|
||||
And install the dependencies:
|
||||
Install the dependencies:
|
||||
|
||||
```bash
|
||||
cd semaphore && yarn
|
||||
```
|
||||
|
||||
And build the repository:
|
||||
|
||||
```bash
|
||||
yarn build
|
||||
```
|
||||
|
||||
## 📜 Usage
|
||||
|
||||
Copy the `.env.example` file as `.env`:
|
||||
@@ -367,12 +373,28 @@ The output will be placed on the `docs` folder.
|
||||
|
||||
### Releases
|
||||
|
||||
Bump a new version with:
|
||||
Steps:
|
||||
|
||||
1. Bump a new version with:
|
||||
|
||||
```bash
|
||||
yarn version:bump <version>
|
||||
# e.g. yarn version:bump 2.0.0
|
||||
```
|
||||
|
||||
It will create a commit and a git tag that will need to pushed on the main branch. A workflow will be triggered and will
|
||||
publish the Semaphore packages on [npm](https://www.npmjs.com/) and release a new version on Github with its changelogs automatically.
|
||||
This step creates a commit and a git tag.
|
||||
|
||||
2. Push the changes to main:
|
||||
|
||||
```bash
|
||||
git push origin main
|
||||
```
|
||||
|
||||
3. Push the new git tag:
|
||||
|
||||
```bash
|
||||
git push origin <version>
|
||||
# e.g. git push origin v2.0.0
|
||||
```
|
||||
|
||||
After pushing the new git tag, a workflow will be triggered to publish the Semaphore packages on [npm](https://www.npmjs.com/) and release a new version on GitHub with its changelogs automatically.
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
🔎 Issues
|
||||
</a>
|
||||
<span> | </span>
|
||||
<a href="https://semaphore.pse.dev/discord">
|
||||
<a href="https://semaphore.pse.dev/telegram">
|
||||
🗣️ Chat & Support
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
BIN
apps/docs/assets/img-benchmarks/browser/browser-benchmarks.png
Normal file
|
After Width: | Height: | Size: 322 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 267 KiB |
|
After Width: | Height: | Size: 185 KiB |
|
After Width: | Height: | Size: 215 KiB |
|
After Width: | Height: | Size: 130 KiB |
|
After Width: | Height: | Size: 134 KiB |
|
After Width: | Height: | Size: 128 KiB |
|
After Width: | Height: | Size: 136 KiB |
|
After Width: | Height: | Size: 124 KiB |
@@ -67,7 +67,7 @@ const config: Config = {
|
||||
announcementBar: {
|
||||
id: "semaphore-v4-beta",
|
||||
content:
|
||||
'<b><a href="https://github.com/semaphore-protocol/semaphore/releases/tag/v4.0.0" target="_blank">Semaphore V4</a> is out 🎉 <a href="/getting-started">Try it out</a> and let us know if you have any feedback on <a href="https://semaphore.pse.dev/discord" target="_blank">Discord</a> or <a href="https://github.com/orgs/semaphore-protocol/discussions" target="_blank">Github</a>!</b>',
|
||||
'<b><a href="https://github.com/semaphore-protocol/semaphore/releases/tag/v4.0.0" target="_blank">Semaphore V4</a> is out 🎉 <a href="/getting-started">Try it out</a> and let us know if you have any feedback on <a href="https://semaphore.pse.dev/telegram" target="_blank">Telegram</a> or <a href="https://github.com/orgs/semaphore-protocol/discussions" target="_blank">Github</a>!</b>',
|
||||
backgroundColor: "#dde6fc",
|
||||
textColor: "#000000"
|
||||
},
|
||||
|
||||
@@ -386,12 +386,9 @@
|
||||
"message": "Connect"
|
||||
},
|
||||
"footer.right.connect.link1": {
|
||||
"message": "Discord"
|
||||
"message": "Telegram"
|
||||
},
|
||||
"footer.right.connect.link2": {
|
||||
"message": "X (Twitter)"
|
||||
},
|
||||
"footer.copyright": {
|
||||
"message": "Copyright © 2024 Ethereum Foundation"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"message": "Valores públicos"
|
||||
},
|
||||
"section.identities.box2.description": {
|
||||
"message": "Semaphore utiliza la función hash Poseidon para crear el identtity commitment a partir de los valores privados. Los identity commitments se pueden compartir públicamente, de forma similar a las direcciones Ethereum."
|
||||
"message": "Semaphore utiliza la función hash Poseidon para crear el identity commitment a partir de los valores privados. Los identity commitments se pueden compartir públicamente, de forma similar a las direcciones Ethereum."
|
||||
},
|
||||
"section.identities.box3.title": {
|
||||
"message": "Generar identidades"
|
||||
@@ -386,12 +386,9 @@
|
||||
"message": "Conecta con nosotros"
|
||||
},
|
||||
"footer.right.connect.link1": {
|
||||
"message": "Discord"
|
||||
"message": "Telegram"
|
||||
},
|
||||
"footer.right.connect.link2": {
|
||||
"message": "X (Twitter)"
|
||||
},
|
||||
"footer.copyright": {
|
||||
"message": "Copyright © 2024 Ethereum Foundation"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,6 @@ as well as relevant circuits in
|
||||
which the Semaphore zk-SNARK uses.
|
||||
|
||||
The summary of the audit results can be found
|
||||
[here](https://github.com/appliedzkp/semaphore/tree/master/audit). After three
|
||||
[here](https://github.com/semaphore-protocol/semaphore/blob/main/apps/docs/versioned_docs/version-V1/audit.md). After three
|
||||
rounds of fixes, all security and performance issues were fixed, and the few
|
||||
remaining issues are minor and do not affect security.
|
||||
|
||||
@@ -58,7 +58,7 @@ Hardhat includes the Hardhat Network, a local Ethereum network for development.
|
||||
|
||||
## Install Semaphore packages
|
||||
|
||||
Semaphore provides contracts, JavaScript libraries and an Hardhat plugin for developers building zero-knowledge applications.
|
||||
Semaphore provides contracts, JavaScript libraries and a Hardhat plugin for developers building zero-knowledge applications.
|
||||
|
||||
- `@semaphore-protocol/contracts` provides contracts to manage groups and verify Semaphore proofs on-chain.
|
||||
- JavaScript libraries help developers build zero-knowledge applications.
|
||||
|
||||
@@ -14,7 +14,7 @@ También proporciona un mecanismo simple para evitar la doble señalización, lo
|
||||
|
||||
## ¿Dónde puedo hacer preguntas sobre Semaphore?
|
||||
|
||||
Puede hacer preguntas sobre Semaphore en [Discord](https://semaphore.pse.dev/discord) o abriendo un [Semaphore Discussion](https://github.com/semaphore-protocol/semaphore/discussions).
|
||||
Puede hacer preguntas sobre Semaphore en [Telegram](https://semaphore.pse.dev/telegram) o abriendo un [Semaphore Discussion](https://github.com/semaphore-protocol/semaphore/discussions).
|
||||
|
||||
## ¿Por qué las identidades requieren tanto `identity trapdoor` como `identity nullifier`?
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ Para utilizar los contratos e interfaces Semaphore en su proyecto, instale el pa
|
||||
|
||||
Semaphore ofrece los siguientes contratos base:
|
||||
|
||||
- [`SemaphoreVerifier.sol`](https://github.com/semaphore-protocol/semaphore/blob/main/packages/contracts/base/SemaphoreVerifier.sol): contiene una función para verificar pruebas Semaphore;
|
||||
- [`SemaphoreVerifier.sol`](https://github.com/semaphore-protocol/semaphore/blob/v3.15.2/packages/contracts/contracts/base/SemaphoreVerifier.sol): contiene una función para verificar pruebas Semaphore;
|
||||
- [`SemaphoreGroups.sol`](https://github.com/semaphore-protocol/semaphore/blob/main/packages/contracts/base/SemaphoreGroups.sol): contiene las funciones para crear grupos y añadir/remover/actualizar miembros.
|
||||
|
||||
Los contratos base están relacionados de forma muy cercana al protocolo.
|
||||
|
||||
@@ -7,7 +7,7 @@ import TabItem from "@theme/TabItem"
|
||||
|
||||
# Solución de problemas
|
||||
|
||||
Si estas sugerencias no funcionan, no dude en preguntar en las [Semaphore Discussions](https://github.com/semaphore-protocol/semaphore/discussions) o en el canal `dev-chat` en el [Semaphore Discord](https://semaphore.pse.dev/discord).
|
||||
Si estas sugerencias no funcionan, no dude en preguntar en las [Semaphore Discussions](https://github.com/semaphore-protocol/semaphore/discussions) o en el canal [Semaphore Telegram](https://semaphore.pse.dev/telegram).
|
||||
|
||||
## Usando Semaphore en the frontend
|
||||
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
"format:write": "remark ./**/*.mdx --output"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.1.1",
|
||||
"@docusaurus/preset-classic": "3.1.1",
|
||||
"@docusaurus/core": "3.5.2",
|
||||
"@docusaurus/preset-classic": "3.5.2",
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"@semaphore-protocol/utils": "4.0.2",
|
||||
"@semaphore-protocol/utils": "4.14.0",
|
||||
"@svgr/webpack": "^5.5.0",
|
||||
"clsx": "^1.2.1",
|
||||
"docusaurus-plugin-sass": "^0.2.5",
|
||||
@@ -31,8 +31,8 @@
|
||||
"url-loader": "^4.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "3.1.1",
|
||||
"@docusaurus/tsconfig": "3.1.1",
|
||||
"@docusaurus/module-type-aliases": "3.5.2",
|
||||
"@docusaurus/tsconfig": "3.5.2",
|
||||
"@types/react": "^18.2.29",
|
||||
"remark-cli": "^12.0.0",
|
||||
"remark-frontmatter": "^5.0.0",
|
||||
|
||||
@@ -32,7 +32,7 @@ function Footer() {
|
||||
id: "footer.right.connect.title"
|
||||
})}
|
||||
</h3>
|
||||
<Link href="https://semaphore.pse.dev/discord" target="_blank">
|
||||
<Link href="https://semaphore.pse.dev/telegram" target="_blank">
|
||||
{translate({
|
||||
id: "footer.right.connect.link1"
|
||||
})}
|
||||
@@ -54,11 +54,7 @@ function Footer() {
|
||||
<hr />
|
||||
|
||||
<div>
|
||||
<p>
|
||||
{translate({
|
||||
id: "footer.copyright"
|
||||
})}
|
||||
</p>
|
||||
<p>Copyright © {new Date().getFullYear()} Ethereum Foundation</p>
|
||||
|
||||
<Logo
|
||||
style={{ marginRight: -8 }}
|
||||
|
||||
196
apps/docs/static/llms.txt
vendored
Normal file
@@ -0,0 +1,196 @@
|
||||
# Semaphore V4 - llms.txt
|
||||
|
||||
> Zero-knowledge protocol for anonymous group membership and signaling
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Core Concept
|
||||
Semaphore allows users to cast messages (votes, endorsements) as provable group members without revealing identity, with built-in double-signaling prevention.
|
||||
|
||||
**Key Components:**
|
||||
- **Identity**: User's cryptographic identity (private key, public key, commitment)
|
||||
- **Group**: Merkle tree of identity commitments
|
||||
- **Proof**: Zero-knowledge proof of group membership + message
|
||||
- **Nullifier**: Unique identifier preventing double-signaling
|
||||
- **Scope**: Topic/context that limits one proof per user
|
||||
|
||||
### Essential Packages
|
||||
```bash
|
||||
# Core functionality
|
||||
npm install @semaphore-protocol/core
|
||||
|
||||
# Individual packages
|
||||
npm install @semaphore-protocol/identity
|
||||
npm install @semaphore-protocol/group
|
||||
npm install @semaphore-protocol/proof
|
||||
npm install @semaphore-protocol/contracts
|
||||
```
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### 1. Identity Management
|
||||
```javascript
|
||||
import { Identity } from "@semaphore-protocol/identity"
|
||||
|
||||
// Random identity
|
||||
const identity = new Identity()
|
||||
const { privateKey, publicKey, commitment } = identity
|
||||
|
||||
// Deterministic identity (from secret)
|
||||
const deterministicIdentity = new Identity("secret-value")
|
||||
|
||||
// Sign/verify messages
|
||||
const message = "Hello World"
|
||||
const signature = identity.signMessage(message)
|
||||
const isValid = Identity.verifySignature(message, signature, identity.publicKey)
|
||||
|
||||
// Export/import
|
||||
const exported = identity.export() // base64 private key
|
||||
const imported = Identity.import(exported)
|
||||
```
|
||||
|
||||
### 2. Group Operations
|
||||
```javascript
|
||||
import { Group } from "@semaphore-protocol/group"
|
||||
|
||||
// Create group
|
||||
const group = new Group()
|
||||
const groupWithMembers = new Group([commitment1, commitment2])
|
||||
|
||||
// Manage members
|
||||
group.addMember(identity.commitment)
|
||||
group.addMembers([commitment1, commitment2])
|
||||
group.removeMember(0) // sets to 0, doesn't change size
|
||||
group.updateMember(0, newCommitment)
|
||||
|
||||
// Generate Merkle proof
|
||||
const merkleProof = group.generateMerkleProof(0)
|
||||
```
|
||||
|
||||
### 3. Proof Generation & Verification
|
||||
```javascript
|
||||
import { generateProof, verifyProof } from "@semaphore-protocol/proof"
|
||||
|
||||
// Generate proof
|
||||
const scope = group.root // or any unique scope
|
||||
const message = 1
|
||||
const proof = await generateProof(identity, group, message, scope)
|
||||
|
||||
// Verify proof
|
||||
const isValid = await verifyProof(proof)
|
||||
```
|
||||
|
||||
### 4. On-Chain Integration
|
||||
```solidity
|
||||
// Contract setup
|
||||
import "@semaphore-protocol/contracts/interfaces/ISemaphore.sol";
|
||||
|
||||
contract YourContract {
|
||||
ISemaphore public semaphore;
|
||||
uint256 public groupId;
|
||||
|
||||
constructor(ISemaphore _semaphore) {
|
||||
semaphore = _semaphore;
|
||||
groupId = semaphore.createGroup();
|
||||
}
|
||||
|
||||
// Validate proof on-chain
|
||||
function validateProof(ISemaphore.SemaphoreProof calldata proof) external {
|
||||
semaphore.validateProof(groupId, proof);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Configuration Reference
|
||||
|
||||
### Circuit Parameters
|
||||
- **MAX_DEPTH**: 1-32 (Merkle tree depth)
|
||||
- **Default proof validity**: 1 hour for old Merkle roots
|
||||
|
||||
### Key Security Settings
|
||||
- **Identity reuse warning**: Same identity across groups compromises all groups
|
||||
- **Nullifier uniqueness**: Prevents double-signaling within same scope
|
||||
- **Message tampering**: Circuit calculates dummy square to prevent tampering
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
**"Proof verification failed"**
|
||||
- Check group contains identity commitment
|
||||
- Verify scope matches between generation and verification
|
||||
- Ensure Merkle proof is current (within validity window)
|
||||
|
||||
**"Nullifier already exists"**
|
||||
- User already submitted proof with this scope
|
||||
- Use different scope or implement nullifier tracking
|
||||
|
||||
**"Identity commitment not found"**
|
||||
- Add identity to group before generating proof
|
||||
- Verify correct group is being used
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
### Circuit Structure
|
||||
The Semaphore circuit proves three things:
|
||||
1. **Membership**: User belongs to group (Merkle proof verification)
|
||||
2. **Authorization**: Same user created message and proof (nullifier check)
|
||||
3. **Message integrity**: Message hasn't been tampered with
|
||||
|
||||
### Contract Architecture
|
||||
- **SemaphoreVerifier.sol**: Groth16 proof verification
|
||||
- **SemaphoreGroups.sol**: Group management (abstract)
|
||||
- **Semaphore.sol**: Complete implementation with proof validation
|
||||
|
||||
## Extended Resources
|
||||
|
||||
### 📚 Complete Guides
|
||||
- [Getting Started Tutorial](https://docs.semaphore.pse.dev/getting-started) - Full project setup with CLI
|
||||
- [Identities Deep Dive](https://docs.semaphore.pse.dev/guides/identities) - Advanced identity management
|
||||
- [Groups Management](https://docs.semaphore.pse.dev/guides/groups) - Comprehensive group operations
|
||||
- [Proof Generation](https://docs.semaphore.pse.dev/guides/proofs) - Detailed proof workflows
|
||||
|
||||
### 🔧 Technical References
|
||||
- [Semaphore V4 Specification](https://github.com/zkspecs/zkspecs/blob/main/specs/3/README.md) - Protocol specification
|
||||
- [Circuit Documentation](https://docs.semaphore.pse.dev/technical-reference/circuits) - Circuit internals
|
||||
- [Contract Reference](https://docs.semaphore.pse.dev/technical-reference/contracts) - Solidity implementation details
|
||||
- [Deployed Contracts](https://docs.semaphore.pse.dev/deployed-contracts) - Network addresses
|
||||
|
||||
### 🛠️ Development Tools
|
||||
- [GitHub Repository](https://github.com/semaphore-protocol/semaphore) - Source code and examples
|
||||
- [CLI Templates](https://github.com/semaphore-protocol/semaphore/tree/main/packages/cli) - Project boilerplates
|
||||
- [Boilerplate App](https://github.com/semaphore-protocol/boilerplate) - Complete example application
|
||||
|
||||
### 🔐 Security & Audits
|
||||
- [Trusted Setup Ceremony](https://ceremony.pse.dev/projects/Semaphore%20V4%20Ceremony) - 400+ participants, July 2024
|
||||
- [Security Audits](https://docs.semaphore.pse.dev/#audits) - PSE and Veridise audit reports
|
||||
- [Best Practices Guide](https://docs.semaphore.pse.dev/) - Security considerations section
|
||||
|
||||
### 🌐 Community & Support
|
||||
- [Documentation](https://docs.semaphore.pse.dev/) - Complete documentation
|
||||
- [GitHub Discussions](https://github.com/semaphore-protocol/semaphore/discussions) - Community support
|
||||
- [PSE Website](https://pse.dev/) - Privacy & Scaling Explorations team
|
||||
|
||||
### 📊 Data & Indexing
|
||||
- [@semaphore-protocol/data](https://github.com/semaphore-protocol/semaphore/tree/main/packages/data) - On-chain data fetching
|
||||
- [Subgraph Templates](https://github.com/semaphore-protocol/semaphore/tree/main/packages/cli-template-monorepo-subgraph) - Graph Protocol integration
|
||||
|
||||
## Quick Start Commands
|
||||
|
||||
```bash
|
||||
# Create new project
|
||||
npx @semaphore-protocol/cli create my-app --template monorepo-ethers
|
||||
|
||||
# Get on-chain groups
|
||||
semaphore get-groups --network sepolia
|
||||
|
||||
# Deploy contract
|
||||
yarn deploy --semaphore <address> --group <id> --network sepolia
|
||||
```
|
||||
|
||||
## Use Cases
|
||||
- **Private Voting**: Anonymous ballots with double-vote prevention
|
||||
- **Whistleblowing**: Anonymous reporting with verified membership
|
||||
- **Anonymous DAOs**: Governance without identity disclosure
|
||||
- **Mixers**: Privacy-preserving value transfers
|
||||
- **Anonymous Authentication**: Prove membership without revealing identity
|
||||
@@ -12,6 +12,6 @@ as well as relevant circuits in
|
||||
which the Semaphore zk-SNARK uses.
|
||||
|
||||
The summary of the audit results can be found
|
||||
[here](https://github.com/appliedzkp/semaphore/tree/master/audit). After three
|
||||
[here](https://github.com/semaphore-protocol/semaphore/blob/main/apps/docs/versioned_docs/version-V1/audit.md). After three
|
||||
rounds of fixes, all security and performance issues were fixed, and the few
|
||||
remaining issues are minor and do not affect security.
|
||||
|
||||
@@ -21,7 +21,7 @@ The first external nullifier will be added as an external nullifier to the
|
||||
contract, and this external nullifier will be active once the deployment
|
||||
completes.
|
||||
|
||||
## Add, deactivate, or reactivate external nullifiiers
|
||||
## Add, deactivate, or reactivate external nullifiers
|
||||
|
||||
**Contract ABI**:
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ An identity is comprised of the following information:
|
||||
|
||||
1. An [EdDSA](https://en.wikipedia.org/wiki/EdDSA) private key. Note that it is
|
||||
_not_ an Ethereum private key.
|
||||
2. An identity nullifier, whih is a random 32-byte value.
|
||||
3. An identity trapdoor, whih is a random 32-byte value.
|
||||
2. An identity nullifier, which is a random 32-byte value.
|
||||
3. An identity trapdoor, which is a random 32-byte value.
|
||||
|
||||
An identity commitment is the Pedersen hash of:
|
||||
|
||||
@@ -121,7 +121,7 @@ authenticity of the signal and prevents front-running attacks.
|
||||
|
||||
## Cryptographic primitives
|
||||
|
||||
Semaphore uses MiMC for the Merkle tree, Pedersen commmitments for the identity
|
||||
Semaphore uses MiMC for the Merkle tree, Pedersen commitments for the identity
|
||||
commitments, Blake2 for the nullifiers hash, and EdDSA for the signature.
|
||||
|
||||
MiMC is a relatively new hash function. We use the recommended MiMC
|
||||
|
||||
@@ -145,7 +145,7 @@ Returns `false` otherwise.
|
||||
|
||||
**`signMsg(privKey: EddsaPrivateKey, msg: SnarkBigInt): EdDSAMiMcSpongeSignature)`**
|
||||
|
||||
Encapsualtes `circomlib.eddsa.signMiMCSponge` to sign a message `msg` using private key `privKey`.
|
||||
Encapsulates `circomlib.eddsa.signMiMCSponge` to sign a message `msg` using private key `privKey`.
|
||||
|
||||
**`verifySignature(msg: SnarkBigInt, signature: EdDSAMiMcSpongeSignature, pubKey: EddsaPublicKey)`: boolean**
|
||||
|
||||
@@ -190,7 +190,7 @@ const genWitness = async (
|
||||
- `circuit` is the output of `genCircuit()`.
|
||||
- `identity` is the `Identity` whose identity commitment you want to prove is
|
||||
in the set of registered identities.
|
||||
- `idCommitments` is an array of registered identity commmitments; i.e. the
|
||||
- `idCommitments` is an array of registered identity commitments; i.e. the
|
||||
leaves of the tree.
|
||||
- `treeDepth` is the number of levels which the Merkle tree used has
|
||||
- `externalNullifier` is the current external nullifier
|
||||
@@ -204,7 +204,7 @@ It returns an object as such:
|
||||
- `msg`: The hash of the external nullifier and the signal hash
|
||||
- `signature`: The signature on the above msg.
|
||||
- `tree`: The Merkle tree object after it has been updated with the identity commitment
|
||||
- `identityPath`: The Merkle path to the identity commmitment
|
||||
- `identityPath`: The Merkle path to the identity commitment
|
||||
- `identityPathIndex`: The leaf index of the identity commitment
|
||||
- `identityPathElements`: The elements along the above Merkle path
|
||||
|
||||
@@ -212,7 +212,7 @@ Only `witness` is essential to generate the proof; the other data is only
|
||||
useful for debugging and additional off-chain checks, such as verifying the
|
||||
signature and the Merkle tree root.
|
||||
|
||||
**`formatForVerifierContract = (proof: SnarkProof, publicSignals: SnarkPublicSignals`**
|
||||
**`formatForVerifierContract = (proof: SnarkProof, publicSignals: SnarkPublicSignals)`**
|
||||
|
||||
Converts the data in `proof` and `publicSignals` to strings and rearranges
|
||||
elements of `proof.pi_b` so that `snarkjs`'s `verifier.sol` will accept it.
|
||||
|
||||
@@ -26,7 +26,7 @@ With the Client contract as the owner of the Semaphore contract, the Client
|
||||
contract may call owner-only Semaphore functions such as
|
||||
`addExternalNullifier()`.
|
||||
|
||||
## Add, deactivate, or reactivate external nullifiiers
|
||||
## Add, deactivate, or reactivate external nullifiers
|
||||
|
||||
These functions add, deactivate, and reactivate an external nullifier respectively.
|
||||
As each identity can only signal once to an external nullifier, and as a signal
|
||||
|
||||
@@ -55,7 +55,7 @@ In sum, Semaphore provides the ability to:
|
||||
### External nullifiers
|
||||
|
||||
Think of an external nullifier as a voting booth where each user may only cast
|
||||
one vote. If they try to cast a second vote a the same booth, that vote is
|
||||
one vote. If they try to cast a second vote at the same booth, that vote is
|
||||
invalid.
|
||||
|
||||
An external nullifier is any 29-byte value. Semaphore always starts with one
|
||||
@@ -89,7 +89,7 @@ An anonymous voting app would be configured differently:
|
||||
| ----------------------------------- | ------------------------ |
|
||||
| The hash of the respondent's answer | The hash of the question |
|
||||
|
||||
This allows any user to vote with an arbitary response (e.g. yes, no, or maybe)
|
||||
This allows any user to vote with an arbitrary response (e.g. yes, no, or maybe)
|
||||
to any question. The user, however, can only vote once per question.
|
||||
|
||||
## About the code
|
||||
|
||||
@@ -9,7 +9,7 @@ Site owners publish _subgraphs_ that expose site data for anyone to query.
|
||||
Semaphore's subgraph allows you to retrieve data from the [`Semaphore.sol`](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1/packages/contracts/Semaphore.sol) smart contract.
|
||||
|
||||
:::tip
|
||||
The Graph protocol uses the [GraphQL](https://graphql.org/) query lanaguage. For examples, see the [GraphQL API documentation](https://thegraph.com/docs/developer/graphql-api). Visit the [subgraph repository](https://github.com/semaphore-protocol/subgraph) to see the list of Semaphore subgraphs.
|
||||
The Graph protocol uses the [GraphQL](https://graphql.org/) query language. For examples, see the [GraphQL API documentation](https://thegraph.com/docs/developer/graphql-api). Visit the [subgraph repository](https://github.com/semaphore-protocol/subgraph) to see the list of Semaphore subgraphs.
|
||||
:::
|
||||
|
||||
## Schema
|
||||
|
||||
@@ -14,7 +14,7 @@ It also provides a simple mechanism to prevent double-signaling, which means you
|
||||
|
||||
## Where can I ask questions about Semaphore?
|
||||
|
||||
You can ask questions about Semaphore on [Discord](https://semaphore.pse.dev/discord) or by opening a [Semaphore Discussion](https://github.com/semaphore-protocol/semaphore/discussions).
|
||||
You can ask questions about Semaphore on [Telegram](https://semaphore.pse.dev/telegram) or by opening a [Semaphore Discussion](https://github.com/semaphore-protocol/semaphore/discussions).
|
||||
|
||||
## Why do identities require both the `identity trapdoor` and the `identity nullifier`?
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ For more information, see [Merkle tree in Wikipedia](https://en.wikipedia.org/wi
|
||||
|
||||
## Nullifier
|
||||
|
||||
A value used to prevent double entry or double signalling.
|
||||
A value used to prevent double entry or double signaling.
|
||||
|
||||
See [Circuit nullifier hash](/V3/technical-reference/circuits/#nullifier-hash).
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import TabItem from "@theme/TabItem"
|
||||
|
||||
# Troubleshooting
|
||||
|
||||
If these suggestions do not work, feel free to ask in the [Semaphore Discussions](https://github.com/semaphore-protocol/semaphore/discussions) or in the `dev-chat` channel in the [Semaphore Discord](https://semaphore.pse.dev/discord).
|
||||
If these suggestions do not work, feel free to ask in the [Semaphore Discussions](https://github.com/semaphore-protocol/semaphore/discussions) or in the [Semaphore Telegram](https://semaphore.pse.dev/telegram).
|
||||
|
||||
## Using Semaphore in the frontend
|
||||
|
||||
|
||||
135
apps/docs/versioned_docs/version-V4/benchmarks.md
Normal file
@@ -0,0 +1,135 @@
|
||||
---
|
||||
sidebar_position: 8
|
||||
---
|
||||
|
||||
# Benchmarks
|
||||
|
||||
Semaphore v4 introduces new features and performance improvements. Detailed changes are available in the [release changelog](https://github.com/semaphore-protocol/semaphore/releases/tag/v4.0.0).
|
||||
|
||||
The primary changes in benchmark values are driven by the two major protocol updates:
|
||||
|
||||
- New [Identity schema](https://github.com/semaphore-protocol/semaphore/tree/main/packages/identity).
|
||||
|
||||
- [LeanIMT](https://github.com/privacy-scaling-explorations/zk-kit/tree/main/packages/lean-imt): New optimized IMT.
|
||||
|
||||
## New Identity schema
|
||||
|
||||
Semaphore v4 includes a new schema for the identities allowing the creation and verification of signatures.
|
||||
|
||||
Although the new Identity package is slightly slower than the one in Semaphore v3 (by just a few milliseconds), the trade-off is minimal considering the included functionality.
|
||||
|
||||
The new identity schema adds additional constraints to the Semaphore v4 circuit; however, this does not negatively impact overall performance of the protocol.
|
||||
|
||||
## LeanIMT
|
||||
|
||||
Semaphore v4 uses the LeanIMT data structure for group operations, an improvement over the IMT used in v3.
|
||||
|
||||
For further details, see the [LeanIMT paper](https://github.com/privacy-scaling-explorations/zk-kit/tree/main/papers/leanimt).
|
||||
|
||||
The LeanIMT offers dynamic depth, resulting in faster and more cost-effective group operations, across Node.js, browser and smart contracts.
|
||||
|
||||
Semaphore v4 support tree depths from 1 to 32, while v3 supports depths from 16 to 32, both for proof generation and verification.
|
||||
|
||||
## System Specifications and Software environment
|
||||
|
||||
All the benchmarks were run in an environment with these properties:
|
||||
|
||||
**System Specifications**
|
||||
|
||||
Computer: MacBook Pro
|
||||
|
||||
Chip: Apple M2 Pro
|
||||
|
||||
Memory (RAM): 16 GB
|
||||
|
||||
Operating System: macOS Sequoia version 15.6.1
|
||||
|
||||
**Software environment**
|
||||
|
||||
Node.js version: 23.10.0
|
||||
|
||||
Browser: Google Chrome Version 139.0.7258.156 (Official Build) (arm64)
|
||||
|
||||
## Running the benchmarks
|
||||
|
||||
### Javascript and Circom
|
||||
|
||||
GitHub repository to the run Node.js, browser and Circom benchmarks: https://github.com/vplasencia/semaphore-benchmarks
|
||||
|
||||
### Solidity
|
||||
|
||||
GitHub repository to run the Solidity benchmarks: https://github.com/semaphore-protocol/semaphore
|
||||
|
||||
Semaphore V3 benchmarks were obtained using the code from the latest v3 Git tag (`v3.15.2`), with the Solidity optimizer enabled.
|
||||
|
||||
## Node.js benchmarks
|
||||
|
||||
### Identities
|
||||
|
||||

|
||||
|
||||
### Create Group
|
||||
|
||||
Create group, either empty or with initial members.
|
||||
|
||||

|
||||
|
||||
### Add Member
|
||||
|
||||
Add a member to groups with different sizes.
|
||||
|
||||

|
||||
|
||||
### Generate Proof
|
||||
|
||||
Generate a proof using groups with different numbers of members.
|
||||
|
||||

|
||||
|
||||
### Verify Proof
|
||||
|
||||
Verify a proof using groups with different numbers of members.
|
||||
|
||||

|
||||
|
||||
## Browser benchmarks
|
||||
|
||||
Main functions used in the browser.
|
||||
|
||||

|
||||
|
||||
## Circuit benchmarks
|
||||
|
||||
Tree depth = 20
|
||||
|
||||
### Semaphore V3
|
||||
|
||||
<img
|
||||
src={require('../../assets/img-benchmarks/circuits/semaphore-v3-circuits-benchmarks.png').default}
|
||||
alt="Circuit benchmarks Semaphore v3"
|
||||
style={{ width: '300px', height: 'auto' }}
|
||||
/>
|
||||
|
||||
### Semaphore V4
|
||||
|
||||
<img
|
||||
src={require('../../assets/img-benchmarks/circuits/semaphore-v4-circuits-benchmarks.png').default}
|
||||
alt="Circuit benchmarks Semaphore v4"
|
||||
style={{ width: '300px', height: 'auto' }}
|
||||
/>
|
||||
|
||||
## Contracts
|
||||
|
||||
<img
|
||||
src={require('../../assets/img-benchmarks/contracts/contract-benchmarks.png').default}
|
||||
alt="Contract Benchmarks"
|
||||
style={{ width: '560px', height: 'auto' }}
|
||||
/>
|
||||
|
||||
### Semaphore V3 gas report
|
||||
|
||||

|
||||
|
||||
### Semaphore V4 gas report
|
||||
|
||||

|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
sidebar_position: 12
|
||||
sidebar_position: 14
|
||||
---
|
||||
|
||||
# Credits
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
sidebar_position: 11
|
||||
sidebar_position: 13
|
||||
---
|
||||
|
||||
# FAQ
|
||||
|
||||
## Where can I ask questions about Semaphore?
|
||||
|
||||
You can ask questions about Semaphore on [Discord](https://semaphore.pse.dev/discord) or by opening a [Semaphore Discussion](https://github.com/semaphore-protocol/semaphore/discussions). The most frequent questions will be listed below.
|
||||
You can ask questions about Semaphore on [Telegram](https://semaphore.pse.dev/telegram) or by opening a [Semaphore Discussion](https://github.com/semaphore-protocol/semaphore/discussions). The most frequent questions will be listed below.
|
||||
|
||||
## Why should I prevent proofs from being verified twice?
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ In the project root folder:
|
||||
2. Go to the `apps/contracts` folder and deploy your contract.
|
||||
|
||||
```bash
|
||||
yarn deploy --semaphore <semaphore-address> --group <group-id> --network sepolia
|
||||
yarn deploy --semaphore <semaphore-address> --network sepolia
|
||||
```
|
||||
|
||||
:::note
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
sidebar_position: 8
|
||||
sidebar_position: 9
|
||||
---
|
||||
|
||||
# Glossary
|
||||
@@ -14,7 +14,7 @@ The public [Semaphore identity](#identity) value used in [Semaphore groups](#gro
|
||||
|
||||
## Group
|
||||
|
||||
A group is a [Merkle tree](#merkle-tree) in which each leaf is an [identity commitment](#identity-commitment) for a user. Semaphore uses the [LeanIMT](https://zkkit.pse.dev/classes/_zk_kit_imt.LeanIMT.html) implementation, which is an optimized binary incremental Merkle tree. The tree nodes are calculated using [Poseidon](https://www.poseidon-hash.info).
|
||||
A group is a [Merkle tree](#merkle-tree) in which each leaf is an [identity commitment](#identity-commitment) for a user. Semaphore uses the [LeanIMT](https://zkkit.pse.dev/classes/_zk_kit_lean_imt.LeanIMT.html) implementation, which is an optimized binary incremental Merkle tree. The tree nodes are calculated using [Poseidon](https://www.poseidon-hash.info).
|
||||
|
||||
## Merkle tree
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ To prevent fraud, the owner should keep their private key secret.
|
||||
|
||||
## Install package
|
||||
|
||||
In your code, use the [`@semaphore-protocol/identity`](https://github.com/semaphore-protocol/semaphore/tree/main/packages/identity) package to manage Semaphore identites.
|
||||
In your code, use the [`@semaphore-protocol/identity`](https://github.com/semaphore-protocol/semaphore/tree/main/packages/identity) package to manage Semaphore identities.
|
||||
|
||||
<Tabs
|
||||
defaultValue="npm"
|
||||
@@ -87,6 +87,11 @@ You may choose to delegate such functionality to existing wallets such as Metama
|
||||
3. The user can now recreate their Semaphore identity whenever they want by signing the same message with their Ethereum account in Metamask.
|
||||
:::
|
||||
|
||||
:::warning Privacy risk
|
||||
If a user signs the **same message** on multiple websites using MetaMask, all those websites will be able to **generate the same Semaphore identity**. This undermines anonymity and may allow third parties to **link identities across platforms** or even **gain control over a user's identity**.\
|
||||
To mitigate this, encourage users to sign **unique messages per application** or implement safeguards that detect and warn about reuse.
|
||||
:::
|
||||
|
||||
## Sign and verify messages
|
||||
|
||||
Semaphore V4 uses asymmetric cryptography and in particular EdDSA to generate the identity keys. It is therefore also possible to sign messages and verify their signatures.
|
||||
@@ -109,3 +114,33 @@ After a message is signed, anyone can verify the signature using the message its
|
||||
// Static method.
|
||||
Identity.verifySignature(message, signature, identity1.publicKey)
|
||||
```
|
||||
|
||||
## Export and import an identity
|
||||
|
||||
A Semaphore Identity can be exported and then imported later for reuse.
|
||||
|
||||
### Export an identity
|
||||
|
||||
Returns the private key encoded as a base64 string.
|
||||
|
||||
```ts
|
||||
import { Identity } from "@semaphore-protocol/identity"
|
||||
|
||||
const identity = new Identity()
|
||||
|
||||
const privateKey = identity.export()
|
||||
```
|
||||
|
||||
### Import an identity
|
||||
|
||||
Returns a Semaphore identity based on a private key encoded as a base64 string.
|
||||
|
||||
```ts
|
||||
import { Identity } from "@semaphore-protocol/identity"
|
||||
|
||||
const identity = new Identity()
|
||||
|
||||
const privateKey = identity.export()
|
||||
|
||||
const identity2 = Identity.import(privateKey)
|
||||
```
|
||||
|
||||
@@ -79,7 +79,7 @@ const group = new Group(members)
|
||||
|
||||
Each proof requires a [scope](/glossary#scope), on which each user may only generate one valid proof. The scope, together with the user's private key, is used to generate the nullifier, which is the value you can actually use to check whether a proof with that scope has already been generated by that user. In a voting application where double-voting must be prevented, the scope could be the ballot id, or the Merkle root of the group.
|
||||
|
||||
### 4. Generate the anomymous message
|
||||
### 4. Generate the anonymous message
|
||||
|
||||
Finally, you can generate the proof with the anonymous message using the `generateProof` function. For example:
|
||||
|
||||
|
||||
55
apps/docs/versioned_docs/version-V4/llm-setup.md
Normal file
@@ -0,0 +1,55 @@
|
||||
---
|
||||
sidebar_position: 11
|
||||
---
|
||||
|
||||
# Code editors and LLM setup
|
||||
|
||||
LLMs often rely on outdated or generic information. Use this guide to help set up your code editor to pull in more accurate, up-to-date documentation and examples. It will help provide better answers and generate more accurate Semaphore code using LLMs (large language models) and MCP (Model Context Protocol) servers.
|
||||
|
||||
## Quick use
|
||||
|
||||
[llms.txt](https://docs.semaphore.pse.dev/llms.txt) is a compact, text version of the Semaphore docs.
|
||||
|
||||
Add this link directly to your chat window for enhanced context.
|
||||
|
||||
## Permanent setup
|
||||
|
||||
Depending on your IDE, you can add custom docs to VS Code, Cursor or others.
|
||||
|
||||
Example for Cursor...
|
||||
|
||||
1. Press `CMD + Shift + P` (unix), `Ctrl + Shift + P` (Windows)
|
||||
1. Type `Add new custom docs`.
|
||||
1. Add https://docs.semaphore.pse.dev/llms.txt
|
||||
1. In chat you can know `@docs` and choose `semaphore` to provide additional context.
|
||||
|
||||
Refer to the documentation of your IDE to properly set it up.
|
||||
|
||||
## MCP Server
|
||||
|
||||
Depending on your IDE, you can add a MCP server to communicate your docs to the AI model.
|
||||
|
||||
- [Context7 MCP server](https://github.com/upstash/context7) is a server that provides many libraries, incl. Semaphore.
|
||||
|
||||
Example for Cursor...
|
||||
|
||||
1. Press `CMD + Shift + J` (unix), `Ctrl + Shift + J` (Windows)
|
||||
1. Click on `MCP` on the sidebar
|
||||
1. Click `Add new global MCP server`
|
||||
1. Add the following code to `mcp.json`
|
||||
|
||||
```
|
||||
{
|
||||
"mcpServers": {
|
||||
"Context7": {
|
||||
"type": "stdio",
|
||||
"command": "npx",
|
||||
"args": ["-y", "@upstash/context7-mcp@latest"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can now prompt anything about Semaphore and write `use context7` at the end of your prompt. E.g. `create a new Semaphore identity in TypeScript. use context`. This will call the MCP tool and automatically fetch the latest documentation.
|
||||
|
||||
Refer to the documentation of your IDE to properly set it up.
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
sidebar_position: 9
|
||||
sidebar_position: 10
|
||||
---
|
||||
|
||||
import Articles from '@site/src/components/Articles';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
sidebar_position: 10
|
||||
sidebar_position: 12
|
||||
---
|
||||
|
||||
import Tabs from "@theme/Tabs"
|
||||
@@ -7,7 +7,7 @@ import TabItem from "@theme/TabItem"
|
||||
|
||||
# Troubleshooting
|
||||
|
||||
If these suggestions do not work, feel free to ask for more help and support on [Github Discussions](https://github.com/semaphore-protocol/semaphore/discussions) or [Discord](https://semaphore.pse.dev/discord) ("dev-chat" channel).
|
||||
If these suggestions do not work, feel free to ask for more help and support on [Github Discussions](https://github.com/semaphore-protocol/semaphore/discussions) or [Telegram](https://semaphore.pse.dev/telegram).
|
||||
|
||||
## Transaction reverted when using the same nullifier
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ slug: /
|
||||
Additionally, it provides a simple mechanism to prevent double-signaling.
|
||||
Use cases include private voting, whistleblowing, anonymous DAOs and mixers.
|
||||
|
||||
For in-depth technical details about Semaphore, refer to the [Semaphore V4 Specification](https://github.com/zkspecs/zkspecs/blob/main/specs/3/README.md).
|
||||
|
||||
## Features
|
||||
|
||||
With Semaphore, you can allow your users to do the following:
|
||||
@@ -33,7 +35,7 @@ Semaphore is designed to be a simple and generic _privacy layer_ for decentraliz
|
||||
|
||||
## About the code
|
||||
|
||||
The core of the protocol is the [circuit logic](https://github.com/semaphore-protocol/semaphore/tree/main/packages/circuits/semaphore.circom).
|
||||
The core of the protocol is the [circuit logic](https://github.com/semaphore-protocol/semaphore/tree/main/packages/circuits/src/semaphore.circom).
|
||||
In addition to circuits,
|
||||
Semaphore provides [Solidity contracts](https://github.com/semaphore-protocol/semaphore/tree/main/packages/contracts)
|
||||
and [JavaScript libraries](https://github.com/semaphore-protocol/semaphore/tree/main#-packages) that allow developers to generate zero-knowledge proofs and verify them with minimal effort.
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
🔎 Issues
|
||||
</a>
|
||||
<span> | </span>
|
||||
<a href="https://semaphore.pse.dev/discord">
|
||||
<a href="https://semaphore.pse.dev/telegram">
|
||||
🗣️ Chat & Support
|
||||
</a>
|
||||
</h4>
|
||||
@@ -42,15 +42,25 @@
|
||||
|
||||
## Networks
|
||||
|
||||
| Semaphore version | Sepolia | Polygon Mumbai | Optimism Sepolia | Arbitrum Sepolia | Arbitrum One | Polygon Amoy |
|
||||
| ----------------- | ------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
|
||||
| v2.0 | N/A | N/A | N/A | N/A | [semaphore-protocol/arbitrum](https://thegraph.com/hosted-service/subgraph/semaphore-protocol/arbitrum) | N/A |
|
||||
| v2.5 | N/A | N/A | N/A | N/A | N/A | N/A |
|
||||
| v2.6 | N/A | N/A | N/A | N/A | [semaphore-protocol/arbitrum-86337c](https://thegraph.com/hosted-service/subgraph/semaphore-protocol/arbitrum-86337c) | N/A |
|
||||
| v3.0 - v3.1 | N/A | N/A | N/A | N/A | [semaphore-protocol/arbitrum-72dca3](https://thegraph.com/hosted-service/subgraph/semaphore-protocol/arbitrum-72dca3) | N/A |
|
||||
| >= v3.2 | [semaphore-sepolia](https://api.studio.thegraph.com/query/14377/semaphore-sepolia/v3.6.1) | [semaphore-mumbai](https://api.studio.thegraph.com/query/14377/semaphore-mumbai/v3.6.1) | N/A | N/A | [semaphore-arbitrum](https://api.studio.thegraph.com/query/14377/semaphore-arbitrum/v3.6.1) | N/A |
|
||||
| v4.0.0-beta | [semaphore-sepolia](https://api.studio.thegraph.com/query/14377/semaphore-sepolia/v4.0.0-beta) | [semaphore-matic-mumbai](https://api.studio.thegraph.com/query/14377/semaphore-matic-mumbai/v4.0.0-beta) | [semaphore-optimism-sepolia](https://api.studio.thegraph.com/query/14377/semaphore-optimism-sepolia/v4.0.0-beta) | [semaphore-arbitrum-sepolia](https://api.studio.thegraph.com/query/14377/semaphore-arbitrum-sepolia/v4.0.0-beta) | N/A | N/A |
|
||||
| >= v4.0.0-beta.17 | [semaphore-sepolia](https://api.studio.thegraph.com/query/14377/semaphore-sepolia/v4.0.0-beta.17) | N/A | [semaphore-optimism-sepolia](https://api.studio.thegraph.com/query/14377/semaphore-optimism-sepolia/v4.0.0-beta.17) | [semaphore-arbitrum-sepolia](https://api.studio.thegraph.com/query/14377/semaphore-arbitrum-sepolia/v4.0.0-beta.17) | N/A | [semaphore-matic-amoy](https://api.studio.thegraph.com/query/14377/semaphore-matic-amoy/v4.0.0-beta.17) |
|
||||
You can access any subgraph supported by Semaphore with the following URL: `https://api.studio.thegraph.com/query/14377/semaphore-<network-name>/v4.5.0`.
|
||||
|
||||
Supported networks:
|
||||
|
||||
- `sepolia`
|
||||
- `ethereum`
|
||||
- `optimism`
|
||||
- `optimism-sepolia`
|
||||
- `arbitrum`
|
||||
- `arbitrum-sepolia`
|
||||
- `matic`
|
||||
- `matic-amoy`
|
||||
- `base-sepolia`
|
||||
- `base`
|
||||
- `linea-sepolia`
|
||||
- `linea`
|
||||
- `scroll-sepolia`
|
||||
- `gnosis-chiado`
|
||||
- `gnosis`
|
||||
|
||||
## 🛠 Install
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
"codegen:sepolia": "yarn codegen sepolia",
|
||||
"build": "graph build",
|
||||
"build:sepolia": "yarn codegen:sepolia && graph build",
|
||||
"auth": "graph auth --studio",
|
||||
"deploy": "graph deploy --studio ${0}",
|
||||
"auth": "graph auth",
|
||||
"deploy": "graph deploy ${0}",
|
||||
"start-ipfs": "node scripts/start-ipfs.js",
|
||||
"create-local": "graph create --node http://localhost:8020/ semaphore",
|
||||
"remove-local": "graph remove --node http://localhost:8020/ semaphore",
|
||||
@@ -18,13 +18,13 @@
|
||||
"test": "graph test Semaphore -v 0.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@graphprotocol/graph-cli": "0.78.0",
|
||||
"@graphprotocol/graph-ts": "0.35.1",
|
||||
"@semaphore-protocol/utils": "4.0.2"
|
||||
"@graphprotocol/graph-cli": "0.95.0",
|
||||
"@graphprotocol/graph-ts": "0.37.0",
|
||||
"@semaphore-protocol/utils": "workspace:packages/utils"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mustache": "^4.2.2",
|
||||
"matchstick-as": "0.5.0",
|
||||
"@types/mustache": "^4.2.5",
|
||||
"matchstick-as": "0.6.0",
|
||||
"mustache": "^4.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,24 @@ const network = process.argv.at(2)
|
||||
|
||||
const template = readFileSync("./subgraph.template.yaml", "utf-8")
|
||||
|
||||
function mapNetwork(n) {
|
||||
if (n === "matic-amoy") {
|
||||
return "polygon-amoy"
|
||||
}
|
||||
|
||||
if (n === "arbitrum") {
|
||||
return "arbitrum-one"
|
||||
}
|
||||
|
||||
if (n === "ethereum") {
|
||||
return "mainnet"
|
||||
}
|
||||
|
||||
return network
|
||||
}
|
||||
|
||||
const subgraph = Mustache.render(template, {
|
||||
network: network === "matic-amoy" ? "polygon-amoy" : network,
|
||||
network: mapNetwork(network),
|
||||
...getDeployedContract(network)
|
||||
})
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
🔎 Issues
|
||||
</a>
|
||||
<span> | </span>
|
||||
<a href="https://semaphore.pse.dev/discord">
|
||||
<a href="https://semaphore.pse.dev/telegram">
|
||||
🗣️ Chat & Support
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"framer-motion": "^10.16.4",
|
||||
"next": "13.5.5",
|
||||
"next": "14.2.35",
|
||||
"react": "^18",
|
||||
"react-code-blocks": "^0.1.4",
|
||||
"react-dom": "^18"
|
||||
|
||||
@@ -26,7 +26,7 @@ export default function Build() {
|
||||
url: "https://github.com/semaphore-protocol/boilerplate",
|
||||
details: [
|
||||
"Begin your projects with a ready-to-use example template",
|
||||
"Create identity, join group, send anonmous feedback",
|
||||
"Create identity, join group, send anonymous feedback",
|
||||
"Easily modify to align with specific project goals"
|
||||
]
|
||||
},
|
||||
@@ -133,7 +133,7 @@ export default function Build() {
|
||||
</VStack>
|
||||
</Flex>
|
||||
|
||||
<Box position="relative" w={{ base: "full", xl: "727px" }} h="630" overflow="hidden">
|
||||
<Box position="relative" w={{ base: "full", xl: "727px" }} h="630px" overflow="hidden">
|
||||
<Image
|
||||
src="https://semaphore.cedoor.dev/flower-shadow.jpg"
|
||||
alt=""
|
||||
|
||||
@@ -40,6 +40,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
||||
href="https://github.com/semaphore-protocol/semaphore/releases/tag/v4.0.0"
|
||||
ml="1"
|
||||
isExternal
|
||||
color="primary.500"
|
||||
>
|
||||
<b>Semaphore V4</b>
|
||||
</Link>{" "}
|
||||
|
||||
@@ -5,7 +5,7 @@ import Carousel from "../components/Carousel"
|
||||
import ProjectCard from "../components/ProjectCard"
|
||||
import events from "../data/events.json"
|
||||
import allProjects from "../data/projects.json"
|
||||
import IconDiscord from "../icons/IconDiscord"
|
||||
import IconTelegram from "../icons/IconTelegram"
|
||||
import HRoadmap from "@/components/HRoadmap"
|
||||
import VRoadmap from "@/components/VRoadmap"
|
||||
|
||||
@@ -131,7 +131,7 @@ export default function Home() {
|
||||
>
|
||||
1
|
||||
</Heading>
|
||||
<VStack align="left">
|
||||
<VStack align="start">
|
||||
<Text
|
||||
fontSize={{ base: "18px", md: "20px" }}
|
||||
fontFamily={sora.style.fontFamily}
|
||||
@@ -152,7 +152,7 @@ export default function Home() {
|
||||
>
|
||||
3
|
||||
</Heading>
|
||||
<VStack align="left">
|
||||
<VStack align="start">
|
||||
<Text
|
||||
fontSize={{ base: "18px", md: "20px" }}
|
||||
fontFamily={sora.style.fontFamily}
|
||||
@@ -181,7 +181,7 @@ export default function Home() {
|
||||
>
|
||||
2
|
||||
</Heading>
|
||||
<VStack align="left">
|
||||
<VStack align="start">
|
||||
<Text
|
||||
fontSize={{ base: "18px", md: "20px" }}
|
||||
fontFamily={sora.style.fontFamily}
|
||||
@@ -203,7 +203,7 @@ export default function Home() {
|
||||
>
|
||||
4
|
||||
</Heading>
|
||||
<VStack align="left">
|
||||
<VStack align="start">
|
||||
<Text
|
||||
fontSize={{ base: "18px", md: "20px" }}
|
||||
fontFamily={sora.style.fontFamily}
|
||||
@@ -225,7 +225,7 @@ export default function Home() {
|
||||
<VStack mb="32" spacing="32">
|
||||
<VStack w="full" maxW="1110px">
|
||||
<Heading fontSize={{ base: "30px", md: "44px" }} pb="90px">
|
||||
2024 Roadmap
|
||||
2024-2025 Roadmap
|
||||
</Heading>
|
||||
|
||||
<HStack display={{ base: "none", md: "flex" }} w="full" mt="60px">
|
||||
@@ -243,9 +243,9 @@ export default function Home() {
|
||||
Ask questions, suggest ideas, stay up-to-date, and meet other people building privacy
|
||||
applications with Zero Knowledge.
|
||||
</Text>
|
||||
<Link href="https://semaphore.pse.dev/discord" isExternal>
|
||||
<Button leftIcon={<IconDiscord />} size="lg">
|
||||
Discord
|
||||
<Link href="https://semaphore.pse.dev/telegram" isExternal>
|
||||
<Button leftIcon={<IconTelegram />} size="lg">
|
||||
Telegram
|
||||
</Button>
|
||||
</Link>
|
||||
</VStack>
|
||||
@@ -287,10 +287,10 @@ export default function Home() {
|
||||
Upcoming Events
|
||||
</Heading>
|
||||
|
||||
<VStack align="left" spacing="10" maxH="600" overflowY="auto">
|
||||
<VStack align="start" spacing="10" maxH="600px" overflowY="auto">
|
||||
{events.map((event) => (
|
||||
<Link href={event.link} key={event.name} isExternal>
|
||||
<VStack align="left">
|
||||
<VStack align="start">
|
||||
<Heading fontSize={{ base: "20px", md: "24px" }}>
|
||||
{event.date} | {event.name}
|
||||
</Heading>
|
||||
|
||||
@@ -5,7 +5,7 @@ import ProjectsList from "../../components/ProjectsList"
|
||||
export default function Projects() {
|
||||
return (
|
||||
<>
|
||||
<VStack pt="170px" pb="56px" w="100%" justify="end" align="left" spacing="40" position="relative">
|
||||
<VStack pt="170px" pb="56px" w="100%" justify="end" align="start" spacing="40" position="relative">
|
||||
<Box
|
||||
zIndex="-1"
|
||||
top="0"
|
||||
@@ -25,7 +25,7 @@ export default function Projects() {
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<VStack align="left" spacing="4" pb="16">
|
||||
<VStack align="start" spacing="4" pb="16">
|
||||
<Heading fontSize={{ base: "40px", sm: "46px", md: "72px" }}>Built with Semaphore</Heading>
|
||||
|
||||
<Text fontSize={{ base: "16px", sm: "18px", md: "20px" }}>
|
||||
@@ -35,7 +35,7 @@ export default function Projects() {
|
||||
</VStack>
|
||||
</VStack>
|
||||
|
||||
<ProjectsList w="100%" align="left" pt="16" spacing="14" />
|
||||
<ProjectsList w="100%" align="start" pt="16" spacing="14" />
|
||||
|
||||
<VStack my="128px">
|
||||
<ActionCard
|
||||
|
||||
@@ -46,7 +46,7 @@ export default function Carousel({ title, sizes, type, ...props }: CarouselProps
|
||||
}, [index, size])
|
||||
|
||||
return (
|
||||
<VStack align="left" w="full" spacing="16" {...props}>
|
||||
<VStack align="start" w="full" spacing="16" {...props}>
|
||||
<HStack justify={type === "projects" ? "center" : "space-between"}>
|
||||
<Heading fontSize={{ base: "30px", md: "44px" }}>{title}</Heading>
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Divider, Heading, HStack, Link, Stack, Text, VStack } from "@chakra-ui/
|
||||
import Image from "next/image"
|
||||
import NextLink from "next/link"
|
||||
import IconArrowUpRight from "../icons/IconArrowUpRight"
|
||||
import IconDiscord from "../icons/IconDiscord"
|
||||
import IconTelegram from "../icons/IconTelegram"
|
||||
import IconThumbsUp from "../icons/IconThumbsUp"
|
||||
import IconX from "@/icons/IconX"
|
||||
|
||||
@@ -59,11 +59,11 @@ export default function Footer() {
|
||||
<Divider />
|
||||
<VStack spacing="5">
|
||||
<HStack spacing="5">
|
||||
<Link href="https://semaphore.pse.dev/discord" isExternal>
|
||||
<Link href="https://semaphore.pse.dev/telegram" isExternal>
|
||||
<HStack>
|
||||
<IconDiscord boxSize={{ base: "16px", md: "24px" }} />
|
||||
<IconTelegram boxSize={{ base: "16px", md: "24px" }} />
|
||||
<Heading fontSize={{ base: "14px", md: "18px" }} fontWeight="normal">
|
||||
Discord
|
||||
Telegram
|
||||
</Heading>
|
||||
</HStack>
|
||||
</Link>
|
||||
@@ -88,7 +88,7 @@ export default function Footer() {
|
||||
</Link>
|
||||
|
||||
<Text fontSize={{ base: "12px", md: "14px" }} color="text.500" pt="2">
|
||||
Copyright © 2024 Ethereum Foundation
|
||||
Copyright © {new Date().getFullYear()} Ethereum Foundation
|
||||
</Text>
|
||||
</VStack>
|
||||
</VStack>
|
||||
|
||||
@@ -23,9 +23,9 @@ export default function InfoCard({ texts }: InfoCardProps) {
|
||||
height={{ base: "auto", md: "474px" }}
|
||||
>
|
||||
<CardBody padding="0">
|
||||
<VStack align="left" spacing="10" maxH="500" overflowY="auto">
|
||||
<VStack align="start" spacing="10" maxH="500" overflowY="auto">
|
||||
{texts.map((text) => (
|
||||
<VStack key={text.title} align="left">
|
||||
<VStack key={text.title} align="start">
|
||||
<Heading textAlign="left" fontSize={{ base: "20px", md: "24px" }}>
|
||||
{text.title}
|
||||
</Heading>
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
} from "@chakra-ui/react"
|
||||
import Image from "next/image"
|
||||
import NextLink from "next/link"
|
||||
import IconDiscord from "../icons/IconDiscord"
|
||||
import IconTelegram from "../icons/IconTelegram"
|
||||
import IconMenu from "../icons/IconMenu"
|
||||
import IconThumbsUp from "../icons/IconThumbsUp"
|
||||
import NavbarLinks from "./NavbarLinks"
|
||||
@@ -71,11 +71,11 @@ export default function Navbar() {
|
||||
|
||||
<VStack w="full" justify="center" spacing="5">
|
||||
<HStack spacing="5">
|
||||
<Link href="https://semaphore.pse.dev/discord" isExternal>
|
||||
<Link href="https://semaphore.pse.dev/telegram" isExternal>
|
||||
<HStack>
|
||||
<IconDiscord boxSize={{ base: "16px", md: "24px" }} />
|
||||
<IconTelegram boxSize={{ base: "16px", md: "24px" }} />
|
||||
<Heading fontSize={{ base: "14px", md: "18px" }} fontWeight="normal">
|
||||
Discord
|
||||
Telegram
|
||||
</Heading>
|
||||
</HStack>
|
||||
</Link>
|
||||
|
||||
@@ -52,7 +52,7 @@ export default function ProjectsList(props: any) {
|
||||
|
||||
return (
|
||||
<VStack {...props}>
|
||||
<VStack align="left" spacing="6">
|
||||
<VStack align="start" spacing="6">
|
||||
<Text fontSize="20">Projects created by</Text>
|
||||
|
||||
<HStack spacing="4" flexWrap="wrap">
|
||||
@@ -83,7 +83,7 @@ export default function ProjectsList(props: any) {
|
||||
</HStack>
|
||||
</VStack>
|
||||
|
||||
<VStack align="left" spacing="6" ref={viewToScrollRef}>
|
||||
<VStack align="start" spacing="6" ref={viewToScrollRef}>
|
||||
<Text fontSize="20">Category</Text>
|
||||
<HStack spacing="3" flexWrap="wrap">
|
||||
{getProjectCategories(sortedProjects).map((category) => (
|
||||
|
||||
@@ -23,7 +23,7 @@ export default function SectionBlock({ title, description, linkText, linkUrl, co
|
||||
return (
|
||||
<VStack w="full">
|
||||
<Flex flexDir={{ base: "column", lg: "row" }} gap="52px" w="full">
|
||||
<VStack align="left" gap="32px" flex="1">
|
||||
<VStack align="start" gap="32px" flex="1">
|
||||
<Text fontSize={{ base: "40px", md: "44px" }} fontWeight={{ base: "400", md: "500" }}>
|
||||
{title}
|
||||
</Text>
|
||||
|
||||
@@ -40,5 +40,19 @@
|
||||
"date": "2024-01-01",
|
||||
"authors": ["Vivek Bhupatiraju"],
|
||||
"url": "https://vivs.wiki/Semaphore"
|
||||
},
|
||||
{
|
||||
"title": "Getting Started with Semaphore: Building Privacy-Preserving dApps on Ethereum",
|
||||
"minRead": 7,
|
||||
"date": "2024-12-09",
|
||||
"authors": ["glasswing"],
|
||||
"url": "https://mirror.xyz/0xBE98D44c29D179588b7E717Db8898529e5cD770F/5Xlv1jzwJKfKgP-m257kjivBlUIM_cwTzsmpf9F0Su8"
|
||||
},
|
||||
{
|
||||
"title": "Semaphore V4 Specification",
|
||||
"minRead": 10,
|
||||
"date": "2025-03-01",
|
||||
"authors": ["Semaphore Team"],
|
||||
"url": "https://github.com/zkspecs/zkspecs/blob/main/specs/3/README.md"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
[
|
||||
{
|
||||
"name": "ETHRome",
|
||||
"date": "Oct 4-6, 2024",
|
||||
"description": "Semaphore team will deliver an in-person talk and sponsor prizes for the hackathon.",
|
||||
"link": "https://www.ethrome.org/"
|
||||
"name": "ETHDam",
|
||||
"date": "May 9-11, 2025",
|
||||
"description": "Semaphore team will deliver an in-person talk.",
|
||||
"link": "https://www.ethdam.com/"
|
||||
},
|
||||
{
|
||||
"name": "Devcon",
|
||||
"date": "Nov 12-15, 2024",
|
||||
"name": "ZuBerlin",
|
||||
"date": "June 14-22, 2025",
|
||||
"description": "Semaphore team will deliver an in-person talk.",
|
||||
"link": "https://zuberlin.city/"
|
||||
},
|
||||
{
|
||||
"name": "Devconnect",
|
||||
"date": "Nov 17-22, 2025",
|
||||
"description": "Semaphore team will deliver an in-person talk and run workshops.",
|
||||
"link": "https://devcon.org/en/"
|
||||
"link": "https://devconnect.org/"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -32,6 +32,16 @@
|
||||
"website": "https://bandada.pse.dev"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ZkDemocracy",
|
||||
"categories": ["Infra", "Data"],
|
||||
"tagline": "ZkDemocracy is a ready-to-use anonymous voting system based on Semaphore.",
|
||||
"pse": false,
|
||||
"icon": "",
|
||||
"links": {
|
||||
"github": "https://github.com/TheBojda/zkdemocracy"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Super Secret ZK Ballot",
|
||||
"tagline": "A Solidity contract for anonymous voting.",
|
||||
@@ -115,20 +125,7 @@
|
||||
"icon": "",
|
||||
"links": {
|
||||
"website": "https://explorer.semaphore.pse.dev",
|
||||
"github": "https://github.com/semaphore-protocol/explorer",
|
||||
"discord": "https://semaphore.pse.dev/discord"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Semaphore Discord Bot",
|
||||
"tagline": "A Discord Bot for Semaphore",
|
||||
"categories": ["Development"],
|
||||
"pse": true,
|
||||
"icon": "",
|
||||
"links": {
|
||||
"website": "https://discord.com/api/oauth2/authorize?client_id=1082429985496772628&permissions=1024&scope=bot",
|
||||
"github": "https://github.com/semaphore-protocol/discord-bot",
|
||||
"discord": "https://semaphore.pse.dev/discord"
|
||||
"github": "https://github.com/semaphore-protocol/explorer"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -558,5 +555,57 @@
|
||||
"github": "https://github.com/GeneralMagicio/pairwise-RPGF4",
|
||||
"website": "https://pairwise.vote"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "VeilEscrow",
|
||||
"categories": ["Privacy", "Coordination"],
|
||||
"tagline": "Secure, private, and decentralized escrows for anonymous transactions",
|
||||
"pse": false,
|
||||
"icon": "",
|
||||
"links": {
|
||||
"github": "https://github.com/evgongora/VeilEscrow"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Obscurus",
|
||||
"categories": ["Voting", "Privacy"],
|
||||
"tagline": "An anonymity layer for Safe Wallet owners, built using Semaphore and Zodiac.",
|
||||
"pse": false,
|
||||
"icon": "",
|
||||
"links": {
|
||||
"github": "https://github.com/quartz-technology/obscurus"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Semaphore Modular Smart Account Modules",
|
||||
"categories": ["Wallet", "Privacy"],
|
||||
"tagline": "Anonymous multi-sig wallet with Semaphore",
|
||||
"pse": false,
|
||||
"icon": "",
|
||||
"links": {
|
||||
"github": "https://github.com/jimmychu0807/semaphore-msa-modules",
|
||||
"website": "https://semaphore-msa-modules.jimmychu0807.hk"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Poll.cc",
|
||||
"categories": ["Voting", "Social"],
|
||||
"tagline": "Public online voting on social and political issues. Semaphore is used for anonymous voting while proving you're a real human verified by KYC.",
|
||||
"pse": false,
|
||||
"icon": "",
|
||||
"links": {
|
||||
"website": "https://poll.cc"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "BringID",
|
||||
"tagline": "Privacy-preserving proof of humanity using verifiable Internet credentials",
|
||||
"categories": ["Identity", "Authenticity", "Trust"],
|
||||
"pse": false,
|
||||
"icon": "",
|
||||
"links": {
|
||||
"website": "https://www.bringid.org",
|
||||
"github": "https://github.com/BringID/whitepaper"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -17,18 +17,34 @@
|
||||
},
|
||||
{
|
||||
"name": "LeanIMT Paper",
|
||||
"done": false
|
||||
"done": true
|
||||
},
|
||||
{
|
||||
"name": "RLN extension",
|
||||
"done": false
|
||||
"name": "Support more Testnets & Mainnets",
|
||||
"done": true
|
||||
},
|
||||
{
|
||||
"name": "Support more Testnets/Mainnets",
|
||||
"done": false
|
||||
"name": "New Explorer",
|
||||
"done": true
|
||||
},
|
||||
{
|
||||
"name": "Documentation Revamp",
|
||||
"name": "Semaphore V4 Specification",
|
||||
"done": true
|
||||
},
|
||||
{
|
||||
"name": "Semaphore Rust Implementation",
|
||||
"done": true
|
||||
},
|
||||
{
|
||||
"name": "Semaphore Noir Implementation",
|
||||
"done": true
|
||||
},
|
||||
{
|
||||
"name": "Scaling Semaphore with PIR",
|
||||
"done": true
|
||||
},
|
||||
{
|
||||
"name": "Maintenance",
|
||||
"done": false
|
||||
}
|
||||
]
|
||||
|
||||
@@ -118,5 +118,21 @@
|
||||
"speakers": ["Vivian Plasencia"],
|
||||
"url": "https://youtu.be/ux5Xy_lpiYk",
|
||||
"thumbnail": "https://img.youtube.com/vi/ux5Xy_lpiYk/0.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Scaling Semaphore",
|
||||
"eventName": "ETHDam",
|
||||
"date": "2025-05-10",
|
||||
"speakers": ["Vivian Plasencia"],
|
||||
"url": "https://youtu.be/IkYtKSQLR-A",
|
||||
"thumbnail": "https://img.youtube.com/vi/IkYtKSQLR-A/0.jpg"
|
||||
},
|
||||
{
|
||||
"title": "Scaling Semaphore: Noir in Action",
|
||||
"eventName": "NoirCon2",
|
||||
"date": "2025-06-19",
|
||||
"speakers": ["Vivian Plasencia"],
|
||||
"url": "https://youtu.be/vfL7z74jGyU",
|
||||
"thumbnail": "https://img.youtube.com/vi/vfL7z74jGyU/0.jpg"
|
||||
}
|
||||
]
|
||||
|
||||
13
apps/website/src/icons/IconTelegram.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import { Icon, IconProps } from "@chakra-ui/react"
|
||||
import React from "react"
|
||||
|
||||
export default function IconTelegram(props: IconProps): JSX.Element {
|
||||
return (
|
||||
<Icon viewBox="0 0 48 48" {...props}>
|
||||
<path
|
||||
d="M41.4193 7.30899C41.4193 7.30899 45.3046 5.79399 44.9808 9.47328C44.8729 10.9883 43.9016 16.2908 43.1461 22.0262L40.5559 39.0159C40.5559 39.0159 40.3401 41.5048 38.3974 41.9377C36.4547 42.3705 33.5408 40.4227 33.0011 39.9898C32.5694 39.6652 24.9068 34.7955 22.2086 32.4148C21.4531 31.7655 20.5897 30.4669 22.3165 28.9519L33.6487 18.1305C34.9438 16.8319 36.2389 13.8019 30.8426 17.4812L15.7331 27.7616C15.7331 27.7616 14.0063 28.8437 10.7686 27.8698L3.75342 25.7055C3.75342 25.7055 1.16321 24.0823 5.58815 22.459C16.3807 17.3729 29.6555 12.1786 41.4193 7.30899Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</Icon>
|
||||
)
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
* This function takes an array and divides it into smaller arrays,
|
||||
* or "chunks", each containing a specified number of elements.
|
||||
* @param array The array to be split into chunks.
|
||||
* @param size The size of each chunk. The default size is 10.
|
||||
* @param size The size of each chunk. The default size is 15.
|
||||
* @returns An array containing smaller subarrays (chunks), each with a length defined by the size.
|
||||
*/
|
||||
export function chunkArray(array: any[], size = 15): any[] {
|
||||
|
||||
14
package.json
@@ -23,12 +23,12 @@
|
||||
"format": "concurrently -c auto -g -n prettier,embark \"prettier -c .\" \"yarn workspace semaphore-docs format\"",
|
||||
"format:write": "concurrently -c auto -g -n prettier,embark \"prettier -w .\" \"yarn workspace semaphore-docs format:write\"",
|
||||
"docs": "typedoc",
|
||||
"version:bump": "yarn workspaces foreach -A --no-private version -d ${0} && yarn version apply --all && yarn remove:stable-version-field && NO_HOOK=1 git commit -am \"chore: v${0}\" && git tag v${0}",
|
||||
"version:publish": "yarn build:libraries && yarn clean:cli-templates && yarn workspaces foreach -A --no-private npm publish --tolerate-republish --access public",
|
||||
"version:bump": "scripts/version.ts ${0}",
|
||||
"version:publish": "scripts/publish.ts",
|
||||
"version:release": "changelogithub",
|
||||
"clean": "ts-node scripts/clean-apps.ts && ts-node scripts/clean-packages.ts && yarn clean:cli-templates && rimraf node_modules",
|
||||
"clean:cli-templates": "ts-node scripts/clean-cli-templates.ts",
|
||||
"remove:stable-version-field": "ts-node scripts/remove-stable-version-field.ts && yarn format:write",
|
||||
"clean": "scripts/clean-apps.ts && scripts/clean-packages.ts && yarn clean:cli-templates && rimraf node_modules",
|
||||
"clean:cli-templates": "scripts/clean-cli-templates.ts",
|
||||
"remove:stable-version-field": "scripts/remove-stable-version-field.ts && yarn format:write",
|
||||
"precommit": "lint-staged",
|
||||
"postinstall": "husky && git config --local core.editor cat"
|
||||
},
|
||||
@@ -57,6 +57,7 @@
|
||||
"@types/glob": "^7.2.0",
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/node": "^20",
|
||||
"@types/semver": "^7",
|
||||
"@typescript-eslint/eslint-plugin": "^7.0.2",
|
||||
"@typescript-eslint/parser": "^7.0.2",
|
||||
"changelogithub": "0.12.7",
|
||||
@@ -78,7 +79,8 @@
|
||||
"lint-staged": "^15.2.2",
|
||||
"prettier": "^3.2.5",
|
||||
"rimraf": "^5.0.5",
|
||||
"snarkjs": "0.7.4",
|
||||
"semver": "^7.6.2",
|
||||
"snarkjs": "0.7.5",
|
||||
"ts-jest": "^29.1.2",
|
||||
"ts-node": "^10.9.2",
|
||||
"tslib": "^2.6.2",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 Ethereum Foundation
|
||||
Copyright (c) 2025 Ethereum Foundation
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
🔎 Issues
|
||||
</a>
|
||||
<span> | </span>
|
||||
<a href="https://semaphore.pse.dev/discord">
|
||||
<a href="https://semaphore.pse.dev/telegram">
|
||||
🗣️ Chat & Support
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@semaphore-protocol/circuits",
|
||||
"version": "4.0.2",
|
||||
"version": "4.14.0",
|
||||
"description": "Semaphore Circom circuits to generate zero-knowledge proofs.",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
@@ -24,15 +24,15 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@zk-kit/binary-merkle-root.circom": "1.0.0",
|
||||
"@zk-kit/binary-merkle-root.circom": "2.0.0",
|
||||
"circomlib": "2.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@semaphore-protocol/core": "workspace:^",
|
||||
"@types/mocha": "^10.0.6",
|
||||
"@zk-kit/baby-jubjub": "1.0.1",
|
||||
"circomkit": "^0.0.19",
|
||||
"@zk-kit/baby-jubjub": "1.0.3",
|
||||
"circomkit": "0.3.3",
|
||||
"mocha": "^10.2.0",
|
||||
"poseidon-lite": "^0.2.0"
|
||||
"poseidon-lite": "^0.3.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ template Semaphore(MAX_DEPTH) {
|
||||
// See the Semaphore identity package to know more about how the identity is generated:
|
||||
// https://github.com/semaphore-protocol/semaphore/tree/main/packages/identity.
|
||||
signal input secret;
|
||||
signal input merkleProofLength, merkleProofIndices[MAX_DEPTH], merkleProofSiblings[MAX_DEPTH];
|
||||
signal input merkleProofLength, merkleProofIndex, merkleProofSiblings[MAX_DEPTH];
|
||||
signal input message;
|
||||
signal input scope;
|
||||
|
||||
@@ -56,9 +56,9 @@ template Semaphore(MAX_DEPTH) {
|
||||
// Proof of membership verification.
|
||||
// The Merkle root passed as output must be equal to that calculated within
|
||||
// the circuit through the inputs of the Merkle proof.
|
||||
// See https://github.com/privacy-scaling-explorations/zk-kit/blob/main/packages/circuits/circom/binary-merkle-root.circom
|
||||
// See https://github.com/privacy-scaling-explorations/zk-kit.circom/blob/main/packages/binary-merkle-root/src/binary-merkle-root.circom
|
||||
// to know more about how the 'BinaryMerkleRoot' template works.
|
||||
merkleRoot <== BinaryMerkleRoot(MAX_DEPTH)(identityCommitment, merkleProofLength, merkleProofIndices, merkleProofSiblings);
|
||||
merkleRoot <== BinaryMerkleRoot(MAX_DEPTH)(identityCommitment, merkleProofLength, merkleProofIndex, merkleProofSiblings);
|
||||
|
||||
// Nullifier generation.
|
||||
// The nullifier is a value that essentially identifies the proof generated in a specific scope
|
||||
|
||||
@@ -12,21 +12,18 @@ export const circomkit = new Circomkit({
|
||||
})
|
||||
|
||||
export function generateMerkleProof(group: Group, _index: number, maxDepth: number) {
|
||||
const { siblings: merkleProofSiblings, index } = group.generateMerkleProof(_index)
|
||||
const { siblings: merkleProofSiblings, index: merkleProofIndex } = group.generateMerkleProof(_index)
|
||||
|
||||
// The index must be converted to a list of indices, 1 for each tree level.
|
||||
// The circuit tree depth is 20, so the number of siblings must be 20, even if
|
||||
// the tree depth is actually 3. The missing siblings can be set to 0, as they
|
||||
// won't be used to calculate the root in the circuit.
|
||||
const merkleProofIndices: number[] = []
|
||||
// For example, if the circuit expects a Merkle tree of depth 20,
|
||||
// the input must always include 20 sibling nodes, even if the actual
|
||||
// tree depth is smaller (e.g., 3). The unused sibling positions can be
|
||||
// filled with 0, as they won't affect the root calculation in the circuit.
|
||||
|
||||
for (let i = 0; i < maxDepth; i += 1) {
|
||||
merkleProofIndices.push((index >> i) & 1)
|
||||
|
||||
if (merkleProofSiblings[i] === undefined) {
|
||||
merkleProofSiblings[i] = BigInt(0)
|
||||
}
|
||||
}
|
||||
|
||||
return { merkleProofSiblings, merkleProofIndices }
|
||||
return { merkleProofSiblings, merkleProofIndex }
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ const r = 2188824287183927522224640574525727508854836440041603434369820418657580
|
||||
|
||||
describe("semaphore", () => {
|
||||
let circuit: WitnessTester<
|
||||
["secret", "merkleProofLength", "merkleProofIndices", "merkleProofSiblings", "scope", "message"],
|
||||
["secret", "merkleProofLength", "merkleProofIndex", "merkleProofSiblings", "scope", "message"],
|
||||
["nullifier", "merkleRoot"]
|
||||
>
|
||||
|
||||
@@ -36,12 +36,12 @@ describe("semaphore", () => {
|
||||
|
||||
const group = new Group([commitment, 2n, 3n])
|
||||
|
||||
const { merkleProofSiblings, merkleProofIndices } = generateMerkleProof(group, 0, MAX_DEPTH)
|
||||
const { merkleProofSiblings, merkleProofIndex } = generateMerkleProof(group, 0, MAX_DEPTH)
|
||||
|
||||
const INPUT = {
|
||||
secret,
|
||||
merkleProofLength: group.depth,
|
||||
merkleProofIndices,
|
||||
merkleProofIndex,
|
||||
merkleProofSiblings,
|
||||
scope,
|
||||
message
|
||||
@@ -61,12 +61,12 @@ describe("semaphore", () => {
|
||||
const commitment = poseidon2(mulPointEscalar(Base8, secret))
|
||||
const group = new Group([commitment, 2n, 3n])
|
||||
|
||||
const { merkleProofSiblings, merkleProofIndices } = generateMerkleProof(group, 0, MAX_DEPTH)
|
||||
const { merkleProofSiblings, merkleProofIndex } = generateMerkleProof(group, 0, MAX_DEPTH)
|
||||
|
||||
const INPUT = {
|
||||
secret,
|
||||
merkleProofLength: group.depth,
|
||||
merkleProofIndices,
|
||||
merkleProofIndex,
|
||||
merkleProofSiblings,
|
||||
scope,
|
||||
message
|
||||
@@ -81,12 +81,12 @@ describe("semaphore", () => {
|
||||
const commitment = poseidon2(mulPointEscalar(Base8, secret))
|
||||
const group = new Group([commitment, 2n, 3n])
|
||||
|
||||
const { merkleProofSiblings, merkleProofIndices } = generateMerkleProof(group, 0, MAX_DEPTH)
|
||||
const { merkleProofSiblings, merkleProofIndex } = generateMerkleProof(group, 0, MAX_DEPTH)
|
||||
|
||||
const INPUT = {
|
||||
secret,
|
||||
merkleProofLength: group.depth,
|
||||
merkleProofIndices,
|
||||
merkleProofIndex,
|
||||
merkleProofSiblings,
|
||||
scope,
|
||||
message
|
||||
@@ -100,12 +100,12 @@ describe("semaphore", () => {
|
||||
|
||||
const group = new Group([commitment, 2n, 3n])
|
||||
|
||||
const { merkleProofSiblings, merkleProofIndices } = generateMerkleProof(group, 0, MAX_DEPTH)
|
||||
const { merkleProofSiblings, merkleProofIndex } = generateMerkleProof(group, 0, MAX_DEPTH)
|
||||
|
||||
const INPUT = {
|
||||
secret,
|
||||
merkleProofLength: group.depth,
|
||||
merkleProofIndices,
|
||||
merkleProofIndex,
|
||||
merkleProofSiblings,
|
||||
scope,
|
||||
message
|
||||
|
||||
13
packages/cli-template-contracts-foundry/.editorconfig
Normal file
@@ -0,0 +1,13 @@
|
||||
#root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
max_line_length = 120
|
||||
indent_size = 4
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
3
packages/cli-template-contracts-foundry/.env.example
Normal file
@@ -0,0 +1,3 @@
|
||||
SEPOLIA_RPC_URL=
|
||||
PRIVATE_KEY=
|
||||
ETHERSCAN_API_KEY=
|
||||
43
packages/cli-template-contracts-foundry/.gitignore
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
node_modules
|
||||
.env
|
||||
|
||||
# solidity-coverage files
|
||||
/coverage
|
||||
/coverage.json
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
.DS_Store
|
||||
|
||||
# yarn v3
|
||||
.pnp.*
|
||||
.pnp.js
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Foundry artifact
|
||||
cache/
|
||||
out/
|
||||
|
||||
# artifact for deploying on local Anvil node
|
||||
**/31337
|
||||
|
||||
30
packages/cli-template-contracts-foundry/.prettierignore
Normal file
@@ -0,0 +1,30 @@
|
||||
# dependencies
|
||||
node_modules
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
.yarn
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# testing
|
||||
coverage
|
||||
coverage.json
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Foundry artifact
|
||||
cache/
|
||||
out/
|
||||
|
||||
# artifact for deploying on local Anvil node
|
||||
**/31337
|
||||
6
packages/cli-template-contracts-foundry/.prettierrc.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"semi": false,
|
||||
"arrowParens": "always",
|
||||
"trailingComma": "none",
|
||||
"plugins": ["prettier-plugin-solidity"]
|
||||
}
|
||||
6
packages/cli-template-contracts-foundry/.solhint.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "solhint:recommended",
|
||||
"rules": {
|
||||
"func-visibility": ["error", { "ignoreConstructors": true }]
|
||||
}
|
||||
}
|
||||
893
packages/cli-template-contracts-foundry/.yarn/releases/yarn-4.1.0.cjs
vendored
Executable file
7
packages/cli-template-contracts-foundry/.yarnrc.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
compressionLevel: mixed
|
||||
|
||||
enableGlobalCache: false
|
||||
|
||||
nodeLinker: node-modules
|
||||
|
||||
yarnPath: .yarn/releases/yarn-4.1.0.cjs
|
||||
113
packages/cli-template-contracts-foundry/README.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# Semaphore Foundry Template
|
||||
|
||||
This project demonstrates a basic Semaphore use case. It comes with a sample contract, a test for that contract and a sample script that deploys that contract.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
This project requires [**Foundry**](https://getfoundry.sh/), and thus a [**Rust environment**](https://www.rust-lang.org/), installed in the machine.
|
||||
|
||||
## Install
|
||||
|
||||
### Install dependencies
|
||||
|
||||
```bash
|
||||
yarn
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Compile contracts
|
||||
|
||||
```bash
|
||||
yarn compile
|
||||
```
|
||||
|
||||
### Test contracts
|
||||
|
||||
```bash
|
||||
yarn test
|
||||
```
|
||||
|
||||
You can also generate a test coverage report:
|
||||
|
||||
```bash
|
||||
yarn test:coverage
|
||||
```
|
||||
|
||||
Or a test gas report:
|
||||
|
||||
```bash
|
||||
yarn test:gas-report
|
||||
```
|
||||
|
||||
You can also start a local [Anvil node](https://book.getfoundry.sh/anvil/) with Semaphore and Feedback contracts deployed on it with:
|
||||
|
||||
```bash
|
||||
yarn dev
|
||||
```
|
||||
|
||||
### Code quality and formatting
|
||||
|
||||
Run [solhint](https://github.com/protofire/solhint) to analyze the code and catch bugs:
|
||||
|
||||
```bash
|
||||
yarn lint
|
||||
```
|
||||
|
||||
Run [Prettier](https://prettier.io/) to check formatting rules:
|
||||
|
||||
```bash
|
||||
yarn prettier
|
||||
```
|
||||
|
||||
Or to automatically format the code:
|
||||
|
||||
```bash
|
||||
yarn prettier:write
|
||||
```
|
||||
|
||||
### Integrating with Semaphore Boilerplate
|
||||
|
||||
You can also integrate this project with [Semaphore Boilerplate](https://github.com/semaphore-protocol/boilerplate), using this project as the contract end and connecting with Boilerplate front end.
|
||||
|
||||
1. In `cli-template-contracts-foundry` package directory, run:
|
||||
|
||||
```sh
|
||||
yarn install
|
||||
yarn dev
|
||||
```
|
||||
|
||||
After running `yarn dev`, notice the output of
|
||||
|
||||
```sh
|
||||
# ...
|
||||
# ...
|
||||
|
||||
== Return ==
|
||||
feedbackAddr: address 0x6f1AFCA8BCA87bF02091AF6187a5002802f9FB31
|
||||
semaphoreAddr: address 0xb730ce6CAE3FB706e83E4E00dFA31623966570eB
|
||||
semaphoreVerifierAddr: address 0xE2c114f548bEf410eaCe04D0390b61cc963df295
|
||||
|
||||
# ...
|
||||
# ...
|
||||
```
|
||||
|
||||
2. Now, with another terminal, clone Semaphore Boilerplate down:
|
||||
|
||||
```sh
|
||||
# Clone Semaphore boilerplate and build dependencies
|
||||
git clone https://github.com/semaphore-protocol/boilerplate.git
|
||||
cd boilerplate
|
||||
yarn install
|
||||
|
||||
# Use the sample .env.example
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
3. Open the file `apps/web-app/.env.development`. Modify the values of `NEXT_PUBLIC_FEEDBACK_CONTRACT_ADDRESS` and `NEXT_PUBLIC_SEMAPHORE_CONTRACT_ADDRESS` with **feedbackAddr** and **semaphoreAddr** values shown in step 1.
|
||||
|
||||
4. Run the Boilerplate front end:
|
||||
|
||||
```sh
|
||||
yarn dev:web-app
|
||||
```
|
||||
15
packages/cli-template-contracts-foundry/foundry.toml
Normal file
@@ -0,0 +1,15 @@
|
||||
[profile.default]
|
||||
src = "src"
|
||||
out = "out"
|
||||
script = "script"
|
||||
libs = ["node_modules"]
|
||||
allow_paths = ["*", "../.."]
|
||||
|
||||
[rpc_endpoints]
|
||||
anvil = "http://127.0.0.1:8545"
|
||||
# sepolia = "${SEPOLIA_RPC_URL}"
|
||||
|
||||
[etherscan]
|
||||
# sepolia = { key = "${ETHERSCAN_API_KEY}" }
|
||||
|
||||
# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
|
||||
45
packages/cli-template-contracts-foundry/package.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "@semaphore-protocol/cli-template-contracts-foundry",
|
||||
"version": "4.14.0",
|
||||
"description": "Semaphore Foundry template.",
|
||||
"license": "Unlicense",
|
||||
"devDependencies": {
|
||||
"@semaphore-protocol/contracts": "4.14.0",
|
||||
"@zk-kit/lean-imt.sol": "2.0.1",
|
||||
"forge-std": "github:foundry-rs/forge-std#v1.9.4",
|
||||
"poseidon-solidity": "0.0.5",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier-plugin-solidity": "^1.3.1",
|
||||
"solhint": "^4.1.1",
|
||||
"wait-on": "^8.0.1"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "anvil & (wait-on tcp:8545 && forge script script/DeployFeedback.s.sol --rpc-url anvil --broadcast --sender 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266)",
|
||||
"compile": "forge build",
|
||||
"clean": "forge clean",
|
||||
"test": "forge test -vvv",
|
||||
"test:report-gas": "forge test --gas-report",
|
||||
"test:coverage": "forge coverage",
|
||||
"lint": "yarn solhint \"{script,src,test}/**/*.sol\"",
|
||||
"prettier": "prettier -c \"**/*.{json,md,svg,yml,sol}\"",
|
||||
"prettier:write": "prettier -w \"**/*.{json,md,svg,yml,sol}\"",
|
||||
"check": "yarn test & yarn lint & yarn prettier",
|
||||
"prepublish": "tar -czf files.tgz .gitignore .yarn .yarnrc.yml"
|
||||
},
|
||||
"files": [
|
||||
"src",
|
||||
"test",
|
||||
"script",
|
||||
"package.json",
|
||||
"foundry.toml",
|
||||
"remappings.txt",
|
||||
"README.md",
|
||||
"files.tgz",
|
||||
".editorconfig",
|
||||
".env.example",
|
||||
".prettierignore",
|
||||
".prettierrc.json",
|
||||
".solhint.json"
|
||||
],
|
||||
"packageManager": "yarn@4.1.0"
|
||||
}
|
||||
4
packages/cli-template-contracts-foundry/remappings.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
@semaphore/contracts/=./node_modules/@semaphore-protocol/contracts/
|
||||
@zk-kit/lean-imt.sol/=./node_modules/@zk-kit/lean-imt.sol/
|
||||
forge-std/=./node_modules/forge-std/src/
|
||||
poseidon-solidity/=./node_modules/poseidon-solidity/
|
||||
@@ -0,0 +1,37 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.23;
|
||||
|
||||
import {Feedback} from "../src/Feedback.sol";
|
||||
import {Semaphore} from "@semaphore/contracts/Semaphore.sol";
|
||||
import {SemaphoreVerifier} from "@semaphore/contracts/base/SemaphoreVerifier.sol";
|
||||
import {ISemaphoreVerifier} from "@semaphore/contracts/interfaces/ISemaphoreVerifier.sol";
|
||||
import {Script} from "forge-std/Script.sol";
|
||||
|
||||
// Passing SALT parameter to use CREATE2 for deterministic contract address
|
||||
bytes32 constant SALT = bytes32(0);
|
||||
|
||||
contract DeployFeedback is Script {
|
||||
function run() external returns (address feedbackAddr, address semaphoreAddr, address semaphoreVerifierAddr) {
|
||||
// Default to use the first test user private key of anvil node
|
||||
uint256 deployerPrivateKey = vm.envOr(
|
||||
"PRIVATE_KEY",
|
||||
uint256(0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80)
|
||||
);
|
||||
|
||||
vm.startBroadcast(deployerPrivateKey);
|
||||
|
||||
// Deploy SemaphoreVerifier
|
||||
SemaphoreVerifier semaphoreVerifierContract = new SemaphoreVerifier{salt: SALT}();
|
||||
semaphoreVerifierAddr = address(semaphoreVerifierContract);
|
||||
|
||||
// Deploy Semaphore
|
||||
Semaphore semaphoreContract = new Semaphore{salt: SALT}(ISemaphoreVerifier(semaphoreVerifierAddr));
|
||||
semaphoreAddr = address(semaphoreContract);
|
||||
|
||||
// Deploy Feedback
|
||||
Feedback feedbackContract = new Feedback{salt: SALT}(semaphoreAddr);
|
||||
feedbackAddr = address(feedbackContract);
|
||||
|
||||
vm.stopBroadcast();
|
||||
}
|
||||
}
|
||||
39
packages/cli-template-contracts-foundry/src/Feedback.sol
Normal file
@@ -0,0 +1,39 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.23;
|
||||
|
||||
import {ISemaphore} from "@semaphore/contracts/interfaces/ISemaphore.sol";
|
||||
|
||||
contract Feedback {
|
||||
ISemaphore public semaphore;
|
||||
|
||||
uint256 public groupId;
|
||||
|
||||
constructor(address semaphoreAddress) {
|
||||
semaphore = ISemaphore(semaphoreAddress);
|
||||
|
||||
groupId = semaphore.createGroup();
|
||||
}
|
||||
|
||||
function joinGroup(uint256 identityCommitment) external {
|
||||
semaphore.addMember(groupId, identityCommitment);
|
||||
}
|
||||
|
||||
function sendFeedback(
|
||||
uint256 merkleTreeDepth,
|
||||
uint256 merkleTreeRoot,
|
||||
uint256 nullifier,
|
||||
uint256 feedback,
|
||||
uint256[8] calldata points
|
||||
) external {
|
||||
ISemaphore.SemaphoreProof memory proof = ISemaphore.SemaphoreProof(
|
||||
merkleTreeDepth,
|
||||
merkleTreeRoot,
|
||||
nullifier,
|
||||
feedback,
|
||||
groupId,
|
||||
points
|
||||
);
|
||||
|
||||
semaphore.validateProof(groupId, proof);
|
||||
}
|
||||
}
|
||||
74
packages/cli-template-contracts-foundry/test/Feedback.t.sol
Normal file
@@ -0,0 +1,74 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.23;
|
||||
|
||||
import {Test} from "forge-std/Test.sol";
|
||||
import {ISemaphore} from "@semaphore/contracts/interfaces/ISemaphore.sol";
|
||||
import {ISemaphoreGroups} from "@semaphore/contracts/interfaces/ISemaphoreGroups.sol";
|
||||
import {Feedback} from "../src/Feedback.sol";
|
||||
import {DeployFeedback} from "../script/DeployFeedback.s.sol";
|
||||
|
||||
contract FeedbackTest is Test {
|
||||
event MemberAdded(uint256 indexed groupId, uint256 index, uint256 identityCommitment, uint256 merkleTreeRoot);
|
||||
|
||||
Feedback internal feedbackContract;
|
||||
ISemaphore internal semaphoreContract;
|
||||
ISemaphoreGroups internal semaphoreGroups;
|
||||
uint256 internal groupId;
|
||||
|
||||
function setUp() external {
|
||||
DeployFeedback deployFeedback = new DeployFeedback();
|
||||
(address feedbackAddress, address semaphoreAddress, ) = deployFeedback.run();
|
||||
feedbackContract = Feedback(feedbackAddress);
|
||||
semaphoreContract = ISemaphore(semaphoreAddress);
|
||||
semaphoreGroups = ISemaphoreGroups(semaphoreAddress);
|
||||
groupId = feedbackContract.groupId();
|
||||
}
|
||||
|
||||
function testGroupCreatedInConstructor() public view {
|
||||
uint256 groupCount = semaphoreContract.groupCounter();
|
||||
assertEq(groupCount, 1);
|
||||
}
|
||||
|
||||
function testJoinGroup() public {
|
||||
// The commitment below is generated with private key of the first account in Anvil
|
||||
uint256 identityCommitment = 15072455385723004728391568434269917452175057560864330595979104241296826134229;
|
||||
|
||||
// Test: expect an event emitted. Check for all event topics and data
|
||||
vm.expectEmit(true, true, true, true);
|
||||
emit MemberAdded(groupId, 0, identityCommitment, identityCommitment);
|
||||
|
||||
feedbackContract.joinGroup(identityCommitment);
|
||||
}
|
||||
|
||||
function testSendFeedback() public {
|
||||
uint256[] memory commitments = new uint256[](2);
|
||||
commitments[0] = uint256(11005642493773047649202648265396872197147567800455247120861783398111750817516);
|
||||
commitments[1] = uint256(14473821761500463903284857947161896352613497175238126022206384102438097355186);
|
||||
|
||||
for (uint256 i = 0; i < commitments.length; ++i) {
|
||||
feedbackContract.joinGroup(commitments[i]);
|
||||
}
|
||||
|
||||
uint256 merkleTreeDepth = 1;
|
||||
uint256 merkleTreeRoot = semaphoreGroups.getMerkleTreeRoot(groupId);
|
||||
uint256 feedback = uint256(bytes32("Hello World"));
|
||||
|
||||
// These values are computed by running through @semaphore-protocol/circuits
|
||||
uint256 nullifier = 14622092170088252518938850323258916742048811914834592843410744760450844885096;
|
||||
uint256[8] memory points = [
|
||||
2004484873491928515306456072357737929124240734208600886081152392890959117520,
|
||||
21291026142870585364296731900941597996672838511394659364623185352043543529323,
|
||||
4657264777014371046112557309523098953851041383509685591373847255581509612788,
|
||||
6904165961903336246592681066375875983213983935764940579845010085396463328555,
|
||||
1952750241178995674697344628236393389729638396609772141225880353616301956443,
|
||||
106937615136633409337870509099767689510837462832227699340906789167349502398,
|
||||
13080722838047436988558418790480431472161933638137155324683844808531903905810,
|
||||
2547578906197450986657523555784319153413167960139250957065929818900731634820
|
||||
];
|
||||
|
||||
vm.expectEmit(true, true, true, true);
|
||||
emit ISemaphore.ProofValidated(groupId, merkleTreeDepth, merkleTreeRoot, nullifier, feedback, groupId, points);
|
||||
|
||||
feedbackContract.sendFeedback(merkleTreeDepth, merkleTreeRoot, nullifier, feedback, points);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@semaphore-protocol/cli-template-contracts-hardhat",
|
||||
"version": "4.0.2",
|
||||
"version": "4.14.0",
|
||||
"description": "Semaphore Hardhat template.",
|
||||
"license": "Unlicense",
|
||||
"files": [
|
||||
@@ -16,7 +16,8 @@
|
||||
".prettierrc.json",
|
||||
"hardhat.config.ts",
|
||||
"tsconfig.json",
|
||||
"README.md"
|
||||
"README.md",
|
||||
".solhint.json"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
@@ -41,9 +42,9 @@
|
||||
"@nomicfoundation/hardhat-network-helpers": "^1.0.0",
|
||||
"@nomicfoundation/hardhat-toolbox": "^4.0.0",
|
||||
"@nomicfoundation/hardhat-verify": "^2.0.0",
|
||||
"@semaphore-protocol/core": "4.0.2",
|
||||
"@semaphore-protocol/hardhat": "4.0.2",
|
||||
"@semaphore-protocol/utils": "4.0.2",
|
||||
"@semaphore-protocol/core": "4.14.0",
|
||||
"@semaphore-protocol/hardhat": "4.14.0",
|
||||
"@semaphore-protocol/utils": "4.14.0",
|
||||
"@typechain/ethers-v6": "^0.5.0",
|
||||
"@typechain/hardhat": "^9.0.0",
|
||||
"@types/chai": "^4.2.0",
|
||||
@@ -59,7 +60,7 @@
|
||||
"eslint-config-airbnb-typescript": "^17.1.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"ethers": "^6.4.0",
|
||||
"ethers": "^6.13.4",
|
||||
"hardhat": "^2.20.1",
|
||||
"hardhat-gas-reporter": "^1.0.8",
|
||||
"prettier": "^3.2.5",
|
||||
@@ -71,7 +72,7 @@
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@semaphore-protocol/contracts": "4.0.2"
|
||||
"@semaphore-protocol/contracts": "4.14.0"
|
||||
},
|
||||
"packageManager": "yarn@4.1.0"
|
||||
}
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
"@nomicfoundation/hardhat-network-helpers": "^1.0.0",
|
||||
"@nomicfoundation/hardhat-toolbox": "^4.0.0",
|
||||
"@nomicfoundation/hardhat-verify": "^2.0.0",
|
||||
"@semaphore-protocol/core": "4.0.2",
|
||||
"@semaphore-protocol/hardhat": "4.0.2",
|
||||
"@semaphore-protocol/utils": "4.0.2",
|
||||
"@semaphore-protocol/core": "4.14.0",
|
||||
"@semaphore-protocol/hardhat": "4.14.0",
|
||||
"@semaphore-protocol/utils": "4.14.0",
|
||||
"@typechain/ethers-v6": "^0.5.0",
|
||||
"@typechain/hardhat": "^9.0.0",
|
||||
"@types/chai": "^4.2.0",
|
||||
@@ -38,7 +38,7 @@
|
||||
"eslint-config-airbnb-typescript": "^17.1.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"ethers": "^6.4.0",
|
||||
"ethers": "^6.13.4",
|
||||
"hardhat": "^2.20.1",
|
||||
"hardhat-gas-reporter": "^1.0.8",
|
||||
"prettier": "^3.2.5",
|
||||
@@ -50,7 +50,7 @@
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@semaphore-protocol/contracts": "4.0.2"
|
||||
"@semaphore-protocol/contracts": "4.14.0"
|
||||
},
|
||||
"packageManager": "yarn@4.1.0"
|
||||
}
|
||||
|
||||