Skip to content

Proof Composition API

SIP Protocol provides a pluggable proof system for generating zero-knowledge proofs that hide transaction details while maintaining verifiability. This reference documents all proof providers, types, and configuration options.

The proof system supports three proof types:

Proof TypePurposeConstraints
Funding ProofProves balance >= minimum without revealing balance~2,000
Validity ProofProves intent authorization without revealing sender~72,000
Fulfillment ProofProves solver delivered output correctly~22,000

All proof providers implement this interface:

interface ProofProvider {
readonly framework: ProofFramework // 'noir' | 'mock'
readonly isReady: boolean
initialize(): Promise<void>
waitUntilReady(timeoutMs?: number): Promise<void>
generateFundingProof(params: FundingProofParams): Promise<ProofResult>
generateValidityProof(params: ValidityProofParams): Promise<ProofResult>
generateFulfillmentProof(params: FulfillmentProofParams): Promise<ProofResult>
verifyProof(proof: ZKProof): Promise<boolean>
}

Production provider using Noir circuits with Barretenberg backend.

import { NoirProofProvider } from '@sip-protocol/sdk/proofs/noir'
const provider = new NoirProofProvider({
verbose: true,
oraclePublicKey: {
x: [...], // 32-byte array
y: [...], // 32-byte array
},
strictMode: true,
})
await provider.initialize()
interface NoirProviderConfig {
/** Path to compiled circuit artifacts (optional) */
artifactsPath?: string
/** Enable verbose logging */
verbose?: boolean
/** Oracle public key for fulfillment proofs */
oraclePublicKey?: PublicKeyCoordinates
/** Enforce configuration requirements */
strictMode?: boolean
}
// Derive public key from private key
const pubKey = NoirProofProvider.derivePublicKey(privateKeyBytes)
// Returns: { x: number[], y: number[] }

Browser-compatible provider with WASM and Web Worker support.

import { BrowserNoirProvider } from '@sip-protocol/sdk/browser'
const provider = new BrowserNoirProvider({
useWorker: true,
timeout: 60000,
mobileMode: false,
})
await provider.initialize((progress) => {
console.log(`${progress.stage}: ${progress.percent}%`)
})
interface BrowserNoirProviderConfig {
/** Use Web Workers for non-blocking proof generation */
useWorker?: boolean // default: true
/** Enable verbose logging */
verbose?: boolean
/** Oracle public key for fulfillment proofs */
oraclePublicKey?: PublicKeyCoordinates
/** Proof generation timeout in ms */
timeout?: number // default: 60000 (mobile: 120000)
/** Enable mobile-optimized mode (auto-detected) */
mobileMode?: boolean
/** Allow initialization with poor compatibility */
forceInitialize?: boolean
}
// Check browser support
const { supported, missing } = BrowserNoirProvider.checkBrowserSupport()
// Get browser info
const info = BrowserNoirProvider.getBrowserInfo()
// Check mobile compatibility
const compat = BrowserNoirProvider.checkMobileCompatibility()
// Returns: { score: number, issues: string[], sharedArrayBuffer: boolean, ... }
// Get recommended config for device
const config = BrowserNoirProvider.getRecommendedConfig()
type ProofProgressCallback = (progress: {
stage: 'initializing' | 'witness' | 'proving' | 'verifying' | 'complete'
percent: number
message: string
}) => void

Testing provider that generates deterministic fake proofs.

import { MockProofProvider } from '@sip-protocol/sdk'
const provider = new MockProofProvider({ silent: true })
await provider.initialize()
// Check if a proof is mock
const isMock = MockProofProvider.isMockProof(proof)

Warning: Mock proofs provide NO cryptographic security. Use only for testing.

Generates ZK proofs for regulatory compliance without revealing sensitive data.

