Integration Guide
Official docs for integration partners — trading bots, terminals, and aggregators that want to quote, buy, and sell hyper.meme coins programmatically: bonding-curve (pre-graduation) coins and graduated coins, on HyperEVM. Everything here is permissionless — no API key or allowlist required.
Questions or a dedicated channel: @xbtdan on Telegram · @xbtdan on X.
Every coin has two phases. Pre-graduation, it trades against its own per-coin BondingCurve contract — a constant-product x·y=k curve priced in the chain's native token. You send native to the curve, it sends tokens back; no pool, no order book. When the curve sells out its 793,100,000-token reserve it closes, and a keeper migrates the raise + 206,900,000 reserved tokens into a full-range V3 pool at the 1% fee tier, with the LP position locked in a fee-only Locker (principal can never be withdrawn — no LP-pull rug vector). Post-graduation, the coin is a plain ERC-20 traded on the chain's DEX.
TOTAL_SUPPLY = 1_000_000_000e18 (fixed; minted to the curve at create) REAL_TOKEN_RESERVE = 793_100_000e18 (sellable on the curve) LP_TOKEN_RESERVE = 206_900_000e18 (seeds the DEX pool at graduation) VIRT_TOKEN_INIT = 1_073_000_000e18 (initial virtual token reserve) token decimals = 18
Native token HYPE · three factory generations with live coins (all new coins mint from the newest; a coin's factory comes with its TokenCreated log or the registry API's factory field) · graduates to HyperSwap V3.
Contracts
Economics
HyperEVM notes: the public RPC allows ~100 req/min/IP and caps eth_getLogs to ~1,000 blocks; no websocket. Failover: https://public.1rpc.io/hyperliquid. The sequencer orders transactions by arrival and burns priority fees — tips/MEV knobs do nothing; slippage is the only outcome-changing setting.
Read two booleans on any coin's curve (multicall them together) to know exactly what venue is live:
complete() = false, migrated() = false → PRE-GRAD: buy()/sell() on the curve
complete() = true, migrated() = false → DEAD WINDOW: nothing works — curve reverts Done(),
pool doesn't exist yet (normally ≤ ~15 s; treat as
unbounded and show a "migrating" state)
complete() = true, migrated() = true → GRADUATED: swap the V3 pool, fee tier 10000Event-driven equivalent (emitted by the coin's curve): CurveClosed → stop curve trading; Graduated → start trading the pool it names. Graduation is executed automatically by our keeper (~15 s poll). graduate() is permissionless and retryable, but on HyperEVM it needs ~13.2M gas — a big-block transaction from a HyperCore big-blocks-enabled EOA. Duplicate calls are harmless.
Every factory emits an identical event at create — watch it with one eth_getLogs over the factory addresses above (one topic0 covers every generation):
event TokenCreated(
address indexed token,
address indexed curve, // ← the address you trade against pre-grad
address indexed creator,
string name, string symbol, string metadataURI, // metadataURI = IPFS (image, socials)
uint256 timestamp
);
// topic0 = 0x463df9e040f1a9181ece2287496672134faffc6e35d4118f691d4280c8a68ee1Dev-buy: createToken(name, symbol, metadataURI) is payable — any value above the creation fee executes as an atomic dev buy in the same tx, emitted as a Buy log after TokenCreated in the same receipt. Provenance: verify an unknown pair with factory.curveOf(token) == curve (newest generation) or curve.token() == token && token.bondingCurve() == curve. Or poll GET /coins/registry (below).
Trade against the coin's curve address. Native rides as msg.value. There is no deadline parameter anywhere, and no cooldowns, max-buys, per-wallet limits, or pause switch — the curve cannot be paused by anyone.
// writes function buy(uint256 minTokensOut) external payable; // 0xd96a094a function buyTo(address to, uint256 minTokensOut) external payable; // 0x09bd4c31 tokens → to function sell(uint256 tokensIn, uint256 minBaseOut) external; // 0xd79875eb approve curve first // quote views (match the trade math exactly, incl. the 1% fee) function getBuyTokensOut(uint256 baseIn) external view returns (uint256); // 0xd8363301 function getSellBaseOut(uint256 tokensIn) external view returns (uint256); // 0x10dba89b function progressBps() external view returns (uint256); // 0x6c1eba15 0..10000 // state getters virtBase() 0xdc4f589d · virtToken() 0x26d7ecfc · realBase() 0x978a7cbc · realToken() 0x76636e5a k() 0xb4f40c61 · virtBaseInit() 0xe0f5449e · feeBps() 0x24a9d853 · token() 0xfc0c546a complete() 0x522e1177 · migrated() 0x2c678c64
Exact quote math (integer, floor division)
# BUY: given baseIn (msg.value) fee = baseIn * feeBps // 10000 # feeBps = 100 (1%) inAfterFee = baseIn - fee tokensOut = virtToken - k // (virtBase + inAfterFee) tokensOut = min(tokensOut, realToken) # final-buy cap # SELL: given tokensIn gross = virtBase - k // (virtToken + tokensIn) baseOut = gross - gross * feeBps // 10000 # spot price & market cap (native, 1e18-scaled) price1e18 = virtBase * 1e18 // virtToken mcapWei = virtBase * TOTAL_SUPPLY // virtToken
One Multicall3 read of virtBase / virtToken / realBase / realToken / k / feeBps / complete / migrated lets you quote any size locally with zero further RPC calls.
Recipes
BUY: out = getBuyTokensOut(value) # re-quote live at submit time
minOut = out - out * slippageBps / 10000 # our UI default: 200 bps
curve.buy(minOut) { value } # or buyTo(userEoa, minOut)
SELL: token.approve(curve, amount) # once; approval target = the coin's curve
out = getSellBaseOut(tokensIn)
curve.sell(tokensIn, out - out * slippageBps / 10000) # native returns to the callerAlways re-quote from the contract immediately before sending — never derive minOut from a cached price.
The final (graduating) buy
A buy that would exceed the remaining realToken is capped to exactly what's left, the input is re-priced, and the overpayment is refunded in the same tx — overshooting the last buy is safe. minTokensOut is checked after the cap, so to "buy the rest" set it ≤ the freshly-read reserve (or 0). The same tx emits Buy then CurveClosed; later racers revert Done() cleanly. Note the Buy event's baseIn is the post-fee, post-refund amount — not msg.value.
Pre-graduation tokens are not normal ERC-20s. Until graduation, a transfer is only allowed if it's a curve leg (from/to the curve) or a direct EOA→EOA transfer where both sides are codeless and msg.sender == tx.origin. Anything else reverts TransfersLocked(). (Coins from the oldest HyperEVM generation are stricter: no wallet-to-wallet transfers at all.)
- ✅ Plain EOAs calling the curve directly (custodial bot wallets, embedded wallets, browser wallets) — works fully; this is how our own site trades.
- ⚠️ Router contracts: can receive tokens from the curve but cannot forward them — use buyTo(user, minOut) so tokens land on the user's EOA directly.
- ❌ Pulling user tokens into a contract (transferFrom) reverts — sells must be sent by the token holder (holder approves the curve and calls sell).
- ❌ Taking platform fees in the pre-grad token reverts — charge fees in native (HYPE/ETH) instead.
Bottom line: execute pre-grad trades from plain EOAs, straight to the curve. At graduation the token becomes a plain ERC-20 forever.
Custom errors
Done() 0x9f9fb434 buy/sell after the curve closed (graduation race) Slippage() 0x7dd37f70 output below minTokensOut / minBaseOut ZeroIn() 0x5c13dc6d zero value/amount TransfersLocked() 0xdb89e3f4 forbidden pre-grad ERC-20 transfer NotClosed() 0x8b4b52de graduate() before the curve closed AlreadyMigrated() 0xca1c3cbc graduate() twice PoolPriceMismatch() 0x34c45899 graduate() vs a pre-created skewed pool — retry later
Events on the curve
Buy (buyer idx, baseIn, tokensOut, virtBase, virtToken, realToken, realBase)
topic0 0x2c5cc05b9a7b53e2478a9af1c94ec079b5be7c669be3df98ad86d28237f689e7
Sell(seller idx, tokensIn, baseOut, virtBase, virtToken, realToken, realBase)
topic0 0xe771a8c700d0802cd276270eb0596a1aead6f28237a9e5f26e00ccf08dad7033
CurveClosed(token idx, realBase)
topic0 0x7af3bd9259c7bc9a2357d79512d0010fa7c7db320399e52280e157a6d725b624
Graduated(token idx, pool, tokenId, hypeLiquidity, tokenLiquidity)
topic0 0x487dc7f66c623fb0ff13f9024a3ff9675453d069e075eceb12d9f8d7870e2374Every Buy/Sell carries the post-trade reserves — one event stream is a full local replica of curve state and price. There is no server-side OHLCV endpoint: build pre-grad candles from these events, the REST tape, or the websocket feed; post-grad, chart from the V3 pool's Swap events (or DexScreener — slugs robinhood and hyperevm).
Standard Uniswap V3 mechanics on both chains (HyperSwap is a V3 fork with identical ABIs). Pool: from the Graduated event, or V3Factory.getPool(token, WNATIVE, 10000) — the 1% tier is the only one with liquidity. Quote with QuoterV2 quoteExactInputSingle. Buy with SwapRouter02 exactInputSingle passing tokenIn = WNATIVE and value = amountIn (the router auto-wraps; no deadline field). Sell by approving the router, swapping to WNATIVE with recipient 0x…0002 (keep-in-router sentinel) and unwrapWETH9(minNativeOut, recipient) in one multicall — slippage is enforced by the unwrap's minimum. We add no platform fee on DEX swaps.
Base URL https://api.hyper.meme — unauthenticated GETs, best consumed server-to-server. Select the chain with ?chain=4663 or ?chain=999 (default 999). Rate limit: 240 req/min/IP with standard RateLimit-* headers. Wei values are decimal strings, addresses lowercased, timestamps unix seconds. The API serves durable ledgers and rosters — quote and phase-check on-chain, not from the API.
GET /coins/registry?chain= coin roster: address, curve, creator, name, symbol,
metadataUri, createdTs, factory, pair, graduated
GET /trades/curve?coin=0x… pre-grad tape (price = post-trade curve price ×1e18)
GET /trades/v3?coin=0x… post-grad tape (derive price = baseAmount/tokenAmount)
GET /market?chain= graduated coins' live price + ATH
GET /coins/activity?chain= per-coin volume / txns / buys / sells (24h + lifetime)
GET /coins/holder-counts?chain= holder counts · GET /coins/:addr/holders top holders
GET /stats/volume-24h?chain= platform 24h volume
GET /health { ok: true }WebSocket (socket.io)
Connect socket.io to the same origin. Emit join with room "feed" (creations, graduations, notable trades) or "coin:0x<address>" — the address must be lowercased (a checksummed address acks joined but receives nothing). All pushes arrive as one event name, event, with {type: coin_created | trade | closed | graduated, coin, chainId, data, ts} — rooms are not chain-namespaced, always filter on chainId. Trade payloads include post-trade reserves, enough to maintain live curve state without RPC polling. Limits: 30 sockets/IP, 50 rooms/socket; a room-cap breach only acks error ("too many rooms") without disconnecting — listen for it.
- Watch TokenCreated on the factories above (or poll /coins/registry, or WS feed).
- Verify the (token, curve) pair on-chain before listing it.
- Multicall curve state; quote locally with the exact math (or the quote views).
- Buy: live re-quote → buy(minOut) with msg.value, from a plain EOA (or buyTo).
- Sell: approve the curve once → live re-quote → sell(amount, minOut).
- Gate every trade on complete() — the quote views do not check it.
- On CurveClosed: freeze (show "migrating"). On Graduated: switch to SwapRouter02 @ 1%.
- Treat Done() and Slippage() reverts as normal race outcomes (refresh and retry).
- Build candles from curve events / the trade tape; post-grad from pool Swap events.
- Use Multicall3 + the websocket; get a dedicated RPC for production traffic.
Integrating? We'll help — full JSON ABIs, a TypeScript mirror of the curve math, test-coin graduation runs on request, and a heads-up channel for parameter changes. Reach out to @xbtdan on Telegram or @xbtdan on X.
Addresses and fees on this page render directly from the deployed configuration. Last reviewed July 2026.