Skip to content
Solana

Docs · Integrations

Building an interface like the reel app

How reel's own app reads Solana with no database, keeps its RPC key server-side, simulates every transaction before a wallet sees it, and shows a dash rather than a guess.

On chain first, no database

The reel app has no database of pools, trades or users. Lists come from getProgramAccounts over reel's accounts, filtered by their 8-byte tag. Stats come from counters the program keeps in its own accounts: Config counts pools, launches, roots, hooks, agents, referrers and blocks; each Pool keeps volume, trades, fees by block, burned and recaptured totals. History comes from transaction logs, fetched and cached on the server.

Another interface can do exactly the same with the SDK: accountFilters("Pool") for the list, decodePool for each one, quoteSwap for prices.

The RPC relay

The browser never sees the RPC URL or its key. Every call from the app goes to /api/rpc, a narrow relay that only posts to the server's own RPC, takes JSON-RPC methods from a fixed allowlist with bounded params, caps batch and body size, limits each client's rate, and refuses cross-site browsers. WebSocket subscriptions don't pass the relay, so the app polls for confirmations instead. /api/health reports whether the RPC answers, its slot and the round trip; the Status page reads it.

The relay is for reel's own pages. An outside interface should run its own RPC.

Build, simulate, sign, send

Every value-moving action follows one pipeline:

  1. Re-read the accounts the transaction depends on, right before building it. Cached figures never decide a transaction.
  2. Build the instructions with the SDK, wrapping SOL in the same transaction when the quote is wSOL.
  3. Simulate it. A failure is shown as the program error's name and nothing reaches the wallet.
  4. Sign in the wallet. The prompt is not a receipt.
  5. Send and follow: rebroadcast while pending, poll the status, and report "expired" if the blockhash lapses, in which case nothing landed.
  6. Read back the changed accounts and show what actually happened.

Copy this order. A wallet approval, a pending toast and a confirmed signature are three different things, and an interface should say which one it has.

Fail closed

A figure on reel is read from chain or an API, or it shows as "—" with the reason. An unread balance is never zero, a failed read never sorts as the smallest value, and a control that depends on a missing figure stays disabled. Identity is an address: a token is its mint, never its ticker. Read Methodology and Where the numbers come from.

Deposit caps

A pool may have a deposit cap, a per-pool setting the admin can set or clear (0 means none). An interface built on reel should read the pool's deposit_cap before offering an add, and expect DepositCapExceeded (6037) if the pool has a cap set and a deposit would pass it. The cap only blocks new adds; swaps, withdrawals, fee collection and claims are never paused by it.