Skip to main content
All trading happens through a single instruction, place_order, parameterized by PlaceOrderParams.

PlaceOrderParams

pub struct PlaceOrderParams {
    pub price: u64,              // 0 for market; tick-aligned for limit
    pub base_amount: u64,        // size in 9-decimal base (SOL)
    pub direction: Direction,    // Long | Short
    pub post_only: bool,
    pub is_market: bool,
    pub max_slippage_bps: u16,   // market orders only
}

Market order

{
  price: 0n,
  baseAmount: 1_000_000_000n,    // 1 SOL
  direction: { __kind: 'Long' },
  postOnly: false,
  isMarket: true,
  maxSlippageBps: 100,            // 1% — revert if avg fill > 1% from quote
}
Behavior:
  • Walks the book immediately, taking up to 4 fills per tx (compute-unit cap).
  • Any remainder is cancelled, not rested, limit orders are a separate thing.
  • Reverts SlippageExceeded if the average fill price exceeds the quote + max_slippage_bps.

Limit order

{
  price: 128_000_000n,            // $128.00
  baseAmount: 2_000_000_000n,
  direction: { __kind: 'Long' },
  postOnly: false,
  isMarket: false,
  maxSlippageBps: 0,              // unused
}
Behavior:
  • If it crosses (the limit price already matches resting orders on the other side), it takes up to 4 fills as a taker and rests the remainder.
  • Otherwise, it rests on the book at price, reserving baseAmount × price × initialMarginRatio / 10_000 of collateral.

Post-only

{
  price: 128_000_000n,
  baseAmount: 1_000_000_000n,
  direction: { __kind: 'Long' },
  postOnly: true,
  isMarket: false,
  maxSlippageBps: 0,
}
Behavior:
  • If placing the order would cross the book (immediately match as a taker), the tx reverts with OrderWouldCross.
  • Otherwise, rests on the book, guaranteed maker fill semantics.

Direction semantics

Direction::Long = bid = buy = entering a long or closing a short. Direction::Short = ask = sell = entering a short or closing a long. Kimia does not distinguish “entering” vs “closing” at the instruction level the direction simply flips your base_amount. If you’re long 1 SOL and place a short order of 2 SOL, you end up short 1 SOL. This is called flipping, and the realized PnL on the closed leg is banked automatically.

Cancel orders

getCancelOrderInstruction({
  signer,
  userAccount,
  market,
  orderbook,
  params: { orderIndex: 0, direction: { __kind: 'Long' } },   // find via fetch + iter
});
Or in bulk:
getCancelAllOrdersInstruction({ signer, userAccount, market, orderbook });
Cancelling refunds the reserved margin back to free_collateral immediately.

Limits

QuantityPer market
Resting bids32
Resting asks32
Fills per place_order4
Orders per userNo hard cap; limited by total_reserved_margin ≤ collateral
If the book is full, new orders revert OrderbookFull. V2 expands this.