import { ComplianceProofProvider } from '@sip-protocol/sdk'
const provider = new ComplianceProofProvider({
defaultValidityPeriod: 86400, // 24 hours
jurisdictions: ['US', 'EU', 'UK'],
})
await provider.initialize()
type ComplianceProofType =
| 'viewing_key_access' // Prove viewing key can decrypt transaction
| 'sanctions_clear' // Prove no sanctions list matches
| 'balance_attestation' // Prove balance meets requirement
| 'history_complete' // Prove complete transaction history
const result = await provider.generateViewingKeyAccessProof({
viewingKey: myViewingKey,
transactionHash: '0x...',
encryptedData: new Uint8Array([...]),
auditorPublicKey: '0x...',
timestamp: Date.now(),
chainId: 'solana', // optional
})
const result = await provider.generateSanctionsClearProof({
senderAddress: '0x...',
recipientAddress: '0x...',
senderBlinding: randomBytes(32),
recipientBlinding: randomBytes(32),
sanctionsListRoot: '0x...',
checkTimestamp: Date.now(),
jurisdiction: 'US',
})
const result = await provider.generateBalanceAttestationProof({
balance: 1000000n,
blindingFactor: randomBytes(32),
minimumRequired: 500000n,
assetId: 'SOL',
accountCommitment: '0x...',
attestationTime: Date.now(),
})
const result = await provider.generateHistoryCompletenessProof({
transactionCount: 42,
historyMerkleRoot: '0x...',
startTimestamp: startOfYear,
endTimestamp: Date.now(),
volumeCommitment: '0x...',
viewingKey: myViewingKey,
})
interface FundingProofParams {
/** User's actual balance (private) */
balance: bigint
/** Minimum amount required (public) */
minimumRequired: bigint
/** Blinding factor for commitment (private) */
blindingFactor: Uint8Array
/** Asset identifier (public) */
assetId: string
/** User's address (private) */
userAddress: string
/** Signature proving ownership (private) */
ownershipSignature: Uint8Array
}
interface ValidityProofParams {
/** Hash of the intent (public) */
intentHash: HexString
/** Sender's address (private) */
senderAddress: string
/** Blinding factor for sender commitment (private) */
senderBlinding: Uint8Array
/** Sender's secret key (private) */
senderSecret: Uint8Array
/** Signature authorizing the intent (private) */
authorizationSignature: Uint8Array
/** Nonce for nullifier generation (private) */
nonce: Uint8Array
/** Intent timestamp (public) */
timestamp: number
/** Intent expiry (public) */
expiry: number
/** Optional: Pre-computed sender public key */
senderPublicKey?: PublicKeyXY
}
interface FulfillmentProofParams {
/** Hash of the original intent (public) */
intentHash: HexString
/** Actual output amount delivered (private) */
outputAmount: bigint
/** Blinding factor for output commitment (private) */
outputBlinding: Uint8Array
/** Minimum required output (public) */
minOutputAmount: bigint
/** Recipient's stealth address (public) */
recipientStealth: HexString
/** Solver's identifier (public) */
solverId: string
/** Solver's secret (private) */
solverSecret: Uint8Array
/** Oracle attestation of delivery (private) */
oracleAttestation: OracleAttestation
/** Time of fulfillment (public) */
fulfillmentTime: number
/** Intent expiry (public) */
expiry: number
}
interface OracleAttestation {
recipient: HexString
amount: bigint
txHash: HexString
blockNumber: bigint
signature: Uint8Array
}
interface ProofResult {
/** The generated ZK proof */
proof: ZKProof
/** Public inputs used in the proof */
publicInputs: HexString[]
/** Commitment (if generated) */
commitment?: Commitment
}
interface ZKProof {
type: 'funding' | 'validity' | 'fulfillment'
proof: HexString
publicInputs: HexString[]
}
import { ProofGenerationError, ProofError, ErrorCode } from '@sip-protocol/sdk'
try {
await provider.generateFundingProof(params)
} catch (error) {
if (error instanceof ProofGenerationError) {
console.log(error.proofType) // 'funding' | 'validity' | 'fulfillment'
console.log(error.cause) // Original error
}
if (error instanceof ProofError) {
console.log(error.code) // ErrorCode enum
}
}
enum ErrorCode {
PROOF_PROVIDER_NOT_READY = 'PROOF_PROVIDER_NOT_READY',
PROOF_NOT_IMPLEMENTED = 'PROOF_NOT_IMPLEMENTED',
VALIDATION_FAILED = 'VALIDATION_FAILED',
// ... other codes
}
import {
isBrowser,
supportsWebWorkers,
supportsSharedArrayBuffer,
getBrowserInfo,
hexToBytes,
bytesToHex,
} from '@sip-protocol/sdk'
import {
DEFAULT_VALIDITY_PERIOD_SECONDS, // 86400 (24 hours)
SUPPORTED_JURISDICTIONS, // ['US', 'EU', 'UK', 'SG', 'CH', 'GLOBAL']
COMPLIANCE_CIRCUIT_IDS, // { viewing_key_access: '...', ... }
} from '@sip-protocol/sdk'
import { SIP } from '@sip-protocol/sdk'
import { NoirProofProvider } from '@sip-protocol/sdk/proofs/noir'
const proofProvider = new NoirProofProvider()
await proofProvider.initialize()
const sip = new SIP({
network: 'mainnet',
proofProvider,
})

For Next.js and other SSR frameworks, use MockProofProvider as a placeholder:

// Server-side (no WASM)
const provider = new MockProofProvider({ silent: true })
// Client-side hydration
if (typeof window !== 'undefined') {
const { BrowserNoirProvider } = await import('@sip-protocol/sdk/browser')
const realProvider = new BrowserNoirProvider()
await realProvider.initialize()
}