Read the callback context
Use authenticated identity, a consistent Clock, typed amounts, and bounded account access.
Every callback receives a versioned HookInvocation. Decode it with the current ABI and authenticate the core caller before using its fields. The SDK's hook resolver prepares accounts and payload; it does not establish identity or replace on-chain checks.
Identity and execution context
| Field | Meaning | Integration rule |
|---|---|---|
pool, mint_a, mint_b | Core-selected pool and reserve pair | Validate the bound pool, never a caller's substitute |
actor | Authenticated operation authority | It can be a router PDA; do not assume an end-user wallet |
phase | One of the ten lifecycle callbacks | Match the reply to the current phase |
operation_sequence | Pool operation counter | It is not randomness, a signature, or a cross-transaction reservation |
clock.slot, clock.unix_timestamp | Runtime Clock captured for this operation | Use the same captured time for before/after policy evaluation |
before, after | Typed pool snapshots; after is optional | Use the snapshot appropriate to the phase |
payload | Caller-supplied bytes, at most 512 | Validate shape and proofs; bytes alone grant no authority |
account_access | Descriptors for declared extras | Validate exact roles as well as ownership |
The Clock is read once for the operation and shared by its callback pair. A failed transaction rolls back the sequence and other state changes. The core serializes the entered pool before CPI; authentication checks this invocation state.
Requested amounts and actual settlement
HookOperationDetails distinguishes initialization, swaps, liquidity changes, and donations. All financial quantities are integers in native units. Pool snapshots include signed ticks, Q64 square-root price, active liquidity, and fee-growth values.
For a swap, HookSwapDetails includes direction, mode, reserve mints, input/output accounts, input authority, output owner, request bounds, and price limit. A before callback evaluates the request. An after callback can inspect settled:
| Settled field | Meaning |
|---|---|
consumed_input | Actual gross input consumed |
net_input | Input used for pricing after the trading fee |
actual_output | Net output delivered after any output fee |
output_fee_amount | Separately charged output fee |
unspent_input | Request input left unspent |
fee_amount, fee_ppm | Actual trading fee and effective rate |
Rewards based on received output must use actual_output. A requested amount is not a receipt. Read lifecycle timing for ExactOut field mapping, partial fills, liquidity deltas, and donation context. Protocol retention partitions the existing trading fee; it does not increase consumed_input or introduce another hook callback.
Extra accounts and nested CPI
The core passes its hook-authority PDA as a read-only signer, the pool read-only, and validated extras with phase-specific privileges. The actor's signature and the vault authority are not forwarded. Pool permissions and each operation's descriptors must both permit a write.
Declare external programs and state explicitly. Check exact PDAs, owners, discriminators, mints, authorities, and pool/actor relationships inside the hook. A hook may sign for its own PDA when calling another program; this cannot authorize spending the AMM vaults. Calling the core back from the hook is not a supported settlement path.
Continue with account permissions, policy composition, and the exact Hook ABI.