Simple Swap
Simple Swap is the one-click swap surface on dreamDEX — a Uniswap-style card that routes through the spot order book via the SpotRouter. It is the consumer entry point alongside the advanced CLOB trading view.
Simple Swap is live on Somnia mainnet (chain ID 5031) and testnet (chain ID 50312). Open it from the Simple Swap card in the dreamDEX app.
Getting started
- Connect your wallet. Simple Swap signs and submits each swap through a Privy-backed smart wallet provisioned for you; your connected EVM wallet (e.g. MetaMask) only signs the smart-wallet operations. The card prompts you to switch if you are on the wrong Somnia network.
- Fund the smart wallet. Copy the smart wallet address from the wallet menu (it differs from your EOA) and fund it with the input token you want to swap, plus a little native SOMI for gas. Balances on your EOA are not used — every swap pulls from the smart wallet.
- First swap — Approve Router. Before your first swap the card shows a one-time Approve Router step that grants the router operator permission to place orders on your behalf (see How a swap works). Subsequent swaps skip it.
Supported tokens: SOMI (native), USDso, USDC.e (mainnet only), WBTC, WETH.
Testing on testnet. On chain
50312, get STT for gas from the Somnia testnet faucet, and mint test tokens (USDso / WETH / WBTC) from the in-app faucet at/simple/debug(no nav link — append the path manually).
Screenshot

How a swap works
- Connect a wallet. Simple Swap uses a Privy-backed smart wallet on the connected Somnia network. If you are on a different network the card prompts you to switch before any read or write.
- Pick the input token and amount. The card multicalls your wallet balance + the pool quote each tick. Output amount updates as you type (debounced).
- Pick the output token. The "Route" row reveals the path the swap will take — a direct pool for
X ↔ USDso, or a two-legX → USDso → Yfor cross-pairs. - First swap only — Approve Router. Before any swap can land, the router needs operator approval to call
placeOrderForon the pools on your behalf. The CTA reads Approve Router and submits a single one-time UserOp granting that approval globally across every pool the router knows about. Subsequent swaps skip this step. - Swap. The CTA flips to Swap (or Approve & Swap the first time you touch a given pool). A single UserOp bundles any missing per-pool ERC-20 approvals + the router call. On confirmation, the output token auto-delivers to your wallet — no withdraw step needed.
Why two confirmations on the first swap? The router-operator approval is a hard prerequisite. Showing it as a discrete CTA makes the trust step legible: you are granting the router permission to act on your behalf before any swap can land. Subsequent swaps need a single confirmation.
Advanced settings
Click the gear icon at the top-right of the card to open the settings sheet. The values you pick apply to every Simple Swap from this device.
Slippage tolerance
Caps how far the executed price can move against you between the quote and the fill.
| Preset | Notes |
|---|---|
| 0.10% | Tight — fills only if the book barely moves. Best for thick books. |
| 0.50% | Default. Comfortable balance for the testnet books. |
| 1.0% | Loose — survives moderate book churn. |
| Custom | Any value > 0 and ≤ 50%. Values above 5% raise a high-slippage warning. |
The slippage tolerance does two things on the router call:
- Sets
minOutputAmounttoquote.amountOut × (1 − slippageBps / 10000). If the realised fill drops below this, the router reverts withInsufficientOutput. - Sizes the per-leg
priceLimitfrom the quote'sworstFillPriceinflated by the slippage, tick-aligned worst-for-user. If the book moves past that limit the affected leg short-fills and the router surfacesLegFillFailed.
Deadline
Caps how long the order can sit between submission and inclusion.
| Preset | Notes |
|---|---|
| 5 m | Tight — useful for fast books. |
| 10 m | Balanced. |
| 30 m | Default. Survives slow bundler runs. |
| Custom | Any value > 0 minutes. |
The deadline translates to deadlineNs on the router call (now + minutes × 60 × 1e9). If the order has not been included by then, the router reverts with DeadlineExpired.
Routing graph
Only USDso-paired pools exist, so the route the UI picks is deterministic:
| Trade | Legs | Route |
|---|---|---|
X ↔ USDso for a listed base X | 1 | direct pool |
X ↔ Y for distinct listed bases X, Y | 2 | X → USDso → Y |
Listed bases are {SOMI, USDC.e, WBTC, WETH} on mainnet and {SOMI, WBTC, WETH} on testnet.
Native SOMI may only appear as the input on leg 0 or the output on the final leg — the router rejects native as an intermediate. The star topology above never needs SOMI as an intermediate, so the constraint is satisfied automatically.
Quote semantics
Simple Swap quotes call quoteMarketExactIn — a pure view function that walks the opposite-side order book naturally and returns:
amountOut— what you would receive right now forinputAmount.amountIn— what would actually leave your wallet (includes the auto-pull fee envelope; pool fees are currently zero).legs[i].worstFillPrice— the deepest price the trade would touch on legi. The UI uses this to size the livepriceLimitfor the swap call, so the executed amount lines up with the quoted amount modulo the slippage cushion.ok—trueif every leg fully filled. Whenok = falsewithamountOut > 0, the visible 64-level book ran out before your full budget could fill; the swap still executes for the partially-filled amount. Whenok = falsewithamountOut = 0, no fill is possible at any depth — the CTA stays disabled.
Error surface
The router decodes every revert into UX copy. Most common cases:
| Condition | What you'll see |
|---|---|
| Book too thin at your price | "No liquidity at your price — try a smaller amount or widen slippage." |
| Price moved past your slippage | "Price moved more than your slippage tolerance. Try again or widen tolerance." |
| Order sat too long | "Order expired before submission. Try again." |
| Router approval missing | "Router approval missing — click Approve Router and try again." |
| Self-match on a pool you make on | "No liquidity at your price — try a smaller amount or widen slippage." (the router cancels the taker side on self-match to avoid double-fee) |
| Wrong network | "Switch to the correct Somnia network." |
A complete enumeration lives in the SpotRouter contract reference.
Limitations
- Tokens. Mainnet: SOMI, USDso, USDC.e, WBTC, WETH. Testnet: SOMI, USDso, WBTC, WETH (no USDC.e). Additional tokens require listing in the underlying SpotPoolRegistry.
- Limit tab disabled. The Simple Swap card renders a Limit tab as "Coming soon" — the router is taker-only by design. For resting limit orders, use the CLOB trading view.
Contract reference
- SpotRouter — direct integration reference (functions, events, errors).
- Spot Contract Specifications — per-pool tick / lot / minimum parameters that the router enforces under the hood.
- Quick Start — the lower-level cast-driven path for placing orders directly on a SpotPool.