@drift-labs/sdk 2.131.0-beta.9 → 2.131.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/browser/driftClient.d.ts +26 -3
- package/lib/browser/driftClient.js +34 -9
- package/lib/browser/idl/drift.json +1 -1
- package/lib/browser/math/margin.d.ts +1 -1
- package/lib/browser/orderSubscriber/WebsocketSubscription.js +2 -2
- package/lib/browser/user.d.ts +13 -13
- package/lib/browser/user.js +56 -31
- package/lib/node/driftClient.d.ts +26 -3
- package/lib/node/driftClient.d.ts.map +1 -1
- package/lib/node/driftClient.js +34 -9
- package/lib/node/idl/drift.json +1 -1
- package/lib/node/math/margin.d.ts +1 -1
- package/lib/node/math/margin.d.ts.map +1 -1
- package/lib/node/orderSubscriber/WebsocketSubscription.d.ts.map +1 -1
- package/lib/node/orderSubscriber/WebsocketSubscription.js +2 -2
- package/lib/node/user.d.ts +13 -13
- package/lib/node/user.d.ts.map +1 -1
- package/lib/node/user.js +56 -31
- package/package.json +1 -1
- package/src/driftClient.ts +53 -19
- package/src/idl/drift.json +2 -2
- package/src/math/margin.ts +1 -1
- package/src/orderSubscriber/WebsocketSubscription.ts +3 -3
- package/src/user.ts +68 -39
package/lib/node/user.js
CHANGED
|
@@ -426,7 +426,7 @@ class User {
|
|
|
426
426
|
* calculates Buying Power = free collateral / initial margin ratio
|
|
427
427
|
* @returns : Precision QUOTE_PRECISION
|
|
428
428
|
*/
|
|
429
|
-
getPerpBuyingPower(marketIndex, collateralBuffer = numericConstants_1.ZERO, enterHighLeverageMode =
|
|
429
|
+
getPerpBuyingPower(marketIndex, collateralBuffer = numericConstants_1.ZERO, enterHighLeverageMode = undefined) {
|
|
430
430
|
const perpPosition = this.getPerpPositionWithLPSettle(marketIndex, undefined, true)[0];
|
|
431
431
|
const perpMarket = this.driftClient.getPerpMarketAccount(marketIndex);
|
|
432
432
|
const oraclePriceData = this.getOracleDataForPerpMarket(marketIndex);
|
|
@@ -436,7 +436,7 @@ class User {
|
|
|
436
436
|
const freeCollateral = this.getFreeCollateral('Initial', enterHighLeverageMode).sub(collateralBuffer);
|
|
437
437
|
return this.getPerpBuyingPowerFromFreeCollateralAndBaseAssetAmount(marketIndex, freeCollateral, worstCaseBaseAssetAmount, enterHighLeverageMode);
|
|
438
438
|
}
|
|
439
|
-
getPerpBuyingPowerFromFreeCollateralAndBaseAssetAmount(marketIndex, freeCollateral, baseAssetAmount, enterHighLeverageMode =
|
|
439
|
+
getPerpBuyingPowerFromFreeCollateralAndBaseAssetAmount(marketIndex, freeCollateral, baseAssetAmount, enterHighLeverageMode = undefined) {
|
|
440
440
|
const marginRatio = (0, market_1.calculateMarketMarginRatio)(this.driftClient.getPerpMarketAccount(marketIndex), baseAssetAmount, 'Initial', this.getUserAccount().maxMarginRatio, enterHighLeverageMode || this.isHighLeverageMode('Initial'));
|
|
441
441
|
return freeCollateral.mul(numericConstants_1.MARGIN_PRECISION).div(new anchor_1.BN(marginRatio));
|
|
442
442
|
}
|
|
@@ -444,7 +444,7 @@ class User {
|
|
|
444
444
|
* calculates Free Collateral = Total collateral - margin requirement
|
|
445
445
|
* @returns : Precision QUOTE_PRECISION
|
|
446
446
|
*/
|
|
447
|
-
getFreeCollateral(marginCategory = 'Initial', enterHighLeverageMode =
|
|
447
|
+
getFreeCollateral(marginCategory = 'Initial', enterHighLeverageMode = undefined) {
|
|
448
448
|
const totalCollateral = this.getTotalCollateral(marginCategory, true);
|
|
449
449
|
const marginRequirement = marginCategory === 'Initial'
|
|
450
450
|
? this.getInitialMarginRequirement(enterHighLeverageMode)
|
|
@@ -455,13 +455,13 @@ class User {
|
|
|
455
455
|
/**
|
|
456
456
|
* @returns The margin requirement of a certain type (Initial or Maintenance) in USDC. : QUOTE_PRECISION
|
|
457
457
|
*/
|
|
458
|
-
getMarginRequirement(marginCategory, liquidationBuffer, strict = false, includeOpenOrders = true, enteringHighLeverage =
|
|
458
|
+
getMarginRequirement(marginCategory, liquidationBuffer, strict = false, includeOpenOrders = true, enteringHighLeverage = undefined) {
|
|
459
459
|
return this.getTotalPerpPositionLiability(marginCategory, liquidationBuffer, includeOpenOrders, strict, enteringHighLeverage).add(this.getSpotMarketLiabilityValue(undefined, marginCategory, liquidationBuffer, includeOpenOrders, strict));
|
|
460
460
|
}
|
|
461
461
|
/**
|
|
462
462
|
* @returns The initial margin requirement in USDC. : QUOTE_PRECISION
|
|
463
463
|
*/
|
|
464
|
-
getInitialMarginRequirement(enterHighLeverageMode =
|
|
464
|
+
getInitialMarginRequirement(enterHighLeverageMode = undefined) {
|
|
465
465
|
return this.getMarginRequirement('Initial', undefined, true, undefined, enterHighLeverageMode);
|
|
466
466
|
}
|
|
467
467
|
/**
|
|
@@ -749,7 +749,7 @@ class User {
|
|
|
749
749
|
}
|
|
750
750
|
return health;
|
|
751
751
|
}
|
|
752
|
-
calculateWeightedPerpPositionLiability(perpPosition, marginCategory, liquidationBuffer, includeOpenOrders, strict = false, enteringHighLeverage =
|
|
752
|
+
calculateWeightedPerpPositionLiability(perpPosition, marginCategory, liquidationBuffer, includeOpenOrders, strict = false, enteringHighLeverage = undefined) {
|
|
753
753
|
const market = this.driftClient.getPerpMarketAccount(perpPosition.marketIndex);
|
|
754
754
|
if (perpPosition.lpShares.gt(numericConstants_1.ZERO)) {
|
|
755
755
|
// is an lp, clone so we dont mutate the position
|
|
@@ -771,7 +771,11 @@ class User {
|
|
|
771
771
|
liabilityValue = (0, margin_1.calculatePerpLiabilityValue)(baseAssetAmount, valuationPrice, (0, types_1.isVariant)(market.contractType, 'prediction'));
|
|
772
772
|
}
|
|
773
773
|
if (marginCategory) {
|
|
774
|
-
|
|
774
|
+
const userCustomMargin = this.getUserAccount().maxMarginRatio;
|
|
775
|
+
let marginRatio = new anchor_1.BN((0, market_1.calculateMarketMarginRatio)(market, baseAssetAmount.abs(), marginCategory, enteringHighLeverage === false
|
|
776
|
+
? Math.max(market.marginRatioInitial, userCustomMargin)
|
|
777
|
+
: userCustomMargin, this.isHighLeverageMode(marginCategory) ||
|
|
778
|
+
enteringHighLeverage === true));
|
|
775
779
|
if (liquidationBuffer !== undefined) {
|
|
776
780
|
marginRatio = marginRatio.add(liquidationBuffer);
|
|
777
781
|
}
|
|
@@ -817,7 +821,7 @@ class User {
|
|
|
817
821
|
* calculates sum of position value across all positions in margin system
|
|
818
822
|
* @returns : Precision QUOTE_PRECISION
|
|
819
823
|
*/
|
|
820
|
-
getTotalPerpPositionLiability(marginCategory, liquidationBuffer, includeOpenOrders, strict = false, enteringHighLeverage =
|
|
824
|
+
getTotalPerpPositionLiability(marginCategory, liquidationBuffer, includeOpenOrders, strict = false, enteringHighLeverage = undefined) {
|
|
821
825
|
return this.getActivePerpPositions().reduce((totalPerpValue, perpPosition) => {
|
|
822
826
|
const baseAssetValue = this.calculateWeightedPerpPositionLiability(perpPosition, marginCategory, liquidationBuffer, includeOpenOrders, strict, enteringHighLeverage);
|
|
823
827
|
return totalPerpValue.add(baseAssetValue);
|
|
@@ -984,7 +988,7 @@ class User {
|
|
|
984
988
|
* @param enterHighLeverageMode can pass this as true to calculate max leverage if the user was to enter high leverage mode
|
|
985
989
|
* @returns : Precision TEN_THOUSAND
|
|
986
990
|
*/
|
|
987
|
-
getMaxLeverageForPerp(perpMarketIndex, _marginCategory = 'Initial', isLp = false, enterHighLeverageMode =
|
|
991
|
+
getMaxLeverageForPerp(perpMarketIndex, _marginCategory = 'Initial', isLp = false, enterHighLeverageMode = undefined) {
|
|
988
992
|
const market = this.driftClient.getPerpMarketAccount(perpMarketIndex);
|
|
989
993
|
const marketPrice = this.driftClient.getOracleDataForPerpMarket(perpMarketIndex).price;
|
|
990
994
|
const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } = this.getLeverageComponents();
|
|
@@ -1166,7 +1170,7 @@ class User {
|
|
|
1166
1170
|
* @param offsetCollateral // allows calculating the liquidation price after this offset collateral is added to the user's account (e.g. : what will the liquidation price be for this position AFTER I deposit $x worth of collateral)
|
|
1167
1171
|
* @returns Precision : PRICE_PRECISION
|
|
1168
1172
|
*/
|
|
1169
|
-
liquidationPrice(marketIndex, positionBaseSizeChange = numericConstants_1.ZERO, estimatedEntryPrice = numericConstants_1.ZERO, marginCategory = 'Maintenance', includeOpenOrders = false, offsetCollateral = numericConstants_1.ZERO, enteringHighLeverage =
|
|
1173
|
+
liquidationPrice(marketIndex, positionBaseSizeChange = numericConstants_1.ZERO, estimatedEntryPrice = numericConstants_1.ZERO, marginCategory = 'Maintenance', includeOpenOrders = false, offsetCollateral = numericConstants_1.ZERO, enteringHighLeverage = undefined) {
|
|
1170
1174
|
const totalCollateral = this.getTotalCollateral(marginCategory, false, includeOpenOrders);
|
|
1171
1175
|
const marginRequirement = this.getMarginRequirement(marginCategory, undefined, false, includeOpenOrders, enteringHighLeverage);
|
|
1172
1176
|
let freeCollateral = anchor_1.BN.max(numericConstants_1.ZERO, totalCollateral.sub(marginRequirement)).add(offsetCollateral);
|
|
@@ -1211,7 +1215,7 @@ class User {
|
|
|
1211
1215
|
}
|
|
1212
1216
|
return liqPrice;
|
|
1213
1217
|
}
|
|
1214
|
-
calculateEntriesEffectOnFreeCollateral(market, oraclePrice, perpPosition, positionBaseSizeChange, estimatedEntryPrice, includeOpenOrders, enteringHighLeverage =
|
|
1218
|
+
calculateEntriesEffectOnFreeCollateral(market, oraclePrice, perpPosition, positionBaseSizeChange, estimatedEntryPrice, includeOpenOrders, enteringHighLeverage = undefined, marginCategory = 'Maintenance') {
|
|
1215
1219
|
let freeCollateralChange = numericConstants_1.ZERO;
|
|
1216
1220
|
// update free collateral to account for change in pnl from new position
|
|
1217
1221
|
if (!estimatedEntryPrice.eq(numericConstants_1.ZERO) &&
|
|
@@ -1248,7 +1252,10 @@ class User {
|
|
|
1248
1252
|
baseAssetAmount = perpPosition.baseAssetAmount;
|
|
1249
1253
|
liabilityValue = (0, margin_1.calculatePerpLiabilityValue)(baseAssetAmount, oraclePrice, (0, types_1.isVariant)(market.contractType, 'prediction'));
|
|
1250
1254
|
}
|
|
1251
|
-
const
|
|
1255
|
+
const userCustomMargin = this.getUserAccount().maxMarginRatio;
|
|
1256
|
+
const marginRatio = (0, market_1.calculateMarketMarginRatio)(market, baseAssetAmount.abs(), marginCategory, enteringHighLeverage === false
|
|
1257
|
+
? Math.max(market.marginRatioInitial, userCustomMargin)
|
|
1258
|
+
: userCustomMargin, this.isHighLeverageMode(marginCategory) || enteringHighLeverage === true);
|
|
1252
1259
|
return liabilityValue.mul(new anchor_1.BN(marginRatio)).div(numericConstants_1.MARGIN_PRECISION);
|
|
1253
1260
|
};
|
|
1254
1261
|
const freeCollateralConsumptionBefore = calculateMarginRequirement(perpPosition);
|
|
@@ -1257,14 +1264,17 @@ class User {
|
|
|
1257
1264
|
const freeCollateralConsumptionAfter = calculateMarginRequirement(perpPositionAfter);
|
|
1258
1265
|
return freeCollateralChange.sub(freeCollateralConsumptionAfter.sub(freeCollateralConsumptionBefore));
|
|
1259
1266
|
}
|
|
1260
|
-
calculateFreeCollateralDeltaForPerp(market, perpPosition, positionBaseSizeChange, oraclePrice, marginCategory = 'Maintenance', includeOpenOrders = false, enteringHighLeverage =
|
|
1267
|
+
calculateFreeCollateralDeltaForPerp(market, perpPosition, positionBaseSizeChange, oraclePrice, marginCategory = 'Maintenance', includeOpenOrders = false, enteringHighLeverage = undefined) {
|
|
1261
1268
|
const baseAssetAmount = includeOpenOrders
|
|
1262
1269
|
? (0, margin_2.calculateWorstCaseBaseAssetAmount)(perpPosition, market, oraclePrice)
|
|
1263
1270
|
: perpPosition.baseAssetAmount;
|
|
1264
1271
|
// zero if include orders == false
|
|
1265
1272
|
const orderBaseAssetAmount = baseAssetAmount.sub(perpPosition.baseAssetAmount);
|
|
1266
1273
|
const proposedBaseAssetAmount = baseAssetAmount.add(positionBaseSizeChange);
|
|
1267
|
-
const
|
|
1274
|
+
const userCustomMargin = this.getUserAccount().maxMarginRatio;
|
|
1275
|
+
const marginRatio = (0, market_1.calculateMarketMarginRatio)(market, proposedBaseAssetAmount.abs(), marginCategory, enteringHighLeverage === false
|
|
1276
|
+
? Math.max(market.marginRatioInitial, userCustomMargin)
|
|
1277
|
+
: userCustomMargin, this.isHighLeverageMode(marginCategory) || enteringHighLeverage === true);
|
|
1268
1278
|
const marginRatioQuotePrecision = new anchor_1.BN(marginRatio)
|
|
1269
1279
|
.mul(numericConstants_1.QUOTE_PRECISION)
|
|
1270
1280
|
.div(numericConstants_1.MARGIN_PRECISION);
|
|
@@ -1353,7 +1363,7 @@ class User {
|
|
|
1353
1363
|
* @param isLp
|
|
1354
1364
|
* @returns { tradeSize: BN, oppositeSideTradeSize: BN} : Precision QUOTE_PRECISION
|
|
1355
1365
|
*/
|
|
1356
|
-
getMaxTradeSizeUSDCForPerp(targetMarketIndex, tradeSide, isLp = false, enterHighLeverageMode =
|
|
1366
|
+
getMaxTradeSizeUSDCForPerp(targetMarketIndex, tradeSide, isLp = false, enterHighLeverageMode = undefined) {
|
|
1357
1367
|
let tradeSize = numericConstants_1.ZERO;
|
|
1358
1368
|
let oppositeSideTradeSize = numericConstants_1.ZERO;
|
|
1359
1369
|
const currentPosition = this.getPerpPositionWithLPSettle(targetMarketIndex, undefined, true)[0] ||
|
|
@@ -1772,7 +1782,7 @@ class User {
|
|
|
1772
1782
|
}
|
|
1773
1783
|
getUserFeeTier(marketType, now) {
|
|
1774
1784
|
const state = this.driftClient.getStateAccount();
|
|
1775
|
-
|
|
1785
|
+
const feeTierIndex = 0;
|
|
1776
1786
|
if ((0, types_1.isVariant)(marketType, 'perp')) {
|
|
1777
1787
|
if (this.isHighLeverageMode('Initial')) {
|
|
1778
1788
|
return state.perpFeeStructure.feeTiers[0];
|
|
@@ -1782,28 +1792,43 @@ class User {
|
|
|
1782
1792
|
.getAccount();
|
|
1783
1793
|
const total30dVolume = (0, trade_1.getUser30dRollingVolumeEstimate)(userStatsAccount, now);
|
|
1784
1794
|
const stakedGovAssetAmount = userStatsAccount.ifStakedGovTokenAmount;
|
|
1785
|
-
const
|
|
1786
|
-
new anchor_1.BN(
|
|
1787
|
-
new anchor_1.BN(50000000).mul(numericConstants_1.QUOTE_PRECISION),
|
|
1795
|
+
const volumeThresholds = [
|
|
1796
|
+
new anchor_1.BN(2000000).mul(numericConstants_1.QUOTE_PRECISION),
|
|
1788
1797
|
new anchor_1.BN(10000000).mul(numericConstants_1.QUOTE_PRECISION),
|
|
1789
|
-
new anchor_1.BN(
|
|
1790
|
-
new anchor_1.BN(
|
|
1798
|
+
new anchor_1.BN(20000000).mul(numericConstants_1.QUOTE_PRECISION),
|
|
1799
|
+
new anchor_1.BN(100000000).mul(numericConstants_1.QUOTE_PRECISION),
|
|
1800
|
+
new anchor_1.BN(200000000).mul(numericConstants_1.QUOTE_PRECISION),
|
|
1791
1801
|
];
|
|
1792
|
-
const
|
|
1793
|
-
new anchor_1.BN(120000 - 1).mul(numericConstants_1.QUOTE_PRECISION),
|
|
1794
|
-
new anchor_1.BN(100000 - 1).mul(numericConstants_1.QUOTE_PRECISION),
|
|
1795
|
-
new anchor_1.BN(25000 - 1).mul(numericConstants_1.QUOTE_PRECISION),
|
|
1796
|
-
new anchor_1.BN(10000 - 1).mul(numericConstants_1.QUOTE_PRECISION),
|
|
1802
|
+
const stakeThresholds = [
|
|
1797
1803
|
new anchor_1.BN(1000 - 1).mul(numericConstants_1.QUOTE_PRECISION),
|
|
1804
|
+
new anchor_1.BN(10000 - 1).mul(numericConstants_1.QUOTE_PRECISION),
|
|
1805
|
+
new anchor_1.BN(50000 - 1).mul(numericConstants_1.QUOTE_PRECISION),
|
|
1806
|
+
new anchor_1.BN(100000 - 1).mul(numericConstants_1.QUOTE_PRECISION),
|
|
1807
|
+
new anchor_1.BN(250000 - 5).mul(numericConstants_1.QUOTE_PRECISION),
|
|
1798
1808
|
];
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1809
|
+
const stakeBenefitFrac = [0, 5, 10, 20, 30, 40];
|
|
1810
|
+
let feeTierIndex = 5;
|
|
1811
|
+
for (let i = 0; i < volumeThresholds.length; i++) {
|
|
1812
|
+
if (total30dVolume.lt(volumeThresholds[i])) {
|
|
1813
|
+
feeTierIndex = i;
|
|
1803
1814
|
break;
|
|
1804
1815
|
}
|
|
1805
1816
|
}
|
|
1806
|
-
|
|
1817
|
+
let stakeBenefitIndex = 5;
|
|
1818
|
+
for (let i = 0; i < stakeThresholds.length; i++) {
|
|
1819
|
+
if (stakedGovAssetAmount.lt(stakeThresholds[i])) {
|
|
1820
|
+
stakeBenefitIndex = i;
|
|
1821
|
+
break;
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
const stakeBenefit = stakeBenefitFrac[stakeBenefitIndex];
|
|
1825
|
+
const tier = { ...state.perpFeeStructure.feeTiers[feeTierIndex] };
|
|
1826
|
+
if (stakeBenefit > 0) {
|
|
1827
|
+
tier.feeNumerator = (tier.feeNumerator * (100 - stakeBenefit)) / 100;
|
|
1828
|
+
tier.makerRebateNumerator =
|
|
1829
|
+
(tier.makerRebateNumerator * (100 + stakeBenefit)) / 100;
|
|
1830
|
+
}
|
|
1831
|
+
return tier;
|
|
1807
1832
|
}
|
|
1808
1833
|
return state.spotFeeStructure.feeTiers[feeTierIndex];
|
|
1809
1834
|
}
|
package/package.json
CHANGED
package/src/driftClient.ts
CHANGED
|
@@ -4357,14 +4357,24 @@ export class DriftClient {
|
|
|
4357
4357
|
});
|
|
4358
4358
|
}
|
|
4359
4359
|
|
|
4360
|
+
/**
|
|
4361
|
+
* Sends a transaction to cancel the provided order ids.
|
|
4362
|
+
*
|
|
4363
|
+
* @param orderIds - The order ids to cancel.
|
|
4364
|
+
* @param txParams - The transaction parameters.
|
|
4365
|
+
* @param subAccountId - The sub account id to cancel the orders for.
|
|
4366
|
+
* @param user - The user to cancel the orders for. If provided, it will be prioritized over the subAccountId.
|
|
4367
|
+
* @returns The transaction signature.
|
|
4368
|
+
*/
|
|
4360
4369
|
public async cancelOrdersByIds(
|
|
4361
4370
|
orderIds?: number[],
|
|
4362
4371
|
txParams?: TxParams,
|
|
4363
|
-
subAccountId?: number
|
|
4372
|
+
subAccountId?: number,
|
|
4373
|
+
user?: User
|
|
4364
4374
|
): Promise<TransactionSignature> {
|
|
4365
4375
|
const { txSig } = await this.sendTransaction(
|
|
4366
4376
|
await this.buildTransaction(
|
|
4367
|
-
await this.getCancelOrdersByIdsIx(orderIds, subAccountId),
|
|
4377
|
+
await this.getCancelOrdersByIdsIx(orderIds, subAccountId, user),
|
|
4368
4378
|
txParams
|
|
4369
4379
|
),
|
|
4370
4380
|
[],
|
|
@@ -4373,21 +4383,34 @@ export class DriftClient {
|
|
|
4373
4383
|
return txSig;
|
|
4374
4384
|
}
|
|
4375
4385
|
|
|
4386
|
+
/**
|
|
4387
|
+
* Returns the transaction instruction to cancel the provided order ids.
|
|
4388
|
+
*
|
|
4389
|
+
* @param orderIds - The order ids to cancel.
|
|
4390
|
+
* @param subAccountId - The sub account id to cancel the orders for.
|
|
4391
|
+
* @param user - The user to cancel the orders for. If provided, it will be prioritized over the subAccountId.
|
|
4392
|
+
* @returns The transaction instruction to cancel the orders.
|
|
4393
|
+
*/
|
|
4376
4394
|
public async getCancelOrdersByIdsIx(
|
|
4377
4395
|
orderIds?: number[],
|
|
4378
|
-
subAccountId?: number
|
|
4396
|
+
subAccountId?: number,
|
|
4397
|
+
user?: User
|
|
4379
4398
|
): Promise<TransactionInstruction> {
|
|
4380
|
-
const
|
|
4399
|
+
const userAccountPubKey =
|
|
4400
|
+
user?.userAccountPublicKey ??
|
|
4401
|
+
(await this.getUserAccountPublicKey(subAccountId));
|
|
4402
|
+
const userAccount =
|
|
4403
|
+
user?.getUserAccount() ?? this.getUserAccount(subAccountId);
|
|
4381
4404
|
|
|
4382
4405
|
const remainingAccounts = this.getRemainingAccounts({
|
|
4383
|
-
userAccounts: [
|
|
4406
|
+
userAccounts: [userAccount],
|
|
4384
4407
|
useMarketLastSlotCache: true,
|
|
4385
4408
|
});
|
|
4386
4409
|
|
|
4387
4410
|
return await this.program.instruction.cancelOrdersByIds(orderIds, {
|
|
4388
4411
|
accounts: {
|
|
4389
4412
|
state: await this.getStatePublicKey(),
|
|
4390
|
-
user,
|
|
4413
|
+
user: userAccountPubKey,
|
|
4391
4414
|
authority: this.wallet.publicKey,
|
|
4392
4415
|
},
|
|
4393
4416
|
remainingAccounts,
|
|
@@ -6969,6 +6992,12 @@ export class DriftClient {
|
|
|
6969
6992
|
return txSig;
|
|
6970
6993
|
}
|
|
6971
6994
|
|
|
6995
|
+
/**
|
|
6996
|
+
* @param orderParams: The parameters for the order to modify.
|
|
6997
|
+
* @param subAccountId: Optional - The subaccount ID of the user to modify the order for.
|
|
6998
|
+
* @param userPublicKey: Optional - The public key of the user to modify the order for. This takes precedence over subAccountId.
|
|
6999
|
+
* @returns
|
|
7000
|
+
*/
|
|
6972
7001
|
public async getModifyOrderIx(
|
|
6973
7002
|
{
|
|
6974
7003
|
orderId,
|
|
@@ -7003,9 +7032,11 @@ export class DriftClient {
|
|
|
7003
7032
|
maxTs?: BN;
|
|
7004
7033
|
policy?: number;
|
|
7005
7034
|
},
|
|
7006
|
-
subAccountId?: number
|
|
7035
|
+
subAccountId?: number,
|
|
7036
|
+
userPublicKey?: PublicKey
|
|
7007
7037
|
): Promise<TransactionInstruction> {
|
|
7008
|
-
const user =
|
|
7038
|
+
const user =
|
|
7039
|
+
userPublicKey ?? (await this.getUserAccountPublicKey(subAccountId));
|
|
7009
7040
|
|
|
7010
7041
|
const remainingAccounts = this.getRemainingAccounts({
|
|
7011
7042
|
userAccounts: [this.getUserAccount(subAccountId)],
|
|
@@ -9854,17 +9885,20 @@ export class DriftClient {
|
|
|
9854
9885
|
})
|
|
9855
9886
|
: undefined;
|
|
9856
9887
|
|
|
9857
|
-
const ix = await this.program.instruction.disableUserHighLeverageMode(
|
|
9858
|
-
|
|
9859
|
-
|
|
9860
|
-
|
|
9861
|
-
|
|
9862
|
-
|
|
9863
|
-
this.
|
|
9864
|
-
|
|
9865
|
-
|
|
9866
|
-
|
|
9867
|
-
|
|
9888
|
+
const ix = await this.program.instruction.disableUserHighLeverageMode(
|
|
9889
|
+
false,
|
|
9890
|
+
{
|
|
9891
|
+
accounts: {
|
|
9892
|
+
state: await this.getStatePublicKey(),
|
|
9893
|
+
user,
|
|
9894
|
+
authority: this.wallet.publicKey,
|
|
9895
|
+
highLeverageModeConfig: getHighLeverageModeConfigPublicKey(
|
|
9896
|
+
this.program.programId
|
|
9897
|
+
),
|
|
9898
|
+
},
|
|
9899
|
+
remainingAccounts,
|
|
9900
|
+
}
|
|
9901
|
+
);
|
|
9868
9902
|
|
|
9869
9903
|
return ix;
|
|
9870
9904
|
}
|
package/src/idl/drift.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.
|
|
2
|
+
"version": "2.131.0",
|
|
3
3
|
"name": "drift",
|
|
4
4
|
"instructions": [
|
|
5
5
|
{
|
|
@@ -16077,4 +16077,4 @@
|
|
|
16077
16077
|
"metadata": {
|
|
16078
16078
|
"address": "dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH"
|
|
16079
16079
|
}
|
|
16080
|
-
}
|
|
16080
|
+
}
|
package/src/math/margin.ts
CHANGED
|
@@ -126,7 +126,7 @@ export function calculateOraclePriceForPerpMargin(
|
|
|
126
126
|
export function calculateBaseAssetValueWithOracle(
|
|
127
127
|
market: PerpMarketAccount,
|
|
128
128
|
perpPosition: PerpPosition,
|
|
129
|
-
oraclePriceData: OraclePriceData,
|
|
129
|
+
oraclePriceData: Pick<OraclePriceData, 'price'>,
|
|
130
130
|
includeOpenOrders = false
|
|
131
131
|
): BN {
|
|
132
132
|
let price = oraclePriceData.price;
|
|
@@ -3,7 +3,7 @@ import { getNonIdleUserFilter, getUserFilter } from '../memcmp';
|
|
|
3
3
|
import { UserAccount } from '../types';
|
|
4
4
|
import { Commitment, Context, PublicKey } from '@solana/web3.js';
|
|
5
5
|
import { ResubOpts } from '../accounts/types';
|
|
6
|
-
import {
|
|
6
|
+
import { WebSocketProgramAccountSubscriber } from '../accounts/webSocketProgramAccountSubscriber';
|
|
7
7
|
|
|
8
8
|
export class WebsocketSubscription {
|
|
9
9
|
private orderSubscriber: OrderSubscriber;
|
|
@@ -12,7 +12,7 @@ export class WebsocketSubscription {
|
|
|
12
12
|
private resubOpts?: ResubOpts;
|
|
13
13
|
private resyncIntervalMs?: number;
|
|
14
14
|
|
|
15
|
-
private subscriber?:
|
|
15
|
+
private subscriber?: WebSocketProgramAccountSubscriber<UserAccount>;
|
|
16
16
|
private resyncTimeoutId?: ReturnType<typeof setTimeout>;
|
|
17
17
|
|
|
18
18
|
private decoded?: boolean;
|
|
@@ -45,7 +45,7 @@ export class WebsocketSubscription {
|
|
|
45
45
|
return;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
this.subscriber = new
|
|
48
|
+
this.subscriber = new WebSocketProgramAccountSubscriber<UserAccount>(
|
|
49
49
|
'OrderSubscriber',
|
|
50
50
|
'User',
|
|
51
51
|
this.orderSubscriber.driftClient.program,
|
package/src/user.ts
CHANGED
|
@@ -662,7 +662,7 @@ export class User {
|
|
|
662
662
|
public getPerpBuyingPower(
|
|
663
663
|
marketIndex: number,
|
|
664
664
|
collateralBuffer = ZERO,
|
|
665
|
-
enterHighLeverageMode =
|
|
665
|
+
enterHighLeverageMode = undefined
|
|
666
666
|
): BN {
|
|
667
667
|
const perpPosition = this.getPerpPositionWithLPSettle(
|
|
668
668
|
marketIndex,
|
|
@@ -697,7 +697,7 @@ export class User {
|
|
|
697
697
|
marketIndex: number,
|
|
698
698
|
freeCollateral: BN,
|
|
699
699
|
baseAssetAmount: BN,
|
|
700
|
-
enterHighLeverageMode =
|
|
700
|
+
enterHighLeverageMode = undefined
|
|
701
701
|
): BN {
|
|
702
702
|
const marginRatio = calculateMarketMarginRatio(
|
|
703
703
|
this.driftClient.getPerpMarketAccount(marketIndex),
|
|
@@ -716,7 +716,7 @@ export class User {
|
|
|
716
716
|
*/
|
|
717
717
|
public getFreeCollateral(
|
|
718
718
|
marginCategory: MarginCategory = 'Initial',
|
|
719
|
-
enterHighLeverageMode =
|
|
719
|
+
enterHighLeverageMode = undefined
|
|
720
720
|
): BN {
|
|
721
721
|
const totalCollateral = this.getTotalCollateral(marginCategory, true);
|
|
722
722
|
const marginRequirement =
|
|
@@ -735,7 +735,7 @@ export class User {
|
|
|
735
735
|
liquidationBuffer?: BN,
|
|
736
736
|
strict = false,
|
|
737
737
|
includeOpenOrders = true,
|
|
738
|
-
enteringHighLeverage =
|
|
738
|
+
enteringHighLeverage = undefined
|
|
739
739
|
): BN {
|
|
740
740
|
return this.getTotalPerpPositionLiability(
|
|
741
741
|
marginCategory,
|
|
@@ -757,7 +757,7 @@ export class User {
|
|
|
757
757
|
/**
|
|
758
758
|
* @returns The initial margin requirement in USDC. : QUOTE_PRECISION
|
|
759
759
|
*/
|
|
760
|
-
public getInitialMarginRequirement(enterHighLeverageMode =
|
|
760
|
+
public getInitialMarginRequirement(enterHighLeverageMode = undefined): BN {
|
|
761
761
|
return this.getMarginRequirement(
|
|
762
762
|
'Initial',
|
|
763
763
|
undefined,
|
|
@@ -1432,7 +1432,7 @@ export class User {
|
|
|
1432
1432
|
liquidationBuffer?: BN,
|
|
1433
1433
|
includeOpenOrders?: boolean,
|
|
1434
1434
|
strict = false,
|
|
1435
|
-
enteringHighLeverage =
|
|
1435
|
+
enteringHighLeverage = undefined
|
|
1436
1436
|
): BN {
|
|
1437
1437
|
const market = this.driftClient.getPerpMarketAccount(
|
|
1438
1438
|
perpPosition.marketIndex
|
|
@@ -1476,13 +1476,17 @@ export class User {
|
|
|
1476
1476
|
}
|
|
1477
1477
|
|
|
1478
1478
|
if (marginCategory) {
|
|
1479
|
+
const userCustomMargin = this.getUserAccount().maxMarginRatio;
|
|
1479
1480
|
let marginRatio = new BN(
|
|
1480
1481
|
calculateMarketMarginRatio(
|
|
1481
1482
|
market,
|
|
1482
1483
|
baseAssetAmount.abs(),
|
|
1483
1484
|
marginCategory,
|
|
1484
|
-
|
|
1485
|
-
|
|
1485
|
+
enteringHighLeverage === false
|
|
1486
|
+
? Math.max(market.marginRatioInitial, userCustomMargin)
|
|
1487
|
+
: userCustomMargin,
|
|
1488
|
+
this.isHighLeverageMode(marginCategory) ||
|
|
1489
|
+
enteringHighLeverage === true
|
|
1486
1490
|
)
|
|
1487
1491
|
);
|
|
1488
1492
|
|
|
@@ -1570,7 +1574,7 @@ export class User {
|
|
|
1570
1574
|
liquidationBuffer?: BN,
|
|
1571
1575
|
includeOpenOrders?: boolean,
|
|
1572
1576
|
strict = false,
|
|
1573
|
-
enteringHighLeverage =
|
|
1577
|
+
enteringHighLeverage = undefined
|
|
1574
1578
|
): BN {
|
|
1575
1579
|
return this.getActivePerpPositions().reduce(
|
|
1576
1580
|
(totalPerpValue, perpPosition) => {
|
|
@@ -1594,7 +1598,7 @@ export class User {
|
|
|
1594
1598
|
*/
|
|
1595
1599
|
public getPerpPositionValue(
|
|
1596
1600
|
marketIndex: number,
|
|
1597
|
-
oraclePriceData: OraclePriceData,
|
|
1601
|
+
oraclePriceData: Pick<OraclePriceData, 'price'>,
|
|
1598
1602
|
includeOpenOrders = false
|
|
1599
1603
|
): BN {
|
|
1600
1604
|
const userPosition =
|
|
@@ -1894,7 +1898,7 @@ export class User {
|
|
|
1894
1898
|
perpMarketIndex: number,
|
|
1895
1899
|
_marginCategory: MarginCategory = 'Initial',
|
|
1896
1900
|
isLp = false,
|
|
1897
|
-
enterHighLeverageMode =
|
|
1901
|
+
enterHighLeverageMode = undefined
|
|
1898
1902
|
): BN {
|
|
1899
1903
|
const market = this.driftClient.getPerpMarketAccount(perpMarketIndex);
|
|
1900
1904
|
const marketPrice =
|
|
@@ -2245,7 +2249,7 @@ export class User {
|
|
|
2245
2249
|
marginCategory: MarginCategory = 'Maintenance',
|
|
2246
2250
|
includeOpenOrders = false,
|
|
2247
2251
|
offsetCollateral = ZERO,
|
|
2248
|
-
enteringHighLeverage =
|
|
2252
|
+
enteringHighLeverage = undefined
|
|
2249
2253
|
): BN {
|
|
2250
2254
|
const totalCollateral = this.getTotalCollateral(
|
|
2251
2255
|
marginCategory,
|
|
@@ -2370,7 +2374,7 @@ export class User {
|
|
|
2370
2374
|
positionBaseSizeChange: BN,
|
|
2371
2375
|
estimatedEntryPrice: BN,
|
|
2372
2376
|
includeOpenOrders: boolean,
|
|
2373
|
-
enteringHighLeverage =
|
|
2377
|
+
enteringHighLeverage = undefined,
|
|
2374
2378
|
marginCategory: MarginCategory = 'Maintenance'
|
|
2375
2379
|
): BN {
|
|
2376
2380
|
let freeCollateralChange = ZERO;
|
|
@@ -2423,12 +2427,15 @@ export class User {
|
|
|
2423
2427
|
);
|
|
2424
2428
|
}
|
|
2425
2429
|
|
|
2430
|
+
const userCustomMargin = this.getUserAccount().maxMarginRatio;
|
|
2426
2431
|
const marginRatio = calculateMarketMarginRatio(
|
|
2427
2432
|
market,
|
|
2428
2433
|
baseAssetAmount.abs(),
|
|
2429
2434
|
marginCategory,
|
|
2430
|
-
|
|
2431
|
-
|
|
2435
|
+
enteringHighLeverage === false
|
|
2436
|
+
? Math.max(market.marginRatioInitial, userCustomMargin)
|
|
2437
|
+
: userCustomMargin,
|
|
2438
|
+
this.isHighLeverageMode(marginCategory) || enteringHighLeverage === true
|
|
2432
2439
|
);
|
|
2433
2440
|
|
|
2434
2441
|
return liabilityValue.mul(new BN(marginRatio)).div(MARGIN_PRECISION);
|
|
@@ -2457,7 +2464,7 @@ export class User {
|
|
|
2457
2464
|
oraclePrice: BN,
|
|
2458
2465
|
marginCategory: MarginCategory = 'Maintenance',
|
|
2459
2466
|
includeOpenOrders = false,
|
|
2460
|
-
enteringHighLeverage =
|
|
2467
|
+
enteringHighLeverage = undefined
|
|
2461
2468
|
): BN | undefined {
|
|
2462
2469
|
const baseAssetAmount = includeOpenOrders
|
|
2463
2470
|
? calculateWorstCaseBaseAssetAmount(perpPosition, market, oraclePrice)
|
|
@@ -2470,12 +2477,16 @@ export class User {
|
|
|
2470
2477
|
|
|
2471
2478
|
const proposedBaseAssetAmount = baseAssetAmount.add(positionBaseSizeChange);
|
|
2472
2479
|
|
|
2480
|
+
const userCustomMargin = this.getUserAccount().maxMarginRatio;
|
|
2481
|
+
|
|
2473
2482
|
const marginRatio = calculateMarketMarginRatio(
|
|
2474
2483
|
market,
|
|
2475
2484
|
proposedBaseAssetAmount.abs(),
|
|
2476
2485
|
marginCategory,
|
|
2477
|
-
|
|
2478
|
-
|
|
2486
|
+
enteringHighLeverage === false
|
|
2487
|
+
? Math.max(market.marginRatioInitial, userCustomMargin)
|
|
2488
|
+
: userCustomMargin,
|
|
2489
|
+
this.isHighLeverageMode(marginCategory) || enteringHighLeverage === true
|
|
2479
2490
|
);
|
|
2480
2491
|
|
|
2481
2492
|
const marginRatioQuotePrecision = new BN(marginRatio)
|
|
@@ -2631,7 +2642,7 @@ export class User {
|
|
|
2631
2642
|
targetMarketIndex: number,
|
|
2632
2643
|
tradeSide: PositionDirection,
|
|
2633
2644
|
isLp = false,
|
|
2634
|
-
enterHighLeverageMode =
|
|
2645
|
+
enterHighLeverageMode = undefined
|
|
2635
2646
|
): { tradeSize: BN; oppositeSideTradeSize: BN } {
|
|
2636
2647
|
let tradeSize = ZERO;
|
|
2637
2648
|
let oppositeSideTradeSize = ZERO;
|
|
@@ -3484,7 +3495,7 @@ export class User {
|
|
|
3484
3495
|
public getUserFeeTier(marketType: MarketType, now?: BN) {
|
|
3485
3496
|
const state = this.driftClient.getStateAccount();
|
|
3486
3497
|
|
|
3487
|
-
|
|
3498
|
+
const feeTierIndex = 0;
|
|
3488
3499
|
if (isVariant(marketType, 'perp')) {
|
|
3489
3500
|
if (this.isHighLeverageMode('Initial')) {
|
|
3490
3501
|
return state.perpFeeStructure.feeTiers[0];
|
|
@@ -3498,34 +3509,52 @@ export class User {
|
|
|
3498
3509
|
userStatsAccount,
|
|
3499
3510
|
now
|
|
3500
3511
|
);
|
|
3501
|
-
|
|
3502
3512
|
const stakedGovAssetAmount = userStatsAccount.ifStakedGovTokenAmount;
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
new BN(
|
|
3513
|
+
|
|
3514
|
+
const volumeThresholds = [
|
|
3515
|
+
new BN(2_000_000).mul(QUOTE_PRECISION),
|
|
3506
3516
|
new BN(10_000_000).mul(QUOTE_PRECISION),
|
|
3507
|
-
new BN(
|
|
3508
|
-
new BN(
|
|
3517
|
+
new BN(20_000_000).mul(QUOTE_PRECISION),
|
|
3518
|
+
new BN(100_000_000).mul(QUOTE_PRECISION),
|
|
3519
|
+
new BN(200_000_000).mul(QUOTE_PRECISION),
|
|
3509
3520
|
];
|
|
3510
|
-
const
|
|
3511
|
-
new BN(
|
|
3512
|
-
new BN(
|
|
3513
|
-
new BN(
|
|
3514
|
-
new BN(
|
|
3515
|
-
new BN(
|
|
3521
|
+
const stakeThresholds = [
|
|
3522
|
+
new BN(1_000 - 1).mul(QUOTE_PRECISION),
|
|
3523
|
+
new BN(10_000 - 1).mul(QUOTE_PRECISION),
|
|
3524
|
+
new BN(50_000 - 1).mul(QUOTE_PRECISION),
|
|
3525
|
+
new BN(100_000 - 1).mul(QUOTE_PRECISION),
|
|
3526
|
+
new BN(250_000 - 5).mul(QUOTE_PRECISION),
|
|
3516
3527
|
];
|
|
3528
|
+
const stakeBenefitFrac = [0, 5, 10, 20, 30, 40];
|
|
3517
3529
|
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
) {
|
|
3523
|
-
feeTierIndex = 5 - i;
|
|
3530
|
+
let feeTierIndex = 5;
|
|
3531
|
+
for (let i = 0; i < volumeThresholds.length; i++) {
|
|
3532
|
+
if (total30dVolume.lt(volumeThresholds[i])) {
|
|
3533
|
+
feeTierIndex = i;
|
|
3524
3534
|
break;
|
|
3525
3535
|
}
|
|
3526
3536
|
}
|
|
3527
3537
|
|
|
3528
|
-
|
|
3538
|
+
let stakeBenefitIndex = 5;
|
|
3539
|
+
for (let i = 0; i < stakeThresholds.length; i++) {
|
|
3540
|
+
if (stakedGovAssetAmount.lt(stakeThresholds[i])) {
|
|
3541
|
+
stakeBenefitIndex = i;
|
|
3542
|
+
break;
|
|
3543
|
+
}
|
|
3544
|
+
}
|
|
3545
|
+
|
|
3546
|
+
const stakeBenefit = stakeBenefitFrac[stakeBenefitIndex];
|
|
3547
|
+
|
|
3548
|
+
const tier = { ...state.perpFeeStructure.feeTiers[feeTierIndex] };
|
|
3549
|
+
|
|
3550
|
+
if (stakeBenefit > 0) {
|
|
3551
|
+
tier.feeNumerator = (tier.feeNumerator * (100 - stakeBenefit)) / 100;
|
|
3552
|
+
|
|
3553
|
+
tier.makerRebateNumerator =
|
|
3554
|
+
(tier.makerRebateNumerator * (100 + stakeBenefit)) / 100;
|
|
3555
|
+
}
|
|
3556
|
+
|
|
3557
|
+
return tier;
|
|
3529
3558
|
}
|
|
3530
3559
|
|
|
3531
3560
|
return state.spotFeeStructure.feeTiers[feeTierIndex];
|