Skip to content
Solana

Docs · ReelBook · Guide

Build your own hook

Compose a hook from Hook Blocks, keep it on chain as a saved hook or behind a root of your own, open pools on it, and integrate it as a launchpad or a liquidity app.

The path

On reel a “hook” is not a program you deploy. It is a set of Hook Blocks and settings that a pool freezes into its PoolParams when it opens. You can keep that set on chain and reuse it in three ways, from lightest to heaviest:

  1. Compose and launch. Build the set in the builder and open pools with it directly. Nothing else is stored.
  2. Save it. Write the set as a saved hook, so your launches, or anyone else’s, can follow it by address and version.
  3. Own a root. Open a root of your own: a namespace pools open under, with its own allowed blocks, an optional saved hook and an integrator payee.

Every pool still runs in the one reel program, so your pools keep reel’s launch flow, positions, claims and fee split.

Compose in the builder

The builder places blocks on a board, adds what a block needs, swaps out what it can’t sit beside, and runs the same checks PoolInit runs: the fee-room caps, the one advisory slot, and each block’s bounds. A board travels as a link (/builder?h=…), and the launch floor opens the same board with /launch?draft=…. Every ReelBook recipe links its pools both ways.

Start from a ready-made hook in the builder, or from the catalog of Hook Blocks. Each block page states its settings, bounds, defaults and who is paid.

Save it as a saved hook

HookSave writes an immutable account at ["hook", owner, salt, version]. It holds the PoolParams defaults, the allowed_blocks mask and two fee ceilings: the most LP-fee room a pool may use and the most it may take for anyone but LPs. Version 1 comes first; each later version must be the previous version + 1 from the same owner and salt, and the old versions stay readable.

A pool that names a saved hook at PoolInit must conform: its blocks are a subset of the allowed mask, its LP-fee room is within the ceiling and its takes are within the other. The saved hook’s following count then goes up by one, so anyone can see how many pools follow it.

ts
import { blocksMask, boardOf, poolParams } from "@/lib/blocks"
import { ix, name32 } from "@/sdk/src"

// The blocks your house style allows, with their default settings.
const { board } = boardOf(["anti-snipe", "dynamic-fees", "auto-burn", "lp-rewards"], "new")

const saveIx = ix.hookSave({
  owner: wallet.publicKey,
  salt, // 32 bytes you keep: later versions reuse it
  name: name32("house-launch"),
  version: 1, // or the previous version + 1, same owner and salt
  params: poolParams(board), // defaults a pool starts from
  allowedBlocks: BigInt(blocksMask(board)),
  maxLpFeePips: 60_000, // the most LP-fee room a pool may use
  maxTakePips: 30_000, // the most a pool may take for anyone but LPs
  flags: 0,
})

The SDK lives in the reel repository at sdk/src; the npm package is coming. See Saved hooks.

Open a root of your own

RootCreate opens a root at ["root", id] and pays Config.root_fee (at most 1 SOL) to the treasury. It fixes allowed_blocks; when it names a saved hook, the mask must be a subset of the hook’s. Root 0 is reel’s shared root: public, every block allowed, recapture allowed.

  • A public root must allow Anti-Snipe, Dynamic fees, LP Rewards and Creator royalty (bits 0, 1, 3 and 4). An owner-only root may allow less.
  • The owner can pause new pools (open pools keep trading), switch between public and owner-only, and set an integrator payee, which must be a listed Integrator.
  • Pools opened under the root copy its integrator, so the integrator’s rate of reel’s cut applies to every swap on them. The trader pays the same either way.
  • The root changes hands in two steps: RootTransfer, then RootAccept by the new owner.

See Owned roots.

Open pools on it

A launch is several transactions linked by a Launch account:

  1. LaunchCreate: for a new token it creates the Token-2022 mint with reel-hook as its transfer hook, mints the whole supply to an escrow and revokes the mint authority. The same transaction should set up reel-hook’s extra account metas for the mint. An existing-token launch only records the mint.
  2. PoolInit for each pool (1 to 8, each on a different quote): it freezes the pool’s params, checks every rule and, when named, the saved hook and root.
  3. PoolSeed for each pool: it creates the vaults, moves the seeds and mints the launch position.
  4. LaunchDevBuy, optional, once per pool for a new token.
  5. LaunchFinalize once every pool is seeded: it applies the supply split, the opening price check and the retention cap, then opens trading.

LaunchReturn, which anyone may send, returns the escrow’s leftover to the creator. A launch that stalls before it goes live can be aborted with LaunchAbort. See Multi-pool launch.

Example: a launchpad on its own root

A launchpad wants every token it launches to carry the same rules and to earn a share of reel’s cut.

  1. Compose the house style in the builder and save it with HookSave.
  2. Open an owner-only root that names the saved hook, with allowed_blocks equal to the hook’s mask.
  3. Ask for an integrator listing; once listed, set it as the root’s integrator payee with RootUpdate.
  4. In your own interface, build LaunchCreate, PoolInit (naming the root and the saved hook), PoolSeed and LaunchFinalize for each creator, who signs them.
  5. After the launch, the creator can lock it with LaunchLock, naming a beneficiary who collects every fee the launch positions earn.

See Integrating as a launcher.

Example: an app that manages liquidity

A liquidity app holds positions on reel pools for its users.

  • PositionOpen creates a position at ["position", pool, owner, nonce]; LiquidityAdd deposits in proportion to the reserves, up to the pool’s deposit cap.
  • FeesCollect pays a position’s fees without touching its principal, and a locked position may still collect.
  • PositionLock extends a lock, never shortens it; the largest value never releases.
  • PositionSplit and the two-step PositionTransfer move shares between owners. The launch position can’t be split or transferred.

See Providing liquidity.

Before the first launch

The program’s upgrade authority, held by the reel treasury, remains the largest power over it until it is revoked.
  • Simulate every transaction before you ask a user to sign it, and show what the wallet will be asked to approve.
  • Check each quote against reel’s mint policy, and know whether it is listed; see Quote tokens and Token-2022 risks.
  • Read the fee split: what reel takes, what an integrator earns and what LPs keep.

Listing

A root, a saved hook or a launchpad integration can ask to be listed on reel’s pages. See Partner review for what a review asks for. A listing is not an audit or an endorsement.