@drift-labs/sdk 2.15.0 → 2.16.0-beta.2
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/lib/driftClient.js +5 -0
- package/lib/events/fetchLogs.js +4 -4
- package/lib/idl/drift.json +6 -1
- package/lib/math/margin.js +1 -3
- package/lib/math/market.js +4 -2
- package/lib/math/spotBalance.d.ts +1 -1
- package/lib/math/spotBalance.js +8 -8
- package/lib/math/spotMarket.d.ts +2 -1
- package/lib/math/spotMarket.js +15 -1
- package/lib/math/spotPosition.js +3 -3
- package/lib/user.d.ts +41 -10
- package/lib/user.js +229 -95
- package/package.json +1 -1
- package/src/driftClient.ts +7 -0
- package/src/events/fetchLogs.ts +4 -4
- package/src/idl/drift.json +6 -1
- package/src/math/margin.ts +1 -5
- package/src/math/market.ts +4 -2
- package/src/math/spotBalance.ts +8 -8
- package/src/math/spotMarket.ts +27 -1
- package/src/math/spotPosition.ts +3 -3
- package/src/user.ts +544 -234
package/lib/driftClient.js
CHANGED
|
@@ -366,11 +366,16 @@ class DriftClient {
|
|
|
366
366
|
}
|
|
367
367
|
async updateUserMarginTradingEnabled(marginTradingEnabled, subAccountId = 0) {
|
|
368
368
|
const userAccountPublicKey = pda_1.getUserAccountPublicKeySync(this.program.programId, this.wallet.publicKey, subAccountId);
|
|
369
|
+
await this.addUser(subAccountId);
|
|
370
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
371
|
+
userAccounts: [this.getUserAccount(subAccountId)],
|
|
372
|
+
});
|
|
369
373
|
const tx = await this.program.transaction.updateUserMarginTradingEnabled(subAccountId, marginTradingEnabled, {
|
|
370
374
|
accounts: {
|
|
371
375
|
user: userAccountPublicKey,
|
|
372
376
|
authority: this.wallet.publicKey,
|
|
373
377
|
},
|
|
378
|
+
remainingAccounts,
|
|
374
379
|
});
|
|
375
380
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
376
381
|
return txSig;
|
package/lib/events/fetchLogs.js
CHANGED
|
@@ -20,11 +20,11 @@ async function fetchLogs(connection, programId, finality, beforeTx, untilTx, lim
|
|
|
20
20
|
return undefined;
|
|
21
21
|
}
|
|
22
22
|
const chunkedSignatures = chunk(filteredSignatures, 100);
|
|
23
|
+
const config = { commitment: finality, maxSupportedTransactionVersion: 0 };
|
|
23
24
|
const transactionLogs = (await Promise.all(chunkedSignatures.map(async (chunk) => {
|
|
24
|
-
const transactions = await connection.getTransactions(chunk.map((confirmedSignature) => confirmedSignature.signature),
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
});
|
|
25
|
+
const transactions = await connection.getTransactions(chunk.map((confirmedSignature) => confirmedSignature.signature),
|
|
26
|
+
//@ts-ignore
|
|
27
|
+
config);
|
|
28
28
|
return transactions.reduce((logs, transaction) => {
|
|
29
29
|
if (transaction) {
|
|
30
30
|
logs.push(mapTransactionResponseToLog(transaction));
|
package/lib/idl/drift.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.
|
|
2
|
+
"version": "2.16.0-beta.2",
|
|
3
3
|
"name": "drift",
|
|
4
4
|
"instructions": [
|
|
5
5
|
{
|
|
@@ -8569,6 +8569,11 @@
|
|
|
8569
8569
|
"code": 6225,
|
|
8570
8570
|
"name": "InvalidOracleForSettlePnl",
|
|
8571
8571
|
"msg": "InvalidOracleForSettlePnl"
|
|
8572
|
+
},
|
|
8573
|
+
{
|
|
8574
|
+
"code": 6226,
|
|
8575
|
+
"name": "MarginOrdersOpen",
|
|
8576
|
+
"msg": "MarginOrdersOpen"
|
|
8572
8577
|
}
|
|
8573
8578
|
]
|
|
8574
8579
|
}
|
package/lib/math/margin.js
CHANGED
|
@@ -12,9 +12,7 @@ imfFactor, liabilityWeight, precision) {
|
|
|
12
12
|
return liabilityWeight;
|
|
13
13
|
}
|
|
14
14
|
const sizeSqrt = utils_1.squareRootBN(size.abs().mul(new anchor_1.BN(10)).add(new anchor_1.BN(1))); //1e9 -> 1e10 -> 1e5
|
|
15
|
-
const
|
|
16
|
-
assert_1.assert(denom0.gt(numericConstants_1.ZERO));
|
|
17
|
-
const liabilityWeightNumerator = liabilityWeight.sub(liabilityWeight.div(anchor_1.BN.max(new anchor_1.BN(1), numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(imfFactor))));
|
|
15
|
+
const liabilityWeightNumerator = liabilityWeight.sub(liabilityWeight.div(new anchor_1.BN(5)));
|
|
18
16
|
const denom = new anchor_1.BN(100000).mul(numericConstants_1.SPOT_MARKET_IMF_PRECISION).div(precision);
|
|
19
17
|
assert_1.assert(denom.gt(numericConstants_1.ZERO));
|
|
20
18
|
const sizePremiumLiabilityWeight = liabilityWeightNumerator.add(sizeSqrt // 1e5
|
package/lib/math/market.js
CHANGED
|
@@ -63,12 +63,14 @@ exports.calculateOracleSpread = calculateOracleSpread;
|
|
|
63
63
|
function calculateMarketMarginRatio(market, size, marginCategory) {
|
|
64
64
|
let marginRatio;
|
|
65
65
|
switch (marginCategory) {
|
|
66
|
-
case 'Initial':
|
|
66
|
+
case 'Initial': {
|
|
67
67
|
marginRatio = margin_1.calculateSizePremiumLiabilityWeight(size, new anchor_1.BN(market.imfFactor), new anchor_1.BN(market.marginRatioInitial), numericConstants_1.MARGIN_PRECISION).toNumber();
|
|
68
68
|
break;
|
|
69
|
-
|
|
69
|
+
}
|
|
70
|
+
case 'Maintenance': {
|
|
70
71
|
marginRatio = margin_1.calculateSizePremiumLiabilityWeight(size, new anchor_1.BN(market.imfFactor), new anchor_1.BN(market.marginRatioMaintenance), numericConstants_1.MARGIN_PRECISION).toNumber();
|
|
71
72
|
break;
|
|
73
|
+
}
|
|
72
74
|
}
|
|
73
75
|
return marginRatio;
|
|
74
76
|
}
|
|
@@ -8,7 +8,7 @@ export declare function getSignedTokenAmount(tokenAmount: BN, balanceType: SpotB
|
|
|
8
8
|
export declare function getStrictTokenValue(tokenAmount: BN, spotDecimals: number, oraclePriceData: OraclePriceData, oraclePriceTwap: BN): BN;
|
|
9
9
|
export declare function getTokenValue(tokenAmount: BN, spotDecimals: number, oraclePriceData: OraclePriceData): BN;
|
|
10
10
|
export declare function calculateAssetWeight(balanceAmount: BN, spotMarket: SpotMarketAccount, marginCategory: MarginCategory): BN;
|
|
11
|
-
export declare function calculateLiabilityWeight(
|
|
11
|
+
export declare function calculateLiabilityWeight(size: BN, spotMarket: SpotMarketAccount, marginCategory: MarginCategory): BN;
|
|
12
12
|
export declare function calculateUtilization(bank: SpotMarketAccount): BN;
|
|
13
13
|
export declare function calculateInterestRate(bank: SpotMarketAccount): BN;
|
|
14
14
|
export declare function calculateDepositRate(bank: SpotMarketAccount): BN;
|
package/lib/math/spotBalance.js
CHANGED
|
@@ -84,30 +84,30 @@ function calculateAssetWeight(balanceAmount, spotMarket, marginCategory) {
|
|
|
84
84
|
return assetWeight;
|
|
85
85
|
}
|
|
86
86
|
exports.calculateAssetWeight = calculateAssetWeight;
|
|
87
|
-
function calculateLiabilityWeight(
|
|
87
|
+
function calculateLiabilityWeight(size, spotMarket, marginCategory) {
|
|
88
88
|
const sizePrecision = numericConstants_1.TEN.pow(new anchor_1.BN(spotMarket.decimals));
|
|
89
89
|
let sizeInAmmReservePrecision;
|
|
90
90
|
if (sizePrecision.gt(numericConstants_1.AMM_RESERVE_PRECISION)) {
|
|
91
|
-
sizeInAmmReservePrecision =
|
|
91
|
+
sizeInAmmReservePrecision = size.div(sizePrecision.div(numericConstants_1.AMM_RESERVE_PRECISION));
|
|
92
92
|
}
|
|
93
93
|
else {
|
|
94
|
-
sizeInAmmReservePrecision =
|
|
94
|
+
sizeInAmmReservePrecision = size
|
|
95
95
|
.mul(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
96
96
|
.div(sizePrecision);
|
|
97
97
|
}
|
|
98
|
-
let
|
|
98
|
+
let liabilityWeight;
|
|
99
99
|
switch (marginCategory) {
|
|
100
100
|
case 'Initial':
|
|
101
|
-
|
|
101
|
+
liabilityWeight = margin_1.calculateSizePremiumLiabilityWeight(sizeInAmmReservePrecision, new anchor_1.BN(spotMarket.imfFactor), new anchor_1.BN(spotMarket.initialLiabilityWeight), numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION);
|
|
102
102
|
break;
|
|
103
103
|
case 'Maintenance':
|
|
104
|
-
|
|
104
|
+
liabilityWeight = margin_1.calculateSizePremiumLiabilityWeight(sizeInAmmReservePrecision, new anchor_1.BN(spotMarket.imfFactor), new anchor_1.BN(spotMarket.maintenanceLiabilityWeight), numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION);
|
|
105
105
|
break;
|
|
106
106
|
default:
|
|
107
|
-
|
|
107
|
+
liabilityWeight = spotMarket.initialLiabilityWeight;
|
|
108
108
|
break;
|
|
109
109
|
}
|
|
110
|
-
return
|
|
110
|
+
return liabilityWeight;
|
|
111
111
|
}
|
|
112
112
|
exports.calculateLiabilityWeight = calculateLiabilityWeight;
|
|
113
113
|
function calculateUtilization(bank) {
|
package/lib/math/spotMarket.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
2
|
import { BN } from '@project-serum/anchor';
|
|
3
|
-
import { SpotMarketAccount } from '../types';
|
|
3
|
+
import { MarginCategory, SpotBalanceType, SpotMarketAccount } from '../types';
|
|
4
4
|
export declare function castNumberToSpotPrecision(value: number, spotMarket: SpotMarketAccount): BN;
|
|
5
|
+
export declare function calculateSpotMarketMarginRatio(market: SpotMarketAccount, marginCategory: MarginCategory, size: BN, balanceType: SpotBalanceType): number;
|
package/lib/math/spotMarket.js
CHANGED
|
@@ -1,8 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.castNumberToSpotPrecision = void 0;
|
|
3
|
+
exports.calculateSpotMarketMarginRatio = exports.castNumberToSpotPrecision = void 0;
|
|
4
4
|
const anchor_1 = require("@project-serum/anchor");
|
|
5
|
+
const types_1 = require("../types");
|
|
6
|
+
const spotBalance_1 = require("./spotBalance");
|
|
7
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
5
8
|
function castNumberToSpotPrecision(value, spotMarket) {
|
|
6
9
|
return new anchor_1.BN(value * Math.pow(10, spotMarket.decimals));
|
|
7
10
|
}
|
|
8
11
|
exports.castNumberToSpotPrecision = castNumberToSpotPrecision;
|
|
12
|
+
function calculateSpotMarketMarginRatio(market, marginCategory, size, balanceType) {
|
|
13
|
+
if (types_1.isVariant(balanceType, 'deposit')) {
|
|
14
|
+
const assetWeight = spotBalance_1.calculateAssetWeight(size, market, marginCategory);
|
|
15
|
+
return numericConstants_1.MARGIN_PRECISION.sub(assetWeight).toNumber();
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
const liabilityWeight = spotBalance_1.calculateLiabilityWeight(size, market, marginCategory);
|
|
19
|
+
return liabilityWeight.sub(numericConstants_1.MARGIN_PRECISION).toNumber();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.calculateSpotMarketMarginRatio = calculateSpotMarketMarginRatio;
|
package/lib/math/spotPosition.js
CHANGED
|
@@ -11,12 +11,12 @@ function getWorstCaseTokenAmounts(spotPosition, spotMarketAccount, oraclePriceDa
|
|
|
11
11
|
const tokenAmount = spotBalance_1.getSignedTokenAmount(spotBalance_1.getTokenAmount(spotPosition.scaledBalance, spotMarketAccount, spotPosition.balanceType), spotPosition.balanceType);
|
|
12
12
|
const tokenAmountAllBidsFill = tokenAmount.add(spotPosition.openBids);
|
|
13
13
|
const tokenAmountAllAsksFill = tokenAmount.add(spotPosition.openAsks);
|
|
14
|
-
if (
|
|
15
|
-
const worstCaseQuoteTokenAmount = spotBalance_1.getTokenValue(spotPosition.
|
|
14
|
+
if (tokenAmountAllBidsFill.abs().gt(tokenAmountAllAsksFill.abs())) {
|
|
15
|
+
const worstCaseQuoteTokenAmount = spotBalance_1.getTokenValue(spotPosition.openBids.neg(), spotMarketAccount.decimals, oraclePriceData);
|
|
16
16
|
return [tokenAmountAllBidsFill, worstCaseQuoteTokenAmount];
|
|
17
17
|
}
|
|
18
18
|
else {
|
|
19
|
-
const worstCaseQuoteTokenAmount = spotBalance_1.getTokenValue(spotPosition.
|
|
19
|
+
const worstCaseQuoteTokenAmount = spotBalance_1.getTokenValue(spotPosition.openAsks.neg(), spotMarketAccount.decimals, oraclePriceData);
|
|
20
20
|
return [tokenAmountAllAsksFill, worstCaseQuoteTokenAmount];
|
|
21
21
|
}
|
|
22
22
|
}
|
package/lib/user.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import StrictEventEmitter from 'strict-event-emitter-types';
|
|
|
6
6
|
import { DriftClient } from './driftClient';
|
|
7
7
|
import { MarginCategory, Order, UserAccount, PerpPosition, SpotPosition, PerpMarketAccount } from './types';
|
|
8
8
|
import { UserAccountSubscriber, UserAccountEvents, DataAndSlot } from './accounts/types';
|
|
9
|
-
import { PositionDirection, BN, SpotMarketAccount } from '.';
|
|
9
|
+
import { PositionDirection, BN, SpotMarketAccount, MarketType } from '.';
|
|
10
10
|
import { OraclePriceData } from './oracles/types';
|
|
11
11
|
import { UserConfig } from './userConfig';
|
|
12
12
|
export declare class User {
|
|
@@ -80,8 +80,8 @@ export declare class User {
|
|
|
80
80
|
* calculates Buying Power = free collateral / initial margin ratio
|
|
81
81
|
* @returns : Precision QUOTE_PRECISION
|
|
82
82
|
*/
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
getPerpBuyingPower(marketIndex: number): BN;
|
|
84
|
+
getPerpBuyingPowerFromFreeCollateralAndBaseAssetAmount(marketIndex: number, freeCollateral: BN, baseAssetAmount: BN): BN;
|
|
85
85
|
/**
|
|
86
86
|
* calculates Free Collateral = Total collateral - initial margin requirement
|
|
87
87
|
* @returns : Precision QUOTE_PRECISION
|
|
@@ -110,10 +110,16 @@ export declare class User {
|
|
|
110
110
|
* @returns : Precision QUOTE_PRECISION
|
|
111
111
|
*/
|
|
112
112
|
getUnrealizedFundingPNL(marketIndex?: number): BN;
|
|
113
|
+
getSpotMarketAssetAndLiabilityValue(marketIndex?: number, marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean, strict?: boolean, now?: BN): {
|
|
114
|
+
totalAssetValue: BN;
|
|
115
|
+
totalLiabilityValue: BN;
|
|
116
|
+
};
|
|
113
117
|
getSpotMarketLiabilityValue(marketIndex?: number, marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean, strict?: boolean, now?: BN): BN;
|
|
114
118
|
getSpotLiabilityValue(tokenAmount: BN, oraclePriceData: OraclePriceData, spotMarketAccount: SpotMarketAccount, marginCategory?: MarginCategory, liquidationBuffer?: BN, strict?: boolean, now?: BN): BN;
|
|
115
119
|
getSpotMarketAssetValue(marketIndex?: number, marginCategory?: MarginCategory, includeOpenOrders?: boolean, strict?: boolean, now?: BN): BN;
|
|
116
120
|
getSpotAssetValue(tokenAmount: BN, oraclePriceData: OraclePriceData, spotMarketAccount: SpotMarketAccount, marginCategory?: MarginCategory, strict?: boolean, now?: BN): BN;
|
|
121
|
+
getSpotTokenAmount(marketIndex: number): BN;
|
|
122
|
+
getSpotPositionValue(marketIndex: number, marginCategory?: MarginCategory, includeOpenOrders?: boolean, strict?: boolean, now?: BN): BN;
|
|
117
123
|
getNetSpotMarketValue(withWeightMarginCategory?: MarginCategory): BN;
|
|
118
124
|
/**
|
|
119
125
|
* calculates TotalCollateral: collateral + unrealized pnl
|
|
@@ -146,6 +152,12 @@ export declare class User {
|
|
|
146
152
|
* @returns : Precision TEN_THOUSAND
|
|
147
153
|
*/
|
|
148
154
|
getLeverage(): BN;
|
|
155
|
+
getLeverageComponents(): {
|
|
156
|
+
perpLiabilityValue: BN;
|
|
157
|
+
perpPnl: BN;
|
|
158
|
+
spotAssetValue: BN;
|
|
159
|
+
spotLiabilityValue: BN;
|
|
160
|
+
};
|
|
149
161
|
getTotalLiabilityValue(marginCategory?: MarginCategory): BN;
|
|
150
162
|
getTotalAssetValue(marginCategory?: MarginCategory): BN;
|
|
151
163
|
/**
|
|
@@ -153,12 +165,19 @@ export declare class User {
|
|
|
153
165
|
* @params category {Initial, Maintenance}
|
|
154
166
|
* @returns : Precision TEN_THOUSAND
|
|
155
167
|
*/
|
|
156
|
-
|
|
168
|
+
getMaxLeverageForPerp(perpMarketIndex: number, category?: MarginCategory): BN;
|
|
157
169
|
/**
|
|
158
|
-
* calculates
|
|
170
|
+
* calculates max allowable leverage exceeding hitting requirement category
|
|
171
|
+
* @param spotMarketIndex
|
|
172
|
+
* @param direction
|
|
159
173
|
* @returns : Precision TEN_THOUSAND
|
|
160
174
|
*/
|
|
161
|
-
|
|
175
|
+
getMaxLeverageForSpot(spotMarketIndex: number, direction: PositionDirection): BN;
|
|
176
|
+
/**
|
|
177
|
+
* calculates margin ratio: 1 / leverage
|
|
178
|
+
* @returns : Precision TEN_THOUSAND
|
|
179
|
+
*/
|
|
180
|
+
getMarginRatio(): BN;
|
|
162
181
|
canBeLiquidated(): boolean;
|
|
163
182
|
isBeingLiquidated(): boolean;
|
|
164
183
|
isBankrupt(): boolean;
|
|
@@ -172,7 +191,7 @@ export declare class User {
|
|
|
172
191
|
* @param marketIndex
|
|
173
192
|
* @returns Precision : PRICE_PRECISION
|
|
174
193
|
*/
|
|
175
|
-
spotLiquidationPrice(marketIndex: number): BN;
|
|
194
|
+
spotLiquidationPrice(marketIndex: number, positionBaseSizeChange?: BN): BN;
|
|
176
195
|
/**
|
|
177
196
|
* Calculate the liquidation price of a perp position, with optional parameter to calculate the liquidation price after a trade
|
|
178
197
|
* @param marketIndex
|
|
@@ -210,15 +229,27 @@ export declare class User {
|
|
|
210
229
|
* @param tradeSide
|
|
211
230
|
* @returns tradeSizeAllowed : Precision QUOTE_PRECISION
|
|
212
231
|
*/
|
|
213
|
-
|
|
232
|
+
getMaxTradeSizeUSDCForPerp(targetMarketIndex: number, tradeSide: PositionDirection): BN;
|
|
233
|
+
/**
|
|
234
|
+
* Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
|
|
235
|
+
*
|
|
236
|
+
* @param targetMarketIndex
|
|
237
|
+
* @param direction
|
|
238
|
+
* @param currentQuoteAssetValue
|
|
239
|
+
* @param currentSpotMarketNetValue
|
|
240
|
+
* @returns tradeSizeAllowed : Precision QUOTE_PRECISION
|
|
241
|
+
*/
|
|
242
|
+
getMaxTradeSizeUSDCForSpot(targetMarketIndex: number, direction: PositionDirection, currentQuoteAssetValue?: BN, currentSpotMarketNetValue?: BN): BN;
|
|
214
243
|
/**
|
|
215
244
|
* Returns the leverage ratio for the account after adding (or subtracting) the given quote size to the given position
|
|
216
245
|
* @param targetMarketIndex
|
|
217
|
-
* @param
|
|
246
|
+
* @param: targetMarketType
|
|
218
247
|
* @param tradeQuoteAmount
|
|
248
|
+
* @param tradeSide
|
|
249
|
+
* @param includeOpenOrders
|
|
219
250
|
* @returns leverageRatio : Precision TEN_THOUSAND
|
|
220
251
|
*/
|
|
221
|
-
accountLeverageRatioAfterTrade(targetMarketIndex: number, tradeQuoteAmount: BN, tradeSide: PositionDirection, includeOpenOrders?: boolean): BN;
|
|
252
|
+
accountLeverageRatioAfterTrade(targetMarketIndex: number, targetMarketType: MarketType, tradeQuoteAmount: BN, tradeSide: PositionDirection, includeOpenOrders?: boolean): BN;
|
|
222
253
|
/**
|
|
223
254
|
* Calculates how much fee will be taken for a given sized trade
|
|
224
255
|
* @param quoteAmount
|