← Articles
Fermi V1: on-chain perps with FIFO matching and POSq logo
fermi

Fermi V1: on-chain perps with FIFO matching and POSq

· OCT 1, 2026 ·
Read
Share

Orders match on-chain. POSq sequences encrypted intents. The harness is the optimistic read path.

devrels.xyz/a/349

Fermi 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.

ItemLive value
ProgramFRMiKrj2hQGvcZQtSDdiFRZ4cmaTjuc1QVkM2B5ShUvA
Group87qUKYQoK1f9gYQjYzw5NcRo7wx6VmfhTGJ7JenoeYAA
MarketsSOL-PERP (0), ETH-PERP (1), BTC-PERP (2)
Taker / maker0.06% / -0.03% (protocol share 0.03%). No tiers.
Account slots8 token, 8 perp, 6 open orders (expandable)
Local portsRelayer 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.

typescript
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

Get new articles in your inbox

Technical deep-dives on Solana tooling, infrastructure, and ecosystem. No noise.

Fermi V1: on-chain perps with FIFO matching and POSq | devrels.xyz