diff --git a/packages/interface/.env.example b/packages/interface/.env.example index 626b7668..a0587600 100644 --- a/packages/interface/.env.example +++ b/packages/interface/.env.example @@ -62,6 +62,13 @@ NEXT_PUBLIC_APPROVAL_SCHEMA=0x858e0bc94997c072d762d90440966759b57c8bca892d4c9447 # (optional) NEXT_PUBLIC_METADATA_SCHEMA=0xd00c966351896bd3dc37d22017bf1ef23165f859d7546a2aba12a01623dec912 +# ----------------- +# Semaphore CONFIGURATION +# ----------------- + +# If you use Semaphore as gatekeeper, please add your semaphore subgraph url below +NEXT_PUBLIC_SEMAPHORE_SUBGRAPH= + # ---------------------- # Advanced Configuration # ---------------------- diff --git a/packages/interface/src/config.ts b/packages/interface/src/config.ts index 50bcb36d..42ef976d 100644 --- a/packages/interface/src/config.ts +++ b/packages/interface/src/config.ts @@ -90,6 +90,7 @@ export const config = { roundOrganizer: process.env.NEXT_PUBLIC_ROUND_ORGANIZER ?? "PSE", pollMode: process.env.NEXT_PUBLIC_POLL_MODE ?? "non-qv", roundLogo: process.env.NEXT_PUBLIC_ROUND_LOGO, + semaphoreSubgraphUrl: process.env.NEXT_PUBLIC_SEMAPHORE_SUBGRAPH, }; export const theme = { diff --git a/packages/interface/src/contexts/Maci.tsx b/packages/interface/src/contexts/Maci.tsx index a9876008..fe15c27b 100644 --- a/packages/interface/src/contexts/Maci.tsx +++ b/packages/interface/src/contexts/Maci.tsx @@ -132,7 +132,10 @@ export const MaciProvider: React.FC = ({ children }: MaciProv // just by fetching the attestation. On the other hand, with other // gatekeepers it might be more difficult to determine it // for instance with semaphore - const isEligibleToVote = useMemo(() => Boolean(sgData) && Boolean(address), [sgData, address]); + const isEligibleToVote = useMemo( + () => gatekeeperTrait && (gatekeeperTrait === GatekeeperTrait.FreeForAll || Boolean(sgData)) && Boolean(address), + [sgData, address], + ); // on load get the key pair from local storage and set the signature message useEffect(() => { @@ -187,7 +190,7 @@ export const MaciProvider: React.FC = ({ children }: MaciProv // function to be used to signup to MACI const onSignup = useCallback( async (onError: () => void) => { - if (!signer || !maciPubKey || !sgData) { + if (!signer || !maciPubKey || (gatekeeperTrait && gatekeeperTrait !== GatekeeperTrait.FreeForAll && !sgData)) { return; } diff --git a/packages/interface/src/env.js b/packages/interface/src/env.js index 1c098597..298ebf7a 100644 --- a/packages/interface/src/env.js +++ b/packages/interface/src/env.js @@ -69,6 +69,8 @@ module.exports = createEnv({ NEXT_PUBLIC_POLL_MODE: z.enum(["qv", "non-qv"]).default("non-qv"), NEXT_PUBLIC_ROUND_LOGO: z.string().optional(), + + NEXT_PUBLIC_SEMAPHORE_SUBGRAPH: z.string().url().optional(), }, /** @@ -108,6 +110,8 @@ module.exports = createEnv({ NEXT_PUBLIC_POLL_MODE: process.env.NEXT_PUBLIC_POLL_MODE, NEXT_PUBLIC_ROUND_LOGO: process.env.NEXT_PUBLIC_ROUND_LOGO, + + NEXT_PUBLIC_SEMAPHORE_SUBGRAPH: process.env.NEXT_PUBLIC_SEMAPHORE_SUBGRAPH, }, /** * Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially diff --git a/packages/interface/src/utils/semaphore.ts b/packages/interface/src/utils/semaphore.ts index 49ad980b..af21a5ac 100644 --- a/packages/interface/src/utils/semaphore.ts +++ b/packages/interface/src/utils/semaphore.ts @@ -1,5 +1,5 @@ import { Group, Identity, generateProof, type SemaphoreProof } from "@semaphore-protocol/core"; -import { SemaphoreEthers } from "@semaphore-protocol/data"; +import { SemaphoreEthers, SemaphoreSubgraph } from "@semaphore-protocol/data"; import { AbiCoder, JsonRpcSigner } from "ethers"; import { getSemaphoreGatekeeperData } from "maci-cli/sdk"; @@ -33,9 +33,11 @@ export const getSemaphoreProof = async (signer: JsonRpcSigner, identity: Identit maciAddress: config.maciAddress!, }); - const semaphore = new SemaphoreEthers(getRPCURL() ?? semaphoreEthersChain(), { - address: semaphoreContractAddress, - }); + const semaphore = config.semaphoreSubgraphUrl + ? new SemaphoreSubgraph(config.semaphoreSubgraphUrl) + : new SemaphoreEthers(getRPCURL() ?? semaphoreEthersChain(), { + address: semaphoreContractAddress, + }); const groupResponse = await semaphore.getGroupMembers(groupId);