Added service worker compatibility for snarkjs proof generation#72
Added service worker compatibility for snarkjs proof generation#72SergeyG-Solicy wants to merge 4 commits intomainfrom
Conversation
PR Compliance Guide 🔍Below is a summary of compliance checks for this PR:
Compliance status legend🟢 - Fully Compliant🟡 - Partial Compliant 🔴 - Not Compliant ⚪ - Requires Further Human Verification 🏷️ - Compliance label |
||||||||||||||||||||||||
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
WalkthroughReplaced a forked snarkjs dependency with the official Changes
Sequence DiagramsequenceDiagram
participant App as Application
participant PG as ProofGenerator
participant Env as EnvDetector
participant SNARK as snarkjs
participant Logger as Logger
App->>PG: configure(config)
PG-->>App: ack
App->>PG: generateIdentityProof(input)
PG->>Env: isRestrictedWorkerEnvironment()
Env-->>PG: envDecision
PG->>PG: willUseSingleThread()
alt singleThread
PG->>Logger: info("using single-thread")
PG->>SNARK: wtns.calculate(...)
SNARK-->>PG: witness
PG->>SNARK: groth16.prove(witness, proverOptions: {singleThread: true})
else multiThread
PG->>Logger: info("using parallel mode")
PG->>SNARK: wtns.calculate(...)
SNARK-->>PG: witness
PG->>SNARK: groth16.prove(witness, proverOptions: {singleThread: false})
end
SNARK-->>PG: {proof, publicSignals}
PG->>PG: annotate proof with curve
PG-->>App: ProofGenerationResult
App->>PG: verifyProof(proof, publicSignals)
PG->>SNARK: groth16.verify(..., annotatedProof)
SNARK-->>PG: boolean
PG-->>App: verificationResult
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Suggested labels
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
PR Code Suggestions ✨Explore these optional code suggestions:
|
||||||||||||
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@package.json`:
- Line 99: The TypeScript types for snarkjs are out of sync with the runtime:
you use snarkjs.fullProve with proverOptions (e.g., singleThread) but
`@types/snarkjs` lacks that overload; either update the `@types/snarkjs` package to
a release that includes the proverOptions type, or change calls to avoid
fullProve with options by switching to groth16.prove (call groth16.prove(..., {
singleThread: true }) where you currently call snarkjs.fullProve(..., {
singleThread: true })) and adjust imports/usages accordingly (references:
snarkjs, fullProve, groth16.prove, proverOptions, `@types/snarkjs`).
In `@src/encryption/zK/identity/ProofGenerator.ts`:
- Around line 100-141: Add a `// REVIEW:` marker immediately before the new
global config API block that defines globalConfig and the
configure/getConfig/willUseSingleThread functions; specifically insert the
comment above the declaration of globalConfig (symbol: globalConfig) and before
the JSDoc for configure (symbol: configure or ProofGenerator.configure) so the
new API surface (ProofGenerator.configure, getConfig, willUseSingleThread and
the ProofGeneratorConfig usage) is clearly marked for review per guidelines.
🧹 Nitpick comments (2)
src/encryption/zK/identity/ProofGenerator.ts (2)
19-75: Reduceanyusage in environment detection.
This block relies on repeatedas any, which conflicts with the “full TypeScript type coverage” guideline. Consider narrowing via a typed record and local guards.♻️ Suggested typing cleanup
- const g = globalThis as any + const g = globalThis as Record<string, unknown> + const ServiceWorkerGlobalScopeCtor = + g.ServiceWorkerGlobalScope as undefined | (new (...args: unknown[]) => unknown) - if (typeof g.ServiceWorkerGlobalScope !== 'undefined' && - typeof self !== 'undefined' && - self instanceof g.ServiceWorkerGlobalScope) { + if (ServiceWorkerGlobalScopeCtor && + typeof self !== 'undefined' && + self instanceof ServiceWorkerGlobalScopeCtor) { return true } - if (typeof globalThis !== 'undefined' && - typeof (globalThis as any).caches !== 'undefined' && - typeof (globalThis as any).window === 'undefined' && - typeof (globalThis as any).document === 'undefined') { + if (typeof globalThis !== 'undefined' && + typeof g.caches !== 'undefined' && + typeof g.window === 'undefined' && + typeof g.document === 'undefined') { // Could be Cloudflare Worker or Service Worker - check for CF-specific globals - if (typeof (globalThis as any).HTMLRewriter !== 'undefined') { + if (typeof g.HTMLRewriter !== 'undefined') { return true } } - if (typeof (globalThis as any).Bun !== 'undefined') { + if (typeof g.Bun !== 'undefined') { return true }As per coding guidelines, please keep full TypeScript type coverage.
286-292: Derivecurvefrom the loaded verification key to prevent mismatches.
The verification key JSON loaded from CDN includes acurvefield according to snarkjs standard export format. Hardcoding'bn128'risks a mismatch if the circuit is regenerated with a different curve (e.g.,bls12-381). Extract the curve fromvkeywith a fallback to ensure consistency:♻️ Safer curve handling
- const snarkjsProof = { + const snarkjsProof = { pi_a: proof.pi_a, pi_b: proof.pi_b, pi_c: proof.pi_c, protocol: proof.protocol, - curve: 'bn128', // Standard curve for Groth16 proofs + curve: (vkey as { curve?: string }).curve ?? 'bn128', }
| "@cosmjs/proto-signing": "^0.32.4", | ||
| "@cosmjs/stargate": "^0.32.4", | ||
| "@cryptkeeperzk/snarkjs": "^0.7.2", | ||
| "snarkjs": "^0.7.5", |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Search for singleThread usage in the codebase
rg -i "singlethread" --type json --type js --type ts -B 2 -A 2Repository: kynesyslabs/sdks
Length of output: 2637
🏁 Script executed:
# Also check the package.json for the exact versions
fd package.json -x cat -n {} | head -200Repository: kynesyslabs/sdks
Length of output: 10900
🌐 Web query:
snarkjs 0.7.5 release notes singleThread prover option fullProve
💡 Result:
In snarkjs v0.7.5 (released Oct 18, 2024), the release notes include “Support for wtns calc and prover options” (PR #517). This change adds the ability for fullProve/fullprove to pass options through to:
- the witness calculator (e.g.
memorySize), and - the prover, including a single-thread mode option (spelled
singleThreadin the API; the PR text contains a minor typo). [1][2]
Where it shows up: the v0.7.5 release notes list the PR, and the PR description explicitly says it “Pass[es] … singleTread option to prover” and adds an options parameter to groth16FullProve (and similarly for PLONK/FFLONK full prove). [1][2]
Sources:
[1] snarkjs v0.7.5 release notes (GitHub Releases) (github.com)
[2] PR #517 “Support for wtns calc and prover options” (github.com)
Citations:
- 1: https://github.com/iden3/snarkjs/releases
- 2: Support for wtns calc and prover options iden3/snarkjs#517
🌐 Web query:
@types/snarkjs 0.7.9 type definitions groth16 fullProve singleThread
💡 Result:
In @types/snarkjs 0.7.9, groth16.fullProve is typed as:
fullProve(input, wasmFile, zkeyFileName, logger?)(no “options” parameter), sosingleThreadcan’t be passed without a TS error. [1]
In snarkjs itself, the documented way to force single-threaded proving is not fullProve, but:
snarkjs.groth16.prove(zkeyFinal, wtns, undefined, { singleThread: true })[2]
So in TS, the practical options are:
- Use
wtns.calculate(...)+groth16.prove(..., { singleThread: true })(instead offullProve). [2] - Override the typing (cast to
anyor add module augmentation) to allow a 4th/5th parameter—because the published DT types don’t include it. [1][2]
Sources: [1] [2]
Fix @types/snarkjs version mismatch with runtime API.
[email protected] supports singleThread in fullProve proverOptions (added Oct 2024, PR #517), but @types/[email protected] type definitions do not include the proverOptions parameter. This causes TypeScript compilation errors despite runtime compatibility. Either upgrade @types/snarkjs to a version that includes proverOptions, or refactor to use separate groth16.prove(..., { singleThread: true }) calls instead of fullProve.
🤖 Prompt for AI Agents
In `@package.json` at line 99, The TypeScript types for snarkjs are out of sync
with the runtime: you use snarkjs.fullProve with proverOptions (e.g.,
singleThread) but `@types/snarkjs` lacks that overload; either update the
`@types/snarkjs` package to a release that includes the proverOptions type, or
change calls to avoid fullProve with options by switching to groth16.prove (call
groth16.prove(..., { singleThread: true }) where you currently call
snarkjs.fullProve(..., { singleThread: true })) and adjust imports/usages
accordingly (references: snarkjs, fullProve, groth16.prove, proverOptions,
`@types/snarkjs`).
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@src/encryption/zK/identity/ProofGenerator.ts`:
- Around line 56-94: The isRestrictedWorkerEnvironment function must treat an
absent Worker constructor as a restricted environment: add an explicit early
check "if (typeof Worker === 'undefined') return true" so runtimes without
Worker choose non-parallel mode; also replace indiscriminate "globalThis as any"
usage with a narrow typed alias or guarded property checks (e.g., cast
globalThis to a small interface or use 'in' / typeof checks for caches,
HTMLRewriter, Bun) to preserve TypeScript type coverage while locating the
checks around globalThis, Worker.prototype and Bun/HTMLRewriter detections.
- Around line 18-43: The current augmentation and usage assume groth16.fullProve
accepts a proverOptions parameter; update ProofGenerator.ts to match snarkjs
0.7.5 by removing the extra proverOptions parameter from the fullProve type
declaration and instead add/augment types for wtnsCalculate and groth16.prove
(accepting zkey, wtns, optional logger, and ProverOptions). Refactor places that
call groth16.fullProve (referenced in this file around the proof generation
logic and the symbols fullProve and Groth16Proof) to compute the witness first
via wtnsCalculate(...) and then call groth16.prove(zkey, wtns, undefined, {
singleThread: true }) so single-threaded proving is enforced and runtime API
matches types.
|
…re/zk-service-worker-compatibility
|



User description
@cryptkeeperzk/snarkjsto[email protected](has singleThread option)singleThreadmode only when Web Workers are unavailableProofGenerator.configure()API for manual overrideFixed ZK proof generation in Chrome MV3 extension service workers.
PR Type
Enhancement, Bug fix
Description
Switched from
@cryptkeeperzk/snarkjsto[email protected]for singleThread supportImplemented hybrid environment detection for restricted contexts
Auto-detects Chrome MV3 service workers, Cloudflare Workers, Bun runtime
Added
ProofGenerator.configure()API for manual override and loggingUses single-threaded mode only when Web Workers unavailable
Diagram Walkthrough
File Walkthrough
ProofGenerator.ts
Hybrid environment detection and configuration APIsrc/encryption/zK/identity/ProofGenerator.ts
isRestrictedWorkerEnvironment()function to detect Chrome MV3service workers, Cloudflare Workers, Bun runtime, and other restricted
contexts
ProofGeneratorConfiginterface withforceSingleThreadandloggeroptionsconfigure(),getConfig(), andwillUseSingleThread()exportedfunctions for global configuration
generateIdentityProof()to usesingleThreadoption based onenvironment detection
verifyProof()to includecurve: 'bn128'in snarkjs proof format@cryptkeeperzk/snarkjstosnarkjspackage.json
Update snarkjs dependency and add type definitionspackage.json
@cryptkeeperzk/snarkjs@^0.7.2withsnarkjs@^0.7.5independencies
@types/snarkjs@^0.7.9to devDependencies for TypeScript typesupport
Summary by CodeRabbit
New Features
Chores