Skip to content

Prover Configuration

The prover generates zero-knowledge proofs for transfers and unshields.

Initialization

Initialize the prover once at app startup:

typescript
import { createProver, setGlobalProver } from '@zkprivacy/sdk';

const prover = await createProver({
  transferCircuit: '/circuits/transfer.json',
  unshieldCircuit: '/circuits/unshield.json',
});

setGlobalProver(prover);

TIP

Prover initialization takes 2-5 seconds. Show a loading state during this time.

Circuit Sources

Browser (URLs)

Fetch circuits from your public folder:

typescript
const prover = await createProver({
  transferCircuit: '/circuits/transfer.json',
  unshieldCircuit: '/circuits/unshield.json',
});

Node.js (File System)

Load circuits from disk:

typescript
import { readFileSync } from 'fs';

const prover = await createProver({
  transferCircuit: JSON.parse(
    readFileSync('circuits/transfer.json', 'utf-8')
  ),
  unshieldCircuit: JSON.parse(
    readFileSync('circuits/unshield.json', 'utf-8')
  ),
});

CDN

Host circuits on a CDN for better caching:

typescript
const prover = await createProver({
  transferCircuit: 'https://cdn.example.com/circuits/transfer.json',
  unshieldCircuit: 'https://cdn.example.com/circuits/unshield.json',
});

Global vs Instance Prover

Global Prover

Set once, used by all PrivacyClient instances:

typescript
setGlobalProver(prover);

// Client uses global prover automatically
const client = new PrivacyClient({ ... });

Instance Prover

Pass to specific client:

typescript
const client = new PrivacyClient({
  prover,  // Use this prover
  // ...
});

Instance prover takes precedence over global.

Proof Generation Performance

CircuitBrowser (WASM)Node.js
Transfer30-60 seconds15-30 seconds
Unshield20-40 seconds10-20 seconds

Factors Affecting Speed

  • CPU cores: More cores = faster proving
  • Memory: Needs ~2GB available
  • Browser: Chrome/Edge faster than Firefox
  • Device: Desktop faster than mobile

Memory Requirements

The prover uses significant memory:

PhaseMemory
Circuit loading~100MB
Proof generation~1.5-2GB
Peak~2.5GB

Browser Considerations

  • Close unnecessary tabs
  • Avoid mobile devices for proving
  • Consider relayer for constrained devices

Error Handling

typescript
try {
  const prover = await createProver({
    transferCircuit: '/circuits/transfer.json',
    unshieldCircuit: '/circuits/unshield.json',
  });
} catch (error) {
  if (error.message.includes('Failed to fetch')) {
    console.error('Circuit files not found');
  } else if (error.message.includes('WASM')) {
    console.error('WASM initialization failed');
  }
}

Checking Prover State

typescript
// Check if prover is ready
if (prover.isReady()) {
  await client.transfer({ ... });
} else {
  console.log('Prover still initializing');
}

Circuit Files

Getting Circuit Files

  1. From deployed app: Download from https://devtools.zkprivacy.dev/circuits/
  2. Build from source: just build-circuits

Required Files

FileSizePurpose
transfer.json~500KB2-in-2-out transfers
unshield.json~400KBWithdrawals

Hosting

Place in your app's public folder:

public/
└── circuits/
    ├── transfer.json
    └── unshield.json

Advanced: Manual Proof Generation

For advanced use cases, generate proofs directly:

typescript
const proof = await prover.generateTransferProof({
  inputs: [...],
  outputs: [...],
  spendingKey: ...,
  merkleRoot: ...,
  // ... other params
});

// proof.proof - the ZK proof bytes
// proof.publicInputs - public inputs for verification

WARNING

Manual proof generation requires careful input construction. Use client.transfer() instead unless you have specific requirements.

Released under the MIT License.