Skip to content

Browser wallet review boundary

In the web app, the futures API builds each transaction and the browser checks it before the wallet signs, without rebuilding it. The wallet signs, and the API adds the sponsor’s signature and sends it. This page describes that boundary: what it guarantees, what it leaves to the wallet and the program, and how the app follows a transaction.

The preparation format is described in Prepared transactions.

Before the wallet is asked to sign, the web app checks the decoded transaction:

  • the fee payer is the sponsor named by the API’s /v1/config;
  • your wallet is a required signer, and no one but you and the sponsor signs;
  • every top-level instruction calls one of the expected programs: the compute budget, token, associated token and system programs, and Amoeba’s futures programs from /v1/config.

If any check fails, the app shows why and signs nothing. After the wallet signs, the app checks that the signed message is byte-identical to the prepared one and that your signature is present, before anything is sent.

  • The app does not decode the futures instruction itself. The order’s side, range, lots and limit come from the ticket’s request and the API’s preparation; the program enforces the limit and every amount when the transaction runs. Petri checks the instruction too: see Prepared transactions.
  • It does not guarantee a fill. The package is proven against the book as it was prepared; if the book moved, the transaction fails and changes nothing.
  • It does not protect a compromised browser or wallet. Check the site address and what your wallet shows.

While you edit an order, the ticket keeps a quote and a prepared transaction for it, refreshed as the quote changes. On your click it signs that transaction as it is if it was prepared less than 45 seconds ago; otherwise it prepares again first. The sponsor accepts a prepared id for 90 seconds.

Phantom, Solflare and Backpack show the transaction in their own window. With a Google sign-in, Magic signs in your browser. In both cases the transaction’s fee payer is Amoeba’s sponsor, so your wallet pays no SOL.

The app submits the signed transaction to /v1/tx/submit once. The API sends it and resends the same bytes until it lands or its blockhash expires. The app then waits for it to be processed, shows the result, and keeps waiting in the background until it is confirmed with its fills.

If an order fails because the book changed (BadProposal, Unbalanced, NotBestPrice, NotMaxFill or FifoViolation), the app prepares it once more, and your wallet signs the new transaction. Any other failure is shown with its name. If the transaction was sent but has not landed, the app says so: check your positions before you retry.

The web app reads chain state through the API’s JSON-RPC gateway at /rpc. It accepts 18 methods, each with an exact parameter grammar, from allowed origins, with per-client limits. It never signs, and it refuses to relay a transaction whose fee payer is the sponsor: sponsored transactions go only through /v1/tx/submit. See API reference.

To test your own client against the same rules, feed it prepared transactions with each field changed in turn (another fee payer, an extra signer, an unexpected program, a changed message after signing) and check that it signs nothing.