Compare commits

...

28 Commits

Author SHA1 Message Date
cedoor
76d7821d97 chore: v4.0.0-alpha.6
Former-commit-id: 9a250db6e6
2024-02-07 16:18:25 +00:00
cedoor
2715fbf7de fix(core): add full import path in esm modules
Former-commit-id: 9e2494b61c
2024-02-07 16:16:03 +00:00
cedoor
d3b825fc1a chore: remove stableVersion auto-generated field
Former-commit-id: a6bc60e8d1
2024-02-07 15:54:42 +00:00
cedoor
fc9aee8e71 chore: v4.0.0-alpha.5
Former-commit-id: a6af175b90
2024-02-07 15:52:49 +00:00
cedoor
85fbb3034c build: fix default exports
Former-commit-id: e8d088ef28
2024-02-07 13:06:01 +00:00
Cedoor
d54fa69cd6 Merge pull request #608 from semaphore-protocol/refactor/deployed-contracts
Update scripts to save deployed contract addresses

Former-commit-id: 33d944f2d4
2024-02-07 13:00:31 +00:00
Cedoor
efbaa7376c Merge pull request #611 from semaphore-protocol/chore/fullproof-occurences
Remove all `fullProof` occurrences

Former-commit-id: 8f8d18a840
2024-02-07 12:59:34 +00:00
Cedoor
41eebe6781 Merge pull request #612 from semaphore-protocol/feat/core-package
New `@semaphore-protocol/core` package

Former-commit-id: 0d6bbec04a
2024-02-07 12:58:29 +00:00
Cedoor
fb6f08d62c Update packages/identity/package.json
Co-authored-by: Vivian Plasencia <v.pcalana@gmail.com>
Former-commit-id: 66b5b07604
2024-02-07 12:58:11 +00:00
cedoor
dff7518cbf chore: update ts, rollup dependencies
Former-commit-id: ad896ce4f2
2024-02-06 21:07:56 +00:00
cedoor
1d9e0c8b30 chore(cli): use semaphore core package
Former-commit-id: a8c241ddaf
2024-02-06 21:07:46 +00:00
cedoor
fe69fa0fcf feat(core): create core package
Former-commit-id: 4928a5ee6d
2024-02-05 12:44:48 +00:00
cedoor
9ae9029ab4 chore: remove all fullProof occurrences
Former-commit-id: 01eb38b331
2024-02-02 18:42:40 +00:00
cedoor
c77125a323 chore(cli): update cli monorepo template app descriptions
Former-commit-id: cc6fa62895
2024-02-02 14:32:33 +00:00
cedoor
ece968c679 chore(cli): replace localhost with 127.0.0.1
Former-commit-id: 5affa35b6c
2024-02-01 11:11:45 +00:00
cedoor
94bdcbccdb chore(cli): sync monorepo templates with boilerplate
Former-commit-id: 4f31a038f0
2024-01-31 17:21:34 +00:00
cedoor
9a1bbb2fcf style(contracts): format code with prettier
Former-commit-id: 82bd140326
2024-01-31 16:25:37 +00:00
cedoor
15716b5a9c refactor(contracts): update scripts to save deployed contract addresses
Former-commit-id: c610213d54
2024-01-31 14:10:45 +00:00
Cedoor
947a4fffbd chore(circuits): update circuit scheme
Former-commit-id: caf1601260
2024-01-30 18:30:47 +00:00
Cedoor
d5b4e88d59 chore(circuits): update circuit scheme
Former-commit-id: 8a1f234bd9
2024-01-30 18:26:05 +00:00
Cedoor
834a1efa47 chore(circuits): add circuit scheme
Former-commit-id: 62a8f4b1d4
2024-01-30 18:20:40 +00:00
cedoor
0b6e3f8dd5 chore: remove stableVersion auto-generated field
Former-commit-id: 596e10c210
2024-01-26 20:20:44 +00:00
cedoor
1c75c090bd chore: v4.0.0-alpha.4
Former-commit-id: da368d0f34
2024-01-26 20:19:13 +00:00
cedoor
51dd7a10a6 fix(data): update semaphore contract abi
Former-commit-id: eb47cc62ef
2024-01-26 20:18:15 +00:00
cedoor
5479adc55a chore: remove stableVersion auto-generated field
Former-commit-id: 4de3ba863f
2024-01-26 20:08:39 +00:00
cedoor
c8d8c5cfd0 chore: v4.0.0-alpha.3
Former-commit-id: 59bfcf7562
2024-01-26 20:06:49 +00:00
cedoor
eef036a8da build(identity): include poseidon code in bundle
Former-commit-id: 8a056da221
2024-01-26 20:05:51 +00:00
cedoor
f0fc38accc chore: remove stableVersion auto-generated field
Former-commit-id: dea043bd64
2024-01-26 17:30:52 +00:00
76 changed files with 721 additions and 430 deletions

3
.gitignore vendored
View File

@@ -73,9 +73,6 @@ dist
artifacts
cache
typechain-types
packages/contracts/deployed-contracts/undefined.json
packages/contracts/deployed-contracts/hardhat.json
packages/contracts/deployed-contracts/localhost.json
# Stores VSCode versions used for testing VSCode extensions
.vscode-test

View File

@@ -12,9 +12,6 @@ coverage.json
artifacts
cache
typechain-types
packages/contracts/deployed-contracts/undefined.json
packages/contracts/deployed-contracts/hardhat.json
packages/contracts/deployed-contracts/localhost.json
# production
dist

View File

