Privacy Operations
Coming Soon
Privacy pools and ZK operations are currently in development. This documentation describes the planned API.
Use PrivChain's privacy pools to transact without revealing your identity or transaction history.
Overview
Privacy operations allow agents to:
- Deposit tokens into a privacy pool
- Wait for the anonymity set to grow
- Withdraw to a fresh address with a ZK proof
- Prove compliance without revealing identity
mermaid
sequenceDiagram
participant Agent
participant SDK
participant Pool as Privacy Pool
participant Chain as Solana
Agent->>SDK: deposit(100 PRIV)
SDK->>Pool: Create commitment
Pool->>Chain: Record on-chain
SDK->>Agent: Return secret note
Note over Pool: Anonymity set grows...
Agent->>SDK: withdraw(note, newAddress)
SDK->>SDK: Generate ZK proof
SDK->>Pool: Submit proof
Pool->>Chain: Verify & release
Chain->>Agent: 100 PRIV (new address)Deposits
Basic Deposit
typescript
// Deposit PRIV into the standard privacy pool
const note = await privchain.privacy.deposit({
amount: 100,
pool: 'standard'
});
// ⚠️ CRITICAL: Store this note securely!
// It's proof of ownership - lose it, lose your funds
const serialized = note.serialize();
fs.writeFileSync('secret-note.enc', encrypt(serialized));
console.log('Deposit complete');
console.log('Commitment:', note.commitment);
console.log('Pool:', note.pool);Pool Selection
typescript
// Available pools
const pools = await privchain.privacy.getPools();
console.log(pools);
// [
// { id: 'standard', minDeposit: 10, anonymitySet: 15234, fee: 0.1 },
// { id: 'high-value', minDeposit: 1000, anonymitySet: 892, fee: 0.05 },
// { id: 'agent', minDeposit: 100, anonymitySet: 3421, fee: 0.08 }
// ]
// Deposit to specific pool
const note = await privchain.privacy.deposit({
amount: 5000,
pool: 'high-value'
});Deposit Options
typescript
const note = await privchain.privacy.deposit({
amount: 100,
pool: 'standard',
// Optional: custom randomness (advanced)
randomness: customRandomBytes,
// Optional: relayer for deposit privacy
relayer: 'https://relayer.privchain.io'
});Withdrawals
Basic Withdrawal
typescript
// Load your secret note
const serialized = decrypt(fs.readFileSync('secret-note.enc'));
const note = PrivChainNote.deserialize(serialized);
// Generate fresh receiving address
const freshWallet = Keypair.generate();
// Withdraw
const tx = await privchain.privacy.withdraw({
note: note,
recipient: freshWallet.publicKey.toBase58()
});
console.log('Withdrawal complete:', tx.signature);
console.log('Received at:', freshWallet.publicKey.toBase58());Withdrawal with Relayer
For maximum privacy, use a relayer to submit your transaction:
typescript
const tx = await privchain.privacy.withdraw({
note: note,
recipient: freshAddress,
// Relayer pays gas and submits tx
relayer: {
url: 'https://relayer.privchain.io',
fee: 1 // 1 PRIV relayer fee
}
});
// Your IP is never associated with the withdrawalCompliance Proofs
Prove your funds are clean without revealing source:
typescript
const tx = await privchain.privacy.withdraw({
note: note,
recipient: freshAddress,
// Prove funds are NOT from excluded set
compliance: {
type: 'exclusion',
set: 'ofac-sanctions-2024'
}
});
// Verifiers see: "Funds proven NOT from sanctioned addresses"
// Verifiers do NOT see: Your actual deposit addressAssociation Set Proofs
Prove membership in a "good" set:
typescript
const tx = await privchain.privacy.withdraw({
note: note,
recipient: freshAddress,
compliance: {
type: 'inclusion',
set: 'verified-agents-2024'
}
});Proof Generation
Local Proving
Generate proofs locally (requires compute):
typescript
// Configure prover
privchain.privacy.configureProver({
mode: 'local',
threads: 4,
useGpu: true // If @privchain/prover-gpu installed
});
// Proof generation happens automatically on withdraw
const tx = await privchain.privacy.withdraw({ note, recipient });
console.log('Proof generated in:', tx.proofTime, 'ms');Remote Proving
Use PrivChain's proving service:
typescript
privchain.privacy.configureProver({
mode: 'remote',
url: 'https://prover.privchain.io',
apiKey: process.env.PRIVCHAIN_PROVER_KEY
});
// Faster, but note leaves your machine briefly
const tx = await privchain.privacy.withdraw({ note, recipient });Anonymity Set
Check Anonymity
typescript
// Get current anonymity set size
const stats = await privchain.privacy.getPoolStats('standard');
console.log(stats);
// {
// pool: 'standard',
// totalDeposits: 15234,
// anonymitySet: 15234, // All deposits look the same
// recentDeposits24h: 523,
// averageWaitTime: '4.2 hours'
// }Wait for Anonymity
typescript
// Wait until anonymity set is large enough
await privchain.privacy.waitForAnonymity({
note: note,
minAnonymitySet: 1000,
timeout: 86400000 // 24 hours max wait
});
// Now safe to withdraw with good privacy
const tx = await privchain.privacy.withdraw({ note, recipient });Note Management
Encrypt Notes
typescript
import { encryptNote, decryptNote } from '@privchain/sdk';
// Encrypt with password
const encrypted = encryptNote(note, 'strong-password-123');
fs.writeFileSync('note.enc', encrypted);
// Decrypt when needed
const decrypted = decryptNote(
fs.readFileSync('note.enc'),
'strong-password-123'
);Check Note Status
typescript
// Verify note is valid and unspent
const status = await privchain.privacy.checkNote(note);
console.log(status);
// {
// valid: true,
// spent: false,
// pool: 'standard',
// amount: 100,
// depositTime: '2024-01-15T10:30:00Z'
// }Recover Lost Notes
If you have the original randomness:
typescript
// Regenerate note from randomness
const note = await privchain.privacy.recoverNote({
randomness: myOriginalRandomness,
amount: 100,
pool: 'standard'
});
// Verify it exists on-chain
const status = await privchain.privacy.checkNote(note);Security
Best Practices
- Store notes encrypted - Use strong encryption
- Wait before withdrawing - Larger anonymity set = better privacy
- Use relayers - Hide your IP address
- Fresh addresses only - Never reuse withdrawal addresses
- Exact amounts - Don't use unique amounts that can be traced
Note Security
Critical
The secret note is equivalent to the funds. Anyone with the note can withdraw.
typescript
// ✅ Good: Encrypted storage
const encrypted = encryptNote(note, password);
await secureStorage.save('note', encrypted);
// ❌ Bad: Plain text
fs.writeFileSync('note.txt', note.serialize()); // Never!Error Handling
typescript
import {
NoteSpentError,
InvalidProofError,
PoolNotFoundError
} from '@privchain/sdk';
try {
await privchain.privacy.withdraw({ note, recipient });
} catch (error) {
if (error instanceof NoteSpentError) {
console.error('Note already spent!');
} else if (error instanceof InvalidProofError) {
console.error('Proof generation failed:', error.message);
} else if (error instanceof PoolNotFoundError) {
console.error('Pool does not exist');
}
}Roadmap
Privacy features launching in phases:
| Feature | Status | Expected |
|---|---|---|
| Standard pool | 🚧 Development | Q1 2024 |
| Basic withdrawals | 🚧 Development | Q1 2024 |
| Relayer network | 📋 Planned | Q2 2024 |
| Compliance proofs | 📋 Planned | Q2 2024 |
| Agent-only pools | 📋 Planned | Q2 2024 |
| Cross-chain | 📋 Planned | Q3 2024 |
Join Discord for updates.