UNPKG

@drift-labs/sdk-browser

Version:
160 lines (159 loc) 6.9 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.fastDecode = exports.restingOrderBeet = exports.orderIdBeet = void 0; const phoenix_sdk_1 = require("@ellipsis-labs/phoenix-sdk"); const beet = __importStar(require("@metaplex-foundation/beet")); exports.orderIdBeet = new beet.BeetArgsStruct([ ['priceInTicks', beet.u64], ['orderSequenceNumber', beet.u64], ], 'fIFOOrderId'); exports.restingOrderBeet = new beet.BeetArgsStruct([ ['traderIndex', beet.u64], ['numBaseLots', beet.u64], ['lastValidSlot', beet.u64], ['lastValidUnixTimestampInSeconds', beet.u64], ], 'fIFORestingOrder'); function deserializeRedBlackTree(data, keyDeserializer, valueDeserializer) { const tree = new Map(); const treeNodes = deserializeRedBlackTreeNodes(data, keyDeserializer, valueDeserializer); const nodes = treeNodes[0]; const freeNodes = treeNodes[1]; for (const [index, [key, value]] of nodes.entries()) { if (!freeNodes.has(index)) { tree.set(key, value); } } return tree; } function deserializeRedBlackTreeNodes(data, keyDeserializer, valueDeserializer) { let offset = 0; const keySize = keyDeserializer.byteSize; const valueSize = valueDeserializer.byteSize; const nodes = new Array(); // Skip RBTree header offset += 16; // Skip node allocator size offset += 8; const bumpIndex = data.readInt32LE(offset); offset += 4; let freeListHead = data.readInt32LE(offset); offset += 4; const freeListPointers = new Array(); for (let index = 0; offset < data.length && index < bumpIndex - 1; index++) { const registers = new Array(); for (let i = 0; i < 4; i++) { registers.push(data.readInt32LE(offset)); // skip padding offset += 4; } const [key] = keyDeserializer.deserialize(data.subarray(offset, offset + keySize)); offset += keySize; const [value] = valueDeserializer.deserialize(data.subarray(offset, offset + valueSize)); offset += valueSize; nodes.push([key, value]); freeListPointers.push([index, registers[0]]); } const freeNodes = new Set(); let indexToRemove = freeListHead - 1; let counter = 0; // If there's an infinite loop here, that means that the state is corrupted while (freeListHead < bumpIndex) { // We need to subtract 1 because the node allocator is 1-indexed const next = freeListPointers[freeListHead - 1]; [indexToRemove, freeListHead] = next; freeNodes.add(indexToRemove); counter += 1; if (counter > bumpIndex) { throw new Error('Infinite loop detected'); } } return [nodes, freeNodes]; } const fastDecode = (buffer) => { let offset = phoenix_sdk_1.marketHeaderBeet.byteSize; const [header] = phoenix_sdk_1.marketHeaderBeet.deserialize(buffer.subarray(0, offset)); const paddingLen = 8 * 32; let remaining = buffer.subarray(offset + paddingLen); offset = 0; const baseLotsPerBaseUnit = Number(remaining.readBigUInt64LE(offset)); offset += 8; const quoteLotsPerBaseUnitPerTick = Number(remaining.readBigUInt64LE(offset)); offset += 8; const sequenceNumber = Number(remaining.readBigUInt64LE(offset)); offset += 8; const takerFeeBps = Number(remaining.readBigUInt64LE(offset)); offset += 8; const collectedQuoteLotFees = Number(remaining.readBigUInt64LE(offset)); offset += 8; const unclaimedQuoteLotFees = Number(remaining.readBigUInt64LE(offset)); offset += 8; remaining = remaining.subarray(offset); const totalNumBids = (0, phoenix_sdk_1.toNum)(header.marketSizeParams.bidsSize); const totalNumAsks = (0, phoenix_sdk_1.toNum)(header.marketSizeParams.asksSize); const totalBidsSize = 16 + 16 + (16 + exports.orderIdBeet.byteSize + exports.restingOrderBeet.byteSize) * totalNumBids; const totalAsksSize = 16 + 16 + (16 + exports.orderIdBeet.byteSize + exports.restingOrderBeet.byteSize) * totalNumAsks; offset = 0; const bidBuffer = remaining.subarray(offset, offset + totalBidsSize); offset += totalBidsSize; const askBuffer = remaining.subarray(offset, offset + totalAsksSize); const bidsUnsorted = deserializeRedBlackTree(bidBuffer, exports.orderIdBeet, exports.restingOrderBeet); const asksUnsorted = deserializeRedBlackTree(askBuffer, exports.orderIdBeet, exports.restingOrderBeet); const bids = [...bidsUnsorted].sort((a, b) => { const priceComparison = (0, phoenix_sdk_1.sign)((0, phoenix_sdk_1.toBN)(b[0].priceInTicks).sub((0, phoenix_sdk_1.toBN)(a[0].priceInTicks))); if (priceComparison !== 0) { return priceComparison; } return (0, phoenix_sdk_1.sign)((0, phoenix_sdk_1.getUiOrderSequenceNumber)(a[0]).sub((0, phoenix_sdk_1.getUiOrderSequenceNumber)(b[0]))); }); const asks = [...asksUnsorted].sort((a, b) => { const priceComparison = (0, phoenix_sdk_1.sign)((0, phoenix_sdk_1.toBN)(a[0].priceInTicks).sub((0, phoenix_sdk_1.toBN)(b[0].priceInTicks))); if (priceComparison !== 0) { return priceComparison; } return (0, phoenix_sdk_1.sign)((0, phoenix_sdk_1.getUiOrderSequenceNumber)(a[0]).sub((0, phoenix_sdk_1.getUiOrderSequenceNumber)(b[0]))); }); const traders = new Map(); const traderPubkeyToTraderIndex = new Map(); const traderIndexToTraderPubkey = new Map(); return { header, baseLotsPerBaseUnit, quoteLotsPerBaseUnitPerTick, sequenceNumber, takerFeeBps, collectedQuoteLotFees, unclaimedQuoteLotFees, bids, asks, traders, traderPubkeyToTraderIndex, traderIndexToTraderPubkey, }; }; exports.fastDecode = fastDecode;