UNPKG

@drift-labs/sdk

Version:
360 lines (359 loc) • 12.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.decodeUser = void 0; const anchor_1 = require("@coral-xyz/anchor"); const types_1 = require("../types"); const web3_js_1 = require("@solana/web3.js"); const numericConstants_1 = require("../constants/numericConstants"); function readUnsignedBigInt64LE(buffer, offset) { return new anchor_1.BN(buffer.subarray(offset, offset + 8), 10, 'le'); } function readSignedBigInt64LE(buffer, offset) { const unsignedValue = new anchor_1.BN(buffer.subarray(offset, offset + 8), 10, 'le'); if (unsignedValue.testn(63)) { const inverted = unsignedValue.notn(64).addn(1); return inverted.neg(); } else { return unsignedValue; } } function decodeUser(buffer) { let offset = 8; const authority = new web3_js_1.PublicKey(buffer.slice(offset, offset + 32)); offset += 32; const delegate = new web3_js_1.PublicKey(buffer.slice(offset, offset + 32)); offset += 32; const name = []; for (let i = 0; i < 32; i++) { name.push(buffer.readUint8(offset + i)); } offset += 32; const spotPositions = []; for (let i = 0; i < 8; i++) { const scaledBalance = readUnsignedBigInt64LE(buffer, offset); const openOrders = buffer.readUInt8(offset + 35); if (scaledBalance.eq(numericConstants_1.ZERO) && openOrders === 0) { offset += 40; continue; } offset += 8; const openBids = readSignedBigInt64LE(buffer, offset); offset += 8; const openAsks = readSignedBigInt64LE(buffer, offset); offset += 8; const cumulativeDeposits = readSignedBigInt64LE(buffer, offset); offset += 8; const marketIndex = buffer.readUInt16LE(offset); offset += 2; const balanceTypeNum = buffer.readUInt8(offset); let balanceType; if (balanceTypeNum === 0) { balanceType = types_1.SpotBalanceType.DEPOSIT; } else { balanceType = types_1.SpotBalanceType.BORROW; } offset += 6; spotPositions.push({ scaledBalance, openBids, openAsks, cumulativeDeposits, marketIndex, balanceType, openOrders, }); } const perpPositions = []; for (let i = 0; i < 8; i++) { const baseAssetAmount = readSignedBigInt64LE(buffer, offset + 8); const quoteAssetAmount = readSignedBigInt64LE(buffer, offset + 16); const lpShares = readUnsignedBigInt64LE(buffer, offset + 64); const openOrders = buffer.readUInt8(offset + 94); if (baseAssetAmount.eq(numericConstants_1.ZERO) && openOrders === 0 && quoteAssetAmount.eq(numericConstants_1.ZERO) && lpShares.eq(numericConstants_1.ZERO)) { offset += 96; continue; } const lastCumulativeFundingRate = readSignedBigInt64LE(buffer, offset); offset += 24; const quoteBreakEvenAmount = readSignedBigInt64LE(buffer, offset); offset += 8; const quoteEntryAmount = readSignedBigInt64LE(buffer, offset); offset += 8; const openBids = readSignedBigInt64LE(buffer, offset); offset += 8; const openAsks = readSignedBigInt64LE(buffer, offset); offset += 8; const settledPnl = readSignedBigInt64LE(buffer, offset); offset += 16; const lastBaseAssetAmountPerLp = readSignedBigInt64LE(buffer, offset); offset += 8; const lastQuoteAssetAmountPerLp = readSignedBigInt64LE(buffer, offset); offset += 8; const maxMarginRatio = buffer.readUInt16LE(offset); offset += 4; const marketIndex = buffer.readUInt16LE(offset); offset += 3; const perLpBase = buffer.readUInt8(offset); offset += 1; perpPositions.push({ lastCumulativeFundingRate, baseAssetAmount, quoteAssetAmount, quoteBreakEvenAmount, quoteEntryAmount, openBids, openAsks, settledPnl, lpShares, remainderBaseAssetAmount: 0, lastBaseAssetAmountPerLp, lastQuoteAssetAmountPerLp, marketIndex, openOrders, perLpBase, maxMarginRatio, }); } const orders = []; for (let i = 0; i < 32; i++) { // skip order if it's not open if (buffer.readUint8(offset + 82) !== 1) { offset += 96; continue; } const slot = readUnsignedBigInt64LE(buffer, offset); offset += 8; const price = readUnsignedBigInt64LE(buffer, offset); offset += 8; const baseAssetAmount = readUnsignedBigInt64LE(buffer, offset); offset += 8; const baseAssetAmountFilled = readUnsignedBigInt64LE(buffer, offset); offset += 8; const quoteAssetAmountFilled = readUnsignedBigInt64LE(buffer, offset); offset += 8; const triggerPrice = readUnsignedBigInt64LE(buffer, offset); offset += 8; const auctionStartPrice = readSignedBigInt64LE(buffer, offset); offset += 8; const auctionEndPrice = readSignedBigInt64LE(buffer, offset); offset += 8; const maxTs = readSignedBigInt64LE(buffer, offset); offset += 8; const oraclePriceOffset = buffer.readInt32LE(offset); offset += 4; const orderId = buffer.readUInt32LE(offset); offset += 4; const marketIndex = buffer.readUInt16LE(offset); offset += 2; const orderStatusNum = buffer.readUInt8(offset); let status; if (orderStatusNum === 0) { status = types_1.OrderStatus.INIT; } else if (orderStatusNum === 1) { status = types_1.OrderStatus.OPEN; } offset += 1; const orderTypeNum = buffer.readUInt8(offset); let orderType; if (orderTypeNum === 0) { orderType = types_1.OrderType.MARKET; } else if (orderTypeNum === 1) { orderType = types_1.OrderType.LIMIT; } else if (orderTypeNum === 2) { orderType = types_1.OrderType.TRIGGER_MARKET; } else if (orderTypeNum === 3) { orderType = types_1.OrderType.TRIGGER_LIMIT; } else if (orderTypeNum === 4) { orderType = types_1.OrderType.ORACLE; } offset += 1; const marketTypeNum = buffer.readUInt8(offset); let marketType; if (marketTypeNum === 0) { marketType = types_1.MarketType.SPOT; } else { marketType = types_1.MarketType.PERP; } offset += 1; const userOrderId = buffer.readUint8(offset); offset += 1; const existingPositionDirectionNum = buffer.readUInt8(offset); let existingPositionDirection; if (existingPositionDirectionNum === 0) { existingPositionDirection = types_1.PositionDirection.LONG; } else { existingPositionDirection = types_1.PositionDirection.SHORT; } offset += 1; const positionDirectionNum = buffer.readUInt8(offset); let direction; if (positionDirectionNum === 0) { direction = types_1.PositionDirection.LONG; } else { direction = types_1.PositionDirection.SHORT; } offset += 1; const reduceOnly = buffer.readUInt8(offset) === 1; offset += 1; const postOnly = buffer.readUInt8(offset) === 1; offset += 1; const immediateOrCancel = buffer.readUInt8(offset) === 1; offset += 1; const triggerConditionNum = buffer.readUInt8(offset); let triggerCondition; if (triggerConditionNum === 0) { triggerCondition = types_1.OrderTriggerCondition.ABOVE; } else if (triggerConditionNum === 1) { triggerCondition = types_1.OrderTriggerCondition.BELOW; } else if (triggerConditionNum === 2) { triggerCondition = types_1.OrderTriggerCondition.TRIGGERED_ABOVE; } else if (triggerConditionNum === 3) { triggerCondition = types_1.OrderTriggerCondition.TRIGGERED_BELOW; } offset += 1; const auctionDuration = buffer.readUInt8(offset); offset += 1; const postedSlotTail = buffer.readUint8(offset); offset += 1; const bitFlags = buffer.readUint8(offset); offset += 1; offset += 1; // padding orders.push({ slot, price, baseAssetAmount, quoteAssetAmount: undefined, baseAssetAmountFilled, quoteAssetAmountFilled, triggerPrice, auctionStartPrice, auctionEndPrice, maxTs, oraclePriceOffset, orderId, marketIndex, status, orderType, marketType, userOrderId, existingPositionDirection, direction, reduceOnly, postOnly, immediateOrCancel, triggerCondition, auctionDuration, bitFlags, postedSlotTail, }); } const lastAddPerpLpSharesTs = readSignedBigInt64LE(buffer, offset); offset += 8; const totalDeposits = readUnsignedBigInt64LE(buffer, offset); offset += 8; const totalWithdraws = readUnsignedBigInt64LE(buffer, offset); offset += 8; const totalSocialLoss = readUnsignedBigInt64LE(buffer, offset); offset += 8; const settledPerpPnl = readSignedBigInt64LE(buffer, offset); offset += 8; const cumulativeSpotFees = readSignedBigInt64LE(buffer, offset); offset += 8; const cumulativePerpFunding = readSignedBigInt64LE(buffer, offset); offset += 8; const liquidationMarginFreed = readUnsignedBigInt64LE(buffer, offset); offset += 8; const lastActiveSlot = readUnsignedBigInt64LE(buffer, offset); offset += 8; const nextOrderId = buffer.readUInt32LE(offset); offset += 4; const maxMarginRatio = buffer.readUInt32LE(offset); offset += 4; const nextLiquidationId = buffer.readUInt16LE(offset); offset += 2; const subAccountId = buffer.readUInt16LE(offset); offset += 2; const status = buffer.readUInt8(offset); offset += 1; const isMarginTradingEnabled = buffer.readUInt8(offset) === 1; offset += 1; const idle = buffer.readUInt8(offset) === 1; offset += 1; const openOrders = buffer.readUInt8(offset); offset += 1; const hasOpenOrder = buffer.readUInt8(offset) === 1; offset += 1; const openAuctions = buffer.readUInt8(offset); offset += 1; const hasOpenAuction = buffer.readUInt8(offset) === 1; offset += 1; let marginMode; const marginModeNum = buffer.readUInt8(offset); if (marginModeNum === 0) { marginMode = types_1.MarginMode.DEFAULT; } else if (marginModeNum === 1) { marginMode = types_1.MarginMode.HIGH_LEVERAGE; } else if (marginModeNum === 2) { marginMode = types_1.MarginMode.HIGH_LEVERAGE_MAINTENANCE; } else { console.error(`Detected unknown margin mode: ${marginModeNum}. Please update @drift-labs/sdk for latest IDL.`); marginMode = types_1.MarginMode.DEFAULT; } offset += 1; const poolId = buffer.readUint8(offset); offset += 1; offset += 3; // padding const lastFuelBonusUpdateTs = buffer.readUint32LE(offset); offset += 4; return { authority, delegate, name, spotPositions, perpPositions, orders, lastAddPerpLpSharesTs, totalDeposits, totalWithdraws, totalSocialLoss, settledPerpPnl, cumulativeSpotFees, cumulativePerpFunding, liquidationMarginFreed, lastActiveSlot, nextOrderId, maxMarginRatio, nextLiquidationId, subAccountId, status, isMarginTradingEnabled, idle, openOrders, hasOpenOrder, openAuctions, hasOpenAuction, marginMode, poolId, lastFuelBonusUpdateTs, }; } exports.decodeUser = decodeUser;