HookForge

Docs

TypeScript SDK

@hookforge/sdk ships the generated catalogue, the address book and the small amount of v4 maths a client needs, with no runtime dependencies. It is the same data the website and the MCP server are built from.

Install

npm i @hookforge/sdk

Query the catalogue

import {hooks, getHook, hooksByTag, hooksByFamily} from "@hookforge/sdk";

hooks.length;                       // every shipped hook
getHook("depeg-shield");            // one manifest summary
hooksByTag("mev");                  // everything tagged mev
hooksByFamily("Risk");              // everything in the risk family

Resolve an address

hookAddress returns the address for a hook on a chain, or null when that hook has no entry there. Check status before treating one as live: a deterministic address is where the hook will be, not where it is.

import {hookAddress, deploymentsFor, poolManagerFor} from "@hookforge/sdk";

hookAddress("arb-tax-decay", 8453);      // Base
deploymentsFor("arb-tax-decay");         // every chain, each with a status
poolManagerFor(4663);                    // Robinhood Chain PoolManager

Build a pool key

poolKeyFor sorts the currencies the way v4 requires, sets the dynamic-fee flag when the hook needs it, and returns a key whose poolId matches keccak256(abi.encode(key)) byte for byte. That equality is asserted in the SDK's tests against values produced by Solidity.

import {poolKeyFor, poolId} from "@hookforge/sdk";

const key = poolKeyFor({
  hook: hookAddress("depeg-shield", 42161),
  currencyA: USDC, currencyB: USDT,
  tickSpacing: 1, dynamicFee: true,
});
poolId(key); // 0x…

Decode any hook address

This works on any v4 hook, not only ours: the flags are in the address, so the answer needs no network call and no registry.

import {permissionsOf} from "@hookforge/sdk";

permissionsOf("0x1A0e586A71F401c2E511c7e6fAf7197112915080");
// { beforeSwap: true, afterInitialize: true, ... }