@@ -69,6 +69,25 @@ The core of the Semaphore protocol is in the [circuit logic](/packages/circuits/
<th>Version</th>
<th>Downloads</th>
<tbody>
<tr>
<td>
<a href="/packages/core">
@semaphore-protocol/core
</a>
</td>
<td>
<!-- NPM version -->
<a href="https://npmjs.org/package/@semaphore-protocol/core">
<img src="https://img.shields.io/npm/v/@semaphore-protocol/core.svg?style=flat-square" alt="NPM version" />
</a>
</td>
<td>
<!-- Downloads -->
<a href="https://npmjs.org/package/@semaphore-protocol/core">
<img src="https://img.shields.io/npm/dm/@semaphore-protocol/core.svg?style=flat-square" alt="Downloads" />
</a>
</td>
</tr>
<tr>
<td>
<a href="/packages/contracts">

View File

@@ -53,7 +53,7 @@
"@babel/preset-typescript": "^7.17.12",
"@commitlint/cli": "^16.0.2",
"@commitlint/config-conventional": "^16.0.0",
"@rollup/plugin-typescript": "^8.3.0",
"@rollup/plugin-typescript": "^11.1.6",
"@types/circomlibjs": "^0.1.4",
"@types/download": "^8.0.1",
"@types/glob": "^7.2.0",
@@ -82,12 +82,12 @@
"lint-staged": "^12.1.7",
"prettier": "^2.5.1",
"rimraf": "^3.0.2",
"rollup": "^2.64.0",
"rollup": "^4.9.6",
"snarkjs": "^0.7.2",
"ts-node": "^10.4.0",
"tslib": "^2.3.1",
"typedoc": "^0.25.1",
"typescript": "^4.7.0"
"ts-node": "^10.9.2",
"tslib": "^2.6.2",
"typedoc": "^0.25.7",
"typescript": "^5.3.3"
},
"config": {
"commitizen": {

View File

@@ -1,6 +1,6 @@
{
"name": "@semaphore-protocol/circuits",
"version": "4.0.0-alpha.2",
"version": "4.0.0-alpha.6",
"description": "Semaphore Circom circuits to generate zero-knowledge proofs.",
"license": "MIT",
"files": [
@@ -35,5 +35,5 @@
"mocha": "^10.2.0",
"poseidon-lite": "^0.2.0"
},
"stableVersion": "4.0.0-alpha.1"
"stableVersion": "4.0.0-alpha.5"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -1,6 +1,6 @@
{
"name": "@semaphore-protocol/cli-template-contracts-hardhat",
"version": "4.0.0-alpha.2",
"version": "4.0.0-alpha.6",
"description": "Semaphore Hardhat template.",
"license": "Unlicense",
"files": [
@@ -35,10 +35,10 @@
"@nomicfoundation/hardhat-network-helpers": "^1.0.0",
"@nomicfoundation/hardhat-toolbox": "^4.0.0",
"@nomicfoundation/hardhat-verify": "^2.0.0",
"@semaphore-protocol/group": "4.0.0-alpha.2",
"@semaphore-protocol/hardhat": "4.0.0-alpha.2",
"@semaphore-protocol/identity": "4.0.0-alpha.2",
"@semaphore-protocol/proof": "4.0.0-alpha.2",
"@semaphore-protocol/group": "4.0.0-alpha.6",
"@semaphore-protocol/hardhat": "4.0.0-alpha.6",
"@semaphore-protocol/identity": "4.0.0-alpha.6",
"@semaphore-protocol/proof": "4.0.0-alpha.6",
"@typechain/ethers-v6": "^0.5.0",
"@typechain/hardhat": "^9.0.0",
"@types/chai": "^4.2.0",
@@ -55,12 +55,12 @@
"typescript": "^5.3.3"
},
"dependencies": {
"@semaphore-protocol/contracts": "4.0.0-alpha.2"
"@semaphore-protocol/contracts": "4.0.0-alpha.6"
},
"config": {
"solidity": {
"version": "0.8.4"
}
},
"stableVersion": "4.0.0-alpha.1"
"stableVersion": "4.0.0-alpha.5"
}

View File

@@ -5,7 +5,7 @@ import { expect } from "chai"
import { encodeBytes32String } from "ethers"
import { run } from "hardhat"
// @ts-ignore: typechain folder will be generated after contracts compilation
import { Feedback } from "../build/typechain"
import { Feedback } from "../typechain-types"
describe("Feedback", () => {
let feedbackContract: Feedback
@@ -45,26 +45,26 @@ describe("Feedback", () => {
it("Should allow users to send feedback anonymously", async () => {
const feedback = encodeBytes32String("Hello World")
const fullProof = await generateProof(users[1], group, feedback, groupId)
const proof = await generateProof(users[1], group, feedback, groupId)
const transaction = feedbackContract.sendFeedback(
fullProof.merkleTreeDepth,
fullProof.merkleTreeRoot,
fullProof.nullifier,
proof.merkleTreeDepth,
proof.merkleTreeRoot,
proof.nullifier,
feedback,
fullProof.points
proof.points
)
await expect(transaction)
.to.emit(semaphoreContract, "ProofValidated")
.withArgs(
groupId,
fullProof.merkleTreeDepth,
fullProof.merkleTreeRoot,
fullProof.nullifier,
fullProof.message,
proof.merkleTreeDepth,
proof.merkleTreeRoot,
proof.nullifier,
proof.message,
groupId,
fullProof.points
proof.points
)
})
})

View File

@@ -19,10 +19,8 @@
"@nomicfoundation/hardhat-network-helpers": "^1.0.0",
"@nomicfoundation/hardhat-toolbox": "^4.0.0",
"@nomicfoundation/hardhat-verify": "^2.0.0",
"@semaphore-protocol/group": "4.0.0-alpha.2",
"@semaphore-protocol/hardhat": "4.0.0-alpha.2",
"@semaphore-protocol/identity": "4.0.0-alpha.2",
"@semaphore-protocol/proof": "4.0.0-alpha.2",
"@semaphore-protocol/data": "4.0.0-alpha.6",
"@semaphore-protocol/hardhat": "4.0.0-alpha.6",
"@typechain/ethers-v6": "^0.5.0",
"@typechain/hardhat": "^9.0.0",
"@types/chai": "^4.2.0",
@@ -39,6 +37,6 @@
"typechain": "^8.3.0"
},
"dependencies": {
"@semaphore-protocol/contracts": "4.0.0-alpha.2"
"@semaphore-protocol/contracts": "4.0.0-alpha.6"
}
}

View File

@@ -1,11 +1,9 @@
import { Group } from "@semaphore-protocol/group"
import { Identity } from "@semaphore-protocol/identity"
import { generateProof } from "@semaphore-protocol/proof"
import { Group, Identity, generateProof } from "@semaphore-protocol/core"
import { expect } from "chai"
import { encodeBytes32String } from "ethers"
import { run } from "hardhat"
// @ts-ignore: typechain folder will be generated after contracts compilation
import { Feedback } from "../build/typechain"
import { Feedback } from "../typechain-types"
describe("Feedback", () => {
let feedbackContract: Feedback
@@ -45,26 +43,26 @@ describe("Feedback", () => {
it("Should allow users to send feedback anonymously", async () => {
const feedback = encodeBytes32String("Hello World")
const fullProof = await generateProof(users[1], group, feedback, groupId)
const proof = await generateProof(users[1], group, feedback, groupId)
const transaction = feedbackContract.sendFeedback(
fullProof.merkleTreeDepth,
fullProof.merkleTreeRoot,
fullProof.nullifier,
proof.merkleTreeDepth,
proof.merkleTreeRoot,
proof.nullifier,
feedback,
fullProof.points
proof.points
)
await expect(transaction)
.to.emit(semaphoreContract, "ProofValidated")
.withArgs(
groupId,
fullProof.merkleTreeDepth,
fullProof.merkleTreeRoot,
fullProof.nullifier,
fullProof.message,
proof.merkleTreeDepth,
proof.merkleTreeRoot,
proof.nullifier,
proof.message,
groupId,
fullProof.points
proof.points
)
})
})

View File

@@ -10,10 +10,8 @@
},
"dependencies": {
"@next/font": "13.0.3",
"@semaphore-protocol/data": "4.0.0-alpha.2",
"@semaphore-protocol/group": "4.0.0-alpha.2",
"@semaphore-protocol/identity": "4.0.0-alpha.2",
"@semaphore-protocol/proof": "4.0.0-alpha.2",
"@semaphore-protocol/core": "4.0.0-alpha.6",
"@semaphore-protocol/data": "4.0.0-alpha.6",
"@types/react": "18.0.25",
"@types/react-dom": "18.0.8",
"dotenv": "^16.0.3",

View File

@@ -6,7 +6,7 @@ import { SemaphoreContextType } from "../context/SemaphoreContext"
const { publicRuntimeConfig: env } = getNextConfig()
const ethereumNetwork = env.DEFAULT_NETWORK === "localhost" ? "http://localhost:8545" : env.DEFAULT_NETWORK
const ethereumNetwork = env.DEFAULT_NETWORK === "localhost" ? "http://127.0.0.1:8545" : env.DEFAULT_NETWORK
export default function useSemaphore(): SemaphoreContextType {
const [_users, setUsers] = useState<any[]>([])

View File

@@ -25,7 +25,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const contractAddress = process.env.FEEDBACK_CONTRACT_ADDRESS
const provider =
ethereumNetwork === "localhost" ? new JsonRpcProvider() : new InfuraProvider(ethereumNetwork, infuraApiKey)
ethereumNetwork === "localhost"
? new JsonRpcProvider("http://127.0.0.1:8545")
: new InfuraProvider(ethereumNetwork, infuraApiKey)
const signer = new Wallet(ethereumPrivateKey, provider)
const contract = new Contract(contractAddress, Feedback.abi, signer)

View File

@@ -25,7 +25,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const contractAddress = process.env.FEEDBACK_CONTRACT_ADDRESS
const provider =
ethereumNetwork === "localhost" ? new JsonRpcProvider() : new InfuraProvider(ethereumNetwork, infuraApiKey)
ethereumNetwork === "localhost"
? new JsonRpcProvider("http://127.0.0.1:8545")
: new InfuraProvider(ethereumNetwork, infuraApiKey)
const signer = new Wallet(ethereumPrivateKey, provider)
const contract = new Contract(contractAddress, Feedback.abi, signer)

View File

@@ -1,4 +1,4 @@
import { Identity } from "@semaphore-protocol/identity"
import { Identity } from "@semaphore-protocol/core"
import getNextConfig from "next/config"
import { useRouter } from "next/router"
import { useCallback, useContext, useEffect, useState } from "react"
@@ -67,7 +67,7 @@ export default function GroupsPage() {
if (response.status === 200) {
addUser(_identity.commitment.toString())
setLogs(`You joined the Feedback group event 🎉 Share your feedback anonymously!`)
setLogs(`You have joined the Feedback group event 🎉 Share your feedback anonymously!`)
} else {
setLogs("Some error occurred, please try again!")
}
@@ -82,22 +82,29 @@ export default function GroupsPage() {
<h2>Groups</h2>
<p>
Semaphore{" "}
<a
href="https://semaphore.pse.dev/docs/guides/groups"
href="https://docs.semaphore.pse.dev/guides/groups"
target="_blank"
rel="noreferrer noopener nofollow"
>
groups
Semaphore groups
</a>{" "}
are binary incremental Merkle trees in which each leaf contains an identity commitment for a user.
Groups can be abstracted to represent events, polls, or organizations.
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>Feedback users ({_users.length})</h3>
<h3>Group users ({_users.length})</h3>
<button className="button-link" onClick={refreshUsers}>
Refresh
</button>

View File

@@ -1,4 +1,4 @@
import { Identity } from "@semaphore-protocol/identity"
import { Identity } from "@semaphore-protocol/core"
import { useRouter } from "next/router"
import { useCallback, useContext, useEffect, useState } from "react"
import Stepper from "../components/Stepper"
@@ -17,7 +17,7 @@ export default function IdentitiesPage() {
setIdentity(identity)
setLogs("Your Semaphore identity was retrieved from the browser cache 👌🏽")
setLogs("Your Semaphore identity has been retrieved from the browser cache 👌🏽")
} else {
setLogs("Create your Semaphore identity 👆🏽")
}
@@ -30,7 +30,7 @@ export default function IdentitiesPage() {
localStorage.setItem("identity", identity.privateKey.toString())
setLogs("Your new Semaphore identity was just created 🎉")
setLogs("Your new Semaphore identity has just been created 🎉")
}, [])
return (
@@ -38,21 +38,24 @@ export default function IdentitiesPage() {
<h2 className="font-size: 3rem;">Identities</h2>
<p>
Users interact with the protocol using a Semaphore{" "}
The identity of a user in the Semaphore protocol. A{" "}
<a
href="https://semaphore.pse.dev/docs/guides/identities"
href="https://docs.semaphore.pse.dev/guides/identities"
target="_blank"
rel="noreferrer noopener nofollow"
>
identity
Semaphore identity
</a>{" "}
(similar to Ethereum accounts). It contains three values:
consists of an{" "}
<a
href="https://github.com/privacy-scaling-explorations/zk-kit/tree/main/packages/eddsa-poseidon"
target="_blank"
rel="noreferrer noopener nofollow"
>
EdDSA
</a>{" "}
public/private key pair and a commitment, used as the public identifier of the identity.
</p>
<ol>
<li>Trapdoor: private, known only by user</li>
<li>Nullifier: private, known only by user</li>
<li>Commitment: public</li>
</ol>
<div className="divider"></div>

View File

@@ -1,6 +1,4 @@
import { Group } from "@semaphore-protocol/group"
import { Identity } from "@semaphore-protocol/identity"
import { generateProof } from "@semaphore-protocol/proof"
import { Group, Identity, generateProof } from "@semaphore-protocol/core"
import { encodeBytes32String } from "ethers"
import getNextConfig from "next/config"
import { useRouter } from "next/router"
@@ -54,12 +52,10 @@ export default function ProofsPage() {
setLogs(`Posting your anonymous feedback...`)
try {
const group = new Group()
const group = new Group(_users)
const message = encodeBytes32String(feedback)
group.addMembers(_users)
const { points, merkleTreeDepth, merkleTreeRoot, nullifier } = await generateProof(
_identity,
group,
@@ -97,7 +93,7 @@ export default function ProofsPage() {
if (response.status === 200) {
addFeedback(feedback)
setLogs(`Your feedback was posted 🎉`)
setLogs(`Your feedback has been posted 🎉`)
} else {
setLogs("Some error occurred, please try again!")
}
@@ -118,20 +114,20 @@ export default function ProofsPage() {
<p>
Semaphore members can anonymously{" "}
<a
href="https://semaphore.pse.dev/docs/guides/proofs"
href="https://docs.semaphore.pse.dev/guides/proofs"
target="_blank"
rel="noreferrer noopener nofollow"
>
prove
</a>{" "}
that they are part of a group and that they are generating their own signals. Signals could be anonymous
votes, leaks, reviews, or feedback.
that they are part of a group and send their anonymous messages. Messages could be votes, leaks,
reviews, or feedback.
</p>
<div className="divider"></div>
<div className="text-top">
<h3>Feedback signals ({_feedback.length})</h3>
<h3>Feedback messages ({_feedback.length})</h3>
<button className="button-link" onClick={refreshFeedback}>
Refresh
</button>

View File

@@ -1,6 +1,6 @@
{
"name": "@semaphore-protocol/cli-template-monorepo-ethers",
"version": "4.0.0-alpha.2",
"version": "4.0.0-alpha.6",
"description": "Semaphore Hardhat + Next.js + SemaphoreEthers template.",
"license": "Unlicense",
"files": [
@@ -40,5 +40,5 @@
"ts-node": "^10.8.1",
"typescript": "^4.7.3"
},
"stableVersion": "4.0.0-alpha.1"
"stableVersion": "4.0.0-alpha.5"
}

View File

@@ -19,10 +19,8 @@
"@nomicfoundation/hardhat-network-helpers": "^1.0.0",
"@nomicfoundation/hardhat-toolbox": "^4.0.0",
"@nomicfoundation/hardhat-verify": "^2.0.0",
"@semaphore-protocol/group": "4.0.0-alpha.2",
"@semaphore-protocol/hardhat": "4.0.0-alpha.2",
"@semaphore-protocol/identity": "4.0.0-alpha.2",
"@semaphore-protocol/proof": "4.0.0-alpha.2",
"@semaphore-protocol/core": "4.0.0-alpha.6",
"@semaphore-protocol/hardhat": "4.0.0-alpha.6",
"@typechain/ethers-v6": "^0.5.0",
"@typechain/hardhat": "^9.0.0",
"@types/chai": "^4.2.0",
@@ -39,6 +37,6 @@
"typechain": "^8.3.0"
},
"dependencies": {
"@semaphore-protocol/contracts": "4.0.0-alpha.2"
"@semaphore-protocol/contracts": "4.0.0-alpha.6"
}
}

View File

@@ -1,11 +1,9 @@
import { Group } from "@semaphore-protocol/group"
import { Identity } from "@semaphore-protocol/identity"
import { generateProof } from "@semaphore-protocol/proof"
import { Group, Identity, generateProof } from "@semaphore-protocol/core"
import { expect } from "chai"
import { encodeBytes32String } from "ethers"
import { run } from "hardhat"
// @ts-ignore: typechain folder will be generated after contracts compilation
import { Feedback } from "../build/typechain"
import { Feedback } from "../typechain-types"
describe("Feedback", () => {
let feedbackContract: Feedback
@@ -45,26 +43,26 @@ describe("Feedback", () => {
it("Should allow users to send feedback anonymously", async () => {
const feedback = encodeBytes32String("Hello World")
const fullProof = await generateProof(users[1], group, feedback, groupId)
const proof = await generateProof(users[1], group, feedback, groupId)
const transaction = feedbackContract.sendFeedback(
fullProof.merkleTreeDepth,
fullProof.merkleTreeRoot,
fullProof.nullifier,
proof.merkleTreeDepth,
proof.merkleTreeRoot,
proof.nullifier,
feedback,
fullProof.points
proof.points
)
await expect(transaction)
.to.emit(semaphoreContract, "ProofValidated")
.withArgs(
groupId,
fullProof.merkleTreeDepth,
fullProof.merkleTreeRoot,
fullProof.nullifier,
fullProof.message,
proof.merkleTreeDepth,
proof.merkleTreeRoot,
proof.nullifier,
proof.message,
groupId,
fullProof.points
proof.points
)
})
})

View File

@@ -10,10 +10,8 @@
},
"dependencies": {
"@next/font": "13.0.3",
"@semaphore-protocol/data": "4.0.0-alpha.2",
"@semaphore-protocol/group": "4.0.0-alpha.2",
"@semaphore-protocol/identity": "4.0.0-alpha.2",
"@semaphore-protocol/proof": "4.0.0-alpha.2",
"@semaphore-protocol/core": "4.0.0-alpha.6",
"@semaphore-protocol/data": "4.0.0-alpha.6",
"@types/react": "18.0.25",
"@types/react-dom": "18.0.8",
"dotenv": "^16.0.3",

View File

@@ -6,7 +6,7 @@ import { SemaphoreContextType } from "../context/SemaphoreContext"
const { publicRuntimeConfig: env } = getNextConfig()
const ethereumNetwork = env.DEFAULT_NETWORK === "localhost" ? "http://localhost:8545" : env.DEFAULT_NETWORK
const ethereumNetwork = env.DEFAULT_NETWORK === "localhost" ? "http://127.0.0.1:8545" : env.DEFAULT_NETWORK
export default function useSemaphore(): SemaphoreContextType {
const [_users, setUsers] = useState<any[]>([])

View File

@@ -25,7 +25,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const contractAddress = process.env.FEEDBACK_CONTRACT_ADDRESS
const provider =
ethereumNetwork === "localhost" ? new JsonRpcProvider() : new InfuraProvider(ethereumNetwork, infuraApiKey)
ethereumNetwork === "localhost"
? new JsonRpcProvider("http://127.0.0.1:8545")
: new InfuraProvider(ethereumNetwork, infuraApiKey)
const signer = new Wallet(ethereumPrivateKey, provider)
const contract = new Contract(contractAddress, Feedback.abi, signer)

View File

@@ -25,7 +25,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const contractAddress = process.env.FEEDBACK_CONTRACT_ADDRESS
const provider =
ethereumNetwork === "localhost" ? new JsonRpcProvider() : new InfuraProvider(ethereumNetwork, infuraApiKey)
ethereumNetwork === "localhost"
? new JsonRpcProvider("http://127.0.0.1:8545")
: new InfuraProvider(ethereumNetwork, infuraApiKey)
const signer = new Wallet(ethereumPrivateKey, provider)
const contract = new Contract(contractAddress, Feedback.abi, signer)

View File

@@ -1,4 +1,4 @@
import { Identity } from "@semaphore-protocol/identity"
import { Identity } from "@semaphore-protocol/core"
import getNextConfig from "next/config"
import { useRouter } from "next/router"
import { useCallback, useContext, useEffect, useState } from "react"

View File

@@ -1,4 +1,4 @@
import { Identity } from "@semaphore-protocol/identity"
import { Identity } from "@semaphore-protocol/core"
import { useRouter } from "next/router"
import { useCallback, useContext, useEffect, useState } from "react"
import Stepper from "../components/Stepper"

View File

@@ -1,6 +1,4 @@
import { Group } from "@semaphore-protocol/group"
import { Identity } from "@semaphore-protocol/identity"
import { generateProof } from "@semaphore-protocol/proof"
import { Group, Identity, generateProof } from "@semaphore-protocol/core"
import { encodeBytes32String } from "ethers"
import getNextConfig from "next/config"
import { useRouter } from "next/router"
@@ -54,12 +52,10 @@ export default function ProofsPage() {
setLogs(`Posting your anonymous feedback...`)
try {
const group = new Group()
const group = new Group(_users)
const message = encodeBytes32String(feedback)
group.addMembers(_users)
const { points, merkleTreeDepth, merkleTreeRoot, nullifier } = await generateProof(
_identity,
group,

View File

@@ -1,6 +1,6 @@
{
"name": "@semaphore-protocol/cli-template-monorepo-subgraph",
"version": "4.0.0-alpha.2",
"version": "4.0.0-alpha.6",
"description": "Semaphore Hardhat + Next.js + SemaphoreSubgraph template.",
"license": "Unlicense",
"files": [
@@ -40,5 +40,5 @@
"ts-node": "^10.8.1",
"typescript": "^4.7.3"
},
"stableVersion": "4.0.0-alpha.1"
"stableVersion": "4.0.0-alpha.5"
}

View File

@@ -1,8 +1,9 @@
{
"compilerOptions": {
"baseUrl": ".",
"target": "es2020",
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "Bundler",
"allowSyntheticDefaultImports": true
},
"include": ["src"]

View File

@@ -1,7 +1,7 @@
{
"name": "@semaphore-protocol/cli",
"type": "module",
"version": "4.0.0-alpha.2",
"version": "4.0.0-alpha.6",
"description": "A command line tool to set up your Semaphore project and get group data.",
"license": "MIT",
"bin": {
@@ -23,7 +23,7 @@
"node": ">=14.16"
},
"scripts": {
"start": "node --loader ts-node/esm --no-warnings src/index.ts",
"start": "node --import 'data:text/javascript,import { register } from \"node:module\"; import { pathToFileURL } from \"node:url\"; register(\"ts-node/esm\", pathToFileURL(\"./\"));' ./src/index.ts",
"build": "rimraf dist && rollup -c rollup.config.ts --configPlugin typescript",
"prepublishOnly": "yarn build"
},
@@ -37,11 +37,10 @@
"@types/pacote": "^11.1.5",
"@types/semver": "^7.3.13",
"rollup-plugin-cleanup": "^3.2.1",
"rollup-plugin-typescript2": "^0.31.2",
"ts-node": "^10.9.1"
"rollup-plugin-typescript2": "^0.36.0"
},
"dependencies": {
"@semaphore-protocol/data": "4.0.0-alpha.2",
"@semaphore-protocol/data": "4.0.0-alpha.6",
"axios": "^1.3.2",
"boxen": "^7.0.1",
"chalk": "^5.1.2",
@@ -54,5 +53,5 @@
"pacote": "^15.1.1",
"semver": "^7.3.8"
},
"stableVersion": "4.0.0-alpha.1"
"stableVersion": "4.0.0-alpha.5"
}

View File

@@ -1,9 +1,9 @@
{
"compilerOptions": {
"baseUrl": ".",
"target": "es2020",
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "Node16",
"moduleResolution": "Bundler",
"allowSyntheticDefaultImports": true
},
"include": ["src", "rollup.config.ts"]

View File

@@ -1,6 +1,6 @@
{
"name": "@semaphore-protocol/contracts",
"version": "4.0.0-alpha.2",
"version": "4.0.0-alpha.6",
"description": "Semaphore contracts to manage groups and broadcast anonymous signals.",
"license": "MIT",
"files": [
@@ -32,5 +32,5 @@
"dependencies": {
"@zk-kit/imt.sol": "2.0.0-beta.5"
},
"stableVersion": "4.0.0-alpha.1"
"stableVersion": "4.0.0-alpha.5"
}

View File

@@ -0,0 +1,19 @@
[
{
"network": "sepolia",
"contracts": [
{
"name": "SemaphoreVerifier",
"address": "0x1E979ECf8C23d45577904974642592f80C464522"
},
{
"name": "PoseidonT3",
"address": "0x43AE9518d9FE43898cD705a06C22A73B015bCf12"
},
{
"name": "Semaphore",
"address": "0x5B8e7cC7bAC61A4b952d472b67056B2f260ba6dc"
}
]
}
]

View File

@@ -1,7 +0,0 @@
{
"Pairing": "0xE3a4C2FE9f025405cA6F60f6E960B4558604A74C",
"SemaphoreVerifier": "0xCAbeED6cB96a287000aBd834b0B79c05e6Ea4d07",
"Poseidon": "0xe0c8d1e53D9Bfc9071F6564755FCFf6cC0dB61d0",
"IncrementalBinaryTree": "0xcDF8efE6334c68aF283C83f2F14648da51fcfFb0",
"Semaphore": "0xc60E0Ee1a2770d5F619858C641f14FC4a6401520"
}

View File

@@ -1,7 +0,0 @@
{
"Pairing": "0xEe44c1e83A768E80A3588B409f1A010f9D1dd7e8",
"SemaphoreVerifier": "0xb908Bcb798e5353fB90155C692BddE3b4937217C",
"Poseidon": "0xe136aBACf78E05988154ed85F4Ea911105302595",
"IncrementalBinaryTree": "0x4621EE309EAc747425F0FEd51931dDC241A27F49",
"Semaphore": "0x3889927F0B5Eb1a02C6E2C20b39a1Bd4EAd76131"
}

View File

@@ -1,7 +0,0 @@
{
"Pairing": "0xEe44c1e83A768E80A3588B409f1A010f9D1dd7e8",
"SemaphoreVerifier": "0xb908Bcb798e5353fB90155C692BddE3b4937217C",
"Poseidon": "0xe136aBACf78E05988154ed85F4Ea911105302595",
"IncrementalBinaryTree": "0x4621EE309EAc747425F0FEd51931dDC241A27F49",
"Semaphore": "0x3889927F0B5Eb1a02C6E2C20b39a1Bd4EAd76131"
}

View File

@@ -1,5 +0,0 @@
{
"Verifier": "0x1E979ECf8C23d45577904974642592f80C464522",
"Poseidon": "0x43AE9518d9FE43898cD705a06C22A73B015bCf12",
"Semaphore": "0x5B8e7cC7bAC61A4b952d472b67056B2f260ba6dc"
}

View File

@@ -20,9 +20,7 @@
"@nomicfoundation/hardhat-toolbox": "^4.0.0",
"@nomicfoundation/hardhat-verify": "^2.0.0",
"@openzeppelin/hardhat-upgrades": "^3.0.2",
"@semaphore-protocol/group": "workspace:packages/group",
"@semaphore-protocol/identity": "workspace:packages/identity",
"@semaphore-protocol/proof": "workspace:packages/proof",
"@semaphore-protocol/core": "workspace:packages/core",
"@typechain/ethers-v6": "^0.5.0",
"@typechain/hardhat": "^9.0.0",
"@types/chai": "^4.2.0",

View File

@@ -2,56 +2,58 @@ import { Group } from "@semaphore-protocol/group"
import { Identity } from "@semaphore-protocol/identity"
import { generateProof } from "@semaphore-protocol/proof"
import { ethers, hardhatArguments } from "hardhat"
import { getDeployedContracts } from "./utils"
import { getDeployedContractAddress } from "./utils"
async function main() {
const deployedContracts = getDeployedContracts(hardhatArguments.network)
if (deployedContracts) {
const semaphoreContract = await ethers.getContractAt("Semaphore", deployedContracts.Semaphore)
const [admin] = await ethers.getSigners()
const adminAddress = await admin.getAddress()
const identity = new Identity(0)
const members = Array.from({ length: 3 }, (_, i) => new Identity(i)).map(({ commitment }) => commitment)
const group = new Group(members)
const groupId = 42
console.info(`Creating group '${groupId}' with ${members.length} members...`)
// Create a group and add 3 members.
await semaphoreContract["createGroup(uint256,address)"](groupId, adminAddress)
await semaphoreContract.addMembers(groupId, members)
console.info(`Removing third member from group '${groupId}'...`)
// Remove the third member.
{
group.removeMember(2)
const { siblings } = group.generateMerkleProof(2)
await semaphoreContract.removeMember(groupId, members[2], siblings)
}
console.info(`Updating second member from group '${groupId}'...`)
// Update the second member.
{
group.updateMember(1, members[2])
const { siblings } = group.generateMerkleProof(1)
await semaphoreContract.updateMember(groupId, members[1], members[2], siblings)
}
console.info(`Validating a proof generated by the first member of group '${groupId}'...`)
// Validate a proof.
const proof = await generateProof(identity, group, 42, 9, 10)
await semaphoreContract.validateProof(groupId, proof)
if (!hardhatArguments.network) {
throw Error("Please, define a supported network")
}
const semaphoreAddress = getDeployedContractAddress(hardhatArguments.network, "Semaphore")
const semaphoreContract = await ethers.getContractAt("Semaphore", semaphoreAddress)
const [admin] = await ethers.getSigners()
const adminAddress = await admin.getAddress()
const identity = new Identity(0)
const members = Array.from({ length: 3 }, (_, i) => new Identity(i)).map(({ commitment }) => commitment)
const group = new Group(members)
const groupId = 42
console.info(`Creating group '${groupId}' with ${members.length} members...`)
// Create a group and add 3 members.
await semaphoreContract["createGroup(uint256,address)"](groupId, adminAddress)
await semaphoreContract.addMembers(groupId, members)
console.info(`Removing third member from group '${groupId}'...`)
// Remove the third member.
{
group.removeMember(2)
const { siblings } = group.generateMerkleProof(2)
await semaphoreContract.removeMember(groupId, members[2], siblings)
}
console.info(`Updating second member from group '${groupId}'...`)
// Update the second member.
{
group.updateMember(1, members[2])
const { siblings } = group.generateMerkleProof(1)
await semaphoreContract.updateMember(groupId, members[1], members[2], siblings)
}
console.info(`Validating a proof generated by the first member of group '${groupId}'...`)
// Validate a proof.
const proof = await generateProof(identity, group, 42, 9, 10)
await semaphoreContract.validateProof(groupId, proof)
}
main()

View File

@@ -1,15 +1,62 @@
import { readFileSync } from "fs"
import { readFileSync, writeFileSync } from "fs"
export type NetworkDeployedContracts = {
name: "Semaphore" | "SemaphoreVerifier" | "PoseidonT3"
address: string
}[]
export type DeployedContracts = {
Poseidon: string
Semaphore: string
Verifier: string
network: string
contracts: NetworkDeployedContracts
}[]
const supportedNetworks = ["sepolia", "arbitrum", "mumbai", "optimism-sepolia", "arbitrum-sepolia"]
export function getDeployedContracts(): DeployedContracts {
return JSON.parse(readFileSync(`./deployed-contracts.json`, "utf8"))
}
export function getDeployedContracts(network: string | undefined): DeployedContracts | null {
try {
return JSON.parse(readFileSync(`./deployed-contracts/${network}.json`, "utf8"))
} catch (error) {
return null
export function getDeployedContractsByNetwork(network: string): NetworkDeployedContracts {
const deployedContracts = getDeployedContracts()
const networkDeployedContracts = deployedContracts.find((n) => n.network === network)
if (!networkDeployedContracts) {
throw Error(`Network '${network}' is not supported`)
}
return networkDeployedContracts.contracts
}
export function getDeployedContractAddress(network: string, contractName: string): string {
const contracts = getDeployedContractsByNetwork(network)
const semaphoreAddress = contracts.find((contract) => contract.name === contractName)
if (!semaphoreAddress) {
throw Error(`Contract with name '${contractName}' does not exist`)
}
return semaphoreAddress.address
}
export function saveDeployedContracts(contracts: NetworkDeployedContracts, network?: string) {
if (network && supportedNetworks.includes(network)) {
const deployedContracts = getDeployedContracts() as DeployedContracts
for (let i = 0; i < deployedContracts.length; i += 1) {
if (deployedContracts[i].network === network) {
deployedContracts[i].contracts = contracts
writeFileSync(`./deployed-contracts.json`, JSON.stringify(deployedContracts, null, 4))
return
}
}
deployedContracts.push({
network,
contracts
})
writeFileSync(`./deployed-contracts.json`, JSON.stringify(deployedContracts, null, 4))
}
}

View File

@@ -1,5 +1,5 @@
import { hardhatArguments, run } from "hardhat"
import { getDeployedContracts } from "./utils"
import { getDeployedContractAddress } from "./utils"
async function verify(address: string, constructorArguments?: any[]): Promise<void> {
try {
@@ -13,13 +13,17 @@ async function verify(address: string, constructorArguments?: any[]): Promise<vo
}
async function main() {
const deployedContracts = getDeployedContracts(hardhatArguments.network)
if (deployedContracts) {
await verify(deployedContracts.Verifier)
await verify(deployedContracts.Poseidon)
await verify(deployedContracts.Semaphore, [deployedContracts.Verifier])
if (!hardhatArguments.network) {
throw Error("Please, define a supported network")
}
const semaphoreVerifierAddress = getDeployedContractAddress(hardhatArguments.network, "SemaphoreVerifier")
const poseidonT3Address = getDeployedContractAddress(hardhatArguments.network, "PoseidonT3")
const semaphoreAddress = getDeployedContractAddress(hardhatArguments.network, "Semaphore")
await verify(semaphoreVerifierAddress)
await verify(poseidonT3Address)
await verify(semaphoreAddress, [semaphoreVerifierAddress])
}
main()

View File

@@ -1,5 +1,5 @@
import { writeFileSync } from "fs"
import { task, types } from "hardhat/config"
import { saveDeployedContracts } from "../scripts/utils"
import { deployContract } from "./utils"
task("deploy", "Deploy a Semaphore contract")
@@ -8,41 +8,41 @@ task("deploy", "Deploy a Semaphore contract")
.addOptionalParam<boolean>("logs", "Print the logs", true, types.boolean)
.setAction(
async (
{ logs, verifier: verifierAddress, poseidon: poseidonAddress },
{ logs, verifier: semaphoreVerifierAddress, poseidon: poseidonT3Address },
{ ethers, hardhatArguments, defender }
): Promise<any> => {
if (!verifierAddress) {
if (!semaphoreVerifierAddress) {
const VerifierFactory = await ethers.getContractFactory(`SemaphoreVerifier`)
const verifier = await deployContract(defender, VerifierFactory, hardhatArguments.network)
verifierAddress = await verifier.getAddress()
semaphoreVerifierAddress = await verifier.getAddress()
if (logs) {
console.info(`SemaphoreVerifier contract has been deployed to: ${verifierAddress}`)
console.info(`SemaphoreVerifier contract has been deployed to: ${semaphoreVerifierAddress}`)
}
}
if (!poseidonAddress) {
if (!poseidonT3Address) {
const PoseidonT3Factory = await ethers.getContractFactory("PoseidonT3")
const poseidonT3 = await deployContract(defender, PoseidonT3Factory, hardhatArguments.network)
poseidonAddress = await poseidonT3.getAddress()
poseidonT3Address = await poseidonT3.getAddress()
if (logs) {
console.info(`Poseidon library has been deployed to: ${poseidonAddress}`)
console.info(`PoseidonT3 library has been deployed to: ${poseidonT3Address}`)
}
}
const SemaphoreFactory = await ethers.getContractFactory("Semaphore", {
libraries: {
PoseidonT3: poseidonAddress
PoseidonT3: poseidonT3Address
}
})
const semaphore = await deployContract(defender, SemaphoreFactory, hardhatArguments.network, [
verifierAddress
semaphoreVerifierAddress
])
const semaphoreAddress = await semaphore.getAddress()
@@ -51,23 +51,28 @@ task("deploy", "Deploy a Semaphore contract")
console.info(`Semaphore contract has been deployed to: ${semaphoreAddress}`)
}
writeFileSync(
`./deployed-contracts/${hardhatArguments.network}.json`,
JSON.stringify(
saveDeployedContracts(
[
{
Verifier: verifierAddress,
Poseidon: poseidonAddress,
Semaphore: semaphoreAddress
name: "SemaphoreVerifier",
address: semaphoreVerifierAddress
},
null,
4
)
{
name: "PoseidonT3",
address: poseidonT3Address
},
{
name: "Semaphore",
address: semaphoreAddress
}
],
hardhatArguments.network
)
return {
semaphore,
verifierAddress,
poseidonAddress
verifierAddress: semaphoreVerifierAddress,
poseidonAddress: poseidonT3Address
}
}
)

View File

@@ -1,11 +1,10 @@
/* eslint-disable @typescript-eslint/no-shadow */
/* eslint-disable jest/valid-expect */
import { Group } from "@semaphore-protocol/group"
import { Identity } from "@semaphore-protocol/identity"
import { SemaphoreProof, generateProof } from "@semaphore-protocol/proof"
import { Group, Identity, SemaphoreProof, generateProof } from "@semaphore-protocol/core"
import { expect } from "chai"
import { Signer, ZeroAddress } from "ethers"
import { run } from "hardhat"
// @ts-ignore
import { Semaphore } from "../typechain-types"
describe("Semaphore", () => {
@@ -229,24 +228,24 @@ describe("Semaphore", () => {
group.addMembers(members)
let fullProof: SemaphoreProof
let proof: SemaphoreProof
before(async () => {
await semaphoreContract["createGroup(uint256,address)"](groupId, accountAddresses[0])
await semaphoreContract.addMembers(groupId, members)
fullProof = await generateProof(identity, group, message, group.root as string, merkleTreeDepth)
proof = await generateProof(identity, group, message, group.root as string, merkleTreeDepth)
})
it("Should not verify a proof if the group does not exist", async () => {
const transaction = semaphoreContract.verifyProof(11, fullProof)
const transaction = semaphoreContract.verifyProof(11, proof)
await expect(transaction).to.be.revertedWithCustomError(semaphoreContract, "Semaphore__GroupDoesNotExist")
})
it("Should not verify a proof if the Merkle tree root is not part of the group", async () => {
const transaction = semaphoreContract.verifyProof(groupId, { ...fullProof, merkleTreeRoot: 1 })
const transaction = semaphoreContract.verifyProof(groupId, { ...proof, merkleTreeRoot: 1 })
await expect(transaction).to.be.revertedWithCustomError(
semaphoreContract,
@@ -255,7 +254,7 @@ describe("Semaphore", () => {
})
it("Should verify a proof for an onchain group", async () => {
const validProof = await semaphoreContract.verifyProof(groupId, fullProof)
const validProof = await semaphoreContract.verifyProof(groupId, proof)
expect(validProof).to.equal(true)
})
@@ -267,9 +266,9 @@ describe("Semaphore", () => {
group.addMembers([members[0], members[1]])
const fullProof = await generateProof(identity, group, message, group.root as string, merkleTreeDepth)
const proof = await generateProof(identity, group, message, group.root as string, merkleTreeDepth)
const transaction = semaphoreContract.verifyProof(groupId, fullProof)
const transaction = semaphoreContract.verifyProof(groupId, proof)
await expect(transaction).to.be.revertedWithCustomError(
semaphoreContract,
@@ -289,8 +288,8 @@ describe("Semaphore", () => {
group.addMembers(members)
groupOneMember.addMember(members[0])
let fullProof: SemaphoreProof
let fullProofOneMember: SemaphoreProof
let proof: SemaphoreProof
let proofOneMember: SemaphoreProof
before(async () => {
await semaphoreContract["createGroup(uint256,address)"](groupOneMemberId, accountAddresses[0])
@@ -298,8 +297,8 @@ describe("Semaphore", () => {
await semaphoreContract.addMembers(groupId, [members[1], members[2]])
await semaphoreContract.addMember(groupOneMemberId, members[0])
fullProof = await generateProof(identity, group, message, group.root as string, merkleTreeDepth)
fullProofOneMember = await generateProof(
proof = await generateProof(identity, group, message, group.root as string, merkleTreeDepth)
proofOneMember = await generateProof(
identity,
groupOneMember,
message,
@@ -309,45 +308,45 @@ describe("Semaphore", () => {
})
it("Should throw an exception if the proof is not valid", async () => {
const transaction = semaphoreContract.validateProof(groupId, { ...fullProof, scope: 0 })
const transaction = semaphoreContract.validateProof(groupId, { ...proof, scope: 0 })
await expect(transaction).to.be.revertedWithCustomError(semaphoreContract, "Semaphore__InvalidProof")
})
it("Should validate a proof for an onchain group with one member correctly", async () => {
const transaction = semaphoreContract.validateProof(groupOneMemberId, fullProofOneMember)
const transaction = semaphoreContract.validateProof(groupOneMemberId, proofOneMember)
await expect(transaction)
.to.emit(semaphoreContract, "ProofValidated")
.withArgs(
groupOneMemberId,
fullProofOneMember.merkleTreeDepth,
fullProofOneMember.merkleTreeRoot,
fullProofOneMember.nullifier,
fullProofOneMember.message,
fullProofOneMember.merkleTreeRoot,
fullProofOneMember.points
proofOneMember.merkleTreeDepth,
proofOneMember.merkleTreeRoot,
proofOneMember.nullifier,
proofOneMember.message,
proofOneMember.merkleTreeRoot,
proofOneMember.points
)
})
it("Should validate a proof for an onchain group with more than one member correctly", async () => {
const transaction = semaphoreContract.validateProof(groupId, fullProof)
const transaction = semaphoreContract.validateProof(groupId, proof)
await expect(transaction)
.to.emit(semaphoreContract, "ProofValidated")
.withArgs(
groupId,
fullProof.merkleTreeDepth,
fullProof.merkleTreeRoot,
fullProof.nullifier,
fullProof.message,
fullProof.merkleTreeRoot,
fullProof.points
proof.merkleTreeDepth,
proof.merkleTreeRoot,
proof.nullifier,
proof.message,
proof.merkleTreeRoot,
proof.points
)
})
it("Should not validate the same proof for an onchain group twice", async () => {
const transaction = semaphoreContract.validateProof(groupId, fullProof)
const transaction = semaphoreContract.validateProof(groupId, proof)
await expect(transaction).to.be.revertedWithCustomError(
semaphoreContract,

21
packages/core/LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Ethereum Foundation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

89
packages/core/README.md Normal file
View File

@@ -0,0 +1,89 @@
<p align="center">
<h1 align="center">
Semaphore core
</h1>
<p align="center">Core library for the essential Semaphore features.</p>
</p>
<p align="center">
<a href="https://github.com/semaphore-protocol">
<img src="https://img.shields.io/badge/project-Semaphore-blue.svg?style=flat-square">
</a>
<a href="https://github.com/semaphore-protocol/semaphore/blob/main/LICENSE">
<img alt="NPM license" src="https://img.shields.io/npm/l/%40semaphore-protocol%2Fcore?style=flat-square">
</a>
<a href="https://www.npmjs.com/package/@semaphore-protocol/core">
<img alt="NPM version" src="https://img.shields.io/npm/v/@semaphore-protocol/core?style=flat-square" />
</a>
<a href="https://npmjs.org/package/@semaphore-protocol/core">
<img alt="Downloads" src="https://img.shields.io/npm/dm/@semaphore-protocol/core.svg?style=flat-square" />
</a>
<a href="https://js.semaphore.pse.dev/core">
<img alt="Documentation typedoc" src="https://img.shields.io/badge/docs-typedoc-744C7C?style=flat-square">
</a>
<a href="https://eslint.org/">
<img alt="Linter eslint" src="https://img.shields.io/badge/linter-eslint-8080f2?style=flat-square&logo=eslint" />
</a>
<a href="https://prettier.io/">
<img alt="Code style prettier" src="https://img.shields.io/badge/code%20style-prettier-f8bc45?style=flat-square&logo=prettier" />
</a>
</p>
<div align="center">
<h4>
<a href="https://github.com/semaphore-protocol/semaphore/blob/main/CONTRIBUTING.md">
👥 Contributing
</a>
<span>&nbsp;&nbsp;|&nbsp;&nbsp;</span>
<a href="https://github.com/semaphore-protocol/semaphore/blob/main/CODE_OF_CONDUCT.md">
🤝 Code of conduct
</a>
<span>&nbsp;&nbsp;|&nbsp;&nbsp;</span>
<a href="https://github.com/semaphore-protocol/semaphore/contribute">
🔎 Issues
</a>
<span>&nbsp;&nbsp;|&nbsp;&nbsp;</span>
<a href="https://semaphore.pse.dev/discord">
🗣️ Chat &amp; Support
</a>
</h4>
</div>
| This library is a simple re-export of the Semaphore core libraries: `@semaphore-protocol/identity`, `@semaphore-protocol/group`, `@semaphore-protocol/proof`. So that developers can install a single package to use all the core functionalities of the protocol. |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
## 🛠 Install
### npm or yarn
Install the `@semaphore-protocol/core` package with npm:
```bash
npm i @semaphore-protocol/core
```
or yarn:
```bash
yarn add @semaphore-protocol/core
```
## 📜 Usage
```typescript
import { Identity, Group, generateProof, verifyProof } from "@semaphore-protocol/core"
import { utils } from "ethers"
const identity1 = new Identity()
const identity2 = new Identity()
const identity3 = new Identity()
const group = new Group([identity1.commitment, identity2.commitment, identity3.commitment])
const scope = utils.formatBytes32String("Semaphore")
const message = utils.formatBytes32String("Hello world")
const proof = await generateProof(identity1, group, message, scope)
await verifyProof(proof)
```

View File

@@ -0,0 +1,50 @@
{
"name": "@semaphore-protocol/core",
"version": "4.0.0-alpha.6",
"description": "Core library for the essential Semaphore features.",
"type": "module",
"license": "MIT",
"main": "src/index.js",
"types": "src/types/index.d.ts",
"exports": {
".": {
"types": "./src/types/index.d.ts",
"require": "./src/index.cjs",
"default": "./src/index.js"
},
"./identity": {
"types": "./src/identity/types/index.d.ts",
"require": "./src/identity/index.cjs",
"default": "./src/identity/index.js"
},
"./group": {
"types": "./src/identity/types/index.d.ts",
"require": "./src/group/index.cjs",
"default": "./src/group/index.js"
},
"./proof": {
"types": "./src/identity/types/index.d.ts",
"require": "./src/proof/index.cjs",
"default": "./src/proof/index.js"
}
},
"files": [
"src/",
"LICENSE",
"README.md"
],
"repository": "https://github.com/semaphore-protocol/semaphore",
"homepage": "https://github.com/semaphore-protocol/semaphore/tree/main/packages/core",
"bugs": {
"url": "https://github.com/semaphore-protocol/semaphore.git/issues"
},
"publishConfig": {
"access": "public"
},
"dependencies": {
"@semaphore-protocol/group": "4.0.0-alpha.6",
"@semaphore-protocol/identity": "4.0.0-alpha.6",
"@semaphore-protocol/proof": "4.0.0-alpha.6"
},
"stableVersion": "4.0.0-alpha.5"
}

View File

@@ -0,0 +1,3 @@
const identity = require("@semaphore-protocol/group")
Object.assign(exports, identity)

View File

@@ -0,0 +1 @@
export * from "@semaphore-protocol/group"

View File

@@ -0,0 +1 @@
export * from "@semaphore-protocol/group"

View File

@@ -0,0 +1,3 @@
const identity = require("@semaphore-protocol/identity")
Object.assign(exports, identity)

View File

@@ -0,0 +1 @@
export * from "@semaphore-protocol/identity"

View File

@@ -0,0 +1 @@
export * from "@semaphore-protocol/identity"

View File

@@ -0,0 +1,5 @@
const identity = require("./identity/index.cjs")
const group = require("./group/index.cjs")
const proof = require("./proof/index.cjs")
Object.assign(exports, identity, group, proof)

View File

@@ -0,0 +1,4 @@
/* eslint-disable import/export */
export * from "./identity/index.js"
export * from "./group/index.js"
export * from "./proof/index.js"

View File

@@ -0,0 +1,3 @@
const identity = require("@semaphore-protocol/proof")
Object.assign(exports, identity)

View File

@@ -0,0 +1 @@
export * from "@semaphore-protocol/proof"

View File

@@ -0,0 +1 @@
export * from "@semaphore-protocol/proof"

4
packages/core/src/types/index.d.ts vendored Normal file
View File

@@ -0,0 +1,4 @@
/* eslint-disable import/export */
export * from "../identity/types"
export * from "../group/types"
export * from "../proof/types"

View File

@@ -1,15 +1,16 @@
{
"name": "@semaphore-protocol/data",
"version": "4.0.0-alpha.2",
"version": "4.0.0-alpha.6",
"description": "A library to query Semaphore contracts.",
"type": "module",
"license": "MIT",
"main": "dist/index.node.js",
"main": "dist/index.js",
"types": "dist/types/index.d.ts",
"exports": {
"import": "./dist/index.mjs",
"require": "./dist/index.node.js",
"types": "./dist/types/index.d.ts"
"types": "./dist/types/index.d.ts",
"require": "./dist/index.cjs",
"default": "./dist/index.js"
},
"types": "./dist/types/index.d.ts",
"files": [
"dist/",
"src/",
@@ -29,13 +30,13 @@
"access": "public"
},
"devDependencies": {
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-json": "^6.1.0",
"rollup-plugin-cleanup": "^3.2.1",
"rollup-plugin-typescript2": "^0.31.2"
"rollup-plugin-typescript2": "^0.36.0"
},
"dependencies": {
"axios": "1.6.6",
"ethers": "6.10.0"
},
"stableVersion": "4.0.0-alpha.1"
"stableVersion": "4.0.0-alpha.5"
}

View File

@@ -17,7 +17,7 @@ export default {
input: "src/index.ts",
output: [
{ file: pkg.exports.require, format: "cjs", banner, exports: "auto" },
{ file: pkg.exports.import, format: "es", banner }
{ file: pkg.exports.default, format: "es", banner }
],
external: Object.keys(pkg.dependencies),
plugins: [

View File

@@ -315,7 +315,7 @@
{
"indexed": false,
"internalType": "uint256[8]",
"name": "proof",
"name": "points",
"type": "uint256[8]"
}
],
@@ -399,6 +399,25 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "groupId",
"type": "uint256"
}
],
"name": "getGroupAdmin",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
@@ -618,34 +637,41 @@
"type": "uint256"
},
{
"internalType": "uint256",
"name": "merkleTreeDepth",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "merkleTreeRoot",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "nullifier",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "message",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "scope",
"type": "uint256"
},
{
"internalType": "uint256[8]",
"components": [
{
"internalType": "uint256",
"name": "merkleTreeDepth",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "merkleTreeRoot",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "nullifier",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "message",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "scope",
"type": "uint256"
},
{
"internalType": "uint256[8]",
"name": "points",
"type": "uint256[8]"
}
],
"internalType": "struct ISemaphore.SemaphoreProof",
"name": "proof",
"type": "uint256[8]"
"type": "tuple"
}
],
"name": "validateProof",
@@ -674,34 +700,41 @@
"type": "uint256"
},
{
"internalType": "uint256",
"name": "merkleTreeDepth",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "merkleTreeRoot",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "nullifier",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "message",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "scope",
"type": "uint256"
},
{
"internalType": "uint256[8]",
"components": [
{
"internalType": "uint256",
"name": "merkleTreeDepth",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "merkleTreeRoot",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "nullifier",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "message",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "scope",
"type": "uint256"
},
{
"internalType": "uint256[8]",
"name": "points",
"type": "uint256[8]"
}
],
"internalType": "struct ISemaphore.SemaphoreProof",
"name": "proof",
"type": "uint256[8]"
"type": "tuple"
}
],
"name": "verifyProof",

View File

@@ -1,15 +1,16 @@
{
"name": "@semaphore-protocol/group",
"version": "4.0.0-alpha.2",
"version": "4.0.0-alpha.6",
"description": "A library to create and manage Semaphore groups.",
"type": "module",
"license": "MIT",
"main": "dist/index.node.js",
"exports": {
"import": "./dist/index.mjs",
"require": "./dist/index.node.js",
"types": "./dist/types/index.d.ts"
},
"main": "dist/index.js",
"types": "dist/types/index.d.ts",
"exports": {
"types": "./dist/types/index.d.ts",
"require": "./dist/index.cjs",
"default": "./dist/index.js"
},
"files": [
"dist/",
"src/",
@@ -29,14 +30,14 @@
"access": "public"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^24.0.1",
"@rollup/plugin-node-resolve": "^15.0.1",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-node-resolve": "^15.2.3",
"poseidon-lite": "^0.2.0",
"rollup-plugin-cleanup": "^3.2.1",
"rollup-plugin-typescript2": "^0.31.2"
"rollup-plugin-typescript2": "^0.36.0"
},
"dependencies": {
"@zk-kit/imt": "^2.0.0-beta"
},
"stableVersion": "4.0.0-alpha.1"
"stableVersion": "4.0.0-alpha.5"
}

View File

@@ -18,7 +18,7 @@ export default {
input: "src/index.ts",
output: [
{ file: pkg.exports.require, format: "cjs", banner, exports: "auto" },
{ file: pkg.exports.import, format: "es", banner }
{ file: pkg.exports.default, format: "es", banner }
],
external: Object.keys(pkg.dependencies),
plugins: [

View File

@@ -1,15 +1,16 @@
{
"name": "@semaphore-protocol/hardhat",
"version": "4.0.0-alpha.2",
"version": "4.0.0-alpha.6",
"description": "A Semaphore Hardhat plugin to deploy verifiers and Semaphore contract.",
"type": "module",
"license": "MIT",
"main": "dist/index.node.js",
"exports": {
"import": "./dist/index.mjs",
"require": "./dist/index.node.js",
"types": "./dist/types/index.d.ts"
},
"main": "dist/index.js",
"types": "dist/types/index.d.ts",
"exports": {
"types": "./dist/types/index.d.ts",
"require": "./dist/index.cjs",
"default": "./dist/index.js"
},
"files": [
"dist/",
"src/",
@@ -31,16 +32,16 @@
"devDependencies": {
"hardhat": "^2.19.4",
"rollup-plugin-cleanup": "^3.2.1",
"rollup-plugin-typescript2": "^0.31.2"
"rollup-plugin-typescript2": "^0.36.0"
},
"peerDependencies": {
"hardhat": "^2.19.4"
},
"dependencies": {
"@nomicfoundation/hardhat-ethers": "^3.0.0",
"@semaphore-protocol/contracts": "4.0.0-alpha.2",
"@semaphore-protocol/contracts": "4.0.0-alpha.6",
"ethers": "^6.4.0",
"hardhat-dependency-compiler": "^1.1.3"
},
"stableVersion": "4.0.0-alpha.1"
"stableVersion": "4.0.0-alpha.5"
}

View File

@@ -16,7 +16,7 @@ export default {
input: "src/index.ts",
output: [
{ file: pkg.exports.require, format: "cjs", banner, exports: "auto" },
{ file: pkg.exports.import, format: "es", banner }
{ file: pkg.exports.default, format: "es", banner }
],
external: [...Object.keys(pkg.dependencies), "hardhat/config"],
plugins: [

View File

@@ -1,15 +1,16 @@
{
"name": "@semaphore-protocol/heyauthn",
"version": "4.0.0-alpha.2",
"version": "4.0.0-alpha.6",
"description": "A library to allow developers to create and manage Semaphore identities using WebAuthn",
"type": "module",
"license": "MIT",
"main": "dist/index.node.js",
"exports": {
"import": "./dist/index.mjs",
"require": "./dist/index.node.js",
"types": "./dist/types/index.d.ts"
},
"main": "dist/index.js",
"types": "dist/types/index.d.ts",
"exports": {
"types": "./dist/types/index.d.ts",
"require": "./dist/index.cjs",
"default": "./dist/index.js"
},
"files": [
"dist/",
"src/",
@@ -30,12 +31,12 @@
},
"devDependencies": {
"rollup-plugin-cleanup": "^3.2.1",
"rollup-plugin-typescript2": "^0.31.2"
"rollup-plugin-typescript2": "^0.36.0"
},
"dependencies": {
"@semaphore-protocol/identity": "4.0.0-alpha.2",
"@semaphore-protocol/identity": "4.0.0-alpha.6",
"@simplewebauthn/browser": "7.2.0",
"@simplewebauthn/server": "7.2.0"
},
"stableVersion": "4.0.0-alpha.1"
"stableVersion": "4.0.0-alpha.5"
}

View File

@@ -16,7 +16,7 @@ export default {
input: "src/index.ts",
output: [
{ file: pkg.exports.require, format: "cjs", banner, exports: "auto" },
{ file: pkg.exports.import, format: "es", banner }
{ file: pkg.exports.default, format: "es", banner }
],
external: Object.keys(pkg.dependencies),
plugins: [

View File

@@ -1,22 +1,22 @@
{
"name": "@semaphore-protocol/identity",
"version": "4.0.0-alpha.2",
"version": "4.0.0-alpha.6",
"description": "A library to create Semaphore identities.",
"type": "module",
"license": "MIT",
"main": "dist/index.node.js",
"browser": "dist/index.browser.mjs",
"main": "dist/index.browser.js",
"types": "dist/types/index.d.ts",
"exports": {
".": {
"types": "./dist/types/index.d.ts",
"node": {
"import": "./dist/index.node.mjs",
"require": "./dist/index.node.js"
"require": "./dist/index.node.cjs",
"default": "./dist/index.node.js"
},
"browser": "./dist/index.browser.mjs",
"default": "./dist/index.browser.mjs",
"types": "./dist/types/index.d.ts"
"browser": "./dist/index.browser.js",
"default": "./dist/index.browser.js"
}
},
"types": "dist/types/index.d.ts",
"files": [
"dist/",
"src/",
@@ -39,14 +39,14 @@
},
"devDependencies": {
"@rollup/plugin-alias": "^5.1.0",
"@rollup/plugin-commonjs": "^24.0.1",
"@rollup/plugin-node-resolve": "^15.0.1",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-node-resolve": "^15.2.3",
"rollup-plugin-cleanup": "^3.2.1",
"rollup-plugin-typescript2": "^0.31.2"
"rollup-plugin-typescript2": "^0.36.0"
},
"dependencies": {
"@zk-kit/eddsa-poseidon": "0.4.1",
"poseidon-lite": "^0.2.0"
},
"stableVersion": "4.0.0-alpha.1"
"stableVersion": "4.0.0-alpha.5"
}

View File

@@ -1,5 +1,7 @@
import alias from "@rollup/plugin-alias"
import commonjs from "@rollup/plugin-commonjs"
import json from "@rollup/plugin-json"
import { nodeResolve } from "@rollup/plugin-node-resolve"
import * as fs from "fs"
import cleanup from "rollup-plugin-cleanup"
import typescript from "rollup-plugin-typescript2"
@@ -23,7 +25,7 @@ export default {
banner
}
],
external: [...Object.keys(pkg.dependencies), "poseidon-lite/poseidon2"],
external: pkg.dependencies,
plugins: [
alias({
entries: [{ find: "./random-number.node", replacement: "./random-number.browser" }]
@@ -32,6 +34,8 @@ export default {
tsconfig: "./build.tsconfig.json",
useTsconfigDeclarationDir: true
}),
commonjs(),
nodeResolve(),
cleanup({ comments: "jsdoc" }),
json()
]

View File

@@ -1,3 +1,5 @@
import commonjs from "@rollup/plugin-commonjs"
import { nodeResolve } from "@rollup/plugin-node-resolve"
import * as fs from "fs"
import cleanup from "rollup-plugin-cleanup"
import typescript from "rollup-plugin-typescript2"
@@ -16,14 +18,16 @@ export default {
input: "src/index.ts",
output: [
{ file: pkg.exports["."].node.require, format: "cjs", banner, exports: "auto" },
{ file: pkg.exports["."].node.import, format: "es", banner }
{ file: pkg.exports["."].node.default, format: "es", banner }
],
external: [...Object.keys(pkg.dependencies), "poseidon-lite/poseidon2", "node:crypto"],
external: [...Object.keys(pkg.dependencies), "node:crypto"],
plugins: [
typescript({
tsconfig: "./build.tsconfig.json",
useTsconfigDeclarationDir: true
}),
commonjs(),
nodeResolve(),
cleanup({ comments: "jsdoc" })
]
}

View File

@@ -93,13 +93,13 @@ const message = utils.formatBytes32String("Hello world")
group.addMembers([...identityCommitments, identity.generateCommitment()])
const fullProof1 = await generateProof(identity, group, message, scope)
const proof1 = await generateProof(identity, group, message, scope)
// You can also specify the maximum tree depth supported by the proof.
const fullProof2 = await generateProof(identity, group, message, scope, 20)
const proof2 = await generateProof(identity, group, message, scope, 20)
// You can also specify the default zkey/wasm files.
const fullProof3 = await generateProof(identity, group, message, scope, 20, {
const proof3 = await generateProof(identity, group, message, scope, 20, {
wasmFilePath: "./semaphore.wasm",
zkeyFilePath: "./semaphore.zkey"
})
@@ -110,5 +110,5 @@ const fullProof3 = await generateProof(identity, group, message, scope, 20, {
```typescript
import { verifyProof } from "@semaphore-protocol/proof"
await verifyProof(fullProof)
await verifyProof(proof1)
```

View File

@@ -1,22 +1,22 @@
{
"name": "@semaphore-protocol/proof",
"version": "4.0.0-alpha.2",
"version": "4.0.0-alpha.6",
"description": "A library to generate and verify Semaphore proofs.",
"type": "module",
"license": "MIT",
"main": "dist/index.node.js",
"browser": "dist/index.browser.mjs",
"main": "dist/index.browser.js",
"types": "dist/types/index.d.ts",
"exports": {
".": {
"types": "./dist/types/index.d.ts",
"node": {
"import": "./dist/index.node.mjs",
"require": "./dist/index.node.js"
"require": "./dist/index.node.cjs",
"default": "./dist/index.node.js"
},
"browser": "./dist/index.browser.mjs",
"default": "./dist/index.browser.mjs",
"types": "./dist/types/index.d.ts"
"browser": "./dist/index.browser.js",
"default": "./dist/index.browser.js"
}
},
"types": "dist/types/index.d.ts",
"files": [
"dist/",
"src/",
@@ -40,18 +40,18 @@
"devDependencies": {
"@ethersproject/strings": "^5.7.0",
"@rollup/plugin-alias": "^5.1.0",
"@rollup/plugin-json": "^5.0.1",
"@rollup/plugin-json": "^6.1.0",
"@types/download": "^8.0.5",
"@types/tmp": "^0.2.6",
"poseidon-lite": "^0.2.0",
"rimraf": "^5.0.5",
"rollup": "^4.0.2",
"rollup-plugin-cleanup": "^3.2.1",
"rollup-plugin-typescript2": "^0.31.2"
"rollup-plugin-typescript2": "^0.36.0"
},
"peerDependencies": {
"@semaphore-protocol/group": "4.0.0-alpha.2",
"@semaphore-protocol/identity": "4.0.0-alpha.2"
"@semaphore-protocol/group": "4.0.0-alpha.6",
"@semaphore-protocol/identity": "4.0.0-alpha.6"
},
"dependencies": {
"@ethersproject/bignumber": "5.7.0",
@@ -62,5 +62,5 @@
"snarkjs": "0.7.3",
"tmp": "0.2.1"
},
"stableVersion": "4.0.0-alpha.1"
"stableVersion": "4.0.0-alpha.5"
}

View File

@@ -23,7 +23,7 @@ export default {
exports: "auto"
},
{
file: pkg.exports["."].node.import,
file: pkg.exports["."].node.default,
format: "es",
banner
}

View File

@@ -6,8 +6,7 @@ import verificationKeys from "./verification-keys.json"
/**
* Verifies a Semaphore proof.
* @param fullProof The SnarkJS Semaphore proof.
* @param treeDepth The depth of the tree.
* @param proof The Semaphore proof.
* @returns True if the proof is valid, false otherwise.
*/
export default async function verifyProof({

View File

@@ -12,7 +12,7 @@ describe("Proof", () => {
const identity = new Identity(42)
let fullProof: SemaphoreProof
let proof: SemaphoreProof
let curve: any
beforeAll(async () => {
@@ -43,31 +43,31 @@ describe("Proof", () => {
it("Should generate a Semaphore proof", async () => {
const group = new Group([BigInt(1), BigInt(2), identity.commitment])
fullProof = await generateProof(identity, group, message, scope, treeDepth)
proof = await generateProof(identity, group, message, scope, treeDepth)
expect(typeof fullProof).toBe("object")
expect(fullProof.merkleTreeRoot).toBe(group.root)
expect(typeof proof).toBe("object")
expect(proof.merkleTreeRoot).toBe(group.root)
}, 20000)
it("Should generate a Semaphore proof passing a Merkle proof instead of a group", async () => {
const group = new Group([BigInt(1), BigInt(2), identity.commitment])
fullProof = await generateProof(identity, group.generateMerkleProof(2), message, scope, treeDepth)
proof = await generateProof(identity, group.generateMerkleProof(2), message, scope, treeDepth)
expect(typeof fullProof).toBe("object")
expect(fullProof.merkleTreeRoot).toBe(group.root)
expect(typeof proof).toBe("object")
expect(proof.merkleTreeRoot).toBe(group.root)
}, 20000)
})
describe("# verifyProof", () => {
it("Should not verify a Semaphore proof if the tree depth is not supported", async () => {
const fun = () => verifyProof({ ...fullProof, merkleTreeDepth: 40 })
const fun = () => verifyProof({ ...proof, merkleTreeDepth: 40 })
await expect(fun).rejects.toThrow("tree depth must be")
})
it("Should verify a Semaphore proof", async () => {
const response = await verifyProof(fullProof)
const response = await verifyProof(proof)
expect(response).toBe(true)
})
@@ -75,10 +75,10 @@ describe("Proof", () => {
describe("# packProof/unpackProof", () => {
it("Should return a packed proof", async () => {
const originalProof = unpackPoints(fullProof.points)
const proof = packPoints(originalProof)
const originalPoints = unpackPoints(proof.points)
const points = packPoints(originalPoints)
expect(proof).toStrictEqual(fullProof.points)
expect(points).toStrictEqual(proof.points)
})
})
})

View File

@@ -1 +1 @@
bfeea664bd00b9b443312a08c451a4f86217a41f
1fd316412002fe4624b72f6da5276ca6997f2380