You can build custom hooks for specialized tracking beyond what the built-in hooks provide. Use the IHook interface and extend BaseHook for operator access control.
Extend BaseHook and call _verifyAndHash(paymentInfo) to enforce caller and payment-existence checks:
contract MyHook is BaseHook { constructor(address escrow, bytes32 authorizedCodehash) BaseHook(escrow, authorizedCodehash) {} function run( AuthCaptureEscrow.PaymentInfo calldata paymentInfo, uint256 amount, address /* caller */, bytes calldata /* data */ ) external override { bytes32 hash = _verifyAndHash(paymentInfo); // Your recording logic here, keyed by `hash` }}
authorizedCodehash is the runtime codehash of an optional trusted caller (e.g. HookCombinator). Pass bytes32(0) to gate solely on msg.sender == paymentInfo.operator.
Extends BaseHook and uses _verifyAndHash for caller and payment-existence checks
Returns early instead of reverting on business-logic edge cases (a reverting hook permanently bricks the surrounding action)
Gas-efficient storage layout
Full test coverage across the public surface
Unlike conditions, hooks do mutate state. BaseHook._verifyAndHash enforces msg.sender == paymentInfo.operator (or matches AUTHORIZED_CODEHASH) plus payment existence in escrow. Calling _verifyAndHash is mandatory.