Build on Ignition
Every Ignition token is a real Uniswap v4 pool on Robinhood Chain with an upgradeable hook: renameable, pair switchable to any tokenized stock, no price ceiling, and Stock Mode circuit breakers. Bonding-curve launches trade on their own curve first and graduate into exactly that kind of pool at 4.2 ETH (spec: contracts/specs/BONDING_CURVE.md). Read it all from a public API, trade and launch from a TypeScript SDK, or call the contracts directly. No keys, no sign-up.
Public API
JSON over HTTPS at https://www.ignition.family/api/v1. Read-only, CORS-open (call it straight from a browser) and cached at the edge. Prices are in the launch's quote currency, plus ETH and USD where the on-chain market allows.
| Endpoint | Returns | Cache |
|---|---|---|
| /api/v1 | Index: every endpoint and contract address | 5 min |
| /api/v1/launches | Every public launch with live price, market cap (quote, ETH, USD) and Stock Mode state, largest first | 30 s |
| /api/v1/launches/{token} | One launch: market data, its pools (launch and active pair) and Stock Mode limits | 15 s |
| /api/v1/launches/{token}/trades?limit=100&hours=168 | Recent trades on the active pair, newest first (limit up to 1,000) | 10 s |
| /api/v1/launches/{token}/candles?interval=15&hours=24 | OHLC candles in quote units; interval 1, 5, 15, 60, 240 or 1440 minutes | 30 s |
| /api/v1/stats | Platform analytics: volume (ETH, with ETH/USD), trades, traders and fees for 24h, 7d and all time, 30 daily buckets, and every launch's volume | 60 s |
curl https://www.ignition.family/api/v1/launches
{
"count": 23,
"ethUsd": 2471.13,
"launches": [{
"token": "0xEBF7…C22d", "name": "VRAX CAT", "symbol": "VRAXCAT",
"quote": { "symbol": "ETH", "decimals": 18 },
"price": { "quote": 0.1035, "eth": 0.1035, "usd": 255.8 },
"marketCap": { "quote": 10.35, "eth": 10.35, "usd": 25580 },
"stockMode": { "live": false },
"pool": { "id": "0xdfb2…", "key": { … }, "switchable": false },
…
}]
}TypeScript SDK
The same code ignition.family runs, as a package (viem only, works in Node and the browser): read launches and markets, get exact quotes, trade, and launch tokens.
npm install https://www.ignition.family/sdk/ignition-family-sdk-0.1.7.tgz viem
import { createPublicClient, createWalletClient, http, parseEther } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { MAINNET, robinhoodChain, listLaunches, getLaunchMarket,
quote, swap, launchToken } from "@ignition-family/sdk";
const client = createPublicClient({ chain: robinhoodChain, transport: http() });
// Every launch, with live market data
const launches = await listLaunches(client, MAINNET.factories);
const m = await getLaunchMarket(client, launches[0], {
poolManager: MAINNET.poolManager,
pairSwitchingImplementations: MAINNET.pairSwitchingImplementations,
});
console.log(m.symbol, m.priceInQuote, m.quote.symbol, m.stockMode);
// Exact quote: price impact, LP fee and the 2% tax included
const q = await quote({ client, poolKey: m.poolKeys.active, token: m.token,
side: "buy", amountIn: parseEther("0.1") });
// Trade (checks Stock Mode first, approves if needed)
const account = privateKeyToAccount(process.env.KEY as `0x${string}`);
const wallet = createWalletClient({ account, chain: robinhoodChain, transport: http() });
await swap({ publicClient: client, walletClient: wallet, account: account.address,
poolKey: m.poolKeys.active, token: m.token, side: "buy", amountIn: parseEther("0.1") });
// Launch a token: no liquidity needed, no price ceiling, Stock Mode on
const { token, hook } = await launchToken({ publicClient: client, walletClient: wallet,
account: account.address, name: "My Token", symbol: "MINE", totalSupply: 1_000_000_000n * 10n ** 18n });Stock Mode, for integrators
Tokens on hook V10 and later have stock-exchange circuit breakers: no burst of trades can take the price more than 20% under its recent high or more than 2x above its recent low; both relax over 5 minutes. A trade past a limit reverts with StockModeLimit(bool down, int24 limitTick) (wrapped in Uniswap's WrappedError).
- Read the live limits with stockModeLimits(poolKey) on the token's hook, or stockMode in the API and SDK.
- Simulate before sending. The SDK's quote() returns limit instead of an amount, and largestFitting() finds the most that fits right now.
- Selling is never blocked, only paced. Room reopens continuously.
Contracts (Robinhood Chain, 4663)
| Direct launches (LaunchpadFactorySafe: V11, approved-only hook upgrades) | 0x4215d789Fb43FF4b332D1910dA361176E80E7E6d |
| Bonding-curve launches (IgnitionCurveFactoryV2) | 0x844562204C6FaA4A566dA43f5b6Ee834c347289a |
| Approved hook implementations (IgnitionHookRegistry) | 0x1e7B5D189465ce5C2889B0AbDFC304BA5199cd28 |
| Latest hook implementation (V11) | 0x1CBe98752c1234422F5494187396aa0529118834 |
| Module registry | 0x882F6eBaBb8113769B6CceE8D18b4563493B388D |
| Module fee vault | 0x7A221167e76dbef5444EFb33753e92B50e9c4Fb5 |
| Holder Staking module | 0xb75bC2238352c44685Cd529fdF4BB5b093964A2e |
| IgnitionSwapRouter (trade any Ignition pool) | 0x606F0c89fA1FA58c0a942d417cEeb1814065A7C6 |
| IgnitionRouteRouter (trade through ETH) | 0x62C797A1F497dE7438D14434F631dCb24b131B38 |
| Pair registry | 0x8CF19D0E1ee66b4e3160b214e1C5f38859972Eb9 |
| Liquidity lock (no price ceiling) | 0x4d4F950d53EED1cDb0EFcE2f0B2Cb2c3ea50F449 |
| Uniswap v4 PoolManager | 0x8366a39CC670B4001A1121B8F6A443A643e40951 |
Every launch: a fixed-supply ERC20 and a hook proxy at a CREATE2-mined address (afterSwap permissions), whose logic its owner can upgrade. Trade fee 2%: buys 1% creator and 1% platform, sells 2% platform. The fee is capped at 3% in the contract.
Hook Modules: earn from every trade
A Hook Module is a contract that tokens switch on in one click. It earns a share of every trade on every token that runs it: up to 0.25% each, at most two modules per token. The share comes out of the platform's part of the 2% fee, so traders pay the same and creators keep their 1%.
- On each trade the hook (V11) pays your share straight from Uniswap's PoolManager into the ModuleFeeVault and credits it to your module, per token, in ETH or the token itself.
- The hook never calls your module. Your logic (staking rewards, raffles, buybacks, airdrops, leaderboards) runs in your own transactions, so no module can block, front-run or change a trade. Stock Mode, the 3% fee cap and holders' ability to sell are untouched.
- Trades emit ModuleFeePaid(module, currency, amount) from the token's hook, and the vault emits Credited. Index them, or read owed(module, token, currency).
- Each enabled module adds about 13k gas to a trade.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
interface IModuleFeeVault {
function owed(address module, address token, address currency) external view returns (uint256);
function claim(address token, address currency, address to) external returns (uint256);
}
/// Minimal module: collects its share of every trade on tokens that run it.
contract MyModule {
IModuleFeeVault public immutable vault;
constructor(IModuleFeeVault _vault) { vault = _vault; }
receive() external payable {}
/// Pull a token's accrued fees, then do something for its holders.
function harvest(address token) external {
if (vault.owed(address(this), token, address(0)) > 0) {
vault.claim(token, address(0), address(this)); // ETH (from sells)
}
if (vault.owed(address(this), token, token) > 0) {
vault.claim(token, token, address(this)); // the token (from buys)
}
// ...your logic: reward stakers, fund a raffle, buy back and burn...
}
}The first module, Holder Staking, is live: holders stake a token and earn its module share of every trade in ETH and the token, with no lockup. Its source is TokenStakingModuleV2.sol.
Get approved: modules go through review before tokens can enable them. Send your module address, source and what it does to @IGNITION_RH on X. Approved modules are listed on every V11 token's page for its owner to switch on. The platform can revoke a module, which stops its fees everywhere at once.
Module IPOs: launch your module with its own token
Build your module on ModuleKit and it launches with its own Ignition token. A fixed part of everything your module earns, on every token that runs it, streams in ETH to the people who stake your token. You get funded and get holders who want your module adopted; they get a token backed by real trading revenue. Listed with live numbers on the Module Market.
- Two numbers, fixed forever at deploy: ownerCutBps (your owners' cut of the module's ETH fees) and holderShareBps (how much of that cut goes to your token's stakers; the rest is yours).
- Call _collect(token, currency) instead of claiming from the vault: the kit takes the cut and hands you the rest for your module's job.
- Stakers earn through ModuleRevenuePool: revenue streams over 3 days, so nobody can stake right before a payout and take it. Unstaking is never locked. No admin keys over anyone's funds.
- On tokens launched since V12 every module fee is paid in ETH; on earlier tokens buys pay modules in the traded token and sells in ETH. Only ETH is shared with your holders.
// contracts/src/modules/kit/TemplateModule.sol
contract MyModule is ModuleKit {
constructor(IModuleKitVault vault, address shareToken, address dev)
ModuleKit(vault, shareToken, dev, 2000 /* 20% owners' cut */, 5000 /* half to stakers */) {}
function process(address token) external nonReentrant {
uint256 eth = _collect(token, address(0)); // your job's ETH, after the cut
uint256 tok = _collect(token, token); // the traded token (no cut)
// ...your logic: raffles, buybacks, streak rewards, holder perks...
}
}On the Hook Layer, every pair pays. Launches there run hook V19, which pays a module its share in whatever the launch is paired with: the gas token, a stablecoin or a stock. Build on ModuleKitV2 and your stakers earn every one of those currencies, each streamed over 3 days (ModuleRevenuePoolV2). Fees in the launched token itself still all go to your module's job. Hook Pad V2 takes both kit versions.
// contracts/src/modules/kit/TemplateModuleV2.sol
contract MyHook is ModuleKitV2 {
constructor(IModuleKitVault vault, address hookToken, address dev)
ModuleKitV2(vault, hookToken, dev, 5000 /* 50% owners' cut */, 10000 /* all of it to stakers */) {}
function process(address token, address[] calldata currencies) external nonReentrant {
for (uint256 i; i < currencies.length; ++i) {
uint256 amount = _collect(token, currencies[i]); // your job's share, after the cut
// ...your logic, in any currency: address(0) is the gas token, or a stock, a stablecoin...
}
}
}Ship it in one command. ShipHook.s.sol launches your hook's token on the Hook Layer, lists it on the Hook Pad and deploys and attaches your module (or the template), ending in review. Give it your contract with ARTIFACT; it passes ModuleKitV2's six constructor arguments. A working example with its own job: src/hooks/examples/StakerStreamHook.sol (everything it earns streams to its stakers).
FACTORY=<v19.factory> HOOK_PAD=<v19.hookPad> VAULT=<genesis.moduleVault> CURRENCY_LIST=<v19.currencyList> \ NAME="My Hook" SYMBOL=MYHOOK METADATA=https://example.com/my-hook.json ARTIFACT="MyHook.sol:MyHook" \ forge script script/hooklayer/ShipHook.s.sol --rpc-url https://testnet-rpc.hooklayer.ignition.family --private-key ... --broadcast # addresses: frontend/lib/hookLayerConfig.json
- Launch your share token on ignition.family/create.
- Write your module from the template (full spec: contracts/specs/MODULE_IPOS.md).
- Deploy: SHARE_TOKEN=0x… forge script script/DeployModuleIPO.s.sol --broadcast
- Send it for review; once approved, any token owner can switch it on and it appears on the Module Market.