Integrate GoodDollar citizen-sdk for Join to Vote face verification#337
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Gaston Review
Verdict: Approved
Score: ███████░░░ 7/10
Pull Request Summary
This PR replaces the old external GoodWallet link with an in-app face verification flow using the @goodsdks/citizen-sdk. On desktop, it opens a popup for face verification and polls the Celo Identity contract for whitelist status; on mobile, it does a full-page redirect and resumes polling on return. A new useGoodDollarVerification hook encapsulates SDK interaction and the on-chain whitelist check.
Review Summary
🔵 Suggestion — handleJoinToVote reconnect triggers checkEligibility, not verification
When a disconnected user clicks 'Join to Vote' (failed state), handleJoinToVote sets pendingCheck=true and opens the connect modal. But pendingCheck triggers checkEligibility — not the verification flow. After reconnecting, the user sees another failure and must click 'Join to Vote' a second time. Consider adding a separate pendingVerification flag that triggers handleJoinToVote after wallet connect, or at least check if this double-click UX is intentional.
🔵 Suggestion — Stale closure risk in watchVerification polling loop
The watchVerification async loop captures checkIsWhitelisted and checkEligibility at call time. If the user switches wallets mid-poll (changing address), the loop continues checking the old address. The watchIdRef only increments on unmount, not on dependency changes. In practice this is rare — users don't switch wallets during face verification — but a defensive bump of watchIdRef.current in a useEffect watching address would close the gap.
Solid integration. The popup/redirect fallback, polling cancellation via ref-based watch IDs, and unmount cleanup are all handled well. I have one UX-level concern about the disconnect-during-failed-state flow requiring an extra click, and a minor note on the stale closure risk in the polling loop, but neither is a blocker. Production-ready.
📌 3 inline comments
🔵 Suggestion: 1 · ⚪ Nitpick: 2
🔍 Reviewed by Gaston
There was a problem hiding this comment.
Gaston Review
Verdict: Approved
Score: ███████░░░ 7/10
Pull Request Summary
This PR replaces the old external GoodWallet link with an in-app face verification flow using @goodsdks/citizen-sdk. It handles desktop (popup) and mobile (redirect) paths, polls Celo's Identity contract for whitelist status, and auto-claims voter eligibility on success. A shared ABI constant and a new useGoodDollarVerification hook encapsulate the SDK and on-chain interactions.
The latest push cleanly addresses both actionable items from my prior review: the ABI is now a shared constant in constants.ts (eliminating the duplication I flagged), and the reconnect-triggers-checkEligibility behavior has an explanatory comment confirming it's intentional. The core logic — polling cancellation, popup/redirect fallback, timeout handling — remains solid. Nothing new to block on.
🔍 Reviewed by Gaston
There was a problem hiding this comment.
Gaston Review
Verdict: Approved
Score: ████████░░ 8/10
Pull Request Summary
This PR replaces the external GoodWallet link with an in-app face verification flow using @goodsdks/citizen-sdk. Desktop users get a popup, mobile users get a full-page redirect. A polling loop watches the Celo Identity contract for whitelist status and auto-claims voter eligibility on success. The latest push adds a notWhitelisted discriminator to the API response so only definitive not-whitelisted results route into face verification — transient errors (RPC hiccups, bot failures) now reset to idle for retry instead of incorrectly pushing users into the verification flow.
All items from prior reviews have been addressed: shared ABI constant, intentional reconnect comment, and now the transient-vs-definitive error distinction. The code is clean, well-structured, and handles edge cases thoughtfully. Production-ready.
🔍 Reviewed by Gaston
What
Replaces the external goodwallet.xyz link on the "Join to Vote" button with in-app GoodDollar face verification via
@goodsdks/citizen-sdk. Users verify with whatever wallet they have connected instead of creating a new GoodWallet. Applies to every round with a GoodDollar voter group (the button already only renders for those).How
useGoodDollarVerificationhook builds the identity SDK with a wallet client pinned to Celo over the connected wallet's own transport. Link generation only needs a message signature, so users connected on Base/OP/Arbitrum never get a network-switch prompt. It also exposes anisWhitelistedread with the same contract and semantics the eligibility API checks.?gdVerified=1marker; the page strips it, waits for the wallet to reconnect, and resumes automatically.addVoter. The eligibility API and bot flow are unchanged.Notes
tsupas a runtime dependency (their packaging bug). Install-time only; the SDK's real runtime dep islz-string, nothing extra is bundled.isWhitelisted(address)directly, so a wallet linked to a whitelisted root identity (IdentityV4 connected accounts) does not pass. Switching togetWhitelistedRootsemantics is a possible follow-up.Manual QA