TypeScript SDK
@clearproof/proof — generate and verify ZK compliance proofs, and discover counterparty VASPs.
Installation
npm install @clearproof/proofRequires Node.js 18+ and compiled circuit artifacts.
Generate a proof
import { generateProof } from '@clearproof/proof';
const result = await generateProof(
{
// Public inputs
sanctionsTreeRoot: '...',
issuerTreeRoot: '...',
amountTier: 2,
transferTimestamp: Math.floor(Date.now() / 1000),
jurisdictionCode: 840,
credentialCommitment: '...',
tier2Threshold: 3000,
tier3Threshold: 10000,
tier4Threshold: 50000,
credentialNullifier: '0xabc...',
proofExpiresAt: Math.floor(Date.now() / 1000) + 3600,
domainChainId: 11155111, // Sepolia
domainContractHash: '0x...', // keccak256(registry address) % BN128_R
transferIdHash: '0x...', // keccak256(transferId) % BN128_R
// Private inputs: credential preimage
issuerDid: '...',
kycTier: 2,
sanctionsClear: 1,
issuedAt: 1700000000,
expiresAt: 1800000000,
// Private inputs: issuer Merkle membership proof
issuerPathElements: ['...', '...'],
issuerPathIndices: ['0', '1'],
// Private inputs: sanctions non-membership gap proof
walletAddressHash: '...',
leftKey: '...',
rightKey: '...',
leftPathElements: ['...'],
leftPathIndices: ['0'],
rightPathElements: ['...'],
rightPathIndices: ['1'],
// Private inputs: amount
actualAmount: 1500000, // cents (integer arithmetic)
},
'artifacts/compliance_js/compliance.wasm',
'artifacts/compliance_final.zkey',
);
console.log(result.proof); // { pi_a, pi_b, pi_c, protocol, curve }
console.log(result.publicSignals); // string[16]
console.log(result.proofTime); // millisecondsThe SDK maps camelCase field names to the snake_case signal names the Circom circuit expects.
Verify a proof
import { verifyProof } from '@clearproof/proof';
const result = await verifyProof(
proof,
publicSignals,
'artifacts/verification_key.json',
);
console.log(result.valid); // true
console.log(result.isCompliant); // true
console.log(result.sarReviewFlag); // falseDiscover counterparty VASPs
import { discoverVASP, supportsChain } from '@clearproof/proof';
// Discover a VASP by domain
const info = await discoverVASP('exchange.example');
if (info) {
console.log(info.clearproof.endpoint); // https://exchange.example/clearproof/v1
console.log(info.clearproof.publicKey); // encryption public key
console.log(info.clearproof.supportedChains); // [1, 42161, 8453]
}
// Quick check: does this VASP support Ethereum mainnet?
const ok = await supportsChain('exchange.example', 1);Discovery fetches https://<domain>/.well-known/clearproof.json and caches results for 1 hour.
Validation rules
As of v0.2.0, these fields are validated at runtime:
proofExpiresAt— must be greater thantransferTimestamp(not just “in the future”)credentialNullifier— must be non-zero and non-emptydomainChainId— if zero or unset, a warning is logged (proof has no domain binding)
Dependencies
snarkjs^0.7.5 (peer dependency)