Overview
Architecture
Components
flowchart TB
subgraph Clients
UI[Lane front<br/>separate project]
App[Wallets / apps / bots]
end
subgraph API process [API process - api/src]
S[server.ts<br/>Fastify HTTP + WS]
I[indexer.ts<br/>pool state]
R[router.ts<br/>pathfinding + estimators]
P[plan.ts<br/>exact quotes + splits]
K[keeper.ts<br/>order filler + fee converter]
PR[probe.ts<br/>honeypot/tax probe]
L[launchpad.ts]
A[account.ts / orders.ts]
end
subgraph Chain [Elysium]
EX[Executor]
OB[OrderBook]
FC[FeeCollector]
POOLS[V2 / V3 / V4 pools]
LP[Launchpad router]
end
RPC[(RPC / WS)]
RD[(Redis, optional)]
UI --> S
App --> S
S --> R --> I
S --> P --> EX
S --> PR
S --> L --> LP
S --> A
K --> P
K --> OB
K --> FC
I <--> RPC
I <--> RD
EX --> POOLS
OB --> EX
FC --> EX| Component | File | Role |
|---|---|---|
| HTTP/WS server | api/src/server.ts | Validation, /v1/* routes, simulation, API keys, rate limits, static UI |
| Indexer | api/src/indexer.ts | Factory discovery, pool state, ticks, reorgs, snapshots, token metadata |
| Router | api/src/router.ts | Path search, V2/V3/V4 estimators, spot prices, hop encoding |
| Planner | api/src/plan.ts | Exact batched quotes, gas-aware ranking, split allocation. Shared by /quote and the keeper |
| Keeper | api/src/keeper.ts | Fills due limit/DCA slices, refunds expired orders, converts collected fees |
| Probe | api/src/probe.ts + TokenProbe.sol | Buy → transfer → sell simulation to measure taxes and detect honeypots |
| Launchpad | api/src/launchpad.ts | Bonding-curve quotes for pre-graduation tokens |
| Orders / account | api/src/orders.ts, api/src/account.ts | Event-indexed orders, portfolio, history |
| Event store | api/src/store.ts | SQLite record of every swap/liquidity event in USD, price samples, TVL, Lane swaps, revenue, notifications (details) |
| Data routes | api/src/data-routes.ts, api/src/pnl.ts | Pools, charts, activity, candles, analytics, PnL, transfers |
| Keys and share cards | api/src/keys.ts, api/src/share.ts | Self-serve API keys and usage; PNG share cards |
| Config | api/src/config.ts + api/networks/*.json | Everything chain-specific, plus env settings |
| Executor | contracts/src/Executor.sol | Executes and quotes routes; takes the fee |
| OrderBook | contracts/src/OrderBook.sol | Escrow for limit/DCA orders; keeper-only fills |
| FeeCollector | contracts/src/FeeCollector.sol | Receives fees; converts them to a target token for the treasury |
Process model
Everything off-chain runs in one Node.js process (pnpm start): the indexer, the HTTP server, the keeper and the fee converter. Routing reads the indexer's in-memory maps directly, so there's no cache to keep in sync and no network hop between "the indexer" and "the router".
Scaling out:
- Run several instances behind a load balancer with
REDIS_URLset. They share the snapshot (each new instance boots from the latest state instead of backfilling) and the rate-limit counters. - Run the keeper on one instance only. The event store is a local SQLite file: with several instances, each keeps its own (point them at one volume, or give one instance the data routes) (set
KEEPER_PRIVATE_KEYthere and nowhere else), so two keepers don't race for the same slice.
Data flow of a quote
sequenceDiagram
participant C as Client
participant S as API
participant I as Indexer (memory)
participant N as RPC node
participant E as Executor (eth_call)
C->>S: GET /v1/quote?in&out&amount&recipient
S->>I: candidate paths + estimates
S->>N: multicall [Executor.quote x20] + feeBps + gasPrice
N->>E: run swaps, revert with amounts
S->>N: multicall [split legs at 5%..95%]
S->>N: allowance, balanceOf, eth_estimateGas(tx)
S-->>C: amountOut, minOut, splits, tx, approval, simulationOn-chain state vs off-chain state
| State | Lives in | Lost on restart? |
|---|---|---|
| Pool reserves, ticks, liquidity | Indexer memory + snapshot | No (snapshot + replay) |
| Token metadata, probe results | Indexer memory + snapshot | No |
| Orders | OrderBook contract (source of truth), indexed from events | No |
| Fees | Forwarded each swap to the FeeCollector | n/a |
| Rate-limit counters | Memory, or Redis | Yes without Redis (harmless) |
| Events, prices, TVL history, Lane swaps, notifications, API keys and usage | SQLite data/events.db (Railway volume) | No |
The API is stateless with respect to users: no accounts, no sessions, no stored quotes.
Next: API at a glance