General Protocol
What is ZKP2P?
What is ZKP2P?
- Direct P2P fiat-to-crypto exchanges without intermediaries
- Support for 8+ major payment platforms (Venmo, PayPal, Wise, etc.)
- Privacy-preserving payment verification using zkTLS attestations
- Intent-based architecture for efficient liquidity matching
How does the protocol ensure trustless trading?
How does the protocol ensure trustless trading?
- Escrow Locking: Maker’s USDC is locked in the Escrow contract when a taker signals intent
- Payment Verification: Off-chain payments are verified using EIP-712 signed attestations from trusted witnesses
- Nullifier Registry: Prevents double-spending by tracking used payment IDs
- Atomic Settlement: Funds are only released after successful payment verification
- Smart Contract Enforcement: All rules are enforced on-chain with no trusted intermediary
What are the main use cases?
What are the main use cases?
- On-ramp: Buy USDC with fiat through supported payment platforms (Venmo, PayPal, Wise, etc.)
- Off-ramp: Sell USDC for fiat with guaranteed settlement
- Cross-border: Access global liquidity through multiple payment rails
- P2P Trading: Direct peer-to-peer exchanges without centralized exchanges
Which networks are supported?
Which networks are supported?
- Base (Production): Fully operational mainnet deployment
- Base Sepolia (Testnet): For testing and development
- Base Staging: Internal staging environment
deployments/ directory.Payment Methods
Which payment platforms are supported?
Which payment platforms are supported?
- Venmo (USD)
- PayPal (USD)
- CashApp (USD, GBP)
- Zelle - Citibank, Chase, Bank of America (USD)
- Chime (USD)
- Wise (30+ currencies)
- Revolut (20+ currencies)
- Monzo (GBP, EUR, USD)
- N26
- MercadoPago (7 countries)
- Alipay
How are payments verified?
How are payments verified?
- Off-chain Payment: Taker sends fiat payment through their chosen platform
- Attestation Generation: Payment receipt is converted to a zkTLS proof
- Witness Signing: Trusted witness signs the payment attestation (EIP-712)
- On-chain Verification: UnifiedPaymentVerifier validates:
- Witness signature authenticity
- Payment details match intent (amount, payee, method, currency)
- Payment timestamp within acceptable buffer
- Payment ID hasn’t been used before (nullifier check)
- Settlement: If valid, USDC is released to taker
contracts/unifiedVerifier/UnifiedPaymentVerifier.sol:128 for implementation details.Can I add a new payment method?
Can I add a new payment method?
- Create a verifier configuration in
deployments/verifiers/your-method.ts - Define the payment method hash using
calculatePaymentMethodHash("method-name") - Specify supported currencies
- Create deployment script in
deploy/ - Register with UnifiedPaymentVerifier and PaymentVerifierRegistry
What is a payment method hash?
What is a payment method hash?
- Venmo:
0x90262a3db0edd0be2369c6b28f9e8511ec0bac7136cefbada0880602f87e7268 - Wise:
0x554a007c2217df766b977723b276671aee5ebb4adaea0edb6433c88b3e61dac5 - Revolut:
0x617f88ab82b5c1b014c539f7e75121427f0bb50a4c58b187a238531e7d58605d
Architecture & Components
What is the Escrow contract?
What is the Escrow contract?
- Deposit Management: Makers create deposits with USDC and specify accepted payment methods
- Fund Custody: Securely holds liquidity until trades are completed
- Configuration: Enforces intent limits, expiry periods, dust thresholds
- Fee Collection: Collects maker fees on successful trades
- Lock/Unlock: Orchestrator can lock/unlock funds during intent processing
contracts/Escrow.solWhat is the Orchestrator contract?
What is the Orchestrator contract?
- Intent Management: Handles signaling, fulfilling, and canceling intents
- Gating: Validates optional gating signatures for access control
- Fund Coordination: Locks/unlocks funds on Escrow during processing
- Verification Routing: Routes verification requests to appropriate verifiers via registry
- Fee Distribution: Collects and distributes protocol/referrer fees
- Hook Execution: Executes optional post-intent hooks for custom logic
contracts/Orchestrator.solWhat is the UnifiedPaymentVerifier?
What is the UnifiedPaymentVerifier?
- Replaces individual payment verifiers (VenmoVerifier, PayPalVerifier, etc.)
- Validates EIP-712 signed attestations from off-chain services
- Configurable per payment method (currencies, timestamp buffers)
- Nullifies payments to prevent double-spending
- Enforces timestamp buffers for L2 flexibility (max 48 hours)
- Single contract to upgrade/manage
- Consistent verification logic across all methods
- Easy to add new payment methods
- Reduced deployment and maintenance costs
contracts/unifiedVerifier/UnifiedPaymentVerifier.solWhat are the Registry contracts?
What are the Registry contracts?
contracts/registries/What is the Protocol Viewer?
What is the Protocol Viewer?
- Optimized for frontend queries and analytics
- Batched data fetching for UI performance
- No state modification, only view functions
- Reduces number of RPC calls needed by frontends
Integration
How do I create a deposit as a maker?
How do I create a deposit as a maker?
contracts/Escrow.sol for complete function signatures.How do I signal an intent as a taker?
How do I signal an intent as a taker?
contracts/Orchestrator.sol:signalIntent for details.How do I fulfill an intent with a payment proof?
How do I fulfill an intent with a payment proof?
test/unifiedVerifier/unifiedPaymentVerifier.spec.ts for examples.How do I query available deposits?
How do I query available deposits?
What TypeScript types are available?
What TypeScript types are available?
typechain/ directory.Security & Privacy
How is privacy preserved?
How is privacy preserved?
- Hashed Identifiers: Payment IDs and payee details are hashed on-chain
- Off-chain Proofs: Sensitive payment details stay off-chain, only proofs are submitted
- Zero-Knowledge: zkTLS proofs verify payments without revealing full data
- Event Emissions: Only necessary data is emitted in events for reconciliation
How is double-spending prevented?
How is double-spending prevented?
- Each payment creates a unique nullifier:
keccak256(abi.encodePacked(paymentMethod, paymentId)) - Nullifier is checked before verification
- If already used, transaction reverts
- If new, nullifier is added to registry after successful verification
- Nullifiers are permanent and cannot be removed
contracts/unifiedVerifier/UnifiedPaymentVerifier.sol:242 for implementation.What are the security assumptions?
What are the security assumptions?
- Trusted Witnesses: Attestation signers are trusted to accurately verify off-chain payments
- Smart Contract Security: Contracts have been audited but use at your own risk
- Payment Platform Integrity: Payment platforms (Venmo, PayPal, etc.) accurately report transaction data
- Timestamp Accuracy: L2 timestamps are reasonably accurate (within buffer window)
- Registry Permissions: Only authorized addresses can modify critical registries
What happens if a payment proof is invalid?
What happens if a payment proof is invalid?
- Transaction reverts with specific error message
- Intent remains locked (can be canceled after expiry)
- No USDC is transferred
- No nullifier is created (payment can be attempted again with valid proof)
- Taker can retry with corrected proof or cancel intent
- Invalid witness signature
- Payment details don’t match intent
- Payment ID already used (double-spend attempt)
- Timestamp outside acceptable buffer
- Payment amount insufficient
Development
How do I set up the development environment?
How do I set up the development environment?
- Node.js 18+
- Yarn 4
- Foundry (for
forge)
How do I run tests?
How do I run tests?
test/ (Hardhat) and test-foundry/ (Foundry).How do I deploy to a network?
How do I deploy to a network?
deploy/ directory (00-17). They run sequentially.Deployment artifacts saved to deployments/{network}/.What build tools are used?
What build tools are used?
- Hardhat: Primary development framework
- Foundry: Fuzz and invariant testing
- Typechain: TypeScript bindings generation
- Ethers.js: Ethereum library
- Waffle: Testing utilities
- Hardhat Deploy: Deployment management
Fees & Economics
What fees does the protocol charge?
What fees does the protocol charge?
- Maker Fee: Fee charged to liquidity providers on successful trades (configured per deposit)
- Protocol Fee: Fee collected by the protocol (configured in Orchestrator)
- Referrer Fee: Optional fee for referrers who bring users
contracts/Orchestrator.sol for fee distribution logic.How are conversion rates handled?
How are conversion rates handled?
- 100 = 1:1 (1 USD = 1 USDC)
- 105 = 1.05:1 (1 USD = 1.05 USDC)
- 98 = 0.98:1 (1 USD = 0.98 USDC)
contracts/Escrow.sol for rate configuration.What are the minimum/maximum trade amounts?
What are the minimum/maximum trade amounts?
- Configured per deposit and payment method by maker
- Prevents dust trades and ensures economic viability
- Typically 10 USDC or equivalent
- Limited by deposit available liquidity
- No protocol-level maximum
- Payment platforms may have their own limits
- Escrow has a global dust threshold (typically 10 USDC)
- Deposits must be above dust threshold
- Prevents griefing with tiny deposits
contracts/Escrow.sol constructor for dust threshold configuration.Need More Help?
If your question isn’t answered here:- Check the Troubleshooting Guide
- Review the API Reference
- Read the Contract Documentation
- Visit docs.zkp2p.xyz
- Open an issue on GitHub