Overview
An intent represents a buyer’s commitment to pay off-chain fiat currency in exchange for on-chain tokens. This page walks through the complete lifecycle from signal to fulfillment, showing all contract interactions and state changes.The intent lifecycle is the core workflow of the zkp2p protocol, coordinating between Orchestrator, Escrow, payment verifiers, and registries.
Lifecycle Stages
Stage 1: Discovery
The buyer browses available deposits (off-chain indexing or on-chain queries) to find one matching their requirements:Stage 2: Gating Service (Optional)
If the deposit has aintentGatingService, the buyer must obtain a signature:
Request Signature
Gating Service Validation
The gating service may:- Perform KYC/AML checks
- Verify the buyer is on an allowlist
- Check reputation scores
- Rate-limit signaling frequency
- Enforce geographic restrictions
If the deposit has no gating service (
intentGatingService == address(0)), this stage is skipped.Stage 3: Signal Intent
The buyer callssignalIntent() on the Orchestrator.
Transaction Flow
Code Example
State Changes
Orchestrator:- Creates Intent struct with all parameters
- Adds intent hash to
accountIntents[buyer] - Stores
intentMinAtSignal[intentHash](deposit’s min amount at signal time) - Increments
intentCounter
- Validates deposit is accepting intents
- Validates amount is within deposit’s
intentAmountRange - Prunes expired intents if liquidity is needed
- Moves
amountfromremainingDepositstooutstandingIntentAmount - Creates Intent struct with
expiryTime = timestamp + intentExpirationPeriod - Adds intent hash to
depositIntentHashes[depositId]
Validation Checks
The Orchestrator performs extensive validation:- Multiple Intent Check: Buyer must be whitelisted relayer OR
allowMultipleIntents == true - Zero Address Check:
toaddress must not be zero - Fee Validation: Referrer fee ≤ 50%, and must be 0 if no referrer
- Hook Validation: If post-intent hook set, must be whitelisted
- Escrow Validation: Must be whitelisted OR registry accepts all escrows
- Payment Method: Must exist in PaymentVerifierRegistry and be active on deposit
- Currency: Must be supported by payment method with non-zero min rate
- Conversion Rate: Must be ≥ deposit’s min conversion rate
- Gating Signature: If deposit has gating service, signature must be valid and not expired
Stage 4: Awaiting Payment
After signaling, the buyer hasintentExpirationPeriod (configured on Escrow) to complete the off-chain payment.
Buyer Actions
- Make Off-Chain Payment: Send fiat to the depositor’s payment account (Venmo username, PayPal email, etc.)
- Include Intent Hash: Some payment methods allow notes/memos - buyer should include intent hash
- Wait for Confirmation: Payment service confirms transaction
Intent Status
Stage 5: Payment Attestation
Once the off-chain payment is confirmed, an attestation service generates a cryptographic proof.Attestation Service Flow
Constructing the Attestation
Stage 6: Fulfill Intent
Anyone can submit the attestation to fulfill the intent.Transaction Flow
Code Example
State Changes
Verifier:- Validates attestation signatures
- Adds payment ID to NullifierRegistry
- Emits
PaymentVerifiedevent
- Deletes Intent from storage
- Removes intent hash from
accountIntents - Deletes
intentMinAtSignal - Emits
IntentPrunedandIntentFulfilledevents
- Moves amount from
outstandingIntentAmountback to available balance - Deletes Intent struct
- Removes intent hash from
depositIntentHashes - Transfers tokens to Orchestrator
- May close deposit if dust threshold reached
- Emits
FundsUnlockedAndTransferredevent
Fee Distribution
Alternative Paths
Path A: Cancellation
If the buyer changes their mind before making payment:- Orchestrator validates caller is intent owner
- Orchestrator deletes intent from storage
- Orchestrator calls
escrow.unlockFunds(depositId, intentHash) - Escrow returns amount to
remainingDeposits - Escrow deletes intent from storage
- Buyer found better rate elsewhere
- Payment service is down
- Buyer doesn’t have sufficient fiat balance
Path B: Expiration
If the intent is not fulfilled beforeexpiryTime:
- Escrow iterates through
depositIntentHashes[depositId] - For each expired intent (
block.timestamp > expiryTime):- Return amount to
remainingDeposits - Delete intent from storage
- Remove from
depositIntentHashes - Emit
FundsUnlockedevent
- Return amount to
- Escrow calls
orchestrator.pruneIntents(expiredIntents) - Orchestrator deletes each intent from storage
- Depositor calls
removeFunds()orwithdrawDeposit() - New intent is signaled and liquidity is needed
- Anyone calls
pruneExpiredIntents()
Path C: Manual Release
If there’s a dispute or special arrangement, the depositor can manually release funds:- Orchestrator validates caller is the deposit’s depositor
- Orchestrator deletes intent from storage
- Orchestrator calls
escrow.unlockAndTransferFunds()with full intent amount - Escrow transfers tokens to Orchestrator
- Orchestrator calculates and transfers fees
- Orchestrator transfers net amount to buyer
- Emit
IntentFulfilled(intentHash, to, netAmount, isManualRelease: true)
Intent States Summary
| State | Description | Can Cancel? | Can Fulfill? | Liquidity |
|---|---|---|---|---|
| Signaled | Intent active, awaiting payment | Yes (owner) | Yes (anyone) | Locked |
| Expired | Past expiryTime, not yet pruned | No | No | Locked |
| Cancelled | Owner cancelled before fulfillment | N/A | N/A | Released |
| Fulfilled | Payment verified and released | N/A | N/A | Transferred |
| Pruned | Expired and cleaned up | N/A | N/A | Released |
| Released | Manually released by depositor | N/A | N/A | Transferred |
Timeline Example
Best Practices
Monitor Expiry
Buyers should complete payment well before
expiryTime to account for attestation delaysInclude Intent Hash
If payment service supports memos, include intent hash for faster attestation matching
Use Relayers
Buyers can outsource fulfillment submission to relayers to save gas and improve UX
Verify Deposit
Before signaling, verify deposit has sufficient liquidity and acceptable parameters
Related Contracts
- Orchestrator - Manages intent lifecycle
- Escrow - Locks and releases liquidity
- Payment Verification - Validates off-chain payments
- Registry System - Whitelisting and configuration