Fermi V1: on-chain perps with FIFO matching and POSq logoFermi V1: on-chain perps with FIFO matching and POSq
Orders match on-chain. POSq sequences encrypted intents. The harness is the optimistic read path.
devrels.xyz/a/349Fermi V1 is a non-custodial perpetual-futures exchange on Solana. The trader signs. The deployed program places, cancels, matches, funds, and liquidates. UI: app.fermi.trade/perps. Docs: docs.fermi.trade. X @FermiTrade.
Four pieces: the on-chain exchange program (source of truth), POSq (encrypted intents ordered over VDF ticks; v1 is single-sequencer, reordering is detectable), a per-market AMQ commit/reveal queue (v5, inside the program), and an optimistic harness that publishes HTTP/SSE state in milliseconds while Solana finality follows. FIFO price-time book. Each side has a Fixed tree and an OraclePegged tree, 1024 nodes each. Event queue length 488.
| Item | Live value |
|---|---|
| Program | FRMiKrj2hQGvcZQtSDdiFRZ4cmaTjuc1QVkM2B5ShUvA |
| Group | 87qUKYQoK1f9gYQjYzw5NcRo7wx6VmfhTGJ7JenoeYAA |
| Markets | SOL-PERP (0), ETH-PERP (1), BTC-PERP (2) |
| Taker / maker | 0.06% / -0.03% (protocol share 0.03%). No tiers. |
| Account slots | 8 token, 8 perp, 6 open orders (expandable) |
| Local ports | Relayer 9090 gRPC, harness 9091 HTTP/SSE, fanout 9094 (auth) |
Hosted relayer and harness URLs live in ts/client/src/ids.json. Harness REST is read-only and unauthenticated. Fanout SSE takes ?api_key= or Bearer JWT from the operator. Devnet IDs rotate; pull them from the same file.
import { FermiClient, FERMI_V1_ID, GROUP_PUBKEY } from "@fermi/client"
import { Connection } from "@solana/web3.js"
const connection = new Connection(RPC_URL, "confirmed")
const client = await FermiClient.connect(connection, FERMI_V1_ID)
const group = await client.getGroup(GROUP_PUBKEY)
const acct = await client.getFermiAccountForOwner(group, owner.publicKey, 0)
const perp = group.getPerpMarketByName("SOL-PERP")
const intent = await client.buildPerpPlaceOrderIntent(acct, perp, {
side: "bid",
priceLots: perp.uiPriceToLots(150),
maxBaseLots: perp.uiBaseToLots(1),
clientOrderId: 1n,
reduceOnly: false,
timeInForceSeconds: 0,
selfTradeBehavior: "decrement_take",
params: { type: "fixed", orderType: "limit" },
})
const signed = await intent.signWith(owner)
const result = await client.submitIntent(signed)npm @fermi/client. Also Rust and a thin Python client. Need ≥ 0.05 SOL plus a supported collateral (USDC recommended). Trace a stuck intent with GET <harness>/trace/sequence/<market>/<seq>. Oracle freshness: GET <harness>/state/oracles. Relayer pre-check can return STALE_ACCOUNT; reload the account view and retry.
Keep reading
Jupiter routes every swap through a live graph of Solana's AMMs, splits orders across pools, and executes via versioned transactions with embedded ALTs. Under that is the JLP vault backing perpetuals, an on-chain DCA program, a limit-order crank, and a community-gated token launchpad. Here's the full picture for builders integrating it.
Two pools: crypto main pool and commodities. createKitClient. Never commit the key.
Docs at docs.bulk.trade. OpenAPI 3.0. Keep Backpack Exchange. Homepage claims 20ms BULKBFT blocks and up to 40x leverage.
Get new articles in your inbox
Technical deep-dives on Solana tooling, infrastructure, and ecosystem. No noise.
