@drift-labs/sdk 2.77.0-beta.4 → 2.79.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/VERSION +1 -1
- package/lib/constants/numericConstants.d.ts +1 -0
- package/lib/constants/numericConstants.js +2 -1
- package/lib/driftClient.d.ts +7 -1
- package/lib/driftClient.js +90 -34
- package/lib/idl/drift.json +1 -1
- package/lib/tx/txParamProcessor.js +6 -3
- package/lib/user.d.ts +2 -0
- package/lib/user.js +29 -0
- package/package.json +1 -1
- package/src/constants/numericConstants.ts +2 -0
- package/src/driftClient.ts +141 -29
- package/src/idl/drift.json +1 -1
- package/src/tx/txParamProcessor.ts +7 -4
- package/src/user.ts +51 -0
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.
|
|
1
|
+
2.79.0-beta.0
|
|
@@ -64,3 +64,4 @@ export declare const DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT: BN;
|
|
|
64
64
|
export declare const ACCOUNT_AGE_DELETION_CUTOFF_SECONDS: number;
|
|
65
65
|
export declare const IDLE_TIME_SLOTS = 9000;
|
|
66
66
|
export declare const SLOT_TIME_ESTIMATE_MS = 400;
|
|
67
|
+
export declare const DUST_POSITION_SIZE: BN;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MARGIN_PRECISION = exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.PRICE_TO_QUOTE_PRECISION = exports.PRICE_DIV_PEG = exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.BASE_PRECISION_EXP = exports.BASE_PRECISION = exports.AMM_RESERVE_PRECISION = exports.PEG_PRECISION = exports.FUNDING_RATE_BUFFER_PRECISION = exports.FUNDING_RATE_PRECISION = exports.PRICE_PRECISION = exports.QUOTE_PRECISION = exports.LIQUIDATION_FEE_PRECISION = exports.SPOT_MARKET_IMF_PRECISION = exports.SPOT_MARKET_IMF_PRECISION_EXP = exports.SPOT_MARKET_BALANCE_PRECISION = exports.SPOT_MARKET_BALANCE_PRECISION_EXP = exports.SPOT_MARKET_WEIGHT_PRECISION = exports.SPOT_MARKET_UTILIZATION_PRECISION = exports.SPOT_MARKET_UTILIZATION_PRECISION_EXP = exports.SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION = exports.SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION_EXP = exports.SPOT_MARKET_RATE_PRECISION = exports.SPOT_MARKET_RATE_PRECISION_EXP = exports.AMM_RESERVE_PRECISION_EXP = exports.PEG_PRECISION_EXP = exports.FUNDING_RATE_PRECISION_EXP = exports.PRICE_PRECISION_EXP = exports.FUNDING_RATE_BUFFER_PRECISION_EXP = exports.QUOTE_PRECISION_EXP = exports.CONCENTRATION_PRECISION = exports.PERCENTAGE_PRECISION = exports.PERCENTAGE_PRECISION_EXP = exports.MAX_LEVERAGE_ORDER_SIZE = exports.MAX_LEVERAGE = exports.TEN_MILLION = exports.BN_MAX = exports.TEN_THOUSAND = exports.TEN = exports.NINE = exports.EIGHT = exports.SEVEN = exports.SIX = exports.FIVE = exports.FOUR = exports.THREE = exports.TWO = exports.ONE = exports.ZERO = void 0;
|
|
4
|
-
exports.SLOT_TIME_ESTIMATE_MS = exports.IDLE_TIME_SLOTS = exports.ACCOUNT_AGE_DELETION_CUTOFF_SECONDS = exports.DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT = exports.OPEN_ORDER_MARGIN_REQUIREMENT = exports.LAMPORTS_EXP = exports.LAMPORTS_PRECISION = exports.QUOTE_SPOT_MARKET_INDEX = exports.ONE_YEAR = exports.ONE_HOUR = exports.FIVE_MINUTE = exports.FUNDING_RATE_OFFSET_DENOMINATOR = exports.LIQUIDATION_PCT_PRECISION = exports.BID_ASK_SPREAD_PRECISION = void 0;
|
|
4
|
+
exports.DUST_POSITION_SIZE = exports.SLOT_TIME_ESTIMATE_MS = exports.IDLE_TIME_SLOTS = exports.ACCOUNT_AGE_DELETION_CUTOFF_SECONDS = exports.DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT = exports.OPEN_ORDER_MARGIN_REQUIREMENT = exports.LAMPORTS_EXP = exports.LAMPORTS_PRECISION = exports.QUOTE_SPOT_MARKET_INDEX = exports.ONE_YEAR = exports.ONE_HOUR = exports.FIVE_MINUTE = exports.FUNDING_RATE_OFFSET_DENOMINATOR = exports.LIQUIDATION_PCT_PRECISION = exports.BID_ASK_SPREAD_PRECISION = void 0;
|
|
5
5
|
const web3_js_1 = require("@solana/web3.js");
|
|
6
6
|
const __1 = require("../");
|
|
7
7
|
exports.ZERO = new __1.BN(0);
|
|
@@ -68,3 +68,4 @@ exports.DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT = new __1.BN(-25).mul(
|
|
|
68
68
|
exports.ACCOUNT_AGE_DELETION_CUTOFF_SECONDS = 60 * 60 * 24 * 13; // 13 days
|
|
69
69
|
exports.IDLE_TIME_SLOTS = 9000;
|
|
70
70
|
exports.SLOT_TIME_ESTIMATE_MS = 400;
|
|
71
|
+
exports.DUST_POSITION_SIZE = exports.QUOTE_PRECISION.divn(100); // Dust position is any position smaller than 1c
|
package/lib/driftClient.d.ts
CHANGED
|
@@ -251,6 +251,7 @@ export declare class DriftClient {
|
|
|
251
251
|
*/
|
|
252
252
|
initializeUserAccountAndDepositCollateral(amount: BN, userTokenAccount: PublicKey, marketIndex?: number, subAccountId?: number, name?: string, fromSubAccountId?: number, referrerInfo?: ReferrerInfo, donateAmount?: BN, txParams?: TxParams, customMaxMarginRatio?: number): Promise<[TransactionSignature, PublicKey]>;
|
|
253
253
|
initializeUserAccountForDevnet(subAccountId: number, name: string, marketIndex: number, tokenFaucet: TokenFaucet, amount: BN, referrerInfo?: ReferrerInfo, txParams?: TxParams): Promise<[TransactionSignature, PublicKey]>;
|
|
254
|
+
private getWithdrawalIxs;
|
|
254
255
|
/**
|
|
255
256
|
* Withdraws from a user account. If deposit doesn't already exist, creates a borrow
|
|
256
257
|
* @param amount
|
|
@@ -259,6 +260,9 @@ export declare class DriftClient {
|
|
|
259
260
|
* @param reduceOnly
|
|
260
261
|
*/
|
|
261
262
|
withdraw(amount: BN, marketIndex: number, associatedTokenAddress: PublicKey, reduceOnly?: boolean, subAccountId?: number, txParams?: TxParams): Promise<TransactionSignature>;
|
|
263
|
+
withdrawAllDustPositions(subAccountId?: number, txParams?: TxParams, opts?: {
|
|
264
|
+
dustPositionCountCallback?: (count: number) => void;
|
|
265
|
+
}): Promise<TransactionSignature | undefined>;
|
|
262
266
|
getWithdrawIx(amount: BN, marketIndex: number, userTokenAccount: PublicKey, reduceOnly?: boolean, subAccountId?: number): Promise<TransactionInstruction>;
|
|
263
267
|
/**
|
|
264
268
|
* Withdraws from the fromSubAccount and deposits into the toSubAccount
|
|
@@ -585,7 +589,9 @@ export declare class DriftClient {
|
|
|
585
589
|
settlePNLs(users: {
|
|
586
590
|
settleeUserAccountPublicKey: PublicKey;
|
|
587
591
|
settleeUserAccount: UserAccount;
|
|
588
|
-
}[], marketIndexes: number[]
|
|
592
|
+
}[], marketIndexes: number[], opts?: {
|
|
593
|
+
filterInvalidMarkets?: boolean;
|
|
594
|
+
}): Promise<TransactionSignature>;
|
|
589
595
|
getSettlePNLsIxs(users: {
|
|
590
596
|
settleeUserAccountPublicKey: PublicKey;
|
|
591
597
|
settleeUserAccount: UserAccount;
|
package/lib/driftClient.js
CHANGED
|
@@ -57,6 +57,7 @@ const marinade_1 = require("./marinade");
|
|
|
57
57
|
const orderParams_1 = require("./orderParams");
|
|
58
58
|
const utils_2 = require("./math/utils");
|
|
59
59
|
const txParamProcessor_1 = require("./tx/txParamProcessor");
|
|
60
|
+
const oracles_1 = require("./math/oracles");
|
|
60
61
|
/**
|
|
61
62
|
* # DriftClient
|
|
62
63
|
* This class is the main way to interact with Drift Protocol. It allows you to subscribe to the various accounts where the Market's state is stored, as well as: opening positions, liquidating, settling funding, depositing & withdrawing, and more.
|
|
@@ -69,7 +70,7 @@ class DriftClient {
|
|
|
69
70
|
this._isSubscribed = val;
|
|
70
71
|
}
|
|
71
72
|
constructor(config) {
|
|
72
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0;
|
|
73
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2;
|
|
73
74
|
this.users = new Map();
|
|
74
75
|
this._isSubscribed = false;
|
|
75
76
|
this.perpMarketLastSlotCache = new Map();
|
|
@@ -78,18 +79,22 @@ class DriftClient {
|
|
|
78
79
|
this.mustIncludeSpotMarketIndexes = new Set();
|
|
79
80
|
this.connection = config.connection;
|
|
80
81
|
this.wallet = config.wallet;
|
|
81
|
-
this.opts = config.opts ||
|
|
82
|
+
this.opts = config.opts || {
|
|
83
|
+
...anchor_1.AnchorProvider.defaultOptions(),
|
|
84
|
+
commitment: (_a = config === null || config === void 0 ? void 0 : config.connection) === null || _a === void 0 ? void 0 : _a.commitment,
|
|
85
|
+
preflightCommitment: (_b = config === null || config === void 0 ? void 0 : config.connection) === null || _b === void 0 ? void 0 : _b.commitment, // At the moment this ensures that our transaction simulations (which use Connection object) will use the same commitment level as our Transaction blockhashes (which use these opts)
|
|
86
|
+
};
|
|
82
87
|
this.provider = new anchor_1.AnchorProvider(config.connection,
|
|
83
88
|
// @ts-ignore
|
|
84
89
|
config.wallet, this.opts);
|
|
85
|
-
this.program = new anchor_1.Program(drift_json_1.default, (
|
|
86
|
-
this.authority = (
|
|
87
|
-
this.activeSubAccountId = (
|
|
88
|
-
this.skipLoadUsers = (
|
|
89
|
-
this.txVersion = (
|
|
90
|
+
this.program = new anchor_1.Program(drift_json_1.default, (_c = config.programID) !== null && _c !== void 0 ? _c : new web3_js_1.PublicKey(config_1.DRIFT_PROGRAM_ID), this.provider);
|
|
91
|
+
this.authority = (_d = config.authority) !== null && _d !== void 0 ? _d : this.wallet.publicKey;
|
|
92
|
+
this.activeSubAccountId = (_e = config.activeSubAccountId) !== null && _e !== void 0 ? _e : 0;
|
|
93
|
+
this.skipLoadUsers = (_f = config.skipLoadUsers) !== null && _f !== void 0 ? _f : false;
|
|
94
|
+
this.txVersion = (_g = config.txVersion) !== null && _g !== void 0 ? _g : 'legacy';
|
|
90
95
|
this.txParams = {
|
|
91
|
-
computeUnits: (
|
|
92
|
-
computeUnitsPrice: (
|
|
96
|
+
computeUnits: (_j = (_h = config.txParams) === null || _h === void 0 ? void 0 : _h.computeUnits) !== null && _j !== void 0 ? _j : 600000,
|
|
97
|
+
computeUnitsPrice: (_l = (_k = config.txParams) === null || _k === void 0 ? void 0 : _k.computeUnitsPrice) !== null && _l !== void 0 ? _l : 0,
|
|
93
98
|
};
|
|
94
99
|
if (config.includeDelegates && config.subAccountIds) {
|
|
95
100
|
throw new Error('Can only pass one of includeDelegates or subAccountIds. If you want to specify subaccount ids for multiple authorities, pass authoritySubaccountMap instead');
|
|
@@ -105,8 +110,8 @@ class DriftClient {
|
|
|
105
110
|
: config.subAccountIds
|
|
106
111
|
? new Map([[this.authority.toString(), config.subAccountIds]])
|
|
107
112
|
: new Map();
|
|
108
|
-
this.includeDelegates = (
|
|
109
|
-
if (((
|
|
113
|
+
this.includeDelegates = (_m = config.includeDelegates) !== null && _m !== void 0 ? _m : false;
|
|
114
|
+
if (((_o = config.accountSubscription) === null || _o === void 0 ? void 0 : _o.type) === 'polling') {
|
|
110
115
|
this.userAccountSubscriptionConfig = {
|
|
111
116
|
type: 'polling',
|
|
112
117
|
accountLoader: config.accountSubscription.accountLoader,
|
|
@@ -119,13 +124,13 @@ class DriftClient {
|
|
|
119
124
|
else {
|
|
120
125
|
this.userAccountSubscriptionConfig = {
|
|
121
126
|
type: 'websocket',
|
|
122
|
-
resubTimeoutMs: (
|
|
123
|
-
commitment: (
|
|
127
|
+
resubTimeoutMs: (_p = config.accountSubscription) === null || _p === void 0 ? void 0 : _p.resubTimeoutMs,
|
|
128
|
+
commitment: (_q = config.accountSubscription) === null || _q === void 0 ? void 0 : _q.commitment,
|
|
124
129
|
};
|
|
125
130
|
this.userStatsAccountSubscriptionConfig = {
|
|
126
131
|
type: 'websocket',
|
|
127
|
-
resubTimeoutMs: (
|
|
128
|
-
commitment: (
|
|
132
|
+
resubTimeoutMs: (_r = config.accountSubscription) === null || _r === void 0 ? void 0 : _r.resubTimeoutMs,
|
|
133
|
+
commitment: (_s = config.accountSubscription) === null || _s === void 0 ? void 0 : _s.commitment,
|
|
129
134
|
};
|
|
130
135
|
}
|
|
131
136
|
if (config.userStats) {
|
|
@@ -142,11 +147,11 @@ class DriftClient {
|
|
|
142
147
|
const noMarketsAndOraclesSpecified = config.perpMarketIndexes === undefined &&
|
|
143
148
|
config.spotMarketIndexes === undefined &&
|
|
144
149
|
config.oracleInfos === undefined;
|
|
145
|
-
if (((
|
|
146
|
-
this.accountSubscriber = new pollingDriftClientAccountSubscriber_1.PollingDriftClientAccountSubscriber(this.program, config.accountSubscription.accountLoader, (
|
|
150
|
+
if (((_t = config.accountSubscription) === null || _t === void 0 ? void 0 : _t.type) === 'polling') {
|
|
151
|
+
this.accountSubscriber = new pollingDriftClientAccountSubscriber_1.PollingDriftClientAccountSubscriber(this.program, config.accountSubscription.accountLoader, (_u = config.perpMarketIndexes) !== null && _u !== void 0 ? _u : [], (_v = config.spotMarketIndexes) !== null && _v !== void 0 ? _v : [], (_w = config.oracleInfos) !== null && _w !== void 0 ? _w : [], noMarketsAndOraclesSpecified);
|
|
147
152
|
}
|
|
148
153
|
else {
|
|
149
|
-
this.accountSubscriber = new webSocketDriftClientAccountSubscriber_1.WebSocketDriftClientAccountSubscriber(this.program, (
|
|
154
|
+
this.accountSubscriber = new webSocketDriftClientAccountSubscriber_1.WebSocketDriftClientAccountSubscriber(this.program, (_x = config.perpMarketIndexes) !== null && _x !== void 0 ? _x : [], (_y = config.spotMarketIndexes) !== null && _y !== void 0 ? _y : [], (_z = config.oracleInfos) !== null && _z !== void 0 ? _z : [], noMarketsAndOraclesSpecified, (_0 = config.accountSubscription) === null || _0 === void 0 ? void 0 : _0.resubTimeoutMs, (_1 = config.accountSubscription) === null || _1 === void 0 ? void 0 : _1.commitment);
|
|
150
155
|
}
|
|
151
156
|
this.eventEmitter = this.accountSubscriber.eventEmitter;
|
|
152
157
|
if (config.enableMetricsEvents) {
|
|
@@ -154,7 +159,7 @@ class DriftClient {
|
|
|
154
159
|
this.metricsEventEmitter = new events_1.EventEmitter();
|
|
155
160
|
}
|
|
156
161
|
this.txSender =
|
|
157
|
-
(
|
|
162
|
+
(_2 = config.txSender) !== null && _2 !== void 0 ? _2 : new retryTxSender_1.RetryTxSender({
|
|
158
163
|
connection: this.connection,
|
|
159
164
|
wallet: this.wallet,
|
|
160
165
|
opts: this.opts,
|
|
@@ -1233,16 +1238,8 @@ class DriftClient {
|
|
|
1233
1238
|
await this.addUser(subAccountId);
|
|
1234
1239
|
return [txSig, userAccountPublicKey];
|
|
1235
1240
|
}
|
|
1236
|
-
|
|
1237
|
-
* Withdraws from a user account. If deposit doesn't already exist, creates a borrow
|
|
1238
|
-
* @param amount
|
|
1239
|
-
* @param marketIndex
|
|
1240
|
-
* @param associatedTokenAddress - the token account to withdraw to. can be the wallet public key if using native sol
|
|
1241
|
-
* @param reduceOnly
|
|
1242
|
-
*/
|
|
1243
|
-
async withdraw(amount, marketIndex, associatedTokenAddress, reduceOnly = false, subAccountId, txParams) {
|
|
1241
|
+
async getWithdrawalIxs(amount, marketIndex, associatedTokenAddress, reduceOnly = false, subAccountId) {
|
|
1244
1242
|
const withdrawIxs = [];
|
|
1245
|
-
const additionalSigners = [];
|
|
1246
1243
|
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
1247
1244
|
const isSolMarket = spotMarketAccount.mint.equals(spotMarkets_1.WRAPPED_SOL_MINT);
|
|
1248
1245
|
const authority = this.wallet.publicKey;
|
|
@@ -1265,11 +1262,46 @@ class DriftClient {
|
|
|
1265
1262
|
if (createWSOLTokenAccount) {
|
|
1266
1263
|
withdrawIxs.push((0, spl_token_1.createCloseAccountInstruction)(associatedTokenAddress, authority, authority, []));
|
|
1267
1264
|
}
|
|
1265
|
+
return withdrawIxs;
|
|
1266
|
+
}
|
|
1267
|
+
/**
|
|
1268
|
+
* Withdraws from a user account. If deposit doesn't already exist, creates a borrow
|
|
1269
|
+
* @param amount
|
|
1270
|
+
* @param marketIndex
|
|
1271
|
+
* @param associatedTokenAddress - the token account to withdraw to. can be the wallet public key if using native sol
|
|
1272
|
+
* @param reduceOnly
|
|
1273
|
+
*/
|
|
1274
|
+
async withdraw(amount, marketIndex, associatedTokenAddress, reduceOnly = false, subAccountId, txParams) {
|
|
1275
|
+
const additionalSigners = [];
|
|
1276
|
+
const withdrawIxs = await this.getWithdrawalIxs(amount, marketIndex, associatedTokenAddress, reduceOnly, subAccountId);
|
|
1268
1277
|
const tx = await this.buildTransaction(withdrawIxs, txParams !== null && txParams !== void 0 ? txParams : this.txParams);
|
|
1269
1278
|
const { txSig, slot } = await this.sendTransaction(tx, additionalSigners, this.opts);
|
|
1270
1279
|
this.spotMarketLastSlotCache.set(marketIndex, slot);
|
|
1271
1280
|
return txSig;
|
|
1272
1281
|
}
|
|
1282
|
+
async withdrawAllDustPositions(subAccountId, txParams, opts) {
|
|
1283
|
+
var _a, _b;
|
|
1284
|
+
const user = this.getUser(subAccountId);
|
|
1285
|
+
const dustPositionSpotMarketAccounts = user.getSpotMarketAccountsWithDustPosition();
|
|
1286
|
+
if (!dustPositionSpotMarketAccounts ||
|
|
1287
|
+
dustPositionSpotMarketAccounts.length === 0) {
|
|
1288
|
+
(_a = opts === null || opts === void 0 ? void 0 : opts.dustPositionCountCallback) === null || _a === void 0 ? void 0 : _a.call(opts, 0);
|
|
1289
|
+
return undefined;
|
|
1290
|
+
}
|
|
1291
|
+
(_b = opts === null || opts === void 0 ? void 0 : opts.dustPositionCountCallback) === null || _b === void 0 ? void 0 : _b.call(opts, dustPositionSpotMarketAccounts.length);
|
|
1292
|
+
let allWithdrawIxs = [];
|
|
1293
|
+
for (const position of dustPositionSpotMarketAccounts) {
|
|
1294
|
+
const tokenAccount = await (0, spl_token_1.getAssociatedTokenAddress)(position.mint, this.wallet.publicKey);
|
|
1295
|
+
const tokenAmount = await user.getTokenAmount(position.marketIndex);
|
|
1296
|
+
const withdrawIxs = await this.getWithdrawalIxs(tokenAmount.muln(2), // 2x to ensure all dust is withdrawn
|
|
1297
|
+
position.marketIndex, tokenAccount, true, // reduce-only true to ensure all dust is withdrawn
|
|
1298
|
+
subAccountId);
|
|
1299
|
+
allWithdrawIxs = allWithdrawIxs.concat(withdrawIxs);
|
|
1300
|
+
}
|
|
1301
|
+
const tx = await this.buildTransaction(allWithdrawIxs, txParams !== null && txParams !== void 0 ? txParams : this.txParams);
|
|
1302
|
+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
1303
|
+
return txSig;
|
|
1304
|
+
}
|
|
1273
1305
|
async getWithdrawIx(amount, marketIndex, userTokenAccount, reduceOnly = false, subAccountId) {
|
|
1274
1306
|
const user = await this.getUserAccountPublicKey(subAccountId);
|
|
1275
1307
|
const remainingAccounts = this.getRemainingAccounts({
|
|
@@ -2524,9 +2556,13 @@ class DriftClient {
|
|
|
2524
2556
|
};
|
|
2525
2557
|
let placeAndTakeTx = await this.buildTransaction(ixs, txParamsWithoutImplicitSimulation);
|
|
2526
2558
|
if (shouldUseSimulationComputeUnits || shouldExitIfSimulationFails) {
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2559
|
+
let versionedPlaceAndTakeTx;
|
|
2560
|
+
if (this.isVersionedTransaction(placeAndTakeTx)) {
|
|
2561
|
+
versionedPlaceAndTakeTx = placeAndTakeTx;
|
|
2562
|
+
}
|
|
2563
|
+
else {
|
|
2564
|
+
versionedPlaceAndTakeTx = (await this.buildTransaction(ixs, txParamsWithoutImplicitSimulation, undefined, undefined, true));
|
|
2565
|
+
}
|
|
2530
2566
|
const simulationResult = await txParamProcessor_1.TransactionProcessor.getTxSimComputeUnits(versionedPlaceAndTakeTx, this.connection);
|
|
2531
2567
|
if (shouldExitIfSimulationFails && !simulationResult.success) {
|
|
2532
2568
|
return;
|
|
@@ -2933,9 +2969,29 @@ class DriftClient {
|
|
|
2933
2969
|
remainingAccounts,
|
|
2934
2970
|
});
|
|
2935
2971
|
}
|
|
2936
|
-
async settlePNLs(users, marketIndexes) {
|
|
2937
|
-
const
|
|
2938
|
-
|
|
2972
|
+
async settlePNLs(users, marketIndexes, opts) {
|
|
2973
|
+
const filterInvalidMarkets = opts === null || opts === void 0 ? void 0 : opts.filterInvalidMarkets;
|
|
2974
|
+
// # Filter market indexes by markets with valid oracle
|
|
2975
|
+
const marketIndexToSettle = filterInvalidMarkets
|
|
2976
|
+
? []
|
|
2977
|
+
: marketIndexes;
|
|
2978
|
+
if (filterInvalidMarkets) {
|
|
2979
|
+
for (const marketIndex of marketIndexes) {
|
|
2980
|
+
const perpMarketAccount = this.getPerpMarketAccount(marketIndex);
|
|
2981
|
+
const oraclePriceData = this.getOracleDataForPerpMarket(marketIndex);
|
|
2982
|
+
const stateAccountAndSlot = this.accountSubscriber.getStateAccountAndSlot();
|
|
2983
|
+
const oracleGuardRails = stateAccountAndSlot.data.oracleGuardRails;
|
|
2984
|
+
const isValid = (0, oracles_1.isOracleValid)(perpMarketAccount, oraclePriceData, oracleGuardRails, stateAccountAndSlot.slot);
|
|
2985
|
+
if (isValid) {
|
|
2986
|
+
marketIndexToSettle.push(marketIndex);
|
|
2987
|
+
}
|
|
2988
|
+
}
|
|
2989
|
+
}
|
|
2990
|
+
// # Settle filtered market indexes
|
|
2991
|
+
const ixs = await this.getSettlePNLsIxs(users, marketIndexToSettle);
|
|
2992
|
+
const tx = await this.buildTransaction(ixs, {
|
|
2993
|
+
computeUnits: 1400000,
|
|
2994
|
+
});
|
|
2939
2995
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
2940
2996
|
return txSig;
|
|
2941
2997
|
}
|
package/lib/idl/drift.json
CHANGED
|
@@ -47,20 +47,23 @@ class TransactionProcessor {
|
|
|
47
47
|
}
|
|
48
48
|
// # Setup
|
|
49
49
|
const { txProps: txProps, txBuilder: txBuilder, processConfig, processParams: processProps, } = props;
|
|
50
|
-
const baseTransaction = await txBuilder(txProps);
|
|
51
50
|
const finalTxProps = {
|
|
52
51
|
...txProps,
|
|
53
52
|
};
|
|
54
53
|
// # Run Processes
|
|
55
54
|
if (processConfig.useSimulatedComputeUnits) {
|
|
56
|
-
const
|
|
55
|
+
const txToSim = await txBuilder({
|
|
56
|
+
...txProps,
|
|
57
|
+
txParams: { ...txProps.txParams, computeUnits: 1400000 },
|
|
58
|
+
});
|
|
59
|
+
const txSimComputeUnitsResult = await this.getTxSimComputeUnits(txToSim, processProps.connection);
|
|
57
60
|
if (txSimComputeUnitsResult.success) {
|
|
58
61
|
const bufferedComputeUnits = txSimComputeUnitsResult.computeUnits *
|
|
59
62
|
((_a = processConfig === null || processConfig === void 0 ? void 0 : processConfig.computeUnitsBufferMultiplier) !== null && _a !== void 0 ? _a : COMPUTE_UNIT_BUFFER_FACTOR);
|
|
60
63
|
// Adjust the transaction based on the simulated compute units
|
|
61
64
|
finalTxProps.txParams = {
|
|
62
65
|
...txProps.txParams,
|
|
63
|
-
computeUnits: bufferedComputeUnits,
|
|
66
|
+
computeUnits: Math.ceil(bufferedComputeUnits), // Round the compute units to a whole number
|
|
64
67
|
};
|
|
65
68
|
}
|
|
66
69
|
}
|
package/lib/user.d.ts
CHANGED
|
@@ -195,6 +195,8 @@ export declare class User {
|
|
|
195
195
|
spotAssetValue: BN;
|
|
196
196
|
spotLiabilityValue: BN;
|
|
197
197
|
};
|
|
198
|
+
isDustDepositPosition(spotMarketAccount: SpotMarketAccount): boolean;
|
|
199
|
+
getSpotMarketAccountsWithDustPosition(): SpotMarketAccount[];
|
|
198
200
|
getTotalLiabilityValue(marginCategory?: MarginCategory): BN;
|
|
199
201
|
getTotalAssetValue(marginCategory?: MarginCategory): BN;
|
|
200
202
|
getNetUsdValue(): BN;
|
package/lib/user.js
CHANGED
|
@@ -848,6 +848,35 @@ class User {
|
|
|
848
848
|
spotLiabilityValue,
|
|
849
849
|
};
|
|
850
850
|
}
|
|
851
|
+
isDustDepositPosition(spotMarketAccount) {
|
|
852
|
+
const marketIndex = spotMarketAccount.marketIndex;
|
|
853
|
+
const spotPosition = this.getSpotPosition(spotMarketAccount.marketIndex);
|
|
854
|
+
if ((0, spotPosition_1.isSpotPositionAvailable)(spotPosition)) {
|
|
855
|
+
return false;
|
|
856
|
+
}
|
|
857
|
+
const depositAmount = this.getTokenAmount(spotMarketAccount.marketIndex);
|
|
858
|
+
if (depositAmount.lte(numericConstants_1.ZERO)) {
|
|
859
|
+
return false;
|
|
860
|
+
}
|
|
861
|
+
const oraclePriceData = this.getOracleDataForSpotMarket(marketIndex);
|
|
862
|
+
const strictOraclePrice = new strictOraclePrice_1.StrictOraclePrice(oraclePriceData.price, oraclePriceData.twap);
|
|
863
|
+
const balanceValue = this.getSpotAssetValue(depositAmount, strictOraclePrice, spotMarketAccount);
|
|
864
|
+
if (balanceValue.lt(numericConstants_1.DUST_POSITION_SIZE)) {
|
|
865
|
+
return true;
|
|
866
|
+
}
|
|
867
|
+
return false;
|
|
868
|
+
}
|
|
869
|
+
getSpotMarketAccountsWithDustPosition() {
|
|
870
|
+
const spotMarketAccounts = this.driftClient.getSpotMarketAccounts();
|
|
871
|
+
const dustPositionAccounts = [];
|
|
872
|
+
for (const spotMarketAccount of spotMarketAccounts) {
|
|
873
|
+
const isDust = this.isDustDepositPosition(spotMarketAccount);
|
|
874
|
+
if (isDust) {
|
|
875
|
+
dustPositionAccounts.push(spotMarketAccount);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
return dustPositionAccounts;
|
|
879
|
+
}
|
|
851
880
|
getTotalLiabilityValue(marginCategory) {
|
|
852
881
|
return this.getTotalPerpPositionValue(marginCategory, undefined, true).add(this.getSpotMarketLiabilityValue(undefined, marginCategory, undefined, true));
|
|
853
882
|
}
|
package/package.json
CHANGED
|
@@ -103,3 +103,5 @@ export const DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT = new BN(
|
|
|
103
103
|
export const ACCOUNT_AGE_DELETION_CUTOFF_SECONDS = 60 * 60 * 24 * 13; // 13 days
|
|
104
104
|
export const IDLE_TIME_SLOTS = 9000;
|
|
105
105
|
export const SLOT_TIME_ESTIMATE_MS = 400;
|
|
106
|
+
|
|
107
|
+
export const DUST_POSITION_SIZE = QUOTE_PRECISION.divn(100); // Dust position is any position smaller than 1c
|
package/src/driftClient.ts
CHANGED
|
@@ -128,6 +128,7 @@ import { getMarinadeDepositIx, getMarinadeFinanceProgram } from './marinade';
|
|
|
128
128
|
import { getOrderParams } from './orderParams';
|
|
129
129
|
import { numberToSafeBN } from './math/utils';
|
|
130
130
|
import { TransactionProcessor as TransactionParamProcessor } from './tx/txParamProcessor';
|
|
131
|
+
import { isOracleValid } from './math/oracles';
|
|
131
132
|
|
|
132
133
|
type RemainingAccountParams = {
|
|
133
134
|
userAccounts: UserAccount[];
|
|
@@ -186,7 +187,11 @@ export class DriftClient {
|
|
|
186
187
|
public constructor(config: DriftClientConfig) {
|
|
187
188
|
this.connection = config.connection;
|
|
188
189
|
this.wallet = config.wallet;
|
|
189
|
-
this.opts = config.opts ||
|
|
190
|
+
this.opts = config.opts || {
|
|
191
|
+
...AnchorProvider.defaultOptions(),
|
|
192
|
+
commitment: config?.connection?.commitment,
|
|
193
|
+
preflightCommitment: config?.connection?.commitment, // At the moment this ensures that our transaction simulations (which use Connection object) will use the same commitment level as our Transaction blockhashes (which use these opts)
|
|
194
|
+
};
|
|
190
195
|
this.provider = new AnchorProvider(
|
|
191
196
|
config.connection,
|
|
192
197
|
// @ts-ignore
|
|
@@ -2183,24 +2188,14 @@ export class DriftClient {
|
|
|
2183
2188
|
return [txSig, userAccountPublicKey];
|
|
2184
2189
|
}
|
|
2185
2190
|
|
|
2186
|
-
|
|
2187
|
-
* Withdraws from a user account. If deposit doesn't already exist, creates a borrow
|
|
2188
|
-
* @param amount
|
|
2189
|
-
* @param marketIndex
|
|
2190
|
-
* @param associatedTokenAddress - the token account to withdraw to. can be the wallet public key if using native sol
|
|
2191
|
-
* @param reduceOnly
|
|
2192
|
-
*/
|
|
2193
|
-
public async withdraw(
|
|
2191
|
+
private async getWithdrawalIxs(
|
|
2194
2192
|
amount: BN,
|
|
2195
2193
|
marketIndex: number,
|
|
2196
2194
|
associatedTokenAddress: PublicKey,
|
|
2197
2195
|
reduceOnly = false,
|
|
2198
|
-
subAccountId?: number
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
const withdrawIxs = [];
|
|
2202
|
-
|
|
2203
|
-
const additionalSigners: Array<Signer> = [];
|
|
2196
|
+
subAccountId?: number
|
|
2197
|
+
) {
|
|
2198
|
+
const withdrawIxs: anchor.web3.TransactionInstruction[] = [];
|
|
2204
2199
|
|
|
2205
2200
|
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
2206
2201
|
|
|
@@ -2258,6 +2253,34 @@ export class DriftClient {
|
|
|
2258
2253
|
);
|
|
2259
2254
|
}
|
|
2260
2255
|
|
|
2256
|
+
return withdrawIxs;
|
|
2257
|
+
}
|
|
2258
|
+
|
|
2259
|
+
/**
|
|
2260
|
+
* Withdraws from a user account. If deposit doesn't already exist, creates a borrow
|
|
2261
|
+
* @param amount
|
|
2262
|
+
* @param marketIndex
|
|
2263
|
+
* @param associatedTokenAddress - the token account to withdraw to. can be the wallet public key if using native sol
|
|
2264
|
+
* @param reduceOnly
|
|
2265
|
+
*/
|
|
2266
|
+
public async withdraw(
|
|
2267
|
+
amount: BN,
|
|
2268
|
+
marketIndex: number,
|
|
2269
|
+
associatedTokenAddress: PublicKey,
|
|
2270
|
+
reduceOnly = false,
|
|
2271
|
+
subAccountId?: number,
|
|
2272
|
+
txParams?: TxParams
|
|
2273
|
+
): Promise<TransactionSignature> {
|
|
2274
|
+
const additionalSigners: Array<Signer> = [];
|
|
2275
|
+
|
|
2276
|
+
const withdrawIxs = await this.getWithdrawalIxs(
|
|
2277
|
+
amount,
|
|
2278
|
+
marketIndex,
|
|
2279
|
+
associatedTokenAddress,
|
|
2280
|
+
reduceOnly,
|
|
2281
|
+
subAccountId
|
|
2282
|
+
);
|
|
2283
|
+
|
|
2261
2284
|
const tx = await this.buildTransaction(
|
|
2262
2285
|
withdrawIxs,
|
|
2263
2286
|
txParams ?? this.txParams
|
|
@@ -2272,6 +2295,59 @@ export class DriftClient {
|
|
|
2272
2295
|
return txSig;
|
|
2273
2296
|
}
|
|
2274
2297
|
|
|
2298
|
+
public async withdrawAllDustPositions(
|
|
2299
|
+
subAccountId?: number,
|
|
2300
|
+
txParams?: TxParams,
|
|
2301
|
+
opts?: {
|
|
2302
|
+
dustPositionCountCallback?: (count: number) => void;
|
|
2303
|
+
}
|
|
2304
|
+
): Promise<TransactionSignature | undefined> {
|
|
2305
|
+
const user = this.getUser(subAccountId);
|
|
2306
|
+
|
|
2307
|
+
const dustPositionSpotMarketAccounts =
|
|
2308
|
+
user.getSpotMarketAccountsWithDustPosition();
|
|
2309
|
+
|
|
2310
|
+
if (
|
|
2311
|
+
!dustPositionSpotMarketAccounts ||
|
|
2312
|
+
dustPositionSpotMarketAccounts.length === 0
|
|
2313
|
+
) {
|
|
2314
|
+
opts?.dustPositionCountCallback?.(0);
|
|
2315
|
+
return undefined;
|
|
2316
|
+
}
|
|
2317
|
+
|
|
2318
|
+
opts?.dustPositionCountCallback?.(dustPositionSpotMarketAccounts.length);
|
|
2319
|
+
|
|
2320
|
+
let allWithdrawIxs: anchor.web3.TransactionInstruction[] = [];
|
|
2321
|
+
|
|
2322
|
+
for (const position of dustPositionSpotMarketAccounts) {
|
|
2323
|
+
const tokenAccount = await getAssociatedTokenAddress(
|
|
2324
|
+
position.mint,
|
|
2325
|
+
this.wallet.publicKey
|
|
2326
|
+
);
|
|
2327
|
+
|
|
2328
|
+
const tokenAmount = await user.getTokenAmount(position.marketIndex);
|
|
2329
|
+
|
|
2330
|
+
const withdrawIxs = await this.getWithdrawalIxs(
|
|
2331
|
+
tokenAmount.muln(2), // 2x to ensure all dust is withdrawn
|
|
2332
|
+
position.marketIndex,
|
|
2333
|
+
tokenAccount,
|
|
2334
|
+
true, // reduce-only true to ensure all dust is withdrawn
|
|
2335
|
+
subAccountId
|
|
2336
|
+
);
|
|
2337
|
+
|
|
2338
|
+
allWithdrawIxs = allWithdrawIxs.concat(withdrawIxs);
|
|
2339
|
+
}
|
|
2340
|
+
|
|
2341
|
+
const tx = await this.buildTransaction(
|
|
2342
|
+
allWithdrawIxs,
|
|
2343
|
+
txParams ?? this.txParams
|
|
2344
|
+
);
|
|
2345
|
+
|
|
2346
|
+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
2347
|
+
|
|
2348
|
+
return txSig;
|
|
2349
|
+
}
|
|
2350
|
+
|
|
2275
2351
|
public async getWithdrawIx(
|
|
2276
2352
|
amount: BN,
|
|
2277
2353
|
marketIndex: number,
|
|
@@ -4577,17 +4653,19 @@ export class DriftClient {
|
|
|
4577
4653
|
);
|
|
4578
4654
|
|
|
4579
4655
|
if (shouldUseSimulationComputeUnits || shouldExitIfSimulationFails) {
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
)
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4656
|
+
let versionedPlaceAndTakeTx: VersionedTransaction;
|
|
4657
|
+
|
|
4658
|
+
if (this.isVersionedTransaction(placeAndTakeTx)) {
|
|
4659
|
+
versionedPlaceAndTakeTx = placeAndTakeTx as VersionedTransaction;
|
|
4660
|
+
} else {
|
|
4661
|
+
versionedPlaceAndTakeTx = (await this.buildTransaction(
|
|
4662
|
+
ixs,
|
|
4663
|
+
txParamsWithoutImplicitSimulation,
|
|
4664
|
+
undefined,
|
|
4665
|
+
undefined,
|
|
4666
|
+
true
|
|
4667
|
+
)) as VersionedTransaction;
|
|
4668
|
+
}
|
|
4591
4669
|
|
|
4592
4670
|
const simulationResult =
|
|
4593
4671
|
await TransactionParamProcessor.getTxSimComputeUnits(
|
|
@@ -5346,11 +5424,45 @@ export class DriftClient {
|
|
|
5346
5424
|
settleeUserAccountPublicKey: PublicKey;
|
|
5347
5425
|
settleeUserAccount: UserAccount;
|
|
5348
5426
|
}[],
|
|
5349
|
-
marketIndexes: number[]
|
|
5427
|
+
marketIndexes: number[],
|
|
5428
|
+
opts?: {
|
|
5429
|
+
filterInvalidMarkets?: boolean;
|
|
5430
|
+
}
|
|
5350
5431
|
): Promise<TransactionSignature> {
|
|
5351
|
-
const
|
|
5432
|
+
const filterInvalidMarkets = opts?.filterInvalidMarkets;
|
|
5433
|
+
|
|
5434
|
+
// # Filter market indexes by markets with valid oracle
|
|
5435
|
+
const marketIndexToSettle: number[] = filterInvalidMarkets
|
|
5436
|
+
? []
|
|
5437
|
+
: marketIndexes;
|
|
5438
|
+
|
|
5439
|
+
if (filterInvalidMarkets) {
|
|
5440
|
+
for (const marketIndex of marketIndexes) {
|
|
5441
|
+
const perpMarketAccount = this.getPerpMarketAccount(marketIndex);
|
|
5442
|
+
const oraclePriceData = this.getOracleDataForPerpMarket(marketIndex);
|
|
5443
|
+
const stateAccountAndSlot =
|
|
5444
|
+
this.accountSubscriber.getStateAccountAndSlot();
|
|
5445
|
+
const oracleGuardRails = stateAccountAndSlot.data.oracleGuardRails;
|
|
5446
|
+
|
|
5447
|
+
const isValid = isOracleValid(
|
|
5448
|
+
perpMarketAccount,
|
|
5449
|
+
oraclePriceData,
|
|
5450
|
+
oracleGuardRails,
|
|
5451
|
+
stateAccountAndSlot.slot
|
|
5452
|
+
);
|
|
5352
5453
|
|
|
5353
|
-
|
|
5454
|
+
if (isValid) {
|
|
5455
|
+
marketIndexToSettle.push(marketIndex);
|
|
5456
|
+
}
|
|
5457
|
+
}
|
|
5458
|
+
}
|
|
5459
|
+
|
|
5460
|
+
// # Settle filtered market indexes
|
|
5461
|
+
const ixs = await this.getSettlePNLsIxs(users, marketIndexToSettle);
|
|
5462
|
+
|
|
5463
|
+
const tx = await this.buildTransaction(ixs, {
|
|
5464
|
+
computeUnits: 1_400_000,
|
|
5465
|
+
});
|
|
5354
5466
|
|
|
5355
5467
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
5356
5468
|
return txSig;
|
package/src/idl/drift.json
CHANGED
|
@@ -93,16 +93,19 @@ export class TransactionProcessor {
|
|
|
93
93
|
processParams: processProps,
|
|
94
94
|
} = props;
|
|
95
95
|
|
|
96
|
-
const baseTransaction = await txBuilder(txProps);
|
|
97
|
-
|
|
98
96
|
const finalTxProps = {
|
|
99
97
|
...txProps,
|
|
100
98
|
};
|
|
101
99
|
|
|
102
100
|
// # Run Processes
|
|
103
101
|
if (processConfig.useSimulatedComputeUnits) {
|
|
102
|
+
const txToSim = await txBuilder({
|
|
103
|
+
...txProps,
|
|
104
|
+
txParams: { ...txProps.txParams, computeUnits: 1_400_000 },
|
|
105
|
+
});
|
|
106
|
+
|
|
104
107
|
const txSimComputeUnitsResult = await this.getTxSimComputeUnits(
|
|
105
|
-
|
|
108
|
+
txToSim,
|
|
106
109
|
processProps.connection
|
|
107
110
|
);
|
|
108
111
|
|
|
@@ -115,7 +118,7 @@ export class TransactionProcessor {
|
|
|
115
118
|
// Adjust the transaction based on the simulated compute units
|
|
116
119
|
finalTxProps.txParams = {
|
|
117
120
|
...txProps.txParams,
|
|
118
|
-
computeUnits: bufferedComputeUnits,
|
|
121
|
+
computeUnits: Math.ceil(bufferedComputeUnits), // Round the compute units to a whole number
|
|
119
122
|
};
|
|
120
123
|
}
|
|
121
124
|
}
|
package/src/user.ts
CHANGED
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
AMM_TO_QUOTE_PRECISION_RATIO,
|
|
22
22
|
BASE_PRECISION,
|
|
23
23
|
BN_MAX,
|
|
24
|
+
DUST_POSITION_SIZE,
|
|
24
25
|
FIVE_MINUTE,
|
|
25
26
|
MARGIN_PRECISION,
|
|
26
27
|
ONE,
|
|
@@ -1563,6 +1564,56 @@ export class User {
|
|
|
1563
1564
|
};
|
|
1564
1565
|
}
|
|
1565
1566
|
|
|
1567
|
+
isDustDepositPosition(spotMarketAccount: SpotMarketAccount): boolean {
|
|
1568
|
+
const marketIndex = spotMarketAccount.marketIndex;
|
|
1569
|
+
|
|
1570
|
+
const spotPosition = this.getSpotPosition(spotMarketAccount.marketIndex);
|
|
1571
|
+
|
|
1572
|
+
if (isSpotPositionAvailable(spotPosition)) {
|
|
1573
|
+
return false;
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
const depositAmount = this.getTokenAmount(spotMarketAccount.marketIndex);
|
|
1577
|
+
|
|
1578
|
+
if (depositAmount.lte(ZERO)) {
|
|
1579
|
+
return false;
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1582
|
+
const oraclePriceData = this.getOracleDataForSpotMarket(marketIndex);
|
|
1583
|
+
|
|
1584
|
+
const strictOraclePrice = new StrictOraclePrice(
|
|
1585
|
+
oraclePriceData.price,
|
|
1586
|
+
oraclePriceData.twap
|
|
1587
|
+
);
|
|
1588
|
+
|
|
1589
|
+
const balanceValue = this.getSpotAssetValue(
|
|
1590
|
+
depositAmount,
|
|
1591
|
+
strictOraclePrice,
|
|
1592
|
+
spotMarketAccount
|
|
1593
|
+
);
|
|
1594
|
+
|
|
1595
|
+
if (balanceValue.lt(DUST_POSITION_SIZE)) {
|
|
1596
|
+
return true;
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
return false;
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1602
|
+
getSpotMarketAccountsWithDustPosition() {
|
|
1603
|
+
const spotMarketAccounts = this.driftClient.getSpotMarketAccounts();
|
|
1604
|
+
|
|
1605
|
+
const dustPositionAccounts: SpotMarketAccount[] = [];
|
|
1606
|
+
|
|
1607
|
+
for (const spotMarketAccount of spotMarketAccounts) {
|
|
1608
|
+
const isDust = this.isDustDepositPosition(spotMarketAccount);
|
|
1609
|
+
if (isDust) {
|
|
1610
|
+
dustPositionAccounts.push(spotMarketAccount);
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1614
|
+
return dustPositionAccounts;
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1566
1617
|
getTotalLiabilityValue(marginCategory?: MarginCategory): BN {
|
|
1567
1618
|
return this.getTotalPerpPositionValue(marginCategory, undefined, true).add(
|
|
1568
1619
|
this.getSpotMarketLiabilityValue(
|