Pool API
The Pool API lists every Uniswap v4 pool initialized on Robinhood Chain and reads live state straight from the PoolManager via StateView.
| Endpoint | What it does |
|---|---|
GET /v1/pools |
Indexed pools, newest first |
GET /v1/pools/:poolId |
Live state by PoolId |
POST /v1/pools/state |
Live state by pool key |
POST /v1/pools/id |
PoolId for a pool key (pure, no chain call) |
GET /v1/stats |
Index totals and v4 contract addresses |
Pool keys and ids
Section titled “Pool keys and ids”A v4 pool is identified by its key:
| Field | Notes |
|---|---|
currency0, currency1 |
Token addresses, sorted ascending. Native ETH is 0x0000000000000000000000000000000000000000 |
fee |
LP fee in hundredths of a bip (500 = 0.05%, 3000 = 0.30%), or 8388608 (0x800000) for a dynamic-fee pool |
tickSpacing |
1 to 32767 |
hooks |
Hook address, or the zero address for none |
The PoolId is keccak256(abi.encode(key)). HookKit accepts currencies in either
order and sorts them for you.
curl -X POST https://api.hookkit.dev/v1/pools/id \ -H "content-type: application/json" \ -d '{ "currency0": "0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168", "currency1": "0x0000000000000000000000000000000000000000", "fee": 500, "tickSpacing": 10 }'{ "poolId": "0x387bf619da4d3fb62bb276482693dba1b9b3520f573cabdfe033384a24125982", "key": { "currency0": "0x0000000000000000000000000000000000000000", "currency1": "0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168", "fee": 500, "tickSpacing": 10, "hooks": "0x0000000000000000000000000000000000000000" }, "sorted": true}sorted: true means the currencies you passed were swapped into canonical order.
List pools
Section titled “List pools”curl "https://api.hookkit.dev/v1/pools?hooked=true&limit=2"| Param | Notes |
|---|---|
hook |
Only pools using this hook |
token |
Only pools containing this token (either side) |
hooked |
true for pools with a hook, false for pools without |
limit |
1 to 100, default 25 |
offset |
Default 0 |
{ "total": 103805, "pools": [ { "poolId": "0x641df1e1715c14a6ed27188b42f1b0ac0cc58dc8ce86ca18fd1810addb97eddc", "key": { "currency0": "0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73", "currency1": "0xe8C701e699e6027654A5634732EC67914BD13Ba3", "fee": 8388608, "tickSpacing": 200, "hooks": "0x4e3468951D49f2EEa976eD0D6e75fFCb44a9a544" }, "pair": "WETH/?", "currency0": { "address": "0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73", "symbol": "WETH", "decimals": 18 }, "currency1": { "address": "0xe8C701e699e6027654A5634732EC67914BD13Ba3", "symbol": null, "decimals": null }, "hooked": true, "dynamicFee": true, "createdBlock": 29508840, "createdAt": "2026-08-06T16:55:59.000Z", "txHash": "0x8fcadfefee6ecc0ead8a6f072f15fd72ce1c07221bb6bdcdc1f14067721e4050" } ], "limit": 2, "offset": 0}List results carry token metadata from the index; symbol and decimals are
null for tokens HookKit has not read yet. The live state endpoints below
always read metadata onchain.
Live pool state
Section titled “Live pool state”curl https://api.hookkit.dev/v1/pools/0x641df1e1715c14a6ed27188b42f1b0ac0cc58dc8ce86ca18fd1810addb97eddc{ "poolId": "0x641df1e1715c14a6ed27188b42f1b0ac0cc58dc8ce86ca18fd1810addb97eddc", "key": { "currency0": "0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73", "currency1": "0xe8C701e699e6027654A5634732EC67914BD13Ba3", "fee": 8388608, "tickSpacing": 200, "hooks": "0x4e3468951D49f2EEa976eD0D6e75fFCb44a9a544" }, "currency0": { "address": "0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73", "symbol": "WETH", "name": "WETH", "decimals": 18 }, "currency1": { "address": "0xe8C701e699e6027654A5634732EC67914BD13Ba3", "symbol": "LARP", "name": "Live Action Roleplay", "decimals": 18 }, "dynamicFee": true, "hooked": true, "state": { "initialized": true, "sqrtPriceX96": "10872425402858764347486285145759394", "tick": 236600, "liquidity": "0", "lpFee": 7000, "lpFeePercent": 0.7, "protocolFee": 0 }, "price": { "WETH/LARP": 18831881196.75212, "LARP/WETH": 5.310143949784831e-11 }, "hook": { "address": "0x4e3468951D49f2EEa976eD0D6e75fFCb44a9a544", "enabled": ["beforeInitialize", "afterAddLiquidity", "afterRemoveLiquidity", "afterSwap", "afterSwapReturnDelta"], "capabilities": [ { "level": "warning", "flag": "afterSwapReturnDelta", "note": "Can charge or rebate tokens after each swap, e.g. a hook fee on top of the LP fee." }, { "level": "info", "flag": "afterSwap", "note": "Runs after every swap: oracles, points, limit orders, rebalancing." }, { "level": "info", "flag": "initialize", "note": "Runs when a pool is created with this hook (can restrict which pools use it)." } ] }, "created": { "block": 29508840, "txHash": "0x8fcadfefee6ecc0ead8a6f072f15fd72ce1c07221bb6bdcdc1f14067721e4050", "at": "2026-08-06T16:55:59.000Z" }}| Field | Meaning |
|---|---|
state.sqrtPriceX96, state.tick |
Current price as Q64.96 and tick |
state.liquidity |
In-range liquidity. 0 does not always mean “no trades”: hooks with beforeSwapReturnDelta or launchpad-style accounting can still fill swaps |
state.lpFee |
Current LP fee in hundredths of a bip. For dynamic-fee pools this is the fee the hook last set |
state.protocolFee |
Packed protocol fee for both directions |
price |
Spot price both ways, adjusted for decimals |
hook |
Decoded permissions and capability notes, or null |
created |
Initialize block and tx from the index, or null when looked up by key and not indexed |
GET /v1/pools/:poolId needs the pool to be in the HookKit index (to recover its
key). For any pool, indexed or not, pass the key instead:
curl -X POST https://api.hookkit.dev/v1/pools/state \ -H "content-type: application/json" \ -d '{ "currency0": "0x0000000000000000000000000000000000000000", "currency1": "0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168", "fee": 500, "tickSpacing": 10, "hooks": "0x0000000000000000000000000000000000000000" }'A pool that is not in the index returns 404 not_found with a message asking for
the key; an uninitialized key returns 404 not_found as well.
Index stats
Section titled “Index stats”curl https://api.hookkit.dev/v1/stats{ "chain": { "id": 4663, "name": "Robinhood Chain", "explorer": "https://robinhoodchain.blockscout.com", "contracts": { "poolManager": "0x8366a39cc670b4001a1121b8f6a443a643e40951", "positionManager": "0x58daec3116aae6d93017baaea7749052e8a04fa7", "stateView": "0xf3334192d15450cdd385c8b70e03f9a6bd9e673b", "quoter": "0x8dc178efb8111bb0973dd9d722ebeff267c98f94", "universalRouter": "0x204FAca1764B154221e35c0d20aBb3c525710498", "permit2": "0x000000000022D473030F116dDEE9F6B43aC78BA3" } }, "index": { "pools": 288928, "hookedPools": 103805, "uniqueHooks": 4115, "tokens": 10557, "indexedThroughBlock": 29509069, "headBlock": 100855225 }}The index follows PoolManager Initialize events from the PoolManager’s
deployment block. Compare indexedThroughBlock with headBlock to see how far
behind the chain head it is; pools created after indexedThroughBlock are not
listed yet but can always be read by key.
import { HookKit } from "@hookkit/sdk"
const hookkit = new HookKit()
const { pools } = await hookkit.pools.list({ hook: "0x4e3468951D49f2EEa976eD0D6e75fFCb44a9a544", limit: 10 })
const { poolId } = await hookkit.pools.id({ currency0: "0x0000000000000000000000000000000000000000", currency1: "0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168", fee: 500, tickSpacing: 10,})
const byId = await hookkit.pools.get({ poolId })const byKey = await hookkit.pools.get({ currency0: "0x0000000000000000000000000000000000000000", currency1: "0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168", fee: 500, tickSpacing: 10,})
const stats = await hookkit.stats()