Skip to Content

JIT-only MM

JIT-only market making means you do not keep a standing book. You compete in JIT auctions (see Matching Engine for liquidity sources). Instead, you:

  • subscribe to on-chain auction / order feeds,
  • compute the current “auction price” / acceptable fill price,
  • atomically fill as maker (and optionally post liquidity) when opportunities arise.

Subscribe to auctions / orders

import { AuctionSubscriber } from "@drift-labs/sdk";
Class AuctionSubscriberReference ↗
NameTypeDefault
driftClientany
optsany
resubOptsany
eventEmitterStrictEventEmitter<EventEmitter, AuctionSubscriberEvents>
subscriberany
subscribe() => Promise<void>
unsubscribe() => Promise<void>
import { OrderSubscriber } from "@drift-labs/sdk";
Class OrderSubscriberReference ↗
NameTypeDefault
driftClientDriftClient
usersAccountsMap<string, { slot: number; userAccount: UserAccount; }>
subscriptionPollingSubscription | WebsocketSubscription | grpcSubscription
commitmentCommitment
eventEmitterStrictEventEmitter<EventEmitter, OrderSubscriberEvents>
fetchPromisePromise<void>
fetchPromiseResolver() => void
mostRecentSlotnumber
decodeFn(name: string, data: Buffer) => UserAccount
decodeDataboolean
fetchAllNonIdleUsersboolean
subscribe() => Promise<void>
fetch() => Promise<void>
tryUpdateUserAccount(key: string, dataType: "raw" | "decoded" | "buffer", data: UserAccount | Buffer | string[], slot: number) => void
createDLOB(protectedMakerParamsMap?: ProtectMakerParamsMap | undefined) => DLOB

Creates a new DLOB for the order subscriber to fill. This will allow a caller to extend the DLOB Subscriber with a custom DLOB type.

getDLOB(slot: number, protectedMakerParamsMap?: ProtectMakerParamsMap | undefined) => Promise<DLOB>
getSlot() => number
addPubkey(userAccountPublicKey: PublicKey) => Promise<void>
mustGetUserAccount(key: string) => Promise<UserAccount>
unsubscribe() => Promise<void>

Compute auction prices (helpers)

import { getAuctionPrice } from "@drift-labs/sdk";
Function getAuctionPriceReference ↗
Parameters:
NameTypeDefault
orderOrder
slotnumber
oraclePriceany

Use MMOraclePriceData source for perp orders, OraclePriceData for spot

Returns:
BN

BN

Fill as maker (atomic place-and-make)

This pattern places your maker order and fills against the taker in one transaction.

// makerOrderParams: OptionalOrderParams // takerInfo: TakerInfo (includes taker user account + the order to fill) await driftClient.placeAndMakePerpOrder(makerOrderParams, takerInfo);
Method DriftClient.placeAndMakePerpOrderReference ↗
Parameters:
NameTypeDefault
orderParamsOptionalOrderParams
takerInfoTakerInfo
referrerInfoReferrerInfo
txParamsTxParams
subAccountIdnumber
Returns:
Promise<string>

Practical filters

In JIT-only workflows you’ll usually want filters like:

  • risk-increasing vs reducing (skip toxic flow)
  • max position size / leverage / free collateral
  • oracle validity / divergence checks
  • skip Swift-origin orders if you’re already handling them via the Swift websocket feed
import { isSignedMsgOrder } from "@drift-labs/sdk";
Function isSignedMsgOrderReference ↗
Parameters:
NameTypeDefault
orderOrder
Returns:
boolean
const oracle = driftClient.getMMOracleDataForPerpMarket(0);
Method DriftClient.getMMOracleDataForPerpMarketReference ↗
Parameters:
NameTypeDefault
marketIndexnumber
Returns:
MMOraclePriceData
const marketIndex = 0; const oracle = driftClient.getMMOracleDataForPerpMarket(marketIndex); const perpMarket = driftClient.getPerpMarketAccount(marketIndex); if (!oracle.isValid) return; if (!perpMarket) return; // Example: skip if oracle is stale or market is volatile for your strategy.
Last updated on