# Reference

## Terminal features

| Area | What it does |
| --- | --- |
| Wallet | EIP-6963 discovery with a `window.ethereum` fallback, switch or add HyperEVM (999), address plus USDC and HYPE balances, designed no-wallet, wrong-chain and rejected states. Watch-only mode with `?watch=0x...`. |
| Session key | Generated by the SDK, registered with one wallet signature after a plain-language summary, stored in `localStorage` with a clear control, expiry shown, re-registered when expired. |
| Trading | Market selector with live marks, long or short, margin, leverage slider up to 1000x, pre-trade panel (notional, entry, bust price, close outcomes), live validation against relayer limits, confirm dialog, session-key signing, submission through the proxy, intent status and toasts. |
| Positions | Live table fed by the wallet SSE stream, close one or close selected (batched at 12 per intent), trade history, pending orders with cancel. |
| Charts | Hyperliquid candles with an interval switcher, entry and bust lines for your positions, a TradingView tab for BTC and ETH, and a HYPE/USDC pool tab with GeckoTerminal candles and DexTools or GeckoTerminal embed toggles. |
| Fund | Deposit through the SDK deposit builder (each step signed in your wallet, activation fee and minimum shown). Withdraw with route (HyperCore or HyperEVM), fee and minimum shown. |
| Swap | KyberSwap quote on HyperEVM with route, rate, minimum received, price impact, gas, exact-amount approve, and a transaction your wallet signs. |
| Layout | Chart left, ticket right (Trade, Fund, Swap), positions below. On a phone it becomes a bottom nav with no horizontal scroll at 360px. Light and dark follow `prefers-color-scheme`. `prefers-reduced-motion` is honoured. |

## Keyboard shortcuts

Shortcuts are ignored while a dialog is open or while you are typing in a field (press `Esc` to leave a field).

| Key | Action |
| --- | --- |
| `B` | Set side to long |
| `S` | Set side to short |
| `/` | Open the Trade tab and focus the margin field |
| `M` | Next market |
| `[` and `]` | Leverage down or up by 1 |
| `Shift` + `[` or `]` | Leverage down or up by 10 |
| `1` `2` `3` `4` | Trade, Positions, Fund, Swap |
| `C` | Chart view |
| `?` | Help dialog |
| `Esc` | Close a dialog or leave a field |

On the side tab bar, the left and right arrow keys move between tabs.

## Deep link parameters

Deep links open the terminal with the order ticket prefilled and show a review banner. They only fill a form: nothing is signed or sent until you confirm in your own wallet. A request to `/` with any of these parameters redirects to `/app/` and keeps them.

```
https://papertrade-terminal.pages.dev/?market=BTC&side=long&margin=50&leverage=10
```

| Parameter | Accepts | Notes |
| --- | --- | --- |
| `market` | Symbol such as `BTC` or `ETH` (1 to 12 letters or digits), or a numeric market id | Resolved against the live market list. Unknown values are ignored. |
| `side` | `long` or `short` | Case-insensitive. |
| `margin` | Decimal USD, up to 8 integer digits and 6 decimals, greater than 0 and at most 10,000,000 | Commas are stripped. |
| `leverage` | Integer 1 to 1000 | Clamped by the selected market's own maximum when the ticket renders. |

Invalid values are dropped individually, so a partly valid link still prefills what it can. After the link is applied the terminal removes the four parameters from the address bar, so a reload does not re-apply a stale link.

The `build_trade_plan` MCP tool returns a link in exactly this format.

## Other URL parameters

| Parameter | Effect |
| --- | --- |
| `embed=1` | Hides marketing chrome and shows only the product. Use it when embedding the terminal in a window or iframe. |
| `watch=0x...` | Read-only view of any address. No wallet is needed and no session key is created. |

The main app route sends `Content-Security-Policy: frame-ancestors` for the Papertrade OS (`https://papertrade-os.pages.dev`) and other `*.pages.dev` hosts, so it can be embedded as a window there. See [security](https://papertrade-terminal.pages.dev/docs/security/).

## Proxy endpoints

The Papertrade API sends no CORS headers, so the browser talks to a same-origin Pages Function mounted at `/api/papertrade/*`. It forwards to `PAPERTRADE_API_URL` and holds no keys.

| Method | Path | Forwarded to |
| --- | --- | --- |
| `GET` | `/api/papertrade/state/*` | Trading state, wallet state, leaderboards, and the SSE stream `/state/user/live?wallet=0x...` |
| `GET` | `/api/papertrade/query/*` | Account, portfolio, queue and protocol queries |
| `GET` | `/api/papertrade/queue-rank/*` | Queue rank lookups |
| `GET` | `/api/papertrade/relayer/health` | Relayer health |
| `POST` | `/api/papertrade/intents` | Already-signed intents |
| `POST` | `/api/papertrade/intents/0x{64 hex}/cancel` | Signed cancel for a queued intent |
| `POST` | `/api/papertrade/intents/0x{64 hex}/onward` | Hyperliquid-signed onward action for non-HyperCore withdrawals |
| `POST` | `/api/papertrade/funding/deposits/check` | Deposit proxy check |
| `OPTIONS` | any | `204` with `Allow: GET, POST, OPTIONS` |

Everything else returns `404` with `{"code":"not_proxied", ...}`. POST bodies are limited to 64 KB (`413 body_too_large`). An unreachable upstream returns `502 upstream_unreachable`. Query strings must be canonical (each parameter once, sorted by name). The SDK does this for you, so call the API through `papertrade-sdk` with `baseUrl: '/api/papertrade'`.

The proxy is also documented in the [OpenAPI spec](https://papertrade-terminal.pages.dev/openapi.json).

## Environment variables

None are required.

| Name | Default | Purpose |
| --- | --- | --- |
| `PAPERTRADE_API_URL` | `https://exchange.papertrade.xyz` | Upstream that both the proxy and the MCP server call. Set it in `site/wrangler.toml` under `[vars]`, in `site/.dev.vars` for local dev, or in the Pages project settings. |

## Scripts

| Script | Does |
| --- | --- |
| `npm run typecheck` | `tsc --noEmit` for the app and for `site/functions` |
| `npm test` | vitest suites |
| `npm run build:docs` | Render `docs/*.md` into `site/public/docs/`, plus `llms.txt`, `llms-full.txt` and `sitemap.xml` |
| `npm run build:site` | Docs first, then the esbuild app bundle |
| `npm run dev:site` | Build and serve with `wrangler pages dev` on port 8788 |
| `npm run deploy:site` | Build and `wrangler pages deploy` |
