Market orders go through the ๏ปฟJust-In-Time (JIT) Auctions where Makers fight to fill orders before the order is allowed to fill against the ๏ปฟDrift AMM.
JIT Maker Bots maintain a local copy of the decentralised orderbook (DLOB) (see: ๏ปฟKeepers & Decentralised Orderbook) in order to see which orders are in the auction phase and can be bid on.
Getting Started
โ ๏ธ This bot requires collateral to run. This tutorial is a developer's guide and holds no responsibility over bot outcomes.
The reference implementation of the JIT Maker Bot is available here.
Follow the instructions at ๏ปฟKeeper Bots to set the required environment variables, initialise theClearingHouseUser and deposit some collateral.
Start the JIT Maker Bot:
Shell
|
yarn run dev:jitmaker
๏ปฟ
Technical Explanation
Streaming User Orders
The Typescript SDK exposes an EventSubscriber object that you can use to receive market orders on-chain.
TypeScript
|
import{
EventSubscriber,
OrderRecord,}from'@drift-labs/sdk'// clearingHouse init omitted for brevityconst pollEventsConfig ={
type:'polling',
frequency:1000,}const websocketEventsConfig ={
type:'websocket',}const eventSubscriber =newEventSubscriber(
connection,
clearingHouse.program,{
maxTx:8192,
maxEventsPerType:8192,
orderBy:'blockchain',
orderDir:'desc',
commitment:'confirmed',
logProviderConfig: pollEventsConfig,});
eventSubscriber.subscribe();
eventSubscriber.eventEmitter.on('newEvent',async(event)=>{if(event.eventType ==='OrderRecord'){const order = event as OrderRecord;// 1) update dlob// 2) get orders from DLOB still in auction// 3) bid on auctions}});
๏ปฟ
๏ปฟ
Bidding on JIT Auctions
Technical details on the JIT Auction and its pricing can be found at ๏ปฟJust-In-Time (JIT) Auctions. The reference implementation acts on each user order received and makes the order in the opposite direction at the auction end price with a random order size between 20 and MAX_TRADE_SIZE_QUOTE.
TypeScript
|
// after finding a DLOB node still in the auction periodconst jitMakerDirection =isVariant(nodeToFill.node.order.direction,'long')? PositionDirection.SHORT: PositionDirection.LONG;// the auction start price will always be valid, but is not necessarily the best priceconst jitMakerPrice = nodeToFill.node.order.auctionStartPrice;// fill the entire orderconst baseAmountToFill = nodeToFill.node.order.baseAssetAmount.sub(
nodeToFill.node.order.baseAssetAmountFilled
);const txSig =awaitthis.driftClient.placeAndMake({
orderType: OrderType.LIMIT,
marketIndex: nodeToFill.node.order.marketIndex,
baseAssetAmount: baseAmountToFill,
direction: jitMakerDirection,
price: jitMakerPrice,
postOnly:true,
immediateOrCancel:true,},{
taker: action.node.userAccount,
order: action.node.order,});console.log(`Bid on JIT auction: ${txSig}`);
๏ปฟ
Determine how much longer the auction will last
It may be helpful to determine how much time is left in the order's auction in order to get the current dutch auction price:
TypeScript
|
// determine how much auction time is leftconst orderSlot = nodeToFill.node.order.slot.toNumber();const currSlot = slotSubscriber.getSlot();const aucDur =newBN(nodeToFill.node.order.auctionDuration);const aucEnd = orderSlot + aucDur;console.log(`it has been ${
currSlot - orderSlot
} slots since order, auction ends in ${
aucEnd - currSlot
} slots`);
๏ปฟ
Tracking Open Positions and Orders
The main ClearingHouse object from the SDK will update (polling or WebSocket) the user's account details behind the scenes. You can access the open orders and open positions of the user account by reading the positions and orders object of the ClearingHouseUser.
TypeScript
|
// you can force the sdk to fetch latest account dataawaitthis.driftClient.fetchAccounts();awaitthis.driftClient.getUser().fetchAccounts();const user =this.driftClient.getUser();// check open positionsfor(const p of user.getUserAccount().positions){if(p.baseAssetAmount.isZero()){// no open position in this indexcontinue;}console.log(p);}// check open ordersfor(const o of user.getUserAccount().orders){if(isVariant(order.status,'init')){// no open order in this indexcontinue;}}