Protocol
FORGE uses a Mobula Enterprise API key for:
GET /api/2/swap/quoting → user wallet signs MobulaRouter calldata PONS remains the launch + fee + on-chain event source of truth (indexer). Mobula is the market UX + execution routing layer for charts and swaps. Do not invent a second aggregator.
Official Mobula docs (re-read at integration time):
Mobula lists Robinhood Chain as evm:4663 for swap routing.
MOBULA_API_KEY= # Enterprise key — API/worker only, NEVER browser
MOBULA_API_BASE_URL=https://api.mobula.io
MOBULA_WS_URL= # from Mobula enterprise docs / dashboard
MOBULA_CHAIN_ID=evm:4663
MOBULA_TRADINGVIEW_ENABLED=true
MOBULA_SWAP_ENABLED=true
MOBULA_DEFAULT_SLIPPAGE_BPS=100 # 1% default UI slippage; user-adjustableMOBULA_API_KEY. /api/v1/market/*, /api/v1/swap/*); Fastify proxies to Mobula with the enterprise key. /token/[address] embed TradingView Charting Library (self-hosted under apps/web static assets per Mobula cookbook). prefers-reduced-motion for non-essential chart chrome only. 1, 5, 15, 60, 240, 1D mapped to Mobula period.Implement Mobula-style datafeed in apps/web that calls FORGE, not Mobula directly:
| Client need | FORGE API | Upstream Mobula |
|---|---|---|
| Symbol resolve / search | GET /market/symbols | Mobula asset/pair metadata |
Historical bars getBars | GET /market/ohlcv | Mobula historical pair/asset OHLCV |
| Real-time | FORGE WS room or SSE proxying Mobula ohlcv stream | Mobula WS OHLCV |
Modes (from Mobula cookbook):
mode=asset): chart the token; Mobula routes to highest-liquidity pool. Use for Agent pages when curve vs pool is abstracted. mode=pool): pin address to the PONS curve or graduated Uniswap v4 pool when the indexer knows the exact venue.Prefer pool mode when launches.curve_address or graduated pool is known so the chart matches the tradeable venue. Fall back to asset mode if pool metadata is missing.
Indexer still tracks CURVE → GRADUATING → POOL. Chart should remain one series:
address to the locked v4 pool; avoid resetting the visible history if Mobula provides continuous OHLCV — if not, stitch at graduation timestamp and label the phase boundary in the UI.Indexed PONS trades remain available for the activity tape; they do not replace Mobula as the TradingView datafeed.
POST /api/v1/swap/quote. GET /api/2/swap/quoting with enterprise key. data.evm.transaction) via MobulaRouter. eth_sendTransaction / wagmi send. chainId=evm:4663
tokenIn=...
tokenOut=...
amount=... | amountRaw=...
walletAddress=0x...
slippage=... # from UI / MOBULA_DEFAULT_SLIPPAGE_BPS
poolAddress=... # optional: PONS curve or graduated pool (pool targeting)
onlyProtocols=... # optional0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE on EVM). poolAddress so routing prefers that venue (see Mobula pool-targeting guide). to against expected MobulaRouter allowlist for evm:4663 before returning to client. GET /api/v1/market/ohlcv # TradingView getBars proxy
GET /api/v1/market/symbols # resolve token/pool for chart
GET /api/v1/market/price # optional spot helper
POST /api/v1/swap/quote # Mobula swap quoting proxy
POST /api/v1/swap/prepare-approval # optional spender + amount helper from quoteWebSocket: either extend forge-ws with market.ohlcv events fed from a Mobula WS subscriber in worker/indexer, or have the TradingView datafeed use a short-lived authenticated SSE from API. Prefer one server-side Mobula WS fan-out to many browsers (enterprise key stays server-side).
packages/market/ # Mobula client, types, quote validation, TV period maps
apps/web/.../charts/ # TradingView widget + datafeed calling FORGE
apps/api/.../market/ # proxy routes
apps/api/.../swap/ # quote routes
apps/worker/mobula-ws.ts # optional shared OHLCV subscriberevm:4663. MOBULA_API_KEY never appears in client bundles or network responses.