Developers
Route through Socket
For routers and aggregators. One integration reaches every Socket pool, whatever hook it has, as long as you read the hook's accounts from the pool and simulate.
Every Socket pool has the same program, the same swap instruction and the same fixed accounts. Hook-specific accounts come from a list stored with the pool, so a router needs no code per hook. What it does need is a policy for which hooks it trusts.
The integration#
Discover pools
Read all pool accounts of the Socket program (8,192 bytes, tag
SOCKPOOL), or page throughGET /poolson a Socket API. Decode with the SDK'sdecodePool, which checks the owner, size, tag, version and parameters, then callvalidatePoolAddressto check the account sits at the address its creator and nonce derive.Check the hook
A pool with the System Program as its hook has no hook. Otherwise, route only if the hook program is on your allowlist. A pool's hook address never changes, but an upgradeable hook program's code can, so review the upgrade authority too.
Resolve the hook's accounts
Read the hook account list at
["extra-account-metas", pool]. It lists up to eight accounts, each with its expected owner and write access. Fetch them and check that each exists with that owner. Append them to the swap in the listed order.Quote
Run the swap through the SDK's math port with the pool's state and ticks, or call
POST /quote/swap. For the built-in hooks, the SDK also reproduces the dynamic fee (dynamicFeeAt) and the range-order guard (rangeOrderAfterSwap). An external hook's fee and behavior can't be predicted from state; quote it at the base fee and let simulation decide.Build and simulate
Build the swap with
swapInstruction, set a compute limit, and simulate. A failed simulation is a clean answer: the pool can't take this trade right now. Route elsewhere.
Swap accounts#
| # | Account | Writable | Signer |
|---|---|---|---|
| 0 | Swapper | ✓ | |
| 1 | Pool | ✓ | |
| 2 | Swapper's token A account | ✓ | |
| 3 | Swapper's token B account | ✓ | |
| 4 | Vault A | ✓ | |
| 5 | Vault B | ✓ | |
| 6 | SPL Token program | ||
| 7 | Hook account list | ||
| 8 | Hook program (System Program if none) | ||
| 9 | Hook authority | ||
| 10+ | The hook's extra accounts, as listed | as listed |
No tick arrays, no oracle accounts, no per-hook additions beyond the list. A pool with a built-in hook adds exactly one account, its hook state.
Swap arguments#
| Field | Type | Meaning |
|---|---|---|
amount | u64 | Input for exact-in, output for exact-out. |
limit | u128 | Square-root price limit, strictly on the swap's side of the current price. The SDK turns 0 into the domain end. |
a_to_b | bool | Sell A for B (price falls) or B for A (price rises). |
exact_in | bool | Which side amount fixes. |
threshold | u64 | Exact-in: minimum output. Exact-out: maximum input including any surcharge. |
max_total_input | u64 | An explicit cap on CLMM input plus surcharge. |
Hooks a router should know#
| Hook | What can differ from a plain pool |
|---|---|
| No hook | Nothing. |
| No-op | Compute only. |
| Dynamic fee | The fee rises after price moves and decays per second. Reproducible from hook state with dynamicFeeAt. |
| TWAP oracle | Compute only. The fee is the base fee. |
| Range order | Liquidity is one owner's order. After a fill, swaps back into the range revert until the owner withdraws. Check with rangeOrderAfterSwap or the quote's blocked field. |
| External | Anything within the pool's bounds: a fee up to the max fee, a surcharge up to the cap, refusals. Allowlist and simulate. |
Compute#
A swap's compute depends on the ticks it crosses and the hook's calls. Measured costs for this build are on the No-op page. Each pool's hook_budget bounds what one hook call may use, but it can't reserve compute: set the transaction's compute limit from simulation, with headroom. Transactions prepared by the Socket API set a limit of 1,000,000 units unless the request asks for another value between 10,000 and 1,400,000.
Multi-hop#
Each Socket pool has its own vaults, so a route through two Socket pools is two swap instructions, each settling separately. Both can sit in one transaction; if either fails, both revert.