Advanced Topics
Custom circuits, performance optimization, and troubleshooting
Custom Circuits
Create custom zkSNARK circuits for specialized privacy requirements.
Circuit Development
// Example: Custom range proof circuit
use zkprime_circuits::{Circuit, ConstraintSystem};
pub struct RangeProofCircuit {
value: Option<u64>,
min: u64,
max: u64,
}
impl Circuit for RangeProofCircuit {
fn synthesize<CS: ConstraintSystem>(
self,
cs: &mut CS,
) -> Result<(), SynthesisError> {
// Allocate value as private witness
let value = cs.alloc_input(|| {
self.value.ok_or(SynthesisError::AssignmentMissing)
})?;
// Constrain: min <= value <= max
cs.enforce_constraint(
value.clone(),
LinearCombination::from(self.min),
ConstraintType::GreaterOrEqual,
)?;
cs.enforce_constraint(
value,
LinearCombination::from(self.max),
ConstraintType::LessOrEqual,
)?;
Ok(())
}
}Using Custom Circuits
import { ZKPrimeClient } from '@zkprime/sdk';
// Load custom circuit
const client = new ZKPrimeClient({ ... });
await client.loadCustomCircuit('range-proof', circuitWasm);
// Generate proof with custom circuit
const proof = await client.generateProof({
circuit: 'range-proof',
statement: 'value in range [100, 1000]',
witness: { value: 500 }
});Circuit Best Practices:
- • Minimize constraint count for faster proving
- • Use lookup tables for complex operations
- • Test circuits thoroughly with edge cases
- • Optimize for verification time (on-chain cost)
Performance Tuning
Proof Caching
Cache generated proofs to avoid regeneration for repeated operations
const client = new ZKPrimeClient({
rpcUrl: '...',
proofCaching: true, // Enable proof caching
cacheSize: 100, // Cache last 100 proofs
});
// First call generates proof (~3s)
const proof1 = await client.generateProof(params);
// Subsequent calls retrieve from cache (~5ms)
const proof2 = await client.generateProof(params);Batch Transactions
Process multiple transactions in a single proof for better throughput
// Batch multiple transfers
const batch = await client.createBatchTransfer({
transfers: [
{ to: recipient1, amount: 100 },
{ to: recipient2, amount: 200 },
{ to: recipient3, amount: 300 },
],
from: wallet,
});
// Single proof for all transfers (~4s total vs 9s individual)
const signature = await client.submitTransaction(batch);Worker Threads
Offload proof generation to web workers for non-blocking UI
const client = new ZKPrimeClient({
rpcUrl: '...',
useWorkers: true, // Enable web workers
workerCount: 4, // Use 4 parallel workers
});
// Proof generation happens in background
const proofPromise = client.generateProof(params);
// UI remains responsive
updateUI('Generating proof...');
const proof = await proofPromise;
updateUI('Proof complete!');Performance Comparison
Troubleshooting
Issue: Proof Generation Fails
Error: "Constraint system unsatisfied"
Solutions:
• Verify witness data matches circuit constraints
• Check that all required fields are provided
• Ensure values are within expected ranges
• Enable debug mode: debug: true
Issue: Transaction Rejected On-Chain
Error: "Invalid proof" or "Nullifier already spent"
Solutions:
• Refresh commitment tree before generating proof
• Check that commitment hasn't been spent already
• Verify you're using correct network (devnet/mainnet)
• Increase transaction priority fee if timing out
Issue: Slow Proof Generation
Proof taking more than 10 seconds
Solutions:
• Enable web workers: useWorkers: true
• Use lower privacy level for testing
• Check device CPU capabilities
• Consider server-side proof generation
Issue: Cannot Decrypt Balance
Error: "Decryption failed" or returns wrong value
Solutions:
• Verify you're using correct private key
• Ensure encrypted state is for your address
• Check key derivation path matches
• Try re-syncing encrypted state
Debug Mode
Enable detailed logging for troubleshooting:
const client = new ZKPrimeClient({
rpcUrl: '...',
debug: true,
logLevel: 'debug' // 'debug' | 'info' | 'warn' | 'error'
});
// Check console for detailed logs
// [ZKPrime:debug] Generating proof...
// [ZKPrime:debug] Circuit constraints: 1543
// [ZKPrime:debug] Witness data loaded
// [ZKPrime:info] Proof generated in 3.2sContributing
ZKPrime is open source and welcomes contributions from the community.
Code Contributions
- • Fork the repository on GitHub
- • Create feature branch
- • Write tests for new features
- • Submit pull request
Documentation
- • Improve existing docs
- • Write tutorials
- • Add code examples
- • Report documentation bugs