Skip to main content

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 IntentLifecycleHookV1 combines whitelist admission with stake-backed dispute protection; 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.

  1. The depositor or delegate calls orchestrator.setDepositPreIntentHook(escrow, depositId, hookAddress).
  2. The depositor configures the signer on the hook.
  3. The taker ABI-encodes the signature and expiration in SignalIntentParams.preIntentHookData.

Base address: 0x62D410a3d6FC766dd2192be2a67a5fc79c5c2e1F.

Historical whitelist admission and stake fallback​

Deposits configured before the Groups retirement can still carry a stored WhitelistPolicy. For those deposits:

  1. OrchestratorV3 snapshots the governance-selected lifecycle hook when an intent is signaled.
  2. The production IntentLifecycleHookV1 checks the stored policy from onIntentSignaled before funds are locked.
  3. An allowed taker bypasses staking. Otherwise the hook evaluates the payment-method-specific DisputeProtectionPolicy route and locks the full intent amount in StakeVault when that route is available.
  4. A restricted intent fails closed when neither route can admit it.

Peer clients no longer publish Group metadata or create and edit these policies. The retained reads and contracts exist only so historical deposits and intents keep their original admission behavior while they settle.

See Stake to Take Protocol for the complete admission and lock lifecycle.

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 admission path and OrchestratorV3 does not expose setDepositWhitelistHook.

Writing a custom pre-intent hook​

  1. Implement IPreIntentHook.validateSignalIntent(ctx).
  2. Revert with a specific error to reject; return normally to approve.
  3. Read ctx.preIntentHookData for request-specific validation data.
  4. Have the depositor or delegate set the contract through setDepositPreIntentHook.

Keep validation deterministic and cheap. A hook failure reverts the complete signalIntent transaction.