Pre-Intent Hooks
Overview
OrchestratorV3 supports one optional pre-intent hook per EscrowV2 deposit. It
runs during signalIntent before intent state is committed or funds are
locked. A hook approves by returning normally and rejects by reverting.
The pre-intent hook is distinct from the global lifecycle hook. Production's
WhitelistLifecycleHook enforces Groups and direct-wallet access policies;
deposit owners do not place that policy hook in the pre-intent slot.
Interface
interface IPreIntentHook {
struct PreIntentContext {
address taker;
address escrow;
uint256 depositId;
uint256 amount;
address to;
bytes32 paymentMethod;
bytes32 fiatCurrency;
uint256 conversionRate;
IReferralFee.ReferralFee[] referralFees;
bytes preIntentHookData;
}
function validateSignalIntent(PreIntentContext calldata ctx) external;
}
Source: zkp2p-contracts/contracts/interfaces/IPreIntentHook.sol
Signature gating
SignatureGatingPreIntentHook is the built-in generic hook. A configurable
signer authorizes a deposit's intent parameters with an EIP-191 signature.
The signed message binds the orchestrator, escrow, deposit, amount, taker,
recipient, payment method, fiat currency, conversion rate, referral fees,
expiration, and chain ID.
- The depositor or delegate calls
orchestrator.setDepositPreIntentHook(escrow, depositId, hookAddress). - The depositor configures the signer on the hook.
- The taker ABI-encodes the signature and expiration in
SignalIntentParams.preIntentHookData.
Base address:
0x62D410a3d6FC766dd2192be2a67a5fc79c5c2e1F.
Groups and direct-wallet access
Current access policies do not use a second pre-intent slot. Instead:
- The deposit owner configures
WhitelistPolicywith Public or Restricted access, direct taker wallets, and up to ten allowed Group IDs. - OrchestratorV3 snapshots the governance-selected lifecycle hook when an intent is signaled.
- The production
WhitelistLifecycleHookcalls the policy fromonIntentSignaledbefore funds are locked. - A Public policy passes. A Restricted policy passes only for a directly listed taker or a current member of one of the allowed Groups.
Group membership lives in AddressGroupRegistry and is managed by each
Group's curator, future curator, or resolver. Policy writes remain
depositor-only.
See Access Groups for the product flow.
Legacy V2 whitelist hook
OrchestratorV2 had two deposit hook slots: generic and whitelist. Its
WhitelistPreIntentHook deployment remains documented for integrations that
own existing V2 deposits or intents, but it is not the current Groups access
path and OrchestratorV3 does not expose setDepositWhitelistHook.
Writing a custom pre-intent hook
- Implement
IPreIntentHook.validateSignalIntent(ctx). - Revert with a specific error to reject; return normally to approve.
- Read
ctx.preIntentHookDatafor request-specific validation data. - Have the depositor or delegate set the contract through
setDepositPreIntentHook.
Keep validation deterministic and cheap. A hook failure reverts the complete
signalIntent transaction.