Skip to content

Build your own hook

Build a hook from Hook Blocks, deploy it, integrate it and open pools on it, for a launchpad and for an app that manages liquidity.

On this page

Launchpads and apps that manage liquidity build their own hook from Hook Blocks, deploy it at an address they own, and open their users' pools on it through Hookr's launcher. This guide follows two builds from the first block to the first pool: one for launchpads and one for liquidity apps.

Both builds use only Hook Blocks and features that are Live. Launch-day blocks lists each block as Live or Deploying soon.

The Path

Every build takes the same six steps. The two examples below fill them in.

  1. Compose. Place Hook Blocks in the Builder and set each one inside the bounds the contracts accept.
  2. Deploy. Under Use this hook, Deploy your own hook saves the blocks as a saved hook and deploys a hook from it through HookrOwnedRootFactory. The hook is an unmodified Hookr root at an address of its owner. The deploy costs gas only: the deploy fee is currently 0 ETH, and Hookr's treasury can raise it to at most 1 ETH.
  3. Own. The wallet or contract that opens pools is named as the hook's owner. An owner other than the deploying wallet is only the pending owner until it calls acceptRootOwnership(hook) on the factory.
  4. Integrate. Integrate this config hands the product the code, the contracts and the reads. The SDK builds the calls, and the agent skill gives an agent the same facts in one file.
  5. Launch. The product's contract calls HookrLauncher.launch(token, hook, members, deadline) with the hook as the root.
  6. Read. The product reads the chain to check the hook and each pool before it shows a user either.

Owned roots describes what a hook of its own does, and Integrating as a launcher describes the launch call and the reverts to surface.

Integrate This Config

Integrate this config sits under Use this hook in the Builder and opens from the address /builder#integrate. The panel has eight sections.

SectionContent
Pick the featuresThe hook's Hook Blocks, each one in or out of what the product offers
Hook and pool shapeEach parameter fixed, or left to the product's creators inside the live bounds
Contracts and addressesThe release's contracts by role, read from the release
Install and codeThe launch call and the quote-and-swap calls, written with the SDK's builders
Reads before a write, and approvalsWhat a launch reads first, and the approvals it needs
Fees for integratorsHookr's share, the integrator rate and the arb recapture cuts, from the release's own figures
Routing, quoting and indexingHow a swap is routed and quoted, and what to index
Next stepsFive checks, and the whole brief as Markdown to copy

The five checks are to read the SDK, check the settings, fork test one launch and one buy, ask to be listed as an integrator, and book a partner review. An address in the panel is the verified release's or none, and a figure is a constant's or none.

Example 1: A Launchpad on Its Own Hook

The launchpad in this example wants every token its users launch to carry the same Hook Blocks, to pay the launchpad a share, and to open from the launchpad's own contract.

  1. Compose. The launchpad places Anti-Snipe, Dynamic fees and LP Rewards in the Builder. Core blocks lists what a creator sets on each and the range the contracts accept. In Integrate this config, each parameter is fixed or left to the creator inside the live bounds.
  2. Deploy. The launchpad chooses the features the hook advertises (ruleMask) within the saved hook's, and chooses that the hook opens pools for its owner alone. An owner-only hook can leave out any of the saved hook's features. A hook that opens pools for everyone keeps Anti-Snipe, dynamic fees, LP Rewards and the creator royalty.
  3. Own. The launchpad names its own contract as the owner. Until the contract calls acceptRootOwnership(hook), the hook has no owner and opens no pools for anyone, so the contract needs a way to make that call. pendingRootOwner(hook) reads who may accept.
  4. Integrate. The SDK's builders refuse any hook that the release manifest does not pin, a hook of its own included, with Unqualified root. The code from Integrate this config adds the hook and its core beside the release's pins, each at the hash of the code it holds. It states the checks that come first: the registry's ownedRegistrarForRoot(hook) is the release's HookrOwnedRootFactory, the factory's runtimeMatchesTemplate(hook) is true, and ownedRoot(hook).paused is false. An agent that runs launches reads the agent skill, which sends launchpads that run their own hook to the launcher guide.
  5. Launch. The contract reads rootOpenFor(hook, msg.sender) on the registry before each launch and shows the reason on a no. For a new token it reads predictToken(contract, token) first. The contract is the opener and a new token's creator, and it owns the launch's positions.
  6. Name the integrator. A pool names its integrator in its core block settings (RulesConfig.integrator). The treasury lists the launchpad's address with a rate first, requested through a partner review. The rate is 50% of Hookr's share of block fees by default, at most 50%, fixed with the pool, and the trader pays the same either way. It never applies to the arb recapture cut, and an advisory block's take is its own. A pool that names an account the treasury does not list fails to open with UnknownIntegrator. The integrator collects by calling claim on the pool's core.
  7. Keep arb recapture off. A hook of its own starts without arb recapture: activeLaneOf(hook) names no executor, and a member that asks for it reverts InvalidConfig(). Only Hookr opens the lane, on the owner's request under Your hooks.

The reads that confirm the build:

ReadResult
ownedRoot(hook) and runtimeMatchesTemplate(hook) on the factoryThe hook is an unmodified Hookr root
rulesOf(hook) on the factoryThe core blocks its pools run
rootOpenFor(hook, caller) on the registryWho may open pools on it
familyOwner(familyId) on the launcherWho owns a launch's positions
The pool's core configThe protocol share, integrator and Hook Block settings the pool froze

Hookr's app trades and launches on a hook of its own only when the chain agrees: the registry calls it an owned root, the release's factory registered it, it runs the template's exact build, and its core is admitted. A paused hook keeps trading its open pools and opens no new ones.

Example 2: An App That Manages Liquidity

An app lets users put liquidity into a token's pools and move it as the price moves. It pays liquidity providers, keeps a reserve in public view, and takes a fee for running the pools. The token already trades, so the app opens new pools beside the ones it has.

  1. Compose. The app places LP Rewards with the creator royalty, and Managed fee.
    • LP Rewards adds an LP fee on buys on top of the base fee, and the pool's LPs earn it after Hookr's share.
    • The creator royalty pays a recipient fixed at launch a share of LP Rewards, up to 10%. The app is that recipient.
    • Managed fee is a surcharge on top of the LP fee that a keeper may move inside a cap fixed at launch. The creator also bounds how far and how often it changes and how long a setting lasts. The block's page says whether a keeper runs, and where none runs the pool charges its starting surcharge.
  2. Deploy and own. The app deploys an owner-only hook and names its contract the owner, as in Example 1.
  3. Launch. The call names the existing token: existing set, an empty name and symbol, and supply and salt zero. The launch opens up to 8 pools, one per quote asset, funded with tokens the app holds. Each pool takes the same Hook Blocks and no dev buy. See Multi-pool launch.
  4. Route positions. Hookr pools take liquidity through the Uniswap v4 PositionManager, with no Hookr liquidity contract and no Hookr position token. A user's add, increase, partial withdrawal, fee collection, range move, rebalance into another pool and full withdrawal are each one modifyLiquidities call, listed in Providing liquidity. While a pool's Anti-Snipe guard is open, only the launcher adds liquidity.
  5. Hold the launch's positions. The launch's own positions belong to the app's contract. Only that owner withdraws them, and it hands them on in two steps, transferFamily then acceptFamily. A launch lock stops withdrawals until a block the app picks, and its beneficiary collects the fees the locked liquidity earns.
  6. Fund a reserve. Recovery reserve is set up on the pool page after launch, with a token, a reviewer, a recipient and caps. Anyone can top it up. A payout needs a reviewer's signed attestation. The reserve holds only what is topped up.
  7. Offer limit orders. Limit orders sit on the pool's trade dock and need no block. A trader sets a price on the Limit tab and escrows the trade, and anyone can fill it once the pool reaches the price.
  8. Claim. The royalty is credited on the pool's core. claimable(currency, account) reads it, and claim(currency) or claimTo(currency, to) pays it.

Before the First Launch

  1. Fork test one launch and one buy against a fork of Robinhood Chain.
  2. Read rootOpenFor(hook, owner) and pendingRootOwner(hook).
  3. Check every setting against its bound. The SDK refuses a value outside it.
  4. Confirm the wallet's chain, the payer, the token approvals, the deadline and the slippage. The SDK page lists them.

Listing

Pools opened through HookrLauncher on a hook of its own are route C under Listing Tiers. The contracts set Hookr's share, so the build carries no separate listing terms. A partner that runs a hook Hookr did not deploy lists on route A or route B.