Compare commits

...

103 Commits

Author SHA1 Message Date
Vivian Plasencia
cd04b0c5c7 chore: v4.12.0 2025-07-17 16:38:26 +02:00
aritra
b6a7a9883b refactor: transport selection logic (#1007) 2025-07-17 16:30:04 +02:00
aritra
fc1fe4d086 Allow injecting existing PublicClient into SemaphoreViem (#1006)
* refactor: allow injecting existing PublicClient into SemaphoreViem

* fix: remove comment
2025-07-17 13:48:13 +02:00
Vivian Plasencia
feb8c9c97d docs(website): add ethdam video recording (#996) 2025-06-09 15:50:00 +02:00
César Henrique
b56e9690a8 Test(data): add test coverage for getEvents utility (#989)
test(data): add test coverage for getEvents utility

re #986
2025-05-26 19:10:24 +02:00
Vivian Plasencia
c973bab503 cocs: add new issue link (#988)
* docs: update contributing file

* docs: update pull request template

* docs: add new issue link to contributing
2025-05-25 23:14:11 +02:00
Vivian Plasencia
27aee4bf43 Docs/update contributing (#987)
* docs: update contributing file

* docs: update pull request template
2025-05-25 22:54:29 +02:00
Vivian Plasencia
ea62310df6 chore: v4.11.1 2025-05-21 16:49:07 +02:00
Vivian Plasencia
6bc415f4d5 fix(data): fix semaphore viem class (#985)
re #984
2025-05-21 16:44:38 +02:00
Vivian Plasencia
18f77ac0bb chore: v4.11.0 2025-05-20 14:00:27 +02:00
Sarkazein
f3c4cf27e2 feat(data): implement Viem lib alternative to SemaphoreEthers (#966)
* feat(data): implement Viem lib alternative to Ethers for @semaphore-protocol/data package class

This adds a Viem-based alternative to SemaphoreEthers, allowing
developers to choose their preferred Ethereum library.

Closes #343

* chore(data): update yarn.lock for viem dependency

* chore(data): improve test coverage for SemaphoreViem class

* chore(data): improve test coverage for SemaphoreViem class
2025-05-20 13:51:34 +02:00
Sri Hari S
57132a38df Added warning to the Semaphore docs (#983)
Update identities.mdx

Added warning to the Semaphore docs
2025-05-19 13:54:36 +02:00
Vivian Plasencia
6ef16976f7 docs(website): update semaphore roadmap (#981) 2025-05-07 14:42:59 +02:00
Vivian Plasencia
2849ca1d24 chore: v4.10.0 2025-05-06 22:36:52 +02:00
Vivian Plasencia
d05d783852 chore:deploy contracts (#980)
* chore: update semaphore contract address

re #978

* feat: add ethereum as a supported network

re #977

* feat: add ethereum subgraph and deploy subgraphs

re #978, #977
2025-05-06 22:28:08 +02:00
Vivian Plasencia
993e46a427 docs(website): update events (#979) 2025-05-05 19:03:45 +02:00
Jimmy Chu
f984c1e864 chore(website): add a new project in project page (#972) 2025-04-03 00:11:54 +02:00
Vivian Plasencia
5c9d1737d3 chore: v4.9.2 2025-03-31 12:50:00 +02:00
Vivian Plasencia
1318b0e74b docs: update releases section in readme file 2025-03-31 12:44:51 +02:00
Vivian Plasencia
c0fcc94e82 docs: add more info to the readme file about the release of the packages (#971) 2025-03-31 12:41:49 +02:00
Vivian Plasencia
e70ae1151b chore: update leanimt sol version (#970) 2025-03-31 12:30:58 +02:00
Vivian Plasencia
fd38539908 docs(website): add scaling semaphore with pir to the roadmap (#969) 2025-03-18 01:03:24 +01:00
Vivian Plasencia
8bd45d8c46 docs: add specification document link to website and docs (#965) 2025-03-06 13:55:29 +01:00
Vivian Plasencia
534e69683a docs(website): update roadmap to add semaphore noir implementation (#962) 2025-03-04 12:35:58 +01:00
Vivian Plasencia
a0a3b9380b docs(website): update spec status to true on roadmap (#959) 2025-03-03 11:02:33 +01:00
Vivian Plasencia
bc9f7df1da chore: v4.9.1 2025-02-24 23:19:29 +01:00
Vivian Plasencia
571ffdab0e chore(group): update leanimt package version (#957) 2025-02-24 23:15:07 +01:00
ewynx
773696f40c Fix broken link for LeanMIT (#956)
chore: fixes broken link for LeanMIT
2025-02-24 22:26:29 +01:00
Vivian Plasencia
f679583498 chore: v4.9.0 2025-02-03 13:26:48 +01:00
Vivian Plasencia
05926d0ef7 chore: update utils package version (#954) 2025-02-03 12:57:30 +01:00
Faezeh Shakouri
eef277281d Refactor/type-validation (#951)
* chore(data): add @zk-kit/utils dependency

* refactor(data): refactor parameter validation using @zk-kit/utils
2025-02-03 12:40:32 +01:00
Chidozie DAVID
b96467f3d4 revert(subgraph): reverses changes made (#952)
re #915
2025-02-03 12:35:25 +01:00
zanastas
e530412f27 Add new article (#918)
* Add new article

* Update apps/website/src/data/articles.json

remove referral link

Co-authored-by: Vivian Plasencia <v.pcalana@gmail.com>

---------

Co-authored-by: Vivian Plasencia <v.pcalana@gmail.com>
2025-01-29 00:04:39 +01:00
Vivian Plasencia
4df7693367 chore(subgraph): update matchstick-as dependency (#946)
* chore(subgraph): update matchstick-as dependency

* chore(subgraph): update dependency versions

* ci: update pull request workflow to install libssl1.1 before testing the subgraph

* ci: update pull requests workflow

* ci: update ubuntu version

* ci: update ubuntu version in tests

* ci: update ubuntu version
2025-01-27 14:47:11 +01:00
Sumit Vekariya
0ca80ca716 docs: fixed circuit logic url (#931)
fix: circuit logic url
2025-01-27 13:13:39 +01:00
youyyytrok
ed8141e873 docs: fix broken link and typo correction (#923)
* broken redirect CONTRIBUTING.md

* typo README.md
2025-01-27 13:10:57 +01:00
Vivian Plasencia
0f4aca3ded docs: make year update dynamically on website and docs (#945)
* docs: make year update dynamically on website and docs

* docs(docs): make year update dynamically
2025-01-20 21:45:32 +01:00
Vivian Plasencia
6e2ef756bc docs(website): update roadmap (#943)
docs(website): update roadmap on the website
2025-01-20 19:59:46 +01:00
hanghuge
c2dce437b4 chore: fix 404 status URL (#917)
Signed-off-by: hanghuge <cmoman@outlook.com>
2025-01-20 12:43:47 +00:00
0xpanoramix
8b91d75c6f feat(website): add obscurus to projects section (#941)
re #939
2025-01-20 13:06:46 +01:00
Vivian Plasencia
abfcf9f006 docs: update contributing and pull_request_template files 2025-01-14 15:10:17 +01:00
Vivian Plasencia
a2e8f5a15c chore: v4.8.2 2024-12-18 13:06:36 +01:00
Vivian Plasencia
f77df8d98f fix: include solhint config file in contracts templates (#929) 2024-12-18 13:01:35 +01:00
Vivian Plasencia
2b9fde2676 chore: v4.8.1 2024-12-18 11:41:01 +01:00
Vivian Plasencia
ac4ddfc6eb chore(cli-template-contracts-foundry): add prepublish script (#927)
chore(cli-template-contracts-foundry): add prepublish script to publish foundry template
2024-12-18 11:32:36 +01:00
Vivian Plasencia
afae06e8e1 chore: v4.8.0 2024-12-17 15:06:02 +01:00
Jimmy Chu
4cc6980b55 Add CLI Foundry Template (cont.) (#905)
* Semaphore identity example code bug fix

* Receive suggestion for consistency

* chore: forge init

* forge install: forge-std

v1.9.2

* Foundry CLI First Draft

* modules

* forge install: semaphore

v4.0.3

* forge install: zk-kit.solidity

* forge install: poseidon-solidity

v0.0.5

* forge install: openzeppelin-contracts

v5.0.2

* modules

* forge install: semaphore

v4.0.3

* forge install: zk-kit.solidity

* forge install: poseidon-solidity

v0.0.5

* forge install: openzeppelin-contracts

v5.0.2

* modules

* forge install: semaphore

v4.0.3

* forge install: zk-kit.solidity

* forge install: poseidon-solidity

v0.0.5

* forge install: openzeppelin-contracts

v5.0.2

* modules

* forge install: semaphore

v4.0.3

* forge install: zk-kit.solidity

* forge install: poseidon-solidity

v0.0.5

* forge install: openzeppelin-contracts

v5.0.2

* modules

* forge install: semaphore

v4.0.3

* forge install: zk-kit.solidity

* forge install: poseidon-solidity

v0.0.5

* forge install: openzeppelin-contracts

v5.0.2

* modules

* forge install: semaphore

v4.0.3

* forge install: zk-kit.solidity

* forge install: poseidon-solidity

v0.0.5

* forge install: openzeppelin-contracts

v5.0.2

* forge install: forge-std

v1.9.2

* modules

* forge install: semaphore

v4.0.3

* forge install: zk-kit.solidity

* forge install: poseidon-solidity

v0.0.5

* forge install: openzeppelin-contracts

v5.0.2

* modules

* forge install: semaphore

v4.0.3

* forge install: zk-kit.solidity

* forge install: poseidon-solidity

v0.0.5

* forge install: openzeppelin-contracts

v5.0.2

* forge install: forge-std

v1.9.2

* modules

* forge install: semaphore

v4.0.3

* forge install: zk-kit.solidity

* forge install: poseidon-solidity

v0.0.5

* forge install: openzeppelin-contracts

v5.0.2

* forge install: forge-std

v1.9.2

* modules

* forge install: semaphore

v4.0.3

* forge install: zk-kit.solidity

* forge install: poseidon-solidity

v0.0.5

* forge install: openzeppelin-contracts

v5.0.2

* modules

* forge install: semaphore

v4.0.3

* forge install: zk-kit.solidity

* forge install: poseidon-solidity

v0.0.5

* forge install: openzeppelin-contracts

v5.0.2

* forge install: forge-std

v1.9.2

* modules

* forge install: semaphore

v4.0.3

* forge install: zk-kit.solidity

* forge install: poseidon-solidity

v0.0.5

* forge install: openzeppelin-contracts

v5.0.2

* forge install: forge-std

v1.9.2

* change test name

* modify declaration of semaphore and verifier

* Modify Test Function Name

* Add Test Chain Target

* forge std install

* refactor(cli-template-contracts-foundry): change default Anvil address and private key

* chore(cli-template-contracts-foundry): add comments

* refactor(cli-template-contracts-foundry): add Semaphore & SemaphoreVerifier addresses for test chain

* chore(cli-template-contracts-foundry): add forge coverage for Makefile

* chore(cli-template-contracts-foundry): add env.example

* docs(cli-template-contracts-foundry): add command instructions

* updated

* forge build works

* Fixed for linting

* chore(cli-template-contracts-foundry): make the lint, prettier, and lint-staged pass

* chore(cli-template-contracts-foundry): replace Makefile(removed) with package.json

* chore(cli-template-contracts-foundry): passing the ci test

* updated test

* feat(cli-template-contracts-foundry): complete cli-template-contracts-foundry

re #854, #185

* Update dependencies

* Add explanation on `yarn dev`

* fix(cli-template-contracts-foundry): fix `yarn dev` command and add docs on integrate w/ boilerplate

* Added yarnrc

* updated version

* Added Foundry in template option

---------

Co-authored-by: weipooppys93030 <55434365+weipooppys93030@users.noreply.github.com>
Co-authored-by: timou0911 <x0928048316@gmail.com>
Co-authored-by: csiejimmyliu <91661606+csiejimmyliu@users.noreply.github.com>
2024-12-17 14:48:36 +01:00
cedoor
6b04ec0eca chore: v4.7.3 2024-12-12 08:55:13 +00:00
Jake C-T
13a9480165 fix(core): bump ethers to v6.13.4 (#921)
Update ethers version to resolve ws security issue (CVE-2024-37890).
Move contract address check outside of branch statement so Typescript can see.
Add build instructions to setup to resolve 'Cannot find module '@semaphore-protocol/...' when
running tests for the first time.

re #920
2024-12-12 08:53:17 +00:00
cedoor
53967a9a3c chore: v4.7.2 2024-12-09 10:44:07 +01:00
Lautaro Di Sanza
5b92c0a2bc fix(group): after a sequence of updates a proof is invalid (#910)
* fix(group): after a sequence of updates a proof is invalid

* fix(group): after a sequence of updates a proof is invalid
2024-12-09 10:43:08 +01:00
Dmytrol
31c776ea68 Fix Typo in Quick Setup Documentation (#916)
typos quick-setup.md
2024-12-06 10:05:56 +05:30
Vivian Plasencia
8d83d59220 chore: v4.7.1 2024-12-05 18:49:30 +01:00
Vivian Plasencia
9e4fb5376c chore: update subgraph versions (#913)
re #912
2024-12-05 18:45:49 +01:00
Vivian Plasencia
745edb8e92 chore(website): add ethindia event to the website (#911) 2024-12-04 19:15:22 +01:00
Cypher Pepe
e732992952 docs: Typo Fixes and Documentation Updates (#907)
* typo howitworks.md

* typos libsemaphore.md

* typos what-is-semaphore.md

* typo subgraph.md

* typo identities.mdx

* typo proofs.mdx

* typos page.tsx

* typo page.tsx
2024-12-02 14:35:45 +07:00
Dmitry
3fcce15375 Fix typo in section.identities.box2.description Update code.json (#909)
Correct "identtity" to "identity"
2024-12-02 14:34:08 +07:00
Cedoor
ebb6731d89 docs(subgraph): update README.md (#906)
* docs(subgraph): update README.md

* docs(subgraph): update README.md
2024-11-28 18:02:55 +07:00
wangjingcun
0c23acf9cf chore: fix 404 status URL (#904)
Signed-off-by: wangjingcun <wangjingcun@aliyun.com>
2024-11-28 14:57:10 +07:00
cedoor
3e7db08eeb chore: v4.7.0 2024-11-27 17:24:57 +07:00
Cedoor
8adfc30da8 chore(contracts): add scroll sepolia to supported networks (#902)
* chore(contracts): add scroll sepolia to supported networks

* chore(contracts): deploy contracts on scroll sepolia

re #899

* chore(contracts): deploy semaphore on correct scroll sepolia network

re #899
2024-11-27 17:24:08 +07:00
sripwoud
42639662c3 docs: add soldeer install instructions (#903)
* docs: add  `soldeer` install instructions

* update README
2024-11-27 12:36:36 +07:00
Shikhar Singh
64025516c0 feat: clean node_modules before building subgraph (#884)
* feat(cli): remove @semaphore-protocol/cli prepublish script

The idea is to remove the prepublish script from the scripts object of the package.json file of
every cli template when the template is downloaded using the CLI.

BREAKING CHANGE: n

* refactor(cli): add comment

* refactor(cli): create seperate file for removePrePublishScript function

* refactor(cli): using updatedPackageJsonContent var instead of calling readFileSync again

* fix(subgraph): clean node_modules before building subgraph

* refactor(subgraph): fix: test typo

* refactor(subgraph): refactor: remove nohoist

* refactor(subgraph): refactor: workspaces structure
2024-11-26 09:42:42 +01:00
sripwoud
91f8a4be2a fix(ci): publish pkg if no releases yet (#900)
* fix(ci): publish pkg if no releases yet

* chore(ci): add workflow release trigger

* fix: workflow dispatch instead of workflow release
2024-11-26 15:21:07 +07:00
Bryer
ebd9a27c1b typo fix Update CONTRIBUTING.md (#901)
Corrected phrasing in "Commit rules" section
2024-11-26 15:20:14 +07:00
cedoor
bada8b8792 chore: v4.6.0 2024-11-25 13:09:50 +07:00
Cedoor
e93b19c566 chore(contracts): deploy contracts (#892)
* chore(contracts): deploy contracts

* chore(subgraph): deploy new subgraphs
2024-11-25 13:08:31 +07:00
leopardracer
862f715d05 fix: typos in documentation files (#898)
* Update usage.md

* Update glossary.md
2024-11-25 12:42:49 +07:00
Dmitry
3ed6c38587 Fixed closing tag issue in Update README.md (#894)
In the table section, there is a minor mistake in the closing tag. Instead of using </tbody>, it should be </tbody>. This is a formatting mistake.
2024-11-20 15:53:14 +07:00
Cedoor
7e183f3d2c refactor(contracts): support version range (#891)
re #888
2024-10-31 13:19:05 +00:00
Jimmy Chu
901d0954c0 refactor(contracts): specify gas cost in SemaphoreVerifier precompile calls (#883)
* chore(contracts): remove sub() from gas() in staticcall at SemaphoreVerifier

re #871

* refactor(contracts): using fixed gas cost on precompile calls

re #871

* refactor(contracts): increease fixed gas cost with safety buffer
2024-10-31 12:35:19 +00:00
Erick Vasquez
caebc1a4ab feat: add veilescrow to projects section (#890) 2024-10-30 18:46:38 +01:00
Vivian Plasencia
9b419f0c78 docs: add benchmarks page (#889)
* docs(docs): add benchmarks page to the docs

re #815

* chore(docs): update the docusaurus version
2024-10-30 10:54:13 +01:00
Vivian Plasencia
c67b888eb6 chore: v4.5.0 2024-10-28 20:23:40 +01:00
Vivian Plasencia
376cd11808 docs(identity): add export import identity to the docs (#887)
re #872
2024-10-28 13:29:35 +01:00
Vivian Plasencia
58132a9478 feat(identity): export point and signature types (#886)
* feat(identity): export point and signature types

re #885

* docs(identity): add the generate commitment function to the readme file
2024-10-28 13:29:03 +01:00
Vivian Plasencia
fadcf19206 chore: v4.4.2 2024-10-23 22:42:39 +02:00
Shikhar Singh
3be17268ab feat: remove prepublish script when creating template with Semaphore CLI (#882)
* feat(cli): remove @semaphore-protocol/cli prepublish script

The idea is to remove the prepublish script from the scripts object of the package.json file of
every cli template when the template is downloaded using the CLI.

BREAKING CHANGE: n

* refactor(cli): add comment

* refactor(cli): create seperate file for removePrePublishScript function

* refactor(cli): using updatedPackageJsonContent var instead of calling readFileSync again
2024-10-23 22:07:48 +02:00
Vivian Plasencia
82cdc60af6 fix: update shebang lines in the ts scripts (#881)
re #880
2024-10-23 10:50:46 +01:00
sripwoud
6c9ede6931 ci: install soldeer in release workflow (#867)
* ci: install `soldeer` in release workflow

* ci: setup soldeer login file (#868)

* chore: trigger release workflow

* chore: format

* ci: set `soldeer` credentials in github workspace

* chore: remove commentouts

* chore: add back tag trigger
2024-10-22 09:20:34 +01:00
cedoor
e6576cdc47 chore: v4.4.1 2024-10-21 12:41:11 +01:00
cedoor
c07dc88490 style: format code with prettier 2024-10-21 12:02:54 +01:00
Yago Pajariño
67060dd412 Update cli monorepo ethers and subgraph web app UI (#841)
* refactor(cli-template-monorepo-ethers): update cli-template-monorepo-ethers web app UI

re #836

* refactor(cli-template-monorepo-subgraph): update cli-template-monorepo-subgraph web app UI

re #836

* refactor(cli-template-monorepo-subgraph): rename subgraph web app on package.json

re #836

* refactor: update yarn.lock

re #836

* chore: fix indentation error on yarn.lock

re 836

* chore: update cli monorepo package.json

re #836

* chore(cli-template-monorepo-ethers): remove .env values

* chore(cli-template-monorepo-subgraph): change .env values

* chore(cli-template-monorepo-ethers): update .gitignore file

* chore(cli-template-monorepo-subgraph): update .gitignore file

* style(cli-template-monorepo-ethers): update globals.css

* refactor(cli-template-monorepo-ethers): replace chakra with plain html+css on cli-ethers page.tsx

* style(cli-template-monorepo-ethers): import globals css in layout

* style(cli-template-monorepo-ethers): remove chakra ui elements

* refactor(cli-template-monorepo-ethers): remove chakra ui from layout

* refactor(cli-template-monorepo-ethers): remove chakra ui from PageContainer, Stepper

* style(cli-template-monorepo-ethers): add font link

* chore(cli-template-monorepo-ethers): remove unused groups page

* style(cli-template-monorepo-ethers): remove chakra ui from group page

* style(cli-template-monorepo-ethers): remove chakra ui from proof page

* style(cli-template-monorepo-ethers): update css and add class names

* style(cli-template-monorepo-ethers): add css declarations

* style(cli-template-monorepo-ethers): add github icon

* style(cli-template-monorepo-ethers): add left arrow on stepper

* style(cli-template-monorepo-ethers): remove chakra from proofs page

* style(cli-template-monorepo-ethers): minor style improvements

* style(cli-template-monorepo-ethers): remove chakra libraries from package.json

* refactor(cli-template-monorepo-ethers): update yarn.lock file after package.json modified

* style(cli-template-monorepo-ethers): fix deepscan issues

* chore(cli-template-monorepo-ethers): remove unused packages and update dotenv version

* style(cli-template-monorepo-ethers): update stylesheet

* chore(cli-template-monorepo-ethers): update github logo

* chore(cli-template-monorepo-ethers): add loader to join group button

* chore(cli-template-monorepo-subgraph): update packages

* style(cli-template-monorepo-subgraph): update stylesheet

* style(cli-template-monorepo-subgraph): update user interface

* chore: update yarn.lock

* style: change styling and add feedback link

* chore(cli-template-monorepo-subgraph): remove unused styles and icons

* chore: remove unused context logs

* chore(cli-template-monorepo-subgraph): change data source subgraph web app

* chore: change repo url

* chore: remove unused hook useSemaphore
2024-10-21 11:58:05 +01:00
Cedoor
a4e540d8f4 chore(website): update roadmap (#878) 2024-10-18 13:03:16 +01:00
Jimmy Chu
79976f33cb Split SemaphoreVerifier key points into a separate library (#875)
* refactor(scripts): added a script to convert bigint to hex

* refactor(contracts): split SemaphoreVerifier verification key points into a separate library (#330)

* chore(contracts): yarn format & lint

* refactor(contracts): update SemaphoreVerifierKeyPts library to be internal

re #330

* chore(contracts): update spacing

* chore(contracts): updated per peer review and added invariant check for VerifierKeyPts lib

* chore(contracts): update invariant check to revert with custom error
2024-10-17 14:21:41 +01:00
cedoor
822530f2cf chore: v4.4.0 2024-10-17 14:19:38 +01:00
Vivian Plasencia
b3f862979d feat(identity): add generate commitment function (#877)
This static method is particularly useful after signature verification, as it allows retrieval of
the corresponding commitment associated with the public key.

re #873
2024-10-17 13:28:49 +02:00
cedoor
06e11d5c34 chore: v4.3.1 2024-10-16 12:20:26 +01:00
cedoor
88d4470b11 ci(circuits): add sudo before running wget command 2024-10-16 12:16:22 +01:00
Vivian Plasencia
bb1c6984b2 ci: add -O flag to the wget command 2024-10-16 13:04:32 +02:00
cedoor
5841327477 ci(circuits): update circom url 2024-10-16 11:52:02 +01:00
cedoor
eab3ab30c6 ci(circuits): update circom url 2024-10-16 11:48:30 +01:00
Cedoor
cd6dc38f9e ci(circuits): set static version of circom (#874)
* fix(circuits): add override for circom_runtime

* chore(circuits): use yarn syntax for overrides

* ci(circuits): set static version of circom
2024-10-16 11:05:07 +01:00
cedoor
3cb1b5757d revert(circuits): set previous circomkit version as static 2024-10-15 11:30:11 +01:00
cedoor
a8db8393c1 chore(circuits): update circomkit config 2024-10-15 11:24:55 +01:00
cedoor
391b571c31 chore(circuits): update circomkit dep version 2024-10-15 11:21:04 +01:00
cedoor
4c2769099f chore(circuits): update dev dependencies 2024-10-15 11:05:08 +01:00
Cedoor
29cabb49d6 build: move poseidon-lite to dependencies (#870) 2024-10-15 10:58:51 +01:00
cedoor
48b0694586 chore: v4.3.0 2024-10-03 12:46:01 +01:00
Cedoor
28684fdb1a Chore/mainnet deployments (#869)
* chore(contracts): deploy semaphore contracts on base

re #865

* chore(contracts): deploy semaphore contracts on linea

re #865

* refactor(data): add types for new networks

re #865
2024-10-03 12:42:36 +01:00
Cedoor
49a16635d8 chore(website): update roadmap.json (#866) 2024-10-01 19:04:11 +01:00
cedoor
4bfe6d8791 chore: v4.2.0 2024-10-01 18:48:37 +01:00
Cedoor
a3d97795fe Chore/new testnets (#864)
* chore(contracts): deploy contracts on base sepolia

re #863

* chore(contracts): deploy contracts on linea sepolia

re #863
2024-10-01 18:36:55 +01:00
169 changed files with 9434 additions and 3455 deletions

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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).

View File

@@ -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 be 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.

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

View File

@@ -390,8 +390,5 @@
},
"footer.right.connect.link2": {
"message": "X (Twitter)"
},
"footer.copyright": {
"message": "Copyright © 2024 Ethereum Foundation"
}
}

View File

@@ -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"
@@ -390,8 +390,5 @@
},
"footer.right.connect.link2": {
"message": "X (Twitter)"
},
"footer.copyright": {
"message": "Copyright © 2024 Ethereum Foundation"
}
}

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.1.0",
"@semaphore-protocol/utils": "4.12.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",

View File

@@ -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 }}

View File

@@ -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.

View File

@@ -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

View File

@@ -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
@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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).

View File

@@ -0,0 +1,131 @@
---
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.0.1
**Software environment**
Node.js version: 20.18.0
Browser: Google Chrome Version 130.0.6723.92 (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
## Node.js benchmarks
### Identities
![Identities](../../assets/img-benchmarks/node/identity-node-benchmarks.png)
### Create Group
Create group, either empty or with initial members.
![Create Group](../../assets/img-benchmarks/node/create-group-node-benchmarks.png)
### Add Member
Add a member to groups with different sizes.
![Add Member](../../assets/img-benchmarks/node/add-member-node-benchmarks.png)
### Generate Proof
Generate a proof using groups with different numbers of members.
![Generate Proof](../../assets/img-benchmarks/node/generate-proof-node-benchmarks.png)
### Verify Proof
Verify a proof using groups with different numbers of members.
![Verify Proof](../../assets/img-benchmarks/node/verify-proof-node-benchmarks.png)
## Browser benchmarks
Main functions used in the browser.
![Browser benchmarks](../../assets/img-benchmarks/browser/browser-benchmarks.png)
## Circuit benchmarks
### 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: '590px', height: 'auto' }}
/>
### Semaphore V3 gas report
![Contracts benchmarks Semaphore v3](../../assets/img-benchmarks/contracts/semaphore-v3-contracts-benchmarks.png)
### Semaphore V4 gas report
![Contracts benchmarks Semaphore v4](../../assets/img-benchmarks/contracts/semaphore-v4-contracts-benchmarks.png)

View File

@@ -1,5 +1,5 @@
---
sidebar_position: 12
sidebar_position: 13
---
# Credits

View File

@@ -1,5 +1,5 @@
---
sidebar_position: 11
sidebar_position: 12
---
# FAQ

View File

@@ -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

View File

@@ -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)
```

View File

@@ -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:

View File

@@ -1,5 +1,5 @@
---
sidebar_position: 9
sidebar_position: 10
---
import Articles from '@site/src/components/Articles';

View File

@@ -1,5 +1,5 @@
---
sidebar_position: 10
sidebar_position: 11
---
import Tabs from "@theme/Tabs"

View File

@@ -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.

View File

@@ -42,17 +42,23 @@
## Networks
You can access any subgraph supported by Semaphore with the following URL: https://api.studio.thegraph.com/query/14377/semaphore-<network-name>/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.2.0`.
Supported networks:
- `sepolia`
- `ethereum`
- `optimism`
- `optimism-sepolia`
- `arbitrum-one`
- `arbitrum`
- `arbitrum-sepolia`
- `matic`
- `polygon-amoy`
- `matic-amoy`
- `base-sepolia`
- `base`
- `linea-sepolia`
- `linea`
- `scroll-sepolia`
## 🛠 Install

View File

@@ -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.1.0"
"@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"
}
}

View File

@@ -15,6 +15,10 @@ function mapNetwork(n) {
return "arbitrum-one"
}
if (n === "ethereum") {
return "mainnet"
}
return network
}

View File

@@ -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=""

View File

@@ -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">
@@ -287,7 +287,7 @@ export default function Home() {
Upcoming Events
</Heading>
<VStack align="left" spacing="10" maxH="600" overflowY="auto">
<VStack align="left" spacing="10" maxH="600px" overflowY="auto">
{events.map((event) => (
<Link href={event.link} key={event.name} isExternal>
<VStack align="left">

View File

@@ -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>

View File

@@ -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"
}
]

View File

@@ -1,14 +1,20 @@
[
{
"name": "DIF - Decentralized Identity Foundation",
"date": "Oct 1 - Nov 4, 2024",
"description": "Semaphore team will deliver a talk and sponsor prizes for the online hackathon.",
"link": "https://identity.foundation/"
"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/"
}
]

View File

@@ -555,5 +555,36 @@
"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"
}
}
]

View File

@@ -17,18 +17,30 @@
},
{
"name": "LeanIMT Paper",
"done": false
},
{
"name": "RLN extension",
"done": false
"done": true
},
{
"name": "Support more Testnets/Mainnets",
"done": true
},
{
"name": "New Explorer",
"done": true
},
{
"name": "Semaphore V4 Specification",
"done": true
},
{
"name": "Semaphore Rust Implementation",
"done": true
},
{
"name": "Semaphore Noir Implementation",
"done": false
},
{
"name": "Documentation Revamp",
"name": "Scaling Semaphore with PIR",
"done": false
}
]

View File

@@ -118,5 +118,13 @@
"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"
}
]

View File

@@ -1,6 +1,6 @@
{
"name": "@semaphore-protocol/circuits",
"version": "4.1.0",
"version": "4.12.0",
"description": "Semaphore Circom circuits to generate zero-knowledge proofs.",
"license": "MIT",
"files": [
@@ -30,9 +30,9 @@
"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.0.19",
"mocha": "^10.2.0",
"poseidon-lite": "^0.2.0"
"poseidon-lite": "^0.3.0"
}
}

View File

@@ -56,7 +56,7 @@ 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);

View 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

View File

@@ -0,0 +1,3 @@
SEPOLIA_RPC_URL=
PRIVATE_KEY=
ETHERSCAN_API_KEY=

View 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

View 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

View File

@@ -0,0 +1,6 @@
{
"semi": false,
"arrowParens": "always",
"trailingComma": "none",
"plugins": ["prettier-plugin-solidity"]
}

View File

@@ -0,0 +1,6 @@
{
"extends": "solhint:recommended",
"rules": {
"func-visibility": ["error", { "ignoreConstructors": true }]
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
compressionLevel: mixed
enableGlobalCache: false
nodeLinker: node-modules
yarnPath: .yarn/releases/yarn-4.1.0.cjs

View 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
```

View 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

View File

@@ -0,0 +1,45 @@
{
"name": "@semaphore-protocol/cli-template-contracts-foundry",
"version": "4.12.0",
"description": "Semaphore Foundry template.",
"license": "Unlicense",
"devDependencies": {
"@semaphore-protocol/contracts": "4.12.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"
}

View 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/

View File

@@ -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();
}
}

View 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);
}
}

View 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);
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@semaphore-protocol/cli-template-contracts-hardhat",
"version": "4.1.0",
"version": "4.12.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.1.0",
"@semaphore-protocol/hardhat": "4.1.0",
"@semaphore-protocol/utils": "4.1.0",
"@semaphore-protocol/core": "4.12.0",
"@semaphore-protocol/hardhat": "4.12.0",
"@semaphore-protocol/utils": "4.12.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.1.0"
"@semaphore-protocol/contracts": "4.12.0"
},
"packageManager": "yarn@4.1.0"
}

View File

@@ -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.1.0",
"@semaphore-protocol/hardhat": "4.1.0",
"@semaphore-protocol/utils": "4.1.0",
"@semaphore-protocol/core": "4.12.0",
"@semaphore-protocol/hardhat": "4.12.0",
"@semaphore-protocol/utils": "4.12.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.1.0"
"@semaphore-protocol/contracts": "4.12.0"
},
"packageManager": "yarn@4.1.0"
}

View File

@@ -1,4 +1,4 @@
NEXT_PUBLIC_DEFAULT_NETWORK=localhost
NEXT_PUBLIC_FEEDBACK_CONTRACT_ADDRESS=0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9
NEXT_PUBLIC_FEEDBACK_CONTRACT_ADDRESS=0xcf7ed3acca5a467e9e704c703e8d87f634fb0fc9
NEXT_PUBLIC_SEMAPHORE_CONTRACT_ADDRESS=0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0
NEXT_PUBLIC_GROUP_ID=0

View File

@@ -1,5 +1,8 @@
NEXT_PUBLIC_DEFAULT_NETWORK=sepolia
NEXT_PUBLIC_INFURA_API_KEY=abf67af1010b4b8d877e04244f1eac3d
NEXT_PUBLIC_FEEDBACK_CONTRACT_ADDRESS=
NEXT_PUBLIC_SEMAPHORE_CONTRACT_ADDRESS=0x1e0d7FF1610e480fC93BdEC510811ea2Ba6d7c2f
NEXT_PUBLIC_OPENZEPPELIN_AUTOTASK_WEBHOOK=https://api.defender.openzeppelin.com/actions/20fce2ae-844b-4ec0-a6a2-90a3350a9d2c/runs/webhook/303216d1-fa7d-4fca-8c5b-7ba1ba544fc7/2T7i9xrkZA5j37hoaQLUuw
NEXT_PUBLIC_GELATO_RELAYER_ENDPOINT=https://api.gelato.digital/relays/v2/sponsored-call
NEXT_PUBLIC_GELATO_RELAYER_CHAIN_ID=11155111
NEXT_PUBLIC_GROUP_ID=

View File

@@ -1,5 +1,8 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# testing
/coverage
# next.js
/.next/
/out/
@@ -7,3 +10,18 @@
# production
/build
# misc
.DS_Store
*.pem
# typescript
*.tsbuildinfo
next-env.d.ts
# Auto Generated PWA files
public/sw.js
public/workbox-*.js
public/worker-*.js
public/sw.js.map
public/workbox-*.js.map
public/worker-*.js.map

View File

@@ -9,11 +9,6 @@
"internalType": "address",
"name": "semaphoreAddress",
"type": "address"
},
{
"internalType": "uint256",
"name": "_groupId",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
@@ -92,8 +87,8 @@
"type": "function"
}
],
"bytecode": "0x608060405234801561001057600080fd5b5060405161083f38038061083f833981810160405281019061003291906101a8565b816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060018190555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c96e71fb600154306040518363ffffffff1660e01b81526004016100d6929190610206565b600060405180830381600087803b1580156100f057600080fd5b505af1158015610104573d6000803e3d6000fd5b50505050505061022f565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061013f82610114565b9050919050565b61014f81610134565b811461015a57600080fd5b50565b60008151905061016c81610146565b92915050565b6000819050919050565b61018581610172565b811461019057600080fd5b50565b6000815190506101a28161017c565b92915050565b600080604083850312156101bf576101be61010f565b5b60006101cd8582860161015d565b92505060206101de85828601610193565b9150509250929050565b6101f181610172565b82525050565b61020081610134565b82525050565b600060408201905061021b60008301856101e8565b61022860208301846101f7565b9392505050565b6106018061023e6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80637b5d2534146100515780637b85d27a1461006f578063a0f44c921461008b578063eed02e4b146100a9575b600080fd5b6100596100c5565b6040516100669190610301565b60405180910390f35b6100896004803603810190610084919061037e565b6100e9565b005b6100936101ea565b6040516100a09190610409565b60405180910390f35b6100c360048036038101906100be9190610424565b6101f0565b005b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006040518060c001604052808781526020018681526020018581526020018481526020016001548152602001836008806020026040519081016040528092919082600860200280828437600081840152601f19601f820116905080830192505050505050815250905060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0d898dd600154836040518363ffffffff1660e01b81526004016101b0929190610578565b600060405180830381600087803b1580156101ca57600080fd5b505af11580156101de573d6000803e3d6000fd5b50505050505050505050565b60015481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631783efc3600154836040518363ffffffff1660e01b815260040161024d9291906105a2565b600060405180830381600087803b15801561026757600080fd5b505af115801561027b573d6000803e3d6000fd5b5050505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006102c76102c26102bd84610282565b6102a2565b610282565b9050919050565b60006102d9826102ac565b9050919050565b60006102eb826102ce565b9050919050565b6102fb816102e0565b82525050565b600060208201905061031660008301846102f2565b92915050565b600080fd5b6000819050919050565b61033481610321565b811461033f57600080fd5b50565b6000813590506103518161032b565b92915050565b600080fd5b60008190508260206008028201111561037857610377610357565b5b92915050565b6000806000806000610180868803121561039b5761039a61031c565b5b60006103a988828901610342565b95505060206103ba88828901610342565b94505060406103cb88828901610342565b93505060606103dc88828901610342565b92505060806103ed8882890161035c565b9150509295509295909350565b61040381610321565b82525050565b600060208201905061041e60008301846103fa565b92915050565b60006020828403121561043a5761043961031c565b5b600061044884828501610342565b91505092915050565b61045a81610321565b82525050565b600060089050919050565b600081905092915050565b6000819050919050565b600061048c8383610451565b60208301905092915050565b6000602082019050919050565b6104ae81610460565b6104b8818461046b565b92506104c382610476565b8060005b838110156104f45781516104db8782610480565b96506104e683610498565b9250506001810190506104c7565b505050505050565b6101a0820160008201516105136000850182610451565b5060208201516105266020850182610451565b5060408201516105396040850182610451565b50606082015161054c6060850182610451565b50608082015161055f6080850182610451565b5060a082015161057260a08501826104a5565b50505050565b60006101c08201905061058e60008301856103fa565b61059b60208301846104fc565b9392505050565b60006040820190506105b760008301856103fa565b6105c460208301846103fa565b939250505056fea2646970667358221220f33606b2d5ad7c0dfc5d22afb43476e1974ea7fd160e1f28203a3e433f29cb4964736f6c63430008170033",
"deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80637b5d2534146100515780637b85d27a1461006f578063a0f44c921461008b578063eed02e4b146100a9575b600080fd5b6100596100c5565b6040516100669190610301565b60405180910390f35b6100896004803603810190610084919061037e565b6100e9565b005b6100936101ea565b6040516100a09190610409565b60405180910390f35b6100c360048036038101906100be9190610424565b6101f0565b005b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006040518060c001604052808781526020018681526020018581526020018481526020016001548152602001836008806020026040519081016040528092919082600860200280828437600081840152601f19601f820116905080830192505050505050815250905060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0d898dd600154836040518363ffffffff1660e01b81526004016101b0929190610578565b600060405180830381600087803b1580156101ca57600080fd5b505af11580156101de573d6000803e3d6000fd5b50505050505050505050565b60015481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631783efc3600154836040518363ffffffff1660e01b815260040161024d9291906105a2565b600060405180830381600087803b15801561026757600080fd5b505af115801561027b573d6000803e3d6000fd5b5050505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006102c76102c26102bd84610282565b6102a2565b610282565b9050919050565b60006102d9826102ac565b9050919050565b60006102eb826102ce565b9050919050565b6102fb816102e0565b82525050565b600060208201905061031660008301846102f2565b92915050565b600080fd5b6000819050919050565b61033481610321565b811461033f57600080fd5b50565b6000813590506103518161032b565b92915050565b600080fd5b60008190508260206008028201111561037857610377610357565b5b92915050565b6000806000806000610180868803121561039b5761039a61031c565b5b60006103a988828901610342565b95505060206103ba88828901610342565b94505060406103cb88828901610342565b93505060606103dc88828901610342565b92505060806103ed8882890161035c565b9150509295509295909350565b61040381610321565b82525050565b600060208201905061041e60008301846103fa565b92915050565b60006020828403121561043a5761043961031c565b5b600061044884828501610342565b91505092915050565b61045a81610321565b82525050565b600060089050919050565b600081905092915050565b6000819050919050565b600061048c8383610451565b60208301905092915050565b6000602082019050919050565b6104ae81610460565b6104b8818461046b565b92506104c382610476565b8060005b838110156104f45781516104db8782610480565b96506104e683610498565b9250506001810190506104c7565b505050505050565b6101a0820160008201516105136000850182610451565b5060208201516105266020850182610451565b5060408201516105396040850182610451565b50606082015161054c6060850182610451565b50608082015161055f6080850182610451565b5060a082015161057260a08501826104a5565b50505050565b60006101c08201905061058e60008301856103fa565b61059b60208301846104fc565b9392505050565b60006040820190506105b760008301856103fa565b6105c460208301846103fa565b939250505056fea2646970667358221220f33606b2d5ad7c0dfc5d22afb43476e1974ea7fd160e1f28203a3e433f29cb4964736f6c63430008170033",
"bytecode": "0x608060405234801561001057600080fd5b506040516108473803806108478339818101604052810190610032919061017d565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c3f3b60306040518263ffffffff1660e01b81526004016100cb91906101b9565b6020604051808303816000875af11580156100ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061010e919061020a565b60018190555050610237565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061014a8261011f565b9050919050565b61015a8161013f565b811461016557600080fd5b50565b60008151905061017781610151565b92915050565b6000602082840312156101935761019261011a565b5b60006101a184828501610168565b91505092915050565b6101b38161013f565b82525050565b60006020820190506101ce60008301846101aa565b92915050565b6000819050919050565b6101e7816101d4565b81146101f257600080fd5b50565b600081519050610204816101de565b92915050565b6000602082840312156102205761021f61011a565b5b600061022e848285016101f5565b91505092915050565b610601806102466000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80637b5d2534146100515780637b85d27a1461006f578063a0f44c921461008b578063eed02e4b146100a9575b600080fd5b6100596100c5565b6040516100669190610301565b60405180910390f35b6100896004803603810190610084919061037e565b6100e9565b005b6100936101ea565b6040516100a09190610409565b60405180910390f35b6100c360048036038101906100be9190610424565b6101f0565b005b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006040518060c001604052808781526020018681526020018581526020018481526020016001548152602001836008806020026040519081016040528092919082600860200280828437600081840152601f19601f820116905080830192505050505050815250905060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0d898dd600154836040518363ffffffff1660e01b81526004016101b0929190610578565b600060405180830381600087803b1580156101ca57600080fd5b505af11580156101de573d6000803e3d6000fd5b50505050505050505050565b60015481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631783efc3600154836040518363ffffffff1660e01b815260040161024d9291906105a2565b600060405180830381600087803b15801561026757600080fd5b505af115801561027b573d6000803e3d6000fd5b5050505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006102c76102c26102bd84610282565b6102a2565b610282565b9050919050565b60006102d9826102ac565b9050919050565b60006102eb826102ce565b9050919050565b6102fb816102e0565b82525050565b600060208201905061031660008301846102f2565b92915050565b600080fd5b6000819050919050565b61033481610321565b811461033f57600080fd5b50565b6000813590506103518161032b565b92915050565b600080fd5b60008190508260206008028201111561037857610377610357565b5b92915050565b6000806000806000610180868803121561039b5761039a61031c565b5b60006103a988828901610342565b95505060206103ba88828901610342565b94505060406103cb88828901610342565b93505060606103dc88828901610342565b92505060806103ed8882890161035c565b9150509295509295909350565b61040381610321565b82525050565b600060208201905061041e60008301846103fa565b92915050565b60006020828403121561043a5761043961031c565b5b600061044884828501610342565b91505092915050565b61045a81610321565b82525050565b600060089050919050565b600081905092915050565b6000819050919050565b600061048c8383610451565b60208301905092915050565b6000602082019050919050565b6104ae81610460565b6104b8818461046b565b92506104c382610476565b8060005b838110156104f45781516104db8782610480565b96506104e683610498565b9250506001810190506104c7565b505050505050565b6101a0820160008201516105136000850182610451565b5060208201516105266020850182610451565b5060408201516105396040850182610451565b50606082015161054c6060850182610451565b50608082015161055f6080850182610451565b5060a082015161057260a08501826104a5565b50505050565b60006101c08201905061058e60008301856103fa565b61059b60208301846104fc565b9392505050565b60006040820190506105b760008301856103fa565b6105c460208301846103fa565b939250505056fea264697066735822122078569abd7f309f3107c4d19e9b4a4f4812522ccc5dc57c7ccbe2b06a5ba461b064736f6c63430008170033",
"deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80637b5d2534146100515780637b85d27a1461006f578063a0f44c921461008b578063eed02e4b146100a9575b600080fd5b6100596100c5565b6040516100669190610301565b60405180910390f35b6100896004803603810190610084919061037e565b6100e9565b005b6100936101ea565b6040516100a09190610409565b60405180910390f35b6100c360048036038101906100be9190610424565b6101f0565b005b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006040518060c001604052808781526020018681526020018581526020018481526020016001548152602001836008806020026040519081016040528092919082600860200280828437600081840152601f19601f820116905080830192505050505050815250905060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0d898dd600154836040518363ffffffff1660e01b81526004016101b0929190610578565b600060405180830381600087803b1580156101ca57600080fd5b505af11580156101de573d6000803e3d6000fd5b50505050505050505050565b60015481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631783efc3600154836040518363ffffffff1660e01b815260040161024d9291906105a2565b600060405180830381600087803b15801561026757600080fd5b505af115801561027b573d6000803e3d6000fd5b5050505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006102c76102c26102bd84610282565b6102a2565b610282565b9050919050565b60006102d9826102ac565b9050919050565b60006102eb826102ce565b9050919050565b6102fb816102e0565b82525050565b600060208201905061031660008301846102f2565b92915050565b600080fd5b6000819050919050565b61033481610321565b811461033f57600080fd5b50565b6000813590506103518161032b565b92915050565b600080fd5b60008190508260206008028201111561037857610377610357565b5b92915050565b6000806000806000610180868803121561039b5761039a61031c565b5b60006103a988828901610342565b95505060206103ba88828901610342565b94505060406103cb88828901610342565b93505060606103dc88828901610342565b92505060806103ed8882890161035c565b9150509295509295909350565b61040381610321565b82525050565b600060208201905061041e60008301846103fa565b92915050565b60006020828403121561043a5761043961031c565b5b600061044884828501610342565b91505092915050565b61045a81610321565b82525050565b600060089050919050565b600081905092915050565b6000819050919050565b600061048c8383610451565b60208301905092915050565b6000602082019050919050565b6104ae81610460565b6104b8818461046b565b92506104c382610476565b8060005b838110156104f45781516104db8782610480565b96506104e683610498565b9250506001810190506104c7565b505050505050565b6101a0820160008201516105136000850182610451565b5060208201516105266020850182610451565b5060408201516105396040850182610451565b50606082015161054c6060850182610451565b50608082015161055f6080850182610451565b5060a082015161057260a08501826104a5565b50505050565b60006101c08201905061058e60008301856103fa565b61059b60208301846104fc565b9392505050565b60006040820190506105b760008301856103fa565b6105c460208301846103fa565b939250505056fea264697066735822122078569abd7f309f3107c4d19e9b4a4f4812522ccc5dc57c7ccbe2b06a5ba461b064736f6c63430008170033",
"linkReferences": {},
"deployedLinkReferences": {}
}

View File

@@ -14,7 +14,8 @@ const nextConfig = withPWA({
})({
env: {
INFURA_API_KEY: process.env.INFURA_API_KEY,
ETHEREUM_PRIVATE_KEY: process.env.ETHEREUM_PRIVATE_KEY
ETHEREUM_PRIVATE_KEY: process.env.ETHEREUM_PRIVATE_KEY,
GELATO_RELAYER_API_KEY: process.env.GELATO_RELAYER_API_KEY
}
})

View File

@@ -9,10 +9,10 @@
"lint": "next lint"
},
"dependencies": {
"@semaphore-protocol/core": "4.1.0",
"@semaphore-protocol/data": "4.1.0",
"@semaphore-protocol/utils": "4.1.0",
"ethers": "^6.11.1",
"@semaphore-protocol/core": "4.12.0",
"@semaphore-protocol/data": "4.12.0",
"@semaphore-protocol/utils": "4.12.0",
"ethers": "^6.13.4",
"next": "14.1.0",
"next-pwa": "^5.6.0",
"react": "^18",

View File

@@ -3,26 +3,14 @@ import { NextRequest } from "next/server"
import Feedback from "../../../../contract-artifacts/Feedback.json"
export async function POST(req: NextRequest) {
if (typeof process.env.NEXT_PUBLIC_FEEDBACK_CONTRACT_ADDRESS !== "string") {
throw new Error("Please, define NEXT_PUBLIC_FEEDBACK_CONTRACT_ADDRESS in your .env file")
}
if (typeof process.env.NEXT_PUBLIC_DEFAULT_NETWORK !== "string") {
throw new Error("Please, define NEXT_PUBLIC_DEFAULT_NETWORK in your .env file")
}
if (typeof process.env.INFURA_API_KEY !== "string" && process.env.NEXT_PUBLIC_DEFAULT_NETWORK !== "localhost") {
throw new Error("Please, define INFURA_API_KEY in your .env file")
}
if (typeof process.env.ETHEREUM_PRIVATE_KEY !== "string") {
throw new Error("Please, define ETHEREUM_PRIVATE_KEY in your .env file")
}
const ethereumPrivateKey = process.env.ETHEREUM_PRIVATE_KEY
const ethereumNetwork = process.env.NEXT_PUBLIC_DEFAULT_NETWORK
const infuraApiKey = process.env.INFURA_API_KEY
const contractAddress = process.env.NEXT_PUBLIC_FEEDBACK_CONTRACT_ADDRESS
const ethereumNetwork = process.env.NEXT_PUBLIC_DEFAULT_NETWORK as string
const infuraApiKey = process.env.NEXT_PUBLIC_INFURA_API_KEY as string
const contractAddress = process.env.NEXT_PUBLIC_FEEDBACK_CONTRACT_ADDRESS as string
const provider =
ethereumNetwork === "localhost"

View File

@@ -3,26 +3,14 @@ import { NextRequest } from "next/server"
import Feedback from "../../../../contract-artifacts/Feedback.json"
export async function POST(req: NextRequest) {
if (typeof process.env.NEXT_PUBLIC_FEEDBACK_CONTRACT_ADDRESS !== "string") {
throw new Error("Please, define NEXT_PUBLIC_FEEDBACK_CONTRACT_ADDRESS in your .env file")
}
if (typeof process.env.NEXT_PUBLIC_DEFAULT_NETWORK !== "string") {
throw new Error("Please, define NEXT_PUBLIC_DEFAULT_NETWORK in your .env file")
}
if (typeof process.env.INFURA_API_KEY !== "string" && process.env.NEXT_PUBLIC_DEFAULT_NETWORK !== "localhost") {
throw new Error("Please, define INFURA_API_KEY in your .env file")
}
if (typeof process.env.ETHEREUM_PRIVATE_KEY !== "string") {
throw new Error("Please, define ETHEREUM_PRIVATE_KEY in your .env file")
}
const ethereumPrivateKey = process.env.ETHEREUM_PRIVATE_KEY
const ethereumNetwork = process.env.NEXT_PUBLIC_DEFAULT_NETWORK
const infuraApiKey = process.env.INFURA_API_KEY
const contractAddress = process.env.NEXT_PUBLIC_FEEDBACK_CONTRACT_ADDRESS
const ethereumNetwork = process.env.NEXT_PUBLIC_DEFAULT_NETWORK as string
const infuraApiKey = process.env.NEXT_PUBLIC_INFURA_API_KEY as string
const contractAddress = process.env.NEXT_PUBLIC_FEEDBACK_CONTRACT_ADDRESS as string
const provider =
ethereumNetwork === "localhost"

View File

@@ -1,29 +1,40 @@
:root {
--slate100: #f1f5f9;
--slate200: #e2e8f0;
--slate300: #cbd5e1;
--slate400: #94a3b8;
--slate500: #64748b;
--slate700: #334155;
--blue200: #bfdbfe;
--blue500: #3b82f6;
--blue600: #2563eb;
--blue700: #1d4ed8;
--blue800: #1e40af;
--blue900: #1e3a8a;
--blue100: #dde6fc;
--blue200: #c3d4fa;
--blue300: #9abaf6;
--blue400: #6a95f0;
--blue500: #4771ea;
--blue600: #3555df;
--blue700: #2940cc;
--blue800: #2735a6;
--blue900: #253183;
--blue950: #1b2050;
--darkBlueBg: #00020d;
--slate50: #f7f7f8;
--slate100: #eeeef0;
--slate200: #d9d9de;
--slate300: #b8b9c1;
--slate400: #92939e;
--slate500: #747583;
--slate600: #5e5f6b;
--slate700: #4d4e57;
--slate800: #42424a;
--slate900: #3a3a40;
--slate950: #26262b;
}
* {
box-sizing: border-box;
padding: 0;
margin: 0;
font-family: "Outfit", sans-serif;
}
html,
body {
max-width: 100vw;
overflow-x: hidden;
height: 100vh;
}
body {
@@ -33,17 +44,30 @@ body {
p {
line-height: 1.5rem;
font-weight: 300;
overflow-wrap: break-word;
font-size: 1rem;
}
b {
font-weight: 600;
}
.key-wrapper {
padding-bottom: 1.5rem;
padding-left: 0.5rem;
}
.container {
display: flex;
flex-direction: column;
height: 100%;
max-width: 32rem;
max-width: 40vw;
min-width: 35rem;
margin: auto;
padding: 1rem;
height: calc(100vh - 7rem - 1px);
padding-bottom: 5rem;
min-height: calc(100vh - 3.5rem);
}
@@ -57,28 +81,25 @@ p {
margin-bottom: 1rem;
}
ol {
padding: 1rem;
}
li {
margin-top: 1rem;
}
h2 {
font-size: 2.25rem;
font-weight: 500;
margin-bottom: 1rem;
line-height: 1.2;
}
h3 {
font-size: 1.125rem;
font-size: 1.15rem;
font-weight: 500;
}
.divider {
height: 1px;
background: var(--slate500);
opacity: 0.6;
border: 0;
border-style: solid;
border-bottom-width: 1px;
width: 100%;
border-color: var(--slate400);
margin: 2rem 0;
}
@@ -89,31 +110,44 @@ h3 {
}
a {
color: var(--blue500);
color: var(--blue400);
text-decoration: none;
}
a:hover {
text-decoration: underline;
text-decoration-color: var(--blue400);
}
.button {
background-color: var(--blue800);
width: 100%;
padding: 0.8rem 1rem;
border: 1px;
border-radius: 100px;
cursor: pointer;
color: var(--slate100);
font-size: 1.125rem;
font-weight: 500;
transition: all 200ms linear;
margin-top: 1rem;
margin-bottom: 1.5rem;
opacity: 0.9;
font-weight: 400;
transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, transform;
transition-duration: 200ms;
padding-left: 18px !important;
padding-right: 18px !important;
height: 2.5rem;
min-width: 2.5rem;
font-size: 1rem;
-webkit-padding-start: 1rem;
padding-inline-start: 1rem;
-webkit-padding-end: 1rem;
padding-inline-end: 1rem;
background: var(--blue500);
color: white;
background-image: linear-gradient(to right, var(--blue500), var(--blue800));
transition-timing-function: linear;
width: 100%;
border: none;
display: flex;
justify-content: center;
height: 3rem;
align-items: center;
justify-content: center;
}
.button:hover {
background-color: var(--blue900);
background-color: var(--blue800);
background-image: none;
cursor: pointer;
}
.button:disabled {
@@ -123,54 +157,126 @@ a {
.button:disabled:hover {
background-color: var(--blue800);
background-image: none;
}
.button-stepper {
cursor: pointer;
color: var(--blue600);
color: var(--blue500);
font-size: 1.1rem;
border: none;
background: none;
width: 4rem;
margin: 0 1rem;
display: flex;
justify-content: center;
}
.button-link {
.button-stepper:hover {
text-decoration: underline;
}
.refresh-wrapper {
color: var(--slate400);
display: flex;
align-items: center;
}
.refresh-wrapper:hover {
text-decoration: underline;
}
.refresh-button {
cursor: pointer;
color: var(--slate300);
font-size: 1.1rem;
border: none;
background: none;
padding-right: 1rem;
display: flex;
align-items: center;
}
.refresh-button:hover {
text-decoration: underline;
}
.refresh-span {
width: 1.5em;
height: 1em;
display: inline-block;
line-height: 1em;
-webkit-flex-shrink: 0;
-ms-flex-negative: 0;
flex-shrink: 0;
color: currentColor;
vertical-align: middle;
}
.refresh-icon {
margin-inline-end: 0.5rem;
}
.stepper-icon {
display: inline-flex;
align-self: center;
-webkit-flex-shrink: 0;
-ms-flex-negative: 0;
flex-shrink: 0;
}
.left-pad {
margin-inline-end: 0.5rem;
}
.right-pad {
margin-inline-start: 0.5rem;
}
.stepper-icon svg {
width: 1em;
height: 1em;
display: inline-block;
line-height: 1em;
-webkit-flex-shrink: 0;
-ms-flex-negative: 0;
flex-shrink: 0;
color: currentColor;
vertical-align: super;
}
.box {
padding: 0.8rem;
border-style: solid;
border-width: 1px;
border-color: var(--slate500);
border-radius: 4px;
border-bottom: 1px solid white;
padding: 0.8rem 0;
max-height: 50px;
}
.box-text {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
margin: 0.5rem;
font-size: 1rem;
}
.header {
display: flex;
justify-content: space-between;
padding: 1.5rem;
padding: 0 1.5rem;
height: 3.5rem;
}
.header-left {
font-size: 1.125rem;
font-weight: 500;
text-decoration: none;
text-decoration: none !important;
display: flex;
align-items: center;
}
.header-right {
display: flex;
gap: 1.5rem;
align-items: center;
}
.footer {
@@ -188,6 +294,57 @@ a {
background: var(--slate500);
}
.users-wrapper,
.feedback-wrapper {
max-height: 300px;
overflow-y: scroll;
}
.keys-header {
margin-bottom: 1.5rem;
}
.users-header {
font-weight: 700;
font-size: 1.125rem;
font-family: "DM Sans", sans-serif;
}
.join-group-button,
.send-feedback-button {
margin-top: 1.5rem;
}
.github-icon {
width: 1.5rem;
height: 1.5rem;
display: inline-block;
line-height: 1em;
-webkit-flex-shrink: 0;
-ms-flex-negative: 0;
flex-shrink: 0;
color: currentColor;
}
.github-button {
cursor: pointer;
color: var(--slate100);
font-size: 1.1rem;
border: none;
background: none;
padding-right: 1rem;
display: flex;
align-items: center;
box-sizing: border-box;
display: inline-block;
overflow: visible !important;
fill: currentColor;
color: #f0f6fc !important;
vertical-align: middle !important;
width: 2rem;
height: 2rem;
}
.loader {
width: 25px;
height: 25px;
@@ -196,7 +353,7 @@ a {
border-right: 2px solid transparent;
animation: spin 1s linear infinite;
z-index: 20;
margin-left: 1rem;
margin-left: 0.5rem;
}
@keyframes spin {

View File

@@ -0,0 +1,177 @@
"use client"
import Stepper from "@/components/Stepper"
import { useLogContext } from "@/context/LogContext"
import { useSemaphoreContext } from "@/context/SemaphoreContext"
import { useRouter } from "next/navigation"
import { useCallback, useEffect, useMemo } from "react"
import Feedback from "../../../contract-artifacts/Feedback.json"
import { ethers } from "ethers"
import useSemaphoreIdentity from "@/hooks/useSemaphoreIdentity"
import { useState } from "react"
export default function GroupsPage() {
const router = useRouter()
const { setLog } = useLogContext()
const { _users, refreshUsers, addUser } = useSemaphoreContext()
const [_loading, setLoading] = useState(false)
const { _identity } = useSemaphoreIdentity()
useEffect(() => {
if (_users.length > 0) {
setLog(`${_users.length} user${_users.length > 1 ? "s" : ""} retrieved from the group 🤙🏽`)
}
}, [_users, setLog])
const users = useMemo(() => [..._users].reverse(), [_users])
const joinGroup = useCallback(async () => {
if (!_identity) {
return
}
setLoading(true)
setLog(`Joining the Feedback group...`)
let joinedGroup: boolean = false
if (process.env.NEXT_PUBLIC_OPENZEPPELIN_AUTOTASK_WEBHOOK) {
const response = await fetch(process.env.NEXT_PUBLIC_OPENZEPPELIN_AUTOTASK_WEBHOOK, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
abi: Feedback.abi,
address: process.env.NEXT_PUBLIC_FEEDBACK_CONTRACT_ADDRESS as string,
functionName: "joinGroup",
functionParameters: [_identity.commitment.toString()]
})
})
if (response.status === 200) {
joinedGroup = true
}
} else if (
process.env.NEXT_PUBLIC_GELATO_RELAYER_ENDPOINT &&
process.env.NEXT_PUBLIC_GELATO_RELAYER_CHAIN_ID &&
process.env.GELATO_RELAYER_API_KEY
) {
const iface = new ethers.Interface(Feedback.abi)
const request = {
chainId: process.env.NEXT_PUBLIC_GELATO_RELAYER_CHAIN_ID,
target: process.env.NEXT_PUBLIC_FEEDBACK_CONTRACT_ADDRESS,
data: iface.encodeFunctionData("joinGroup", [_identity.commitment.toString()]),
sponsorApiKey: process.env.GELATO_RELAYER_API_KEY
}
const response = await fetch(process.env.NEXT_PUBLIC_GELATO_RELAYER_ENDPOINT, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(request)
})
if (response.status === 201) {
joinedGroup = true
}
} else {
const response = await fetch("api/join", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
identityCommitment: _identity.commitment.toString()
})
})
if (response.status === 200) {
joinedGroup = true
}
}
if (joinedGroup) {
addUser(_identity.commitment.toString())
setLog(`You have joined the Feedback group event 🎉 Share your feedback anonymously!`)
} else {
setLog("Some error occurred, please try again!")
}
setLoading(false)
}, [_identity, addUser, setLoading, setLog])
const userHasJoined = useMemo(
() => _identity !== undefined && _users.includes(_identity.commitment.toString()),
[_identity, _users]
)
return (
<>
<h2>Groups</h2>
<p>
<a
href="https://docs.semaphore.pse.dev/guides/groups"
target="_blank"
rel="noreferrer noopener nofollow"
>
Semaphore groups
</a>{" "}
are{" "}
<a
href="https://zkkit.pse.dev/classes/_zk_kit_lean_imt.LeanIMT.html"
target="_blank"
rel="noreferrer noopener nofollow"
>
Lean incremental Merkle trees
</a>{" "}
in which each leaf contains an identity commitment for a user. Groups can be abstracted to represent
events, polls, or organizations.
</p>
<div className="divider"></div>
<div className="text-top">
<h3 className="users-header">Group users ({_users.length})</h3>
<button className="refresh-button" onClick={refreshUsers}>
<span className="refresh-span">
<svg viewBox="0 0 24 24" focusable="false" className="refresh-icon">
<path
fill="currentColor"
d="M5.463 4.43301C7.27756 2.86067 9.59899 1.99666 12 2.00001C17.523 2.00001 22 6.47701 22 12C22 14.136 21.33 16.116 20.19 17.74L17 12H20C20.0001 10.4316 19.5392 8.89781 18.6747 7.58927C17.8101 6.28072 16.5799 5.25517 15.1372 4.64013C13.6944 4.0251 12.1027 3.84771 10.56 4.13003C9.0172 4.41234 7.59145 5.14191 6.46 6.22801L5.463 4.43301ZM18.537 19.567C16.7224 21.1393 14.401 22.0034 12 22C6.477 22 2 17.523 2 12C2 9.86401 2.67 7.88401 3.81 6.26001L7 12H4C3.99987 13.5684 4.46075 15.1022 5.32534 16.4108C6.18992 17.7193 7.42007 18.7449 8.86282 19.3599C10.3056 19.9749 11.8973 20.1523 13.44 19.87C14.9828 19.5877 16.4085 18.8581 17.54 17.772L18.537 19.567Z"
></path>
</svg>
</span>
Refresh
</button>
</div>
{_users.length > 0 && (
<div className="users-wrapper">
{users.map((user, i) => (
<div key={i}>
<p className="box box-text">
{_identity?.commitment.toString() === user ? <b>{user}</b> : user}
</p>
</div>
))}
</div>
)}
<div className="join-group-button">
<button
className="button"
onClick={joinGroup}
disabled={_loading || !_identity || userHasJoined}
type="button"
>
<span>Join group</span>
{_loading && <div className="loader"></div>}
</button>
</div>
<div className="divider" />
<Stepper
step={2}
onPrevClick={() => router.push("/")}
onNextClick={userHasJoined ? () => router.push("/proofs") : undefined}
/>
</>
)
}

View File

@@ -1,142 +0,0 @@
"use client"
import { Identity } from "@semaphore-protocol/core"
import { useRouter } from "next/navigation"
import { useCallback, useContext, useEffect, useState } from "react"
import Feedback from "../../../contract-artifacts/Feedback.json"
import Stepper from "@/components/Stepper"
import LogsContext from "@/context/LogsContext"
import SemaphoreContext from "@/context/SemaphoreContext"
export default function GroupsPage() {
const router = useRouter()
const { setLogs } = useContext(LogsContext)
const { _users, refreshUsers, addUser } = useContext(SemaphoreContext)
const [_loading, setLoading] = useState(false)
const [_identity, setIdentity] = useState<Identity>()
useEffect(() => {
const privateKey = localStorage.getItem("identity")
if (!privateKey) {
router.push("/")
return
}
setIdentity(new Identity(privateKey))
}, [router])
useEffect(() => {
if (_users.length > 0) {
setLogs(`${_users.length} user${_users.length > 1 ? "s" : ""} retrieved from the group 🤙🏽`)
}
}, [_users, setLogs])
const joinGroup = useCallback(async () => {
if (!_identity) {
return
}
setLoading(true)
setLogs(`Joining the Feedback group...`)
let response: any
if (process.env.OPENZEPPELIN_AUTOTASK_WEBHOOK) {
response = await fetch(process.env.OPENZEPPELIN_AUTOTASK_WEBHOOK, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
abi: Feedback.abi,
address: process.env.FEEDBACK_CONTRACT_ADDRESS,
functionName: "joinGroup",
functionParameters: [_identity.commitment.toString()]
})
})
} else {
response = await fetch("api/join", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
identityCommitment: _identity.commitment.toString()
})
})
}
if (response.status === 200) {
addUser(_identity.commitment.toString())
setLogs(`You have joined the Feedback group event 🎉 Share your feedback anonymously!`)
} else {
setLogs("Some error occurred, please try again!")
}
setLoading(false)
}, [_identity, addUser, setLogs])
const userHasJoined = useCallback((identity: Identity) => _users.includes(identity.commitment.toString()), [_users])
return (
<>
<h2>Groups</h2>
<p>
<a
href="https://docs.semaphore.pse.dev/guides/groups"
target="_blank"
rel="noreferrer noopener nofollow"
>
Semaphore groups
</a>{" "}
are{" "}
<a
href="https://zkkit.pse.dev/classes/_zk_kit_imt.LeanIMT.html"
target="_blank"
rel="noreferrer noopener nofollow"
>
Lean incremental Merkle trees
</a>{" "}
in which each leaf contains an identity commitment for a user. Groups can be abstracted to represent
events, polls, or organizations.
</p>
<div className="divider"></div>
<div className="text-top">
<h3>Group users ({_users.length})</h3>
<button className="button-link" onClick={refreshUsers}>
Refresh
</button>
</div>
<div>
<button
className="button"
onClick={joinGroup}
disabled={_loading || !_identity || userHasJoined(_identity)}
>
<span>Join group</span>
{_loading && <div className="loader"></div>}
</button>
</div>
{_users.length > 0 && (
<div>
{_users.map((user, i) => (
<div key={i}>
<p className="box box-text">{user.toString()}</p>
</div>
))}
</div>
)}
<div className="divider"></div>
<Stepper
step={2}
onPrevClick={() => router.push("/")}
onNextClick={_identity && userHasJoined(_identity) ? () => router.push("/proofs") : undefined}
/>
</>
)
}

View File

@@ -1,8 +1,10 @@
import PageContainer from "@/components/PageContainer"
import type { Metadata } from "next"
import { Inter } from "next/font/google"
import { LogContextProvider } from "@/context/LogContext"
import { SemaphoreContextProvider } from "@/context/SemaphoreContext"
import "./globals.css"
import { Inter } from "next/font/google"
const inter = Inter({ subsets: ["latin"] })
export const metadata: Metadata = {
@@ -32,8 +34,20 @@ export default function RootLayout({
}>) {
return (
<html lang="en" suppressHydrationWarning>
<head>
<link rel="preconnect" href="https://fonts.googleapis.com"></link>
<link rel="preconnect" href="https://fonts.gstatic.com"></link>
<link
href="https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap"
rel="stylesheet"
></link>
</head>
<body suppressHydrationWarning className={inter.className}>
<PageContainer>{children}</PageContainer>
<SemaphoreContextProvider>
<LogContextProvider>
<PageContainer>{children}</PageContainer>
</LogContextProvider>
</SemaphoreContextProvider>
</body>
</html>
)

View File

@@ -2,42 +2,42 @@
import { Identity } from "@semaphore-protocol/core"
import { useRouter } from "next/navigation"
import { useCallback, useContext, useEffect, useState } from "react"
import { useCallback, useEffect, useState } from "react"
import Stepper from "../components/Stepper"
import LogsContext from "../context/LogsContext"
import { useLogContext } from "../context/LogContext"
export default function IdentitiesPage() {
const router = useRouter()
const { setLogs } = useContext(LogsContext)
const { setLog } = useLogContext()
const [_identity, setIdentity] = useState<Identity>()
useEffect(() => {
const privateKey = localStorage.getItem("identity")
if (privateKey) {
const identity = new Identity(privateKey)
const identity = Identity.import(privateKey)
setIdentity(identity)
setLogs("Your Semaphore identity has been retrieved from the browser cache 👌🏽")
setLog("Your Semaphore identity has been retrieved from the browser cache 👌🏽")
} else {
setLogs("Create your Semaphore identity 👆🏽")
setLog("Create your Semaphore identity 👆🏽")
}
}, [setLogs])
}, [setLog])
const createIdentity = useCallback(async () => {
const identity = new Identity()
setIdentity(identity)
localStorage.setItem("identity", identity.privateKey.toString())
localStorage.setItem("identity", identity.export())
setLogs("Your new Semaphore identity has just been created 🎉")
}, [setLogs])
setLog("Your new Semaphore identity has just been created 🎉")
}, [setLog])
return (
<>
<h2 className="font-size: 3rem;">Identities</h2>
<h2>Identities</h2>
<p>
The identity of a user in the Semaphore protocol. A{" "}
@@ -59,35 +59,36 @@ export default function IdentitiesPage() {
public/private key pair and a commitment, used as the public identifier of the identity.
</p>
<div className="divider"></div>
<div className="divider" />
<div className="text-top">
<div className="keys-header">
<h3>Identity</h3>
{_identity && (
<button className="button-link" onClick={createIdentity}>
New
</button>
)}
</div>
{_identity ? (
<div>
<div className="box">
<p className="box-text">Private Key: {_identity.privateKey.toString()}</p>
<p className="box-text">Commitment: {_identity.commitment.toString()}</p>
</div>
</div>
) : (
<div>
<button className="button" onClick={createIdentity}>
Create identity
</button>
{_identity && (
<div className="key-wrapper">
<p>
<b>Private Key (base64)</b>:<br /> {_identity.export()}
</p>
<p>
<b>Public Key</b>:<br /> [{_identity.publicKey[0].toString()},{" "}
{_identity.publicKey[1].toString()}]
</p>
<p>
<b>Commitment</b>:<br /> {_identity.commitment.toString()}
</p>
</div>
)}
<div className="divider"></div>
<div>
<button className="button" onClick={createIdentity} type="button">
Create identity
</button>
</div>
<Stepper step={1} onNextClick={_identity && (() => router.push("/groups"))} />
<div className="divider" />
<Stepper step={1} onNextClick={_identity && (() => router.push("/group"))} />
</>
)
}

View File

@@ -1,78 +1,94 @@
"use client"
import { Group, Identity, generateProof } from "@semaphore-protocol/core"
import Stepper from "@/components/Stepper"
import { useLogContext } from "@/context/LogContext"
import { useSemaphoreContext } from "@/context/SemaphoreContext"
import { generateProof, Group } from "@semaphore-protocol/core"
import { encodeBytes32String, ethers } from "ethers"
import { useRouter } from "next/navigation"
import { useCallback, useContext, useEffect, useState } from "react"
import { useCallback, useEffect, useMemo, useState } from "react"
import Feedback from "../../../contract-artifacts/Feedback.json"
import Stepper from "../../components/Stepper"
import LogsContext from "../../context/LogsContext"
import SemaphoreContext from "../../context/SemaphoreContext"
import useSemaphoreIdentity from "@/hooks/useSemaphoreIdentity"
export default function ProofsPage() {
const router = useRouter()
const { setLogs } = useContext(LogsContext)
const { _users, _feedback, refreshFeedback, addFeedback } = useContext(SemaphoreContext)
const { setLog } = useLogContext()
const { _users, _feedback, refreshFeedback, addFeedback } = useSemaphoreContext()
const [_loading, setLoading] = useState(false)
const [_identity, setIdentity] = useState<Identity>()
useEffect(() => {
const privateKey = localStorage.getItem("identity")
if (!privateKey) {
router.push("/")
return
}
setIdentity(new Identity(privateKey))
}, [router])
const { _identity } = useSemaphoreIdentity()
useEffect(() => {
if (_feedback.length > 0) {
setLogs(`${_feedback.length} feedback retrieved from the group 🤙🏽`)
setLog(`${_feedback.length} feedback retrieved from the group 🤙🏽`)
}
}, [_feedback, setLogs])
}, [_feedback, setLog])
const feedback = useMemo(() => [..._feedback].reverse(), [_feedback])
const sendFeedback = useCallback(async () => {
if (!_identity) {
return
}
if (typeof process.env.NEXT_PUBLIC_GROUP_ID !== "string") {
throw new Error("Please, define NEXT_PUBLIC_GROUP_ID in your .env file")
}
const feedback = prompt("Please enter your feedback:")
if (feedback && _users) {
setLoading(true)
setLogs(`Posting your anonymous feedback...`)
setLog(`Posting your anonymous feedback...`)
try {
const group = new Group(_users)
const { points, merkleTreeDepth, merkleTreeRoot, nullifier, message } = await generateProof(
const message = encodeBytes32String(feedback)
const { points, merkleTreeDepth, merkleTreeRoot, nullifier } = await generateProof(
_identity,
group,
feedback,
message,
process.env.NEXT_PUBLIC_GROUP_ID as string
)
let response: any
if (process.env.OPENZEPPELIN_AUTOTASK_WEBHOOK) {
response = await fetch(process.env.OPENZEPPELIN_AUTOTASK_WEBHOOK, {
let feedbackSent: boolean = false
const params = [merkleTreeDepth, merkleTreeRoot, nullifier, message, points]
if (process.env.NEXT_PUBLIC_OPENZEPPELIN_AUTOTASK_WEBHOOK) {
const response = await fetch(process.env.NEXT_PUBLIC_OPENZEPPELIN_AUTOTASK_WEBHOOK, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
abi: Feedback.abi,
address: process.env.FEEDBACK_CONTRACT_ADDRESS,
address: process.env.NEXT_PUBLIC_FEEDBACK_CONTRACT_ADDRESS,
functionName: "sendFeedback",
functionParameters: [merkleTreeDepth, merkleTreeRoot, nullifier, message, points]
functionParameters: params
})
})
if (response.status === 200) {
feedbackSent = true
}
} else if (
process.env.NEXT_PUBLIC_GELATO_RELAYER_ENDPOINT &&
process.env.NEXT_PUBLIC_GELATO_RELAYER_CHAIN_ID &&
process.env.GELATO_RELAYER_API_KEY
) {
const iface = new ethers.Interface(Feedback.abi)
const request = {
chainId: process.env.NEXT_PUBLIC_GELATO_RELAYER_CHAIN_ID,
target: process.env.NEXT_PUBLIC_FEEDBACK_CONTRACT_ADDRESS,
data: iface.encodeFunctionData("sendFeedback", params),
sponsorApiKey: process.env.GELATO_RELAYER_API_KEY
}
const response = await fetch(process.env.NEXT_PUBLIC_GELATO_RELAYER_ENDPOINT, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(request)
})
if (response.status === 201) {
feedbackSent = true
}
} else {
response = await fetch("api/feedback", {
const response = await fetch("api/feedback", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
@@ -83,24 +99,28 @@ export default function ProofsPage() {
points
})
})
if (response.status === 200) {
feedbackSent = true
}
}
if (response.status === 200) {
if (feedbackSent) {
addFeedback(feedback)
setLogs(`Your feedback has been posted 🎉`)
setLog(`Your feedback has been posted 🎉`)
} else {
setLogs("Some error occurred, please try again!")
setLog("Some error occurred, please try again!")
}
} catch (error) {
console.error(error)
setLogs("Some error occurred, please try again!")
setLog("Some error occurred, please try again!")
} finally {
setLoading(false)
}
}
}, [_identity, _users, addFeedback, setLogs])
}, [_identity, _users, addFeedback, setLoading, setLog])
return (
<>
@@ -122,22 +142,23 @@ export default function ProofsPage() {
<div className="divider"></div>
<div className="text-top">
<h3>Feedback messages ({_feedback.length})</h3>
<button className="button-link" onClick={refreshFeedback}>
<h3>Feedback ({_feedback.length})</h3>
<button className="refresh-button" onClick={refreshFeedback}>
<span className="refresh-span">
<svg viewBox="0 0 24 24" focusable="false" className="refresh-icon">
<path
fill="currentColor"
d="M5.463 4.43301C7.27756 2.86067 9.59899 1.99666 12 2.00001C17.523 2.00001 22 6.47701 22 12C22 14.136 21.33 16.116 20.19 17.74L17 12H20C20.0001 10.4316 19.5392 8.89781 18.6747 7.58927C17.8101 6.28072 16.5799 5.25517 15.1372 4.64013C13.6944 4.0251 12.1027 3.84771 10.56 4.13003C9.0172 4.41234 7.59145 5.14191 6.46 6.22801L5.463 4.43301ZM18.537 19.567C16.7224 21.1393 14.401 22.0034 12 22C6.477 22 2 17.523 2 12C2 9.86401 2.67 7.88401 3.81 6.26001L7 12H4C3.99987 13.5684 4.46075 15.1022 5.32534 16.4108C6.18992 17.7193 7.42007 18.7449 8.86282 19.3599C10.3056 19.9749 11.8973 20.1523 13.44 19.87C14.9828 19.5877 16.4085 18.8581 17.54 17.772L18.537 19.567Z"
></path>
</svg>
</span>
Refresh
</button>
</div>
<div>
<button className="button" onClick={sendFeedback} disabled={_loading}>
<span>Send Feedback</span>
{_loading && <div className="loader"></div>}
</button>
</div>
{_feedback.length > 0 && (
<div>
{_feedback.map((f, i) => (
{feedback.length > 0 && (
<div className="feedback-wrapper">
{feedback.map((f, i) => (
<div key={i}>
<p className="box box-text">{f}</p>
</div>
@@ -145,9 +166,16 @@ export default function ProofsPage() {
</div>
)}
<div className="send-feedback-button">
<button className="button" onClick={sendFeedback} disabled={_loading}>
<span>Send Feedback</span>
{_loading && <div className="loader"></div>}
</button>
</div>
<div className="divider"></div>
<Stepper step={3} onPrevClick={() => router.push("/groups")} />
<Stepper step={3} onPrevClick={() => router.push("/group")} />
</>
)
}

View File

@@ -1,12 +1,8 @@
"use client"
import LogsContext from "@/context/LogsContext"
import SemaphoreContext from "@/context/SemaphoreContext"
import useSemaphore from "@/hooks/useSemaphore"
import { useLogContext } from "@/context/LogContext"
import shortenString from "@/utils/shortenString"
import { SupportedNetwork } from "@semaphore-protocol/utils"
import { usePathname } from "next/navigation"
import { useEffect, useState } from "react"
import Link from "next/link"
export default function PageContainer({
@@ -15,15 +11,9 @@ export default function PageContainer({
children: React.ReactNode
}>) {
const pathname = usePathname()
const semaphore = useSemaphore()
const [_logs, setLogs] = useState<string>("")
const { log } = useLogContext()
useEffect(() => {
semaphore.refreshUsers()
semaphore.refreshFeedback()
}, [])
function getExplorerLink(network: SupportedNetwork, address: string) {
function getExplorerLink(network: string, address: string) {
switch (network) {
case "sepolia":
return `https://sepolia.etherscan.io/address/${address}`
@@ -35,7 +25,7 @@ export default function PageContainer({
}
return (
<div>
<>
<div className="header">
<Link href="/" className="header-left">
Feedback
@@ -43,7 +33,7 @@ export default function PageContainer({
<div className="header-right">
<a
href={getExplorerLink(
process.env.NEXT_PUBLIC_DEFAULT_NETWORK as SupportedNetwork,
process.env.NEXT_PUBLIC_DEFAULT_NETWORK as string,
process.env.NEXT_PUBLIC_FEEDBACK_CONTRACT_ADDRESS as string
)}
target="_blank"
@@ -52,47 +42,34 @@ export default function PageContainer({
<div>{shortenString(process.env.NEXT_PUBLIC_FEEDBACK_CONTRACT_ADDRESS as string, [6, 4])}</div>
</a>
<a
href="https://github.com/semaphore-protocol/semaphore"
href="https://github.com/semaphore-protocol/semaphore/tree/main/packages/cli-template-monorepo-ethers"
target="_blank"
rel="noreferrer noopener nofollow"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="feather feather-github"
>
<path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path>
</svg>
<button type="button" className="github-button" aria-label="Github repository">
<svg
height="32"
aria-hidden="true"
viewBox="0 0 24 24"
version="1.1"
width="32"
data-view-component="true"
>
<path d="M12.5.75C6.146.75 1 5.896 1 12.25c0 5.089 3.292 9.387 7.863 10.91.575.101.79-.244.79-.546 0-.273-.014-1.178-.014-2.142-2.889.532-3.636-.704-3.866-1.35-.13-.331-.69-1.352-1.18-1.625-.402-.216-.977-.748-.014-.762.906-.014 1.553.834 1.769 1.179 1.035 1.74 2.688 1.25 3.349.948.1-.747.402-1.25.733-1.538-2.559-.287-5.232-1.279-5.232-5.678 0-1.25.445-2.285 1.178-3.09-.115-.288-.517-1.467.115-3.048 0 0 .963-.302 3.163 1.179.92-.259 1.897-.388 2.875-.388.977 0 1.955.13 2.875.388 2.2-1.495 3.162-1.179 3.162-1.179.633 1.581.23 2.76.115 3.048.733.805 1.179 1.825 1.179 3.09 0 4.413-2.688 5.39-5.247 5.678.417.36.776 1.05.776 2.128 0 1.538-.014 2.774-.014 3.162 0 .302.216.662.79.547C20.709 21.637 24 17.324 24 12.25 24 5.896 18.854.75 12.5.75Z"></path>
</svg>
</button>
</a>
</div>
</div>
<div className="container">
<SemaphoreContext.Provider value={semaphore}>
<LogsContext.Provider
value={{
_logs,
setLogs
}}
>
{children}
</LogsContext.Provider>
</SemaphoreContext.Provider>
</div>
<div className="container">{children}</div>
<div className="divider-footer"></div>
<div className="divider-footer" />
<div className="footer">
{_logs.endsWith("...")}
<p>{_logs || `Current step: ${pathname}`}</p>
{log.endsWith("...")}
<p>{log || `Current step: ${pathname}`}</p>
</div>
</div>
</>
)
}

View File

@@ -1,3 +1,5 @@
"use client"
export type StepperProps = {
step: number
onPrevClick?: () => void
@@ -8,21 +10,47 @@ export default function Stepper({ step, onPrevClick, onNextClick }: StepperProps
return (
<div className="stepper">
{onPrevClick !== undefined ? (
<button className="button-stepper" disabled={!onPrevClick} onClick={onPrevClick || undefined}>
<button
className="button-stepper"
disabled={!onPrevClick}
onClick={onPrevClick || undefined}
type="button"
>
<span className="stepper-icon left-pad">
<svg viewBox="0 0 24 24" focusable="false">
<path
fill="currentColor"
d="M16.2425 6.34317L14.8283 4.92896L7.75732 12L14.8284 19.0711L16.2426 17.6569L10.5857 12L16.2425 6.34317Z"
></path>
</svg>
</span>
Prev
</button>
) : (
<span></span>
<button className="button-stepper"></button>
)}
<p>{step.toString()}/3</p>
{onNextClick !== undefined ? (
<button className="button-stepper" disabled={!onNextClick} onClick={onNextClick || undefined}>
<button
className="button-stepper"
disabled={!onNextClick}
onClick={onNextClick || undefined}
type="button"
>
Next
<span className="stepper-icon right-pad">
<svg viewBox="0 0 24 24" focusable="false">
<path
fill="currentColor"
d="M10.5859 6.34317L12.0001 4.92896L19.0712 12L12.0001 19.0711L10.5859 17.6569L16.2428 12L10.5859 6.34317Z"
></path>
</svg>
</span>
</button>
) : (
<span></span>
<span className="button-stepper" />
)}
</div>
)

View File

@@ -0,0 +1,37 @@
"use client"
import React, { createContext, ReactNode, useContext, useState } from "react"
export type LogContextType = {
log: string
setLog: (logs: string) => void
}
const LogContext = createContext<LogContextType | null>(null)
interface ProviderProps {
children: ReactNode
}
export const LogContextProvider: React.FC<ProviderProps> = ({ children }) => {
const [log, setLog] = useState<string>("")
return (
<LogContext.Provider
value={{
log,
setLog
}}
>
{children}
</LogContext.Provider>
)
}
export const useLogContext = () => {
const context = useContext(LogContext)
if (context === null) {
throw new Error("LogContext must be used within a LogContextProvider")
}
return context
}

View File

@@ -1,11 +0,0 @@
import React from "react"
export type LogsContextType = {
_logs: string
setLogs: (logs: string) => void
}
export default React.createContext<LogsContextType>({
_logs: "",
setLogs: (logs: string) => logs
})

View File

@@ -1,19 +0,0 @@
import React from "react"
export type SemaphoreContextType = {
_users: string[]
_feedback: string[]
refreshUsers: () => Promise<void>
addUser: (user: string) => void
refreshFeedback: () => Promise<void>
addFeedback: (feedback: string) => void
}
export default React.createContext<SemaphoreContextType>({
_users: [],
_feedback: [],
refreshUsers: () => Promise.resolve(),
addUser: () => {},
refreshFeedback: () => Promise.resolve(),
addFeedback: () => {}
})

View File

@@ -0,0 +1,94 @@
"use client"
import React, { createContext, ReactNode, useCallback, useContext, useEffect, useState } from "react"
import { SemaphoreEthers } from "@semaphore-protocol/data"
import { decodeBytes32String, toBeHex } from "ethers"
export type SemaphoreContextType = {
_users: string[]
_feedback: string[]
refreshUsers: () => Promise<void>
addUser: (user: string) => void
refreshFeedback: () => Promise<void>
addFeedback: (feedback: string) => void
}
const SemaphoreContext = createContext<SemaphoreContextType | null>(null)
interface ProviderProps {
children: ReactNode
}
const ethereumNetwork =
process.env.NEXT_PUBLIC_DEFAULT_NETWORK === "localhost"
? "http://127.0.0.1:8545"
: process.env.NEXT_PUBLIC_DEFAULT_NETWORK
export const SemaphoreContextProvider: React.FC<ProviderProps> = ({ children }) => {
const [_users, setUsers] = useState<any[]>([])
const [_feedback, setFeedback] = useState<string[]>([])
const refreshUsers = useCallback(async (): Promise<void> => {
const semaphore = new SemaphoreEthers(ethereumNetwork, {
address: process.env.NEXT_PUBLIC_SEMAPHORE_CONTRACT_ADDRESS,
projectId: process.env.NEXT_PUBLIC_INFURA_API_KEY
})
const members = await semaphore.getGroupMembers(process.env.NEXT_PUBLIC_GROUP_ID as string)
setUsers(members.map((member) => member.toString()))
}, [])
const addUser = useCallback(
(user: any) => {
setUsers([..._users, user])
},
[_users]
)
const refreshFeedback = useCallback(async (): Promise<void> => {
const semaphore = new SemaphoreEthers(ethereumNetwork, {
address: process.env.NEXT_PUBLIC_SEMAPHORE_CONTRACT_ADDRESS,
projectId: process.env.NEXT_PUBLIC_INFURA_API_KEY
})
const proofs = await semaphore.getGroupValidatedProofs(process.env.NEXT_PUBLIC_GROUP_ID as string)
setFeedback(proofs.map(({ message }: any) => decodeBytes32String(toBeHex(message, 32))))
}, [])
const addFeedback = useCallback(
(feedback: string) => {
setFeedback([..._feedback, feedback])
},
[_feedback]
)
useEffect(() => {
refreshUsers()
refreshFeedback()
}, [refreshFeedback, refreshUsers])
return (
<SemaphoreContext.Provider
value={{
_users,
_feedback,
refreshUsers,
addUser,
refreshFeedback,
addFeedback
}}
>
{children}
</SemaphoreContext.Provider>
)
}
export const useSemaphoreContext = () => {
const context = useContext(SemaphoreContext)
if (context === null) {
throw new Error("SemaphoreContext must be used within a SemaphoreContextProvider")
}
return context
}

View File

@@ -1,57 +0,0 @@
import { SemaphoreEthers } from "@semaphore-protocol/data"
import { decodeBytes32String, toBeHex } from "ethers"
import { useCallback, useState } from "react"
import { SemaphoreContextType } from "../context/SemaphoreContext"
const ethereumNetwork =
process.env.NEXT_PUBLIC_DEFAULT_NETWORK === "localhost"
? "http://127.0.0.1:8545"
: process.env.NEXT_PUBLIC_DEFAULT_NETWORK
export default function useSemaphore(): SemaphoreContextType {
const [_users, setUsers] = useState<string[]>([])
const [_feedback, setFeedback] = useState<string[]>([])
const refreshUsers = useCallback(async (): Promise<void> => {
const semaphore = new SemaphoreEthers(ethereumNetwork, {
address: process.env.NEXT_PUBLIC_SEMAPHORE_CONTRACT_ADDRESS
})
const members = await semaphore.getGroupMembers(process.env.NEXT_PUBLIC_GROUP_ID as string)
setUsers(members)
}, [])
const addUser = useCallback(
(user: any) => {
setUsers([..._users, user])
},
[_users]
)
const refreshFeedback = useCallback(async (): Promise<void> => {
const semaphore = new SemaphoreEthers(ethereumNetwork, {
address: process.env.NEXT_PUBLIC_SEMAPHORE_CONTRACT_ADDRESS
})
const proofs = await semaphore.getGroupValidatedProofs(process.env.NEXT_PUBLIC_GROUP_ID as string)
setFeedback(proofs.map(({ message }: any) => decodeBytes32String(toBeHex(message, 32))))
}, [])
const addFeedback = useCallback(
(feedback: string) => {
setFeedback([..._feedback, feedback])
},
[_feedback]
)
return {
_users,
_feedback,
refreshUsers,
addUser,
refreshFeedback,
addFeedback
}
}

View File

@@ -0,0 +1,23 @@
import { useEffect, useState } from "react"
import { Identity } from "@semaphore-protocol/core"
import { useRouter } from "next/navigation"
export default function useSemaphoreIdentity() {
const router = useRouter()
const [_identity, setIdentity] = useState<Identity>()
useEffect(() => {
const privateKey = localStorage.getItem("identity")
if (!privateKey) {
router.push("/")
return
}
setIdentity(new Identity(privateKey))
}, [router])
return {
_identity
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@semaphore-protocol/cli-template-monorepo-ethers",
"version": "4.1.0",
"version": "4.12.0",
"description": "Semaphore Hardhat + Next.js + SemaphoreEthers template.",
"license": "Unlicense",
"files": [

View File

@@ -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.1.0",
"@semaphore-protocol/hardhat": "4.1.0",
"@semaphore-protocol/utils": "4.1.0",
"@semaphore-protocol/core": "4.12.0",
"@semaphore-protocol/hardhat": "4.12.0",
"@semaphore-protocol/utils": "4.12.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.1.0"
"@semaphore-protocol/contracts": "4.12.0"
},
"packageManager": "yarn@4.1.0"
}

View File

@@ -1,4 +1,4 @@
NEXT_PUBLIC_DEFAULT_NETWORK=localhost
NEXT_PUBLIC_FEEDBACK_CONTRACT_ADDRESS=0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9
NEXT_PUBLIC_FEEDBACK_CONTRACT_ADDRESS=0xcf7ed3acca5a467e9e704c703e8d87f634fb0fc9
NEXT_PUBLIC_SEMAPHORE_CONTRACT_ADDRESS=0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0
NEXT_PUBLIC_GROUP_ID=0

View File

@@ -1,5 +1,8 @@
NEXT_PUBLIC_DEFAULT_NETWORK=sepolia
NEXT_PUBLIC_INFURA_API_KEY=abf67af1010b4b8d877e04244f1eac3d
NEXT_PUBLIC_FEEDBACK_CONTRACT_ADDRESS=
NEXT_PUBLIC_SEMAPHORE_CONTRACT_ADDRESS=0x1e0d7FF1610e480fC93BdEC510811ea2Ba6d7c2f
NEXT_PUBLIC_OPENZEPPELIN_AUTOTASK_WEBHOOK=https://api.defender.openzeppelin.com/actions/20fce2ae-844b-4ec0-a6a2-90a3350a9d2c/runs/webhook/303216d1-fa7d-4fca-8c5b-7ba1ba544fc7/2T7i9xrkZA5j37hoaQLUuw
NEXT_PUBLIC_GELATO_RELAYER_ENDPOINT=https://api.gelato.digital/relays/v2/sponsored-call
NEXT_PUBLIC_GELATO_RELAYER_CHAIN_ID=11155111
NEXT_PUBLIC_GROUP_ID=

View File

@@ -1,5 +1,8 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# testing
/coverage
# next.js
/.next/
/out/
@@ -7,3 +10,18 @@
# production
/build
# misc
.DS_Store
*.pem
# typescript
*.tsbuildinfo
next-env.d.ts
# Auto Generated PWA files
public/sw.js
public/workbox-*.js
public/worker-*.js
public/sw.js.map
public/workbox-*.js.map
public/worker-*.js.map

View File

@@ -9,11 +9,6 @@
"internalType": "address",
"name": "semaphoreAddress",
"type": "address"
},
{
"internalType": "uint256",
"name": "_groupId",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
@@ -92,8 +87,8 @@
"type": "function"
}
],
"bytecode": "0x608060405234801561001057600080fd5b5060405161083f38038061083f833981810160405281019061003291906101a8565b816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060018190555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c96e71fb600154306040518363ffffffff1660e01b81526004016100d6929190610206565b600060405180830381600087803b1580156100f057600080fd5b505af1158015610104573d6000803e3d6000fd5b50505050505061022f565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061013f82610114565b9050919050565b61014f81610134565b811461015a57600080fd5b50565b60008151905061016c81610146565b92915050565b6000819050919050565b61018581610172565b811461019057600080fd5b50565b6000815190506101a28161017c565b92915050565b600080604083850312156101bf576101be61010f565b5b60006101cd8582860161015d565b92505060206101de85828601610193565b9150509250929050565b6101f181610172565b82525050565b61020081610134565b82525050565b600060408201905061021b60008301856101e8565b61022860208301846101f7565b9392505050565b6106018061023e6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80637b5d2534146100515780637b85d27a1461006f578063a0f44c921461008b578063eed02e4b146100a9575b600080fd5b6100596100c5565b6040516100669190610301565b60405180910390f35b6100896004803603810190610084919061037e565b6100e9565b005b6100936101ea565b6040516100a09190610409565b60405180910390f35b6100c360048036038101906100be9190610424565b6101f0565b005b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006040518060c001604052808781526020018681526020018581526020018481526020016001548152602001836008806020026040519081016040528092919082600860200280828437600081840152601f19601f820116905080830192505050505050815250905060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0d898dd600154836040518363ffffffff1660e01b81526004016101b0929190610578565b600060405180830381600087803b1580156101ca57600080fd5b505af11580156101de573d6000803e3d6000fd5b50505050505050505050565b60015481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631783efc3600154836040518363ffffffff1660e01b815260040161024d9291906105a2565b600060405180830381600087803b15801561026757600080fd5b505af115801561027b573d6000803e3d6000fd5b5050505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006102c76102c26102bd84610282565b6102a2565b610282565b9050919050565b60006102d9826102ac565b9050919050565b60006102eb826102ce565b9050919050565b6102fb816102e0565b82525050565b600060208201905061031660008301846102f2565b92915050565b600080fd5b6000819050919050565b61033481610321565b811461033f57600080fd5b50565b6000813590506103518161032b565b92915050565b600080fd5b60008190508260206008028201111561037857610377610357565b5b92915050565b6000806000806000610180868803121561039b5761039a61031c565b5b60006103a988828901610342565b95505060206103ba88828901610342565b94505060406103cb88828901610342565b93505060606103dc88828901610342565b92505060806103ed8882890161035c565b9150509295509295909350565b61040381610321565b82525050565b600060208201905061041e60008301846103fa565b92915050565b60006020828403121561043a5761043961031c565b5b600061044884828501610342565b91505092915050565b61045a81610321565b82525050565b600060089050919050565b600081905092915050565b6000819050919050565b600061048c8383610451565b60208301905092915050565b6000602082019050919050565b6104ae81610460565b6104b8818461046b565b92506104c382610476565b8060005b838110156104f45781516104db8782610480565b96506104e683610498565b9250506001810190506104c7565b505050505050565b6101a0820160008201516105136000850182610451565b5060208201516105266020850182610451565b5060408201516105396040850182610451565b50606082015161054c6060850182610451565b50608082015161055f6080850182610451565b5060a082015161057260a08501826104a5565b50505050565b60006101c08201905061058e60008301856103fa565b61059b60208301846104fc565b9392505050565b60006040820190506105b760008301856103fa565b6105c460208301846103fa565b939250505056fea2646970667358221220f33606b2d5ad7c0dfc5d22afb43476e1974ea7fd160e1f28203a3e433f29cb4964736f6c63430008170033",
"deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80637b5d2534146100515780637b85d27a1461006f578063a0f44c921461008b578063eed02e4b146100a9575b600080fd5b6100596100c5565b6040516100669190610301565b60405180910390f35b6100896004803603810190610084919061037e565b6100e9565b005b6100936101ea565b6040516100a09190610409565b60405180910390f35b6100c360048036038101906100be9190610424565b6101f0565b005b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006040518060c001604052808781526020018681526020018581526020018481526020016001548152602001836008806020026040519081016040528092919082600860200280828437600081840152601f19601f820116905080830192505050505050815250905060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0d898dd600154836040518363ffffffff1660e01b81526004016101b0929190610578565b600060405180830381600087803b1580156101ca57600080fd5b505af11580156101de573d6000803e3d6000fd5b50505050505050505050565b60015481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631783efc3600154836040518363ffffffff1660e01b815260040161024d9291906105a2565b600060405180830381600087803b15801561026757600080fd5b505af115801561027b573d6000803e3d6000fd5b5050505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006102c76102c26102bd84610282565b6102a2565b610282565b9050919050565b60006102d9826102ac565b9050919050565b60006102eb826102ce565b9050919050565b6102fb816102e0565b82525050565b600060208201905061031660008301846102f2565b92915050565b600080fd5b6000819050919050565b61033481610321565b811461033f57600080fd5b50565b6000813590506103518161032b565b92915050565b600080fd5b60008190508260206008028201111561037857610377610357565b5b92915050565b6000806000806000610180868803121561039b5761039a61031c565b5b60006103a988828901610342565b95505060206103ba88828901610342565b94505060406103cb88828901610342565b93505060606103dc88828901610342565b92505060806103ed8882890161035c565b9150509295509295909350565b61040381610321565b82525050565b600060208201905061041e60008301846103fa565b92915050565b60006020828403121561043a5761043961031c565b5b600061044884828501610342565b91505092915050565b61045a81610321565b82525050565b600060089050919050565b600081905092915050565b6000819050919050565b600061048c8383610451565b60208301905092915050565b6000602082019050919050565b6104ae81610460565b6104b8818461046b565b92506104c382610476565b8060005b838110156104f45781516104db8782610480565b96506104e683610498565b9250506001810190506104c7565b505050505050565b6101a0820160008201516105136000850182610451565b5060208201516105266020850182610451565b5060408201516105396040850182610451565b50606082015161054c6060850182610451565b50608082015161055f6080850182610451565b5060a082015161057260a08501826104a5565b50505050565b60006101c08201905061058e60008301856103fa565b61059b60208301846104fc565b9392505050565b60006040820190506105b760008301856103fa565b6105c460208301846103fa565b939250505056fea2646970667358221220f33606b2d5ad7c0dfc5d22afb43476e1974ea7fd160e1f28203a3e433f29cb4964736f6c63430008170033",
"bytecode": "0x608060405234801561001057600080fd5b506040516108473803806108478339818101604052810190610032919061017d565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635c3f3b60306040518263ffffffff1660e01b81526004016100cb91906101b9565b6020604051808303816000875af11580156100ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061010e919061020a565b60018190555050610237565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061014a8261011f565b9050919050565b61015a8161013f565b811461016557600080fd5b50565b60008151905061017781610151565b92915050565b6000602082840312156101935761019261011a565b5b60006101a184828501610168565b91505092915050565b6101b38161013f565b82525050565b60006020820190506101ce60008301846101aa565b92915050565b6000819050919050565b6101e7816101d4565b81146101f257600080fd5b50565b600081519050610204816101de565b92915050565b6000602082840312156102205761021f61011a565b5b600061022e848285016101f5565b91505092915050565b610601806102466000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80637b5d2534146100515780637b85d27a1461006f578063a0f44c921461008b578063eed02e4b146100a9575b600080fd5b6100596100c5565b6040516100669190610301565b60405180910390f35b6100896004803603810190610084919061037e565b6100e9565b005b6100936101ea565b6040516100a09190610409565b60405180910390f35b6100c360048036038101906100be9190610424565b6101f0565b005b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006040518060c001604052808781526020018681526020018581526020018481526020016001548152602001836008806020026040519081016040528092919082600860200280828437600081840152601f19601f820116905080830192505050505050815250905060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0d898dd600154836040518363ffffffff1660e01b81526004016101b0929190610578565b600060405180830381600087803b1580156101ca57600080fd5b505af11580156101de573d6000803e3d6000fd5b50505050505050505050565b60015481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631783efc3600154836040518363ffffffff1660e01b815260040161024d9291906105a2565b600060405180830381600087803b15801561026757600080fd5b505af115801561027b573d6000803e3d6000fd5b5050505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006102c76102c26102bd84610282565b6102a2565b610282565b9050919050565b60006102d9826102ac565b9050919050565b60006102eb826102ce565b9050919050565b6102fb816102e0565b82525050565b600060208201905061031660008301846102f2565b92915050565b600080fd5b6000819050919050565b61033481610321565b811461033f57600080fd5b50565b6000813590506103518161032b565b92915050565b600080fd5b60008190508260206008028201111561037857610377610357565b5b92915050565b6000806000806000610180868803121561039b5761039a61031c565b5b60006103a988828901610342565b95505060206103ba88828901610342565b94505060406103cb88828901610342565b93505060606103dc88828901610342565b92505060806103ed8882890161035c565b9150509295509295909350565b61040381610321565b82525050565b600060208201905061041e60008301846103fa565b92915050565b60006020828403121561043a5761043961031c565b5b600061044884828501610342565b91505092915050565b61045a81610321565b82525050565b600060089050919050565b600081905092915050565b6000819050919050565b600061048c8383610451565b60208301905092915050565b6000602082019050919050565b6104ae81610460565b6104b8818461046b565b92506104c382610476565b8060005b838110156104f45781516104db8782610480565b96506104e683610498565b9250506001810190506104c7565b505050505050565b6101a0820160008201516105136000850182610451565b5060208201516105266020850182610451565b5060408201516105396040850182610451565b50606082015161054c6060850182610451565b50608082015161055f6080850182610451565b5060a082015161057260a08501826104a5565b50505050565b60006101c08201905061058e60008301856103fa565b61059b60208301846104fc565b9392505050565b60006040820190506105b760008301856103fa565b6105c460208301846103fa565b939250505056fea264697066735822122078569abd7f309f3107c4d19e9b4a4f4812522ccc5dc57c7ccbe2b06a5ba461b064736f6c63430008170033",
"deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80637b5d2534146100515780637b85d27a1461006f578063a0f44c921461008b578063eed02e4b146100a9575b600080fd5b6100596100c5565b6040516100669190610301565b60405180910390f35b6100896004803603810190610084919061037e565b6100e9565b005b6100936101ea565b6040516100a09190610409565b60405180910390f35b6100c360048036038101906100be9190610424565b6101f0565b005b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006040518060c001604052808781526020018681526020018581526020018481526020016001548152602001836008806020026040519081016040528092919082600860200280828437600081840152601f19601f820116905080830192505050505050815250905060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0d898dd600154836040518363ffffffff1660e01b81526004016101b0929190610578565b600060405180830381600087803b1580156101ca57600080fd5b505af11580156101de573d6000803e3d6000fd5b50505050505050505050565b60015481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631783efc3600154836040518363ffffffff1660e01b815260040161024d9291906105a2565b600060405180830381600087803b15801561026757600080fd5b505af115801561027b573d6000803e3d6000fd5b5050505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006102c76102c26102bd84610282565b6102a2565b610282565b9050919050565b60006102d9826102ac565b9050919050565b60006102eb826102ce565b9050919050565b6102fb816102e0565b82525050565b600060208201905061031660008301846102f2565b92915050565b600080fd5b6000819050919050565b61033481610321565b811461033f57600080fd5b50565b6000813590506103518161032b565b92915050565b600080fd5b60008190508260206008028201111561037857610377610357565b5b92915050565b6000806000806000610180868803121561039b5761039a61031c565b5b60006103a988828901610342565b95505060206103ba88828901610342565b94505060406103cb88828901610342565b93505060606103dc88828901610342565b92505060806103ed8882890161035c565b9150509295509295909350565b61040381610321565b82525050565b600060208201905061041e60008301846103fa565b92915050565b60006020828403121561043a5761043961031c565b5b600061044884828501610342565b91505092915050565b61045a81610321565b82525050565b600060089050919050565b600081905092915050565b6000819050919050565b600061048c8383610451565b60208301905092915050565b6000602082019050919050565b6104ae81610460565b6104b8818461046b565b92506104c382610476565b8060005b838110156104f45781516104db8782610480565b96506104e683610498565b9250506001810190506104c7565b505050505050565b6101a0820160008201516105136000850182610451565b5060208201516105266020850182610451565b5060408201516105396040850182610451565b50606082015161054c6060850182610451565b50608082015161055f6080850182610451565b5060a082015161057260a08501826104a5565b50505050565b60006101c08201905061058e60008301856103fa565b61059b60208301846104fc565b9392505050565b60006040820190506105b760008301856103fa565b6105c460208301846103fa565b939250505056fea264697066735822122078569abd7f309f3107c4d19e9b4a4f4812522ccc5dc57c7ccbe2b06a5ba461b064736f6c63430008170033",
"linkReferences": {},
"deployedLinkReferences": {}
}

View File

@@ -14,7 +14,8 @@ const nextConfig = withPWA({
})({
env: {
INFURA_API_KEY: process.env.INFURA_API_KEY,
ETHEREUM_PRIVATE_KEY: process.env.ETHEREUM_PRIVATE_KEY
ETHEREUM_PRIVATE_KEY: process.env.ETHEREUM_PRIVATE_KEY,
GELATO_RELAYER_API_KEY: process.env.GELATO_RELAYER_API_KEY
}
})

View File

@@ -9,10 +9,10 @@
"lint": "next lint"
},
"dependencies": {
"@semaphore-protocol/core": "4.1.0",
"@semaphore-protocol/data": "4.1.0",
"@semaphore-protocol/utils": "4.1.0",
"ethers": "^6.11.1",
"@semaphore-protocol/core": "4.12.0",
"@semaphore-protocol/data": "4.12.0",
"@semaphore-protocol/utils": "4.12.0",
"ethers": "^6.13.4",
"next": "14.1.0",
"next-pwa": "^5.6.0",
"react": "^18",

Some files were not shown because too many files have changed in this diff Show More