All files / src orderbook.ts

25% Statements 6/24
0% Branches 0/5
0% Functions 0/8
25% Lines 6/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105    1x 1x 1x 1x 1x         1x                                                                                                                                                                                          
import { Slab } from "@bonfida/aaob";
import { PublicKey, Connection } from "@solana/web3.js";
import { Market } from "./market";
import { throwIfNull } from "./utils";
import * as aaob from "@bonfida/aaob";
import { CALLBACK_INFO_LEN } from "./state";
import BN from "bn.js";
 
/**
 * Orderbook class
 */
export class Orderbook {
  /** Market of the orderbook
   * @private
   */
  private _market: Market;
 
  /** Slab that contains asks
   * @private
   */
  private _slabAsks: Slab;
 
  /** Slab that contains bids
   * @private
   */
  private _slabBids: Slab;
 
  constructor(market: Market, slabBids: Slab, slabAsks: Slab) {
    this._market = market;
    this._slabBids = slabBids;
    this._slabAsks = slabAsks;
  }
 
  /**
   * Returns the market object associated to the orderbook
   */
  get market(): Market {
    return this._market;
  }
 
  /**
   * Returns the asks slab of the orderbook
   */
  get slabAsks(): Slab {
    return this._slabAsks;
  }
 
  /**
   * Returns the bids slab of the orderbook
   */
  get slabBids(): Slab {
    return this._slabBids;
  }
 
  /**
   *
   * @param connection The solana connection object to the RPC node
   * @param slabAddress The address of the Slab
   * @returns A deserialized Slab object
   */
  static async loadSlab(connection, slabAddress: PublicKey) {
    const { data } = throwIfNull(await connection.getAccountInfo(slabAddress));
    const slab = aaob.Slab.deserialize(data, new BN(CALLBACK_INFO_LEN));
    return slab;
  }
 
  /**
   *
   * @param connection The solana connection object to the RPC node
   * @param marketAddress The address of the market
   * @returns Returns an orderbook object
   */
  static async load(connection: Connection, marketAddress: PublicKey) {
    const market = await Market.load(connection, marketAddress);
    const slabBids = await Orderbook.loadSlab(connection, market.bidsAddress);
    const slabAsks = await Orderbook.loadSlab(connection, market.asksAddress);
    return new Orderbook(market, slabBids, slabAsks);
  }
 
  // Comment to use Webassembly
  /**
   *
   * @param depth Depth of orders to deserialize
   * @param asks Asks or bids boolean
   * @param uiAmount Optional, whether to return the amounts in uiAmount
   * @returns Returns an L2 orderbook
   */
  getL2(depth: number, asks: boolean, uiAmount?: boolean) {
    const convert = (p: aaob.Price) => {
      return {
        price: p.price,
        size: p.size.divn(Math.pow(10, this.market.baseDecimals)),
      };
    };
    Iif (uiAmount) {
      return asks
        ? this._slabAsks.getL2DepthJS(depth, asks).map(convert)
        : this._slabBids.getL2DepthJS(depth, asks).map(convert);
    }
    return asks
      ? this._slabAsks.getL2DepthJS(depth, asks)
      : this._slabBids.getL2DepthJS(depth, asks);
  }
}