Documentation
Introduction
zKmex is a GPU-accelerated perpetual futures protocol on Solana. Orders are matched in massively parallel batches on GPU compute, risk is enforced on-chain by a Solana program, marks are anchored to Pyth oracles, and every position settles in USDC.
The fastest way to feel it is the trading app — connect a wallet and open a GPU-matched perp on devnet.
How the GPU engine works
A perpetual is a leveraged bet on a price with no expiry. The hard part at scale is matching: with thousands of resting orders across many markets, a serial CPU matcher becomes the bottleneck. zKmex offloads matching to the GPU.
Each block, the engine loads the orderbook into GPU memory, runs a parallel price-time priority match across all markets at once, then commits the resulting fills and the post-match book state to Solana. Because the match is a pure function of the inputs, anyone can re-run it and verify the engine produced the correct fills.
block N
├─ load orderbook → GPU memory (all markets)
├─ parallel match → price-time priority, batched
├─ risk pass → scan every position for maint. margin
└─ commit → fills + book root → SolanaInstall
Pick the SDK that matches your stack. The TypeScript SDK is the most complete.
# TypeScript / Node
npm install @zkmex/sdk
# Python
pip install zkmexQuickstart
Connect, open a long with leverage, and read it back in a few lines.
import { ZKmex } from '@zkmex/sdk'
const zk = new ZKmex({ cluster: 'mainnet-beta', wallet })
// 1. open a 5x long on SOL-PERP with 200 USDC margin
const pos = await zk.orders.market({
market: 'SOL-PERP',
side: 'long',
marginUsdc: 200,
leverage: 5,
})
// 2. read live position state
const live = await zk.positions.get(pos.id)
console.log(live.entryPrice, live.markPrice, live.unrealizedPnl)
// 3. close it
await zk.positions.close(pos.id)Perp markets
Each market is a USDC-margined perpetual on a single underlying. Markets share one cross-margin collateral pool by default, or can be traded in isolated mode.
const market = await zk.markets.get('SOL-PERP')
// { symbol, markPrice, indexPrice, fundingRate, openInterest, maxLeverage }Margin & leverage
Leverage runs up to 50x depending on the market. Initial margin opens the position; maintenance margin keeps it alive. Cross out below maintenance and the engine liquidates you.
await zk.orders.market({
market: 'BTC-PERP',
side: 'short',
marginUsdc: 1000,
leverage: 20, // 20,000 USDC notional
reduceOnly: false,
})On-chain risk
Risk parameters live in a Solana PDA and are evaluated by the program before any order fills. Max leverage, max notional, and maintenance ratios are cryptographic constraints — there is no application-side path that lets an account over-leverage.
await zk.risk.set(account, {
maxLeverage: 24, // hard cap per position
maxNotionalUsdc: 250000,// per market
maintMarginRatio: 0.05, // 5% maintenance
})Funding
Funding ties the perp mark to the index. When the mark trades above the index, longs pay shorts; below, shorts pay longs. zKmex accrues funding per block instead of on a fixed 8-hour clock, so the rate tracks reality continuously.
const f = await zk.markets.funding('SOL-PERP')
// { rate1h: 0.0094%, nextAccrualSlot, longsPay: true }Liquidations
Every block the engine runs a GPU-parallel risk pass over all open positions. Any account below maintenance margin is liquidated atomically in the same commit — no keeper race, no mempool sniping. The insurance fund backstops residual bad debt.
zk.on('liquidation', (e) => {
// { account, market, side, notionalUsdc, markPrice, slot }
})REST & WebSocket
Place orders over REST, stream GPU-matched fills and book deltas over WebSocket.
curl https://api.zkmex.fun/v1/orders \
-H "Authorization: Bearer zk_live_..." \
-d '{ "market": "SOL-PERP", "side": "long", "margin_usdc": 200, "leverage": 5 }'Errors
Errors use stable string codes. Risk blocks return 200 with ok:false.
{
"error": {
"code": "risk_violation",
"message": "leverage 60x exceeds market cap 50x",
"risk_pda": "RiSk…7x"
}
}Ready to trade for real? Open the app →