@drift-labs/sdk
Version:
SDK for Drift Protocol
123 lines (122 loc) • 6.27 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRemainingAccounts = void 0;
const web3_js_1 = require("@solana/web3.js");
const types_1 = require("../types");
const numericConstants_1 = require("../constants/numericConstants");
const spotPosition_1 = require("../math/spotPosition");
const position_1 = require("../math/position");
function getRemainingAccounts(ctx, params) {
var _a;
const { oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap } = getRemainingAccountMapsForUsers(ctx, params.userAccounts);
if (params.useMarketLastSlotCache) {
const lastUserSlot = (_a = ctx.getUserAccountAndSlot(params.userAccounts.length > 0
? params.userAccounts[0].subAccountId
: ctx.activeSubAccountId, params.userAccounts.length > 0
? params.userAccounts[0].authority
: ctx.authority)) === null || _a === void 0 ? void 0 : _a.slot;
for (const [marketIndex, slot] of ctx.perpMarketLastSlotCache.entries()) {
if (slot > lastUserSlot) {
addPerpMarketToRemainingAccountMaps(ctx, marketIndex, false, oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap);
}
else {
ctx.perpMarketLastSlotCache.delete(marketIndex);
}
}
for (const [marketIndex, slot] of ctx.spotMarketLastSlotCache.entries()) {
if (slot > lastUserSlot) {
addSpotMarketToRemainingAccountMaps(ctx, marketIndex, false, oracleAccountMap, spotMarketAccountMap);
}
else {
ctx.spotMarketLastSlotCache.delete(marketIndex);
}
}
}
if (params.readablePerpMarketIndex !== undefined) {
const readablePerpMarketIndexes = Array.isArray(params.readablePerpMarketIndex)
? params.readablePerpMarketIndex
: [params.readablePerpMarketIndex];
for (const marketIndex of readablePerpMarketIndexes) {
addPerpMarketToRemainingAccountMaps(ctx, marketIndex, false, oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap);
}
}
for (const perpMarketIndex of ctx.mustIncludePerpMarketIndexes.values()) {
addPerpMarketToRemainingAccountMaps(ctx, perpMarketIndex, false, oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap);
}
if (params.readableSpotMarketIndexes !== undefined) {
for (const readableSpotMarketIndex of params.readableSpotMarketIndexes) {
addSpotMarketToRemainingAccountMaps(ctx, readableSpotMarketIndex, false, oracleAccountMap, spotMarketAccountMap);
}
}
for (const spotMarketIndex of ctx.mustIncludeSpotMarketIndexes.values()) {
addSpotMarketToRemainingAccountMaps(ctx, spotMarketIndex, false, oracleAccountMap, spotMarketAccountMap);
}
if (params.writablePerpMarketIndexes !== undefined) {
for (const writablePerpMarketIndex of params.writablePerpMarketIndexes) {
addPerpMarketToRemainingAccountMaps(ctx, writablePerpMarketIndex, true, oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap);
}
}
if (params.writableSpotMarketIndexes !== undefined) {
for (const writableSpotMarketIndex of params.writableSpotMarketIndexes) {
addSpotMarketToRemainingAccountMaps(ctx, writableSpotMarketIndex, true, oracleAccountMap, spotMarketAccountMap);
}
}
return [
...oracleAccountMap.values(),
...spotMarketAccountMap.values(),
...perpMarketAccountMap.values(),
];
}
exports.getRemainingAccounts = getRemainingAccounts;
function addPerpMarketToRemainingAccountMaps(ctx, marketIndex, writable, oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap) {
const perpMarketAccount = ctx.getPerpMarketAccount(marketIndex);
perpMarketAccountMap.set(marketIndex, {
pubkey: perpMarketAccount.pubkey,
isSigner: false,
isWritable: writable,
});
const oracleWritable = writable && (0, types_1.isVariant)(perpMarketAccount.amm.oracleSource, 'prelaunch');
oracleAccountMap.set(perpMarketAccount.amm.oracle.toString(), {
pubkey: perpMarketAccount.amm.oracle,
isSigner: false,
isWritable: oracleWritable,
});
addSpotMarketToRemainingAccountMaps(ctx, perpMarketAccount.quoteSpotMarketIndex, false, oracleAccountMap, spotMarketAccountMap);
}
function addSpotMarketToRemainingAccountMaps(ctx, marketIndex, writable, oracleAccountMap, spotMarketAccountMap) {
const spotMarketAccount = ctx.getSpotMarketAccount(marketIndex);
spotMarketAccountMap.set(spotMarketAccount.marketIndex, {
pubkey: spotMarketAccount.pubkey,
isSigner: false,
isWritable: writable,
});
if (!spotMarketAccount.oracle.equals(web3_js_1.PublicKey.default)) {
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
pubkey: spotMarketAccount.oracle,
isSigner: false,
isWritable: false,
});
}
}
function getRemainingAccountMapsForUsers(ctx, userAccounts) {
const oracleAccountMap = new Map();
const spotMarketAccountMap = new Map();
const perpMarketAccountMap = new Map();
for (const userAccount of userAccounts) {
for (const spotPosition of userAccount.spotPositions) {
if (!(0, spotPosition_1.isSpotPositionAvailable)(spotPosition)) {
addSpotMarketToRemainingAccountMaps(ctx, spotPosition.marketIndex, false, oracleAccountMap, spotMarketAccountMap);
if (!spotPosition.openAsks.eq(numericConstants_1.ZERO) ||
!spotPosition.openBids.eq(numericConstants_1.ZERO)) {
addSpotMarketToRemainingAccountMaps(ctx, numericConstants_1.QUOTE_SPOT_MARKET_INDEX, false, oracleAccountMap, spotMarketAccountMap);
}
}
}
for (const position of userAccount.perpPositions) {
if (!(0, position_1.positionIsAvailable)(position)) {
addPerpMarketToRemainingAccountMaps(ctx, position.marketIndex, false, oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap);
}
}
}
return { oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap };
}