Read the Kitchen from the chain.
There is no Kitchen API yet. Everything the app shows is read straight from the Kitchen's contracts on Robinhood Chain, and anyone can read them the same way, with no key and no agreement.
The contracts
chain 4663Nothing is deployed on Robinhood Chain yet. The addresses below are the ones this build of the app was configured with; a build with none says set at deploy.
| Contract | What it does | Address |
|---|---|---|
| KitchenFactory | The one-transaction launch: clones the coin, opens its pool, locks the supply, makes the optional first buy. No owner; its only privileged call is the one-shot genesis of $HOOKING. | set at deploy |
| KitchenHook | The Uniswap v4 hook of every Kitchen pool: 0% LP fee, cost basis, the win tip, the anti-snipe window and the price oracle. No owner, no setters after wiring. | set at deploy |
| LiquidityLocker | Owns every Kitchen pool's liquidity forever. No function removes liquidity or collects fees. | set at deploy |
| FeeRouter | Receives win tips and launch fees and runs the fixed splits: the burns, the creator's $HOOKING, the liquidity band and the team. No owner. | set at deploy |
| KitchenRouter | The app's router: ETH in or out of any coin straight through the PoolManager, and the way to the menu. Holds nothing between transactions, no owner. | set at deploy |
| IngredientRegistry | The menu items the Kitchen accepts: proposed by a multisig, in effect 72 hours later, paused at once by the owner or a guardian key. | set at deploy |
| Flambe | Double or nothing on a buy, with commit and reveal randomness from the house. | set at deploy |
| FlambeVault | Flambé's ETH bankroll: an ERC-4626 vault over WETH that holds every risk cap. | set at deploy |
| Parachute | The automatic exit. Holds no coins between transactions and has no vault; sells a position once its line is crossed, never below its floor. | set at deploy |
| Every coin | A fixed-supply ERC-20 clone that carries each holder's cost basis. One per launch: list them with coinCount() and coinAt(i) on the factory. | one per coin |
| $HOOKING | Coin number one, made by genesis. | factory.hooking(), after genesis |
| Team vesting | The team's 10% of $HOOKING, vesting for 3 + 12 months. | in GenesisLaunched, after genesis |
Outside the Kitchen
| Contract | Address |
|---|---|
| Uniswap v4 PoolManager | 0x8366a39CC670B4001A1121B8F6A443A643e40951 |
| Uniswap v4 Quoter | 0x8Dc178eFB8111BB0973Dd9d722ebeFF267c98F94 |
| Multicall3 | 0xcA11bde05977b3631167028862bE2a173976CA11 |
Events to index
from the interfacesNames and arguments as in the contracts. The one-shot wiring at deploy is left out.
KitchenFactory
Launched(address indexed coin, address indexed creator, address quote, uint256 openPrice, bytes32 poolId)FirstBuy(address indexed coin, address indexed creator, uint256 coins, uint256 paid, uint256 refunded)GenesisLaunched(address indexed hooking, address indexed teamVesting, uint256 teamAllocation)
KitchenHook
PoolRegistered(bytes32 indexed id, address indexed coin, address indexed quote)Traded(address indexed coin, address indexed trader, bool isBuy, uint256 amountCoin, uint256 amountQuote, uint256 price)TipCharged(address indexed coin, address indexed seller, uint256 profitQuote, uint256 tipQuote)TipsFlushed(address indexed coin, address indexed quote, uint256 amount)
Every coin
BasisUpdated(address indexed account, uint256 cost, uint256 basis)Transfer(address indexed from, address indexed to, uint256 value)
LiquidityLocker
LaunchLocked(address indexed coin, bytes32 indexed id, int24 tickLower, int24 tickUpper, uint128 liquidity, uint256 coins)BandAdded(address indexed coin, bytes32 indexed id, int24 tickLower, int24 tickUpper, uint128 liquidity, uint256 quoteAmount)
FeeRouter
TipsCredited(address indexed coin, address indexed quote, uint256 amount)LaunchFeeCredited(address indexed coin, uint256 amount)Burned(address indexed token, uint256 amount, bytes32 indexed source)CreatorAccrued(address indexed coin, address indexed creator, uint256 hookingAmount)CreatorClaimed(address indexed creator, uint256 hookingAmount)LiquidityAdded(address indexed coin, uint256 quoteAmount)TeamPaid(address indexed quote, uint256 amount)Flushed(address indexed coin, address indexed caller, uint256 processed, uint256 reward, uint256 carried)BurnCredited(bytes32 indexed source, address indexed from, uint256 amount)
KitchenRouter
Trade(address indexed trader, address indexed coin, bool isBuy, uint256 coinAmount, uint256 ethAmount, address recipient)BoundedBuy(address indexed caller, address indexed coin, address indexed recipient, uint256 ethIn, uint256 coinsOut, uint256 ethBack)
IngredientRegistry
Proposed(address indexed ingredient, bytes32 indexed kind, uint64 eta)Cancelled(address indexed ingredient)Activated(address indexed ingredient, bytes32 indexed kind)PausedSet(address indexed ingredient, bool paused, address by)
Flambe
ChainCommitted(uint256 indexed chainId, bytes32 anchor, uint256 length, uint256 firstFlip)FlambeRequested(uint256 indexed id, address indexed trader, address indexed coin, uint256 stake)FlipSeeded(uint256 indexed id, bytes32 userSeed, uint256 chainId, uint256 position)SeedRevealed(uint256 indexed id, bytes32 seed)FlambeResolved(uint256 indexed id, bool won, uint256 coinOut)WinPaidInEth(uint256 indexed id, address indexed trader, uint256 eth)FlambeRefunded(uint256 indexed id, address indexed trader, uint256 stake)FlipAbandoned(uint256 indexed id)Owed(address indexed to, uint256 amount)
FlambeVault
Reserved(address indexed game, address indexed coin, uint256 amount)Released(address indexed game, uint256 amount, int256 pnl)RedeemRequested(address indexed owner, uint256 shares, uint64 maturesAt, uint64 lapsesAt)RedeemCancelled(address indexed owner, uint256 shares)ProfitSettled(uint256 profit, uint256 toBurn, uint256 toTeam)
Parachute
Opened(uint256 indexed id, address indexed owner, address indexed coin, uint256 amount, int24 lineTick, int24 floorTick, uint64 expiresAt)Ejected(uint256 indexed id, address indexed caller, uint256 coinsSold, uint256 ethOut, uint256 toOwner, uint256 reward, uint256 burned)Closed(uint256 indexed id)
Reading them right
- On a sell through the KitchenRouter, the hook's
TradedandTipChargedname the router, which pulls the coins first. The router'sTradein the same transaction names the trader. BasisUpdatedgives the holder's totalcostandbasis, the cost in quote units per 1018 coins. The quote is the zero address for ETH, otherwise $HOOKING.Burnedcarries itssourceas a short string in bytes32:tip.hooking,tip.coin,launch,flambeorparachute.- A flip is
FlambeRequestedthenFlambeResolved.FlipSeededcarries what a verifier needs besides the reveal, andWinPaidInEththe part of a win its bounded buy could not place. - A parachute is
Opened, thenEjectedorClosed. Its line and floor are ETH-price ticks: log base 1.0001 of the ETH one coin is worth. - The vault is also an ERC-4626 and ERC-20 token, with their standard events.
- The contracts declare a few more events than their interfaces: the hook's
TipHeld,TicketandOwed, and the locker'sDustBurned.
Useful reads
view callsThe questions people ask most, and the call that answers each one.
| Question | Call |
|---|---|
| Every coin | factory.coinCount(), factory.coinAt(i) |
| Is it a Kitchen coin, and whose | factory.isKitchenCoin(coin), factory.creatorOf(coin) |
| What a launch costs | factory.launchFee(quoteIsEth) |
| A coin's pool, quote and age | hook.homePool(coin), hook.quoteOf(coin), hook.launchedAt(coin) |
| A price | hook.meanTick(poolId, secondsAgo): the mean tick over a window, and whether the pool has that much history. The app asks for 0 seconds to get the current tick. hook.quoteValue(coin, amount, window) values coins at the mean over a window. |
| A holder's cost basis | coin.costOf(holder), the total, and coin.basisOf(holder), in quote units per 1018 coins |
| Anti-snipe used so far | hook.snipeBought(coin, origin) |
| Tips waiting for a flush | hook.claimsHeld(coin) |
| A creator's $HOOKING | feeRouter.creatorClaimable(creator); the creator takes it with claimCreator() |
| Flambé's limits now | flambeVault.maxStake(), flambeVault.hourTaken(coin), flambe.seedsLeft() |
| A flip | flambe.flipOf(id), flambe.seedSlot(id), and flambe.outcome(seed, userSeed, id) to check a result yourself |
| A parachute | parachute.positionOf(id), and parachute.canEject(id), which answers yes or no with a reason: Ready, NotOpen, Expired, NoPrice, AboveLine, NothingToSell or BelowFloor |
| A menu item's state | registry.isActive(item) (activated, paused or not), registry.isLive(item) (activated and not paused), registry.current(kind) |
How the app reads the chain
todayThe app has no indexer and no database of its own yet. Its screens read the chain over RPC, with viem and react-query, through one data layer that no screen goes around.
- The present is read with view calls: the coin list from the factory, each coin's name, symbol, metadata, quote and creator, its pool from the hook; prices from the hook's oracle, turned into an ETH price the way the contracts do it, with the $HOOKING pool folded in for a $HOOKING-paired coin; a wallet's balances, cost and approvals; a creator's earnings; quotes, by running the router's own buy and sell as calls or by the Uniswap v4 Quoter; flips and parachutes.
- The history is read from events with
eth_getLogs, from the block this build names inNEXT_PUBLIC_KITCHEN_FROM_BLOCK, over the factory, the hook, the router, the FeeRouter, Flambé, Parachute and the locker, in pieces of 5,000 blocks. After the first read only new blocks are read, and if the chain changed under the last block read, it is read again from the start. A build with no start block shows the present and no history. - In the browser the calls go to a route on the same site,
/api/rpc, which forwards a small read-only set of JSON-RPC methods to the chain's node, unless a build pointsNEXT_PUBLIC_RPCat a node of its own. Transactions are sent by your wallet, never by that route.
The same read, from your own code
Every launch since a block, with viem (any Node, Bun or Deno that runs it):
import { createPublicClient, http, parseAbiItem } from "viem";
// The chain's public node turns away requests that do not look like a browser's.
const client = createPublicClient({
transport: http("https://rpc.mainnet.chain.robinhood.com", {
fetchOptions: {
headers: {
"user-agent":
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
},
},
}),
});
const FACTORY = "0x..."; // the KitchenFactory
const START = 0n; // the block before the Kitchen was deployed
const launched = parseAbiItem(
"event Launched(address indexed coin, address indexed creator, address quote, uint256 openPrice, bytes32 poolId)",
);
const logs = await client.getLogs({ address: FACTORY, event: launched, fromBlock: START, toBlock: START + 4999n });
for (const log of logs) console.log(log.args.coin, log.args.creator);Ask for a few thousand blocks at a time: public nodes cap the range of one eth_getLogs, which is why the app reads 5,000 blocks a call.
The indexer
milestone 5The indexer is the next piece. When it exists it replaces the history read above: it fills the same index from its own tables, and no screen changes. Until then there is no Kitchen REST API and no key to ask for; read the contracts directly, as the app does.
If this page and the chain ever disagree, the chain is right. updated 16 October 2026
