Skip to content

Rust and Petri integration

From Rust, you can integrate with capped futures in two ways: through the futures API, following the same prepare, check, sign and submit flow as the web app, or by building transactions from the chain with Amoeba’s futures client, as Petri does. The SDK’s Rust crate, ameba_sdk, re-exports that client as ameba_sdk::futures.

Component Status
Futures API https://api.amoeba.farm, on Solana mainnet; usable from any language.
Futures client (Rust) Amoeba’s futures client crate, re-exported by ameba_sdk as ameba_sdk::futures: instruction builders, the market account decoder and the package solver. Not published to crates.io.
TypeScript SDK ameba-sdk/futures: the API client, instruction builders and market decoder. A published package is coming. See SDK overview.
Petri Trades capped futures on Solana mainnet. Its mainnet release is coming; the packages published today (v0.1.9) run older code. See Petri CLI.
  1. Read GET /v1/config and check the genesis hash and the futures program against the values you trust. Ask your RPC for getGenesisHash too.
  2. Quote with POST /v1/quote, then prepare with POST /v1/tx/prepare (submit, close, cancel, deposit, withdraw). Set the limit from the quote plus your slippage.
  3. Decode the base64 transaction and run the checks in Prepared transactions.
  4. Sign the message bytes with the owner’s key, unchanged.
  5. Submit with POST /v1/tx/submit, then wait on GET /v1/tx/:signature/wait.

Keep amounts as integer atoms (u64 or u128), never floating point.

The futures client is what the futures API and Petri build with:

use ameba_sdk::futures::{Book, Market, Side, SubmitArgs, MODE_IOC};
let book = Book::decode(&market_account_data)?;
let h = book.header;
let m = Market::derive(program, market, h.vault, h.period, h.quote_mint, &h.product_id, h.expiry_ts);
let order = SubmitArgs { side: Side::Long, lo: 86, hi: 104, lots: 3, limit: 180_000, min_fill: 1, mode: MODE_IOC, close: None };
let ix = m.submit(&owner, &order, book.propose(&order.taker()).proposal);
  • Builders for every instruction: deposit, withdraw, submit, cancel, quote, split, merge, redeem, transfer, settlement, and the Earn vault’s (EarnVault).
  • The account decoders for the market account (traders, orders, ladders, claims and the market’s parameters) and the Earn vault and its positions.
  • Book::propose, the exact package solver. It computes the package for an order on the market account as read from chain, with the potentials the program verifies. The program rebuilds the whole book itself, so a proposal from any honest solver on the same account passes, and a stale one fails without changing anything.

Petri builds every order the way the web app’s ticket does, and checks more before it signs:

  • Trusted deployment. It reads the program addresses from a deployment manifest (--deployment) or /v1/config, and every market parameter (grid, k, step, mint, period, oracle program) from the market account. It refuses a market the trusted futures program does not own, or one with another USDC mint or oracle program.
  • Identity gate. Before any signature it checks that the RPC’s genesis is the trusted deployment’s and that the programs are deployed there.
  • Clock. It uses the cluster’s clock, not your computer’s, for anything time-related.
  • Orders. It quotes first and asks before sending, unless --yes. A market order sends at most the quoted fill, with a minimum fill of one lot and a limit no worse than the quote plus --slippage. A close names its position and carries the same kind of limit.
  • Two routes. With --route local, Petri solves the package itself with Book::propose on the account read from chain, builds the transaction with the futures client, signs it, and sends it through your RPC; your wallet pays the fee. With --route sponsored, the futures API prepares it, and Petri checks it in full before signing: sponsor fee payer, only the compute budget, the owner’s own USDC account creation and the trusted futures program, this market only, the owner as signer with their own token account, exactly the requested order, and a deposit no larger than the order can need.
  • Limits and errors. Every transaction sets a 1.4 million compute-unit limit, and each order a 256 KiB heap frame. Program errors are named: futures errors are 0x46520000 + n.

Every Petri command takes --json for structured output, and --yes to send without asking. Read commands work with any public address and need no key file. Petri’s MCP server gives AI agents read access only; trades are signed in your own terminal. See Petri CLI and Connect an AI agent.