Skip to main content
Nothing in the repository hard-codes a chain. A new one is an entry in packages/abis/chains.json, a row in the deploy script’s chain table, a deployment, and one keeper and indexer more. Robinhood Chain was added this way; Arc mainnet is registered and waits for its deployment.

What the chain must have

  • Cancun EVM. The contracts and Uniswap v4 are compiled for evm_version = "cancun" and use transient storage (TSTORE and TLOAD) and MCOPY. Arbitrum Orbit (ArbOS 40 and later) and OP Stack chains qualify. Check by executing, not by reading docs.
  • A dollar stablecoin launches settle in, 6 decimals preferred (USDC, USDG). On a testnet without one, Deploy.s.sol can deploy a mintable mock (DEPLOY_TEST_DOLLAR=true) and the app offers a “Get test dollars” button for it.
  • Permit2, canonical 0x000000000022D473030F116dDEE9F6B43aC78BA3 on most chains. The PositionManager and the LaunchFactory use it.
  • Uniswap v4: either the official PoolManager, PositionManager, StateView and Quoter (put them under uniswapV4 in the registry and in _defaults, and run the indexer with INDEX_POOL_SWAPS=false, because a shared PoolManager emits every swap on the chain) or nothing, in which case Deploy.s.sol deploys its own set and the indexer can index swaps.
  • An FX price source. The keeper oracle works anywhere; add Pyth (pyth in the registry) or a Chainlink adapter where FX feeds exist.
  • Optional: EURC or a bridged equivalent (eurc; without it EUR is simply not registered), Multicall3 (probed at runtime), a Blockscout instance (explorerApi, for verification), a faucet.

Checklist

1

Register the chain

Add an entry to packages/abis/chains.json. The loader validates it at startup.Required: id, key (slug, used for token-list file names and as the Ponder chain name), name (shown in the UI), testnet, rpc, explorer, nativeCurrency (name, symbol, decimals; the symbol appears in “Gas is paid in …”), gas (maxFeeGwei, priorityGwei; add minBaseFeeGwei only when the chain enforces a floor like Arc’s 20 gwei, which pins the fee in the deploy scripts and is mentioned in the UI), dollar (symbol, decimals, optional address, mintable, logo; leave address out until a mock is deployed).Optional: rpcs (alternates; the indexer and deploy script default to them), ws, explorerApi, eurc, faucet, multicall3, permit2, pyth, uniswapV4, ethGetLogsBlockRange (the public RPC’s limit for the indexer), maxLogAddresses (addresses per log filter), notes.
2

Mirror the addresses in the deploy script

Add a row to _defaults() in contracts/script/Deploy.s.sol with usdc, usdcSymbol, eurc, permit2, pyth and the Uniswap v4 addresses (or testDollarAllowed on a testnet). A chain without a row must pass USDC, EURC (0x0 skips EUR) and PERMIT2 in the environment.
3

Deploy

Fund the deployer with the chain’s gas token, then CHAIN_ID=<id> bash scripts/deploy-testnet.sh (or the mainnet script). It writes packages/abis/deployments/<id>.json; if it deployed a mock dollar, copy that address into dollar.address of the registry entry. See Deploy contracts.
4

Run the keeper and the indexer

Keeper with CHAIN_ID=<id> (pnpm --filter @launchpad/keeper once first so every currency has a rate, then start). Indexer with CHAIN_ID=<id>, PORT=<free port>, PONDER_RPC_URL_<id>, START_BLOCK_<id>=<deploy block> and INDEX_POOL_SWAPS=false on a shared PoolManager. Add both to deploy/ecosystem.config.cjs and a server block or location for the indexer to the reverse proxy.
5

Wire the web app

Add a row for the chain id to RPC_ENV and INDEXER_ENV in apps/web/src/lib/chain.ts (Next.js only inlines literal process.env.NEXT_PUBLIC_* reads), set NEXT_PUBLIC_INDEXER_URL_<id>=<that indexer> (plus NEXT_PUBLIC_RPC_URL_<id> if the registry RPC is not the one to use) and rebuild. The switcher lists the chain as soon as its deployment file exists at build time; NEXT_PUBLIC_CHAIN_ID=<id> only makes it the default.
6

Assets

CHAIN_ID=<id> pnpm abis:logos and CHAIN_ID=<id> pnpm abis:tokenlist. If the dollar is a new token, add apps/web/public/tokens/<symbol>.svg (the CoinLogo component falls back to initials when it is missing).
7

Copy

Product copy that names the dollar, the chain, the gas token or the faucet is registry-driven; brand strings are not. Check the chain’s terms of use: Robinhood’s, for instance, forbid “Robinhood” in product or token names, while “Built on Robinhood Chain” is fine.

Worked example: Robinhood Chain

Arbitrum Orbit L2 (ArbOS 61, Nitro 3.12), ETH gas, permissionless deployment, Cancun opcodes verified by execution. Both networks are in the registry with ethGetLogsBlockRange: 1000 and maxLogAddresses: 60. RPC limits: the official public RPC caps eth_getLogs at 10,000 logs and answers 429 after a burst; thirdweb’s testnet endpoint caps 1,000 blocks and rejects server IPs without a client id; Alchemy’s free tier caps 10 blocks; dRPC’s free plan caps 100 blocks but is the only public archive endpoint. Use an Alchemy or QuickNode key for PONDER_RPC_URL_<chainId> (a paid endpoint for mainnet) and keep MAX_REQUESTS_PER_SECOND low on the public one.