@drift-labs/sdk 2.155.0-beta.4 → 2.155.0-beta.6

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.
Files changed (51) hide show
  1. package/VERSION +1 -1
  2. package/lib/browser/constants/spotMarkets.js +21 -14
  3. package/lib/browser/decode/user.js +8 -5
  4. package/lib/browser/driftClient.d.ts +15 -10
  5. package/lib/browser/driftClient.js +137 -23
  6. package/lib/browser/marginCalculation.d.ts +0 -12
  7. package/lib/browser/marginCalculation.js +0 -20
  8. package/lib/browser/math/margin.js +1 -0
  9. package/lib/browser/math/position.d.ts +1 -0
  10. package/lib/browser/math/position.js +10 -2
  11. package/lib/browser/types.d.ts +9 -6
  12. package/lib/browser/types.js +11 -7
  13. package/lib/browser/user.js +13 -7
  14. package/lib/node/constants/spotMarkets.d.ts.map +1 -1
  15. package/lib/node/constants/spotMarkets.js +21 -14
  16. package/lib/node/decode/user.d.ts.map +1 -1
  17. package/lib/node/decode/user.js +8 -5
  18. package/lib/node/driftClient.d.ts +15 -10
  19. package/lib/node/driftClient.d.ts.map +1 -1
  20. package/lib/node/driftClient.js +137 -23
  21. package/lib/node/marginCalculation.d.ts +0 -12
  22. package/lib/node/marginCalculation.d.ts.map +1 -1
  23. package/lib/node/marginCalculation.js +0 -20
  24. package/lib/node/math/margin.d.ts.map +1 -1
  25. package/lib/node/math/margin.js +1 -0
  26. package/lib/node/math/position.d.ts +1 -0
  27. package/lib/node/math/position.d.ts.map +1 -1
  28. package/lib/node/math/position.js +10 -2
  29. package/lib/node/math/spotBalance.d.ts.map +1 -1
  30. package/lib/node/types.d.ts +9 -6
  31. package/lib/node/types.d.ts.map +1 -1
  32. package/lib/node/types.js +11 -7
  33. package/lib/node/user.d.ts.map +1 -1
  34. package/lib/node/user.js +13 -7
  35. package/package.json +1 -1
  36. package/scripts/deposit-isolated-positions.ts +110 -0
  37. package/scripts/find-flagged-users.ts +216 -0
  38. package/scripts/single-grpc-client-test.ts +71 -21
  39. package/scripts/withdraw-isolated-positions.ts +174 -0
  40. package/src/constants/spotMarkets.ts +21 -14
  41. package/src/decode/user.ts +14 -6
  42. package/src/driftClient.ts +297 -65
  43. package/src/margin/README.md +139 -0
  44. package/src/marginCalculation.ts +0 -32
  45. package/src/math/margin.ts +2 -3
  46. package/src/math/position.ts +12 -2
  47. package/src/math/spotBalance.ts +0 -1
  48. package/src/types.ts +11 -7
  49. package/src/user.ts +17 -8
  50. package/tests/dlob/helpers.ts +1 -1
  51. package/tests/user/test.ts +1 -1
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.155.0-beta.4
1
+ 2.155.0-beta.6
@@ -173,8 +173,8 @@ exports.MainnetSpotMarkets = [
173
173
  symbol: 'wETH',
174
174
  marketIndex: 4,
175
175
  poolId: 0,
176
- oracle: new web3_js_1.PublicKey('6bEp2MiyoiiiDxcVqE8rUHQWwHirXUXtKfAEATTVqNzT'),
177
- oracleSource: types_1.OracleSource.PYTH_PULL,
176
+ oracle: new web3_js_1.PublicKey('93FG52TzNKCnMiasV14Ba34BYcHDb9p4zK4GjZnLwqWR'),
177
+ oracleSource: types_1.OracleSource.PYTH_LAZER,
178
178
  mint: new web3_js_1.PublicKey('7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs'),
179
179
  precision: new anchor_1.BN(10).pow(numericConstants_1.EIGHT),
180
180
  precisionExp: numericConstants_1.EIGHT,
@@ -182,6 +182,7 @@ exports.MainnetSpotMarkets = [
182
182
  phoenixMarket: new web3_js_1.PublicKey('Ew3vFDdtdGrknJAVVfraxCA37uNJtimXYPY4QjnfhFHH'),
183
183
  openbookMarket: new web3_js_1.PublicKey('AT1R2jUNb9iTo4EaRfKSTPiNTX4Jb64KSwnVmig6Hu4t'),
184
184
  pythFeedId: '0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace',
185
+ pythLazerId: 2,
185
186
  },
186
187
  {
187
188
  symbol: 'USDT',
@@ -228,13 +229,14 @@ exports.MainnetSpotMarkets = [
228
229
  symbol: 'bSOL',
229
230
  marketIndex: 8,
230
231
  poolId: 0,
231
- oracle: new web3_js_1.PublicKey('BmDWPMsytWmYkh9n6o7m79eVshVYf2B5GVaqQ2EWKnGH'),
232
- oracleSource: types_1.OracleSource.PYTH_PULL,
232
+ oracle: new web3_js_1.PublicKey('6YEQjxkbhfrWV2VdR9zxBJxWYshcMYRs6bpuX1ng2CbP'),
233
+ oracleSource: types_1.OracleSource.PYTH_LAZER,
233
234
  mint: new web3_js_1.PublicKey('bSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1'),
234
235
  precision: new anchor_1.BN(10).pow(numericConstants_1.NINE),
235
236
  precisionExp: numericConstants_1.NINE,
236
237
  serumMarket: new web3_js_1.PublicKey('ARjaHVxGCQfTvvKjLd7U7srvk6orthZSE6uqWchCczZc'),
237
238
  pythFeedId: '0x89875379e70f8fbadc17aef315adf3a8d5d160b811435537e03c97e8aac97d9c',
239
+ pythLazerId: 389,
238
240
  },
239
241
  {
240
242
  symbol: 'JTO',
@@ -339,25 +341,27 @@ exports.MainnetSpotMarkets = [
339
341
  symbol: 'INF',
340
342
  marketIndex: 16,
341
343
  poolId: 0,
342
- oracle: new web3_js_1.PublicKey('B7RUYg2zF6UdUSHv2RmpnriPVJccYWojgFydNS1NY5F8'),
343
- oracleSource: types_1.OracleSource.PYTH_PULL,
344
+ oracle: new web3_js_1.PublicKey('7SAxf2SCJe5c72rZNo4etpGjz5TaEAqi8QkbfpRbouuT'),
345
+ oracleSource: types_1.OracleSource.PYTH_LAZER,
344
346
  mint: new web3_js_1.PublicKey('5oVNBeEEQvYi1cX3ir8Dx5n1P7pdxydbGF2X4TxVusJm'),
345
347
  precision: new anchor_1.BN(10).pow(numericConstants_1.NINE),
346
348
  precisionExp: numericConstants_1.NINE,
347
349
  launchTs: 1716595200000,
348
350
  pythFeedId: '0xf51570985c642c49c2d6e50156390fdba80bb6d5f7fa389d2f012ced4f7d208f',
351
+ pythLazerId: 455,
349
352
  },
350
353
  {
351
354
  symbol: 'dSOL',
352
355
  marketIndex: 17,
353
356
  poolId: 0,
354
- oracle: new web3_js_1.PublicKey('4YstsHafLyDbYFxmJbgoEr33iJJEp6rNPgLTQRgXDkG2'),
355
- oracleSource: types_1.OracleSource.PYTH_PULL,
357
+ oracle: new web3_js_1.PublicKey('EopUQMXT56Lbyg1DKDbc7VAQFcx4QGBKBepZxeKe1sJf'),
358
+ oracleSource: types_1.OracleSource.PYTH_LAZER,
356
359
  mint: new web3_js_1.PublicKey('Dso1bDeDjCQxTrWHqUUi63oBvV7Mdm6WaobLbQ7gnPQ'),
357
360
  precision: new anchor_1.BN(10).pow(numericConstants_1.NINE),
358
361
  precisionExp: numericConstants_1.NINE,
359
362
  launchTs: 1716595200000,
360
363
  pythFeedId: '0x41f858bae36e7ee3f4a3a6d4f176f0893d4a261460a52763350d00f8648195ee',
364
+ pythLazerId: 415,
361
365
  },
362
366
  {
363
367
  symbol: 'USDY',
@@ -476,13 +480,14 @@ exports.MainnetSpotMarkets = [
476
480
  symbol: 'cbBTC',
477
481
  marketIndex: 27,
478
482
  poolId: 0,
479
- oracle: new web3_js_1.PublicKey('9jPy6EHpLkXaMdvfkoVnRnSdJoQysQDKKj3bW5Amz4Ci'),
480
- oracleSource: types_1.OracleSource.PYTH_PULL,
483
+ oracle: new web3_js_1.PublicKey('D1QgWnMoPzB4wJ79Egrc6MGYYM3HHVNhpff1QQHDSoCq'),
484
+ oracleSource: types_1.OracleSource.PYTH_LAZER,
481
485
  mint: new web3_js_1.PublicKey('cbbtcf3aa214zXHbiAZQwf4122FBYbraNdFqgw4iMij'),
482
486
  precision: new anchor_1.BN(10).pow(numericConstants_1.EIGHT),
483
487
  precisionExp: numericConstants_1.EIGHT,
484
488
  openbookMarket: new web3_js_1.PublicKey('2HXgKaXKsMUEzQaSBZiXSd54eMHaS3roiefyGWtkW97W'),
485
489
  pythFeedId: '0x2817d7bfe5c64b8ea956e9a26f573ef64e72e4d7891f2d6af9bcc93f7aff9a97',
490
+ pythLazerId: 397,
486
491
  },
487
492
  {
488
493
  symbol: 'USDS',
@@ -548,12 +553,13 @@ exports.MainnetSpotMarkets = [
548
553
  symbol: 'JLP-1',
549
554
  marketIndex: 33,
550
555
  poolId: 1,
551
- oracle: new web3_js_1.PublicKey('3ZLn5XDgSLWhTk2NjqAU44cPkSeC5JAhW5o6w5Nz4p8R'),
552
- oracleSource: types_1.OracleSource.PYTH_PULL,
556
+ oracle: new web3_js_1.PublicKey('DtmeBbyWat6p2vSpRhuZ4MGRndXr2cdpd4GV8izCFvLb'),
557
+ oracleSource: types_1.OracleSource.PYTH_LAZER,
553
558
  mint: new web3_js_1.PublicKey('27G8MtK7VtTcCHkpASjSDdkWWYfoqT6ggEuKidVJidD4'),
554
559
  precision: new anchor_1.BN(10).pow(numericConstants_1.SIX),
555
560
  precisionExp: numericConstants_1.SIX,
556
561
  pythFeedId: '0x6704952e00b6a088b6dcdb8170dcd591eaf64cff9e996ca75ae0ca55bfb96687',
562
+ pythLazerId: 694,
557
563
  launchTs: 1735255852000,
558
564
  },
559
565
  {
@@ -835,13 +841,14 @@ exports.MainnetSpotMarkets = [
835
841
  symbol: 'LBTC',
836
842
  marketIndex: 58,
837
843
  poolId: 0,
838
- oracle: new web3_js_1.PublicKey('Fa3VKWbdb9yQ89vA9JfYnR6micY9LwGneoQ1So9JgXHT'),
839
- oracleSource: types_1.OracleSource.PYTH_PULL,
844
+ oracle: new web3_js_1.PublicKey('BmU3Hp9SZn77dUhWuED3ySuV3HenBgCoPZZP58M2ZMCr'),
845
+ oracleSource: types_1.OracleSource.PYTH_LAZER,
840
846
  mint: new web3_js_1.PublicKey('LBTCgU4b3wsFKsPwBn1rRZDx5DoFutM6RPiEt1TPDsY'),
841
847
  precision: new anchor_1.BN(10).pow(numericConstants_1.EIGHT),
842
848
  precisionExp: numericConstants_1.EIGHT,
843
849
  pythFeedId: '0x8f257aab6e7698bb92b15511915e593d6f8eae914452f781874754b03d0c612b',
844
850
  launchTs: 1756392947000,
851
+ pythLazerId: 468,
845
852
  },
846
853
  {
847
854
  symbol: '2Z',
@@ -70,12 +70,17 @@ function decodeUser(buffer) {
70
70
  const baseAssetAmount = readSignedBigInt64LE(buffer, offset + 8);
71
71
  const quoteAssetAmount = readSignedBigInt64LE(buffer, offset + 16);
72
72
  const lpShares = readUnsignedBigInt64LE(buffer, offset + 64);
73
+ const isolatedPositionScaledBalance = readSignedBigInt64LE(buffer, offset + 72);
73
74
  const openOrders = buffer.readUInt8(offset + 94);
74
75
  const positionFlag = buffer.readUInt8(offset + 95);
75
76
  if (baseAssetAmount.eq(numericConstants_1.ZERO) &&
76
77
  openOrders === 0 &&
77
78
  quoteAssetAmount.eq(numericConstants_1.ZERO) &&
78
- lpShares.eq(numericConstants_1.ZERO)) {
79
+ lpShares.eq(numericConstants_1.ZERO) &&
80
+ isolatedPositionScaledBalance.eq(numericConstants_1.ZERO) &&
81
+ !((positionFlag &
82
+ (types_1.PositionFlag.BeingLiquidated | types_1.PositionFlag.Bankruptcy)) >
83
+ 0)) {
79
84
  offset += 96;
80
85
  continue;
81
86
  }
@@ -90,9 +95,7 @@ function decodeUser(buffer) {
90
95
  const openAsks = readSignedBigInt64LE(buffer, offset);
91
96
  offset += 8;
92
97
  const settledPnl = readSignedBigInt64LE(buffer, offset);
93
- offset += 16;
94
- const isolatedPositionScaledBalance = readSignedBigInt64LE(buffer, offset);
95
- offset += 8;
98
+ offset += 24;
96
99
  const lastQuoteAssetAmountPerLp = readSignedBigInt64LE(buffer, offset);
97
100
  offset += 8;
98
101
  const maxMarginRatio = buffer.readUInt16LE(offset);
@@ -117,8 +120,8 @@ function decodeUser(buffer) {
117
120
  openOrders,
118
121
  perLpBase,
119
122
  maxMarginRatio,
120
- isolatedPositionScaledBalance,
121
123
  positionFlag,
124
+ isolatedPositionScaledBalance,
122
125
  });
123
126
  }
124
127
  const orders = [];
@@ -5,7 +5,7 @@
5
5
  import * as anchor from '@coral-xyz/anchor';
6
6
  import { AnchorProvider, BN, Program, ProgramAccount } from '@coral-xyz/anchor';
7
7
  import { Idl as Idl30, Program as Program30 } from '@coral-xyz/anchor-30';
8
- import { DriftClientMetricsEvents, HighLeverageModeConfig, IWallet, MakerInfo, MappedRecord, MarketType, ModifyOrderPolicy, OpenbookV2FulfillmentConfigAccount, OptionalOrderParams, OracleSource, Order, OrderParams, OrderTriggerCondition, PerpMarketAccount, PerpMarketExtendedInfo, PhoenixV1FulfillmentConfigAccount, PlaceAndTakeOrderSuccessCondition, PositionDirection, ReferrerInfo, ReferrerNameAccount, SerumV3FulfillmentConfigAccount, SettlePnlMode, SignedTxData, SpotMarketAccount, SpotPosition, StateAccount, SwapReduceOnly, SignedMsgOrderParamsMessage, TakerInfo, TxParams, UserAccount, UserStatsAccount, ProtectedMakerModeConfig, SignedMsgOrderParamsDelegateMessage, PostOnlyParams, LPPoolAccount, ConstituentAccount, ConstituentTargetBaseAccount, AmmCache } from './types';
8
+ import { DriftClientMetricsEvents, HighLeverageModeConfig, IWallet, MakerInfo, MappedRecord, MarketType, ModifyOrderPolicy, OpenbookV2FulfillmentConfigAccount, OptionalOrderParams, OracleSource, Order, OrderParams, OrderTriggerCondition, PerpMarketAccount, PerpMarketExtendedInfo, PhoenixV1FulfillmentConfigAccount, PlaceAndTakeOrderSuccessCondition, PositionDirection, ReferrerInfo, ReferrerNameAccount, SerumV3FulfillmentConfigAccount, SettlePnlMode, SignedTxData, SpotMarketAccount, SpotPosition, StateAccount, SwapReduceOnly, SignedMsgOrderParamsMessage, TxParams, UserAccount, UserStatsAccount, ProtectedMakerModeConfig, SignedMsgOrderParamsDelegateMessage, PostOnlyParams, LPPoolAccount, ConstituentAccount, ConstituentTargetBaseAccount, AmmCache } from './types';
9
9
  import { AccountMeta, AddressLookupTableAccount, BlockhashWithExpiryBlockHeight, ConfirmOptions, Connection, Keypair, PublicKey, Signer, Transaction, TransactionInstruction, TransactionSignature, TransactionVersion, VersionedTransaction } from '@solana/web3.js';
10
10
  import { TokenFaucet } from './tokenFaucet';
11
11
  import { EventEmitter } from 'events';
@@ -24,6 +24,7 @@ import { UserStatsSubscriptionConfig } from './userStatsConfig';
24
24
  import { TxHandler } from './tx/txHandler';
25
25
  import { Slothash } from './slot/SlothashSubscriber';
26
26
  import { SignedMsgOrderParams } from './types';
27
+ import { TakerInfo } from './types';
27
28
  import { ConstituentMap } from './constituentMap/constituentMap';
28
29
  import { RevenueShareEscrowMap } from './userMap/revenueShareEscrowMap';
29
30
  import { TitanClient } from './titan/titanClient';
@@ -88,6 +89,7 @@ export declare class DriftClient {
88
89
  sbOnDemandProgram?: Program30<Idl30>;
89
90
  sbProgramFeedConfigs?: Map<string, any>;
90
91
  get isSubscribed(): boolean;
92
+ private getPrePlaceOrderIxs;
91
93
  set isSubscribed(val: boolean);
92
94
  constructor(config: DriftClientConfig);
93
95
  getUserMapKey(subAccountId: number, authority: PublicKey): string;
@@ -477,9 +479,10 @@ export declare class DriftClient {
477
479
  getTransferPerpPositionIx(fromSubAccountId: number, toSubAccountId: number, marketIndex: number, amount: BN): Promise<TransactionInstruction>;
478
480
  depositIntoIsolatedPerpPosition(amount: BN, perpMarketIndex: number, userTokenAccount: PublicKey, subAccountId?: number, txParams?: TxParams): Promise<TransactionSignature>;
479
481
  getDepositIntoIsolatedPerpPositionIx(amount: BN, perpMarketIndex: number, userTokenAccount: PublicKey, subAccountId?: number): Promise<TransactionInstruction>;
480
- transferIsolatedPerpPositionDeposit(amount: BN, perpMarketIndex: number, subAccountId?: number, txParams?: TxParams): Promise<TransactionSignature>;
481
- getTransferIsolatedPerpPositionDepositIx(amount: BN, perpMarketIndex: number, subAccountId?: number): Promise<TransactionInstruction>;
482
+ transferIsolatedPerpPositionDeposit(amount: BN, perpMarketIndex: number, subAccountId?: number, txParams?: TxParams, trySettle?: boolean, noBuffer?: boolean): Promise<TransactionSignature>;
483
+ getTransferIsolatedPerpPositionDepositIx(amount: BN, perpMarketIndex: number, subAccountId?: number, noAmountBuffer?: boolean, signingAuthority?: PublicKey): Promise<TransactionInstruction>;
482
484
  withdrawFromIsolatedPerpPosition(amount: BN, perpMarketIndex: number, userTokenAccount: PublicKey, subAccountId?: number, txParams?: TxParams): Promise<TransactionSignature>;
485
+ getWithdrawFromIsolatedPerpPositionIxsBundle(amount: BN, perpMarketIndex: number, subAccountId?: number, userTokenAccount?: PublicKey): Promise<TransactionInstruction[]>;
483
486
  getWithdrawFromIsolatedPerpPositionIx(amount: BN, perpMarketIndex: number, userTokenAccount: PublicKey, subAccountId?: number): Promise<TransactionInstruction>;
484
487
  updateSpotMarketCumulativeInterest(marketIndex: number, txParams?: TxParams): Promise<TransactionSignature>;
485
488
  updateSpotMarketCumulativeInterestIx(marketIndex: number): Promise<TransactionInstruction>;
@@ -497,7 +500,7 @@ export declare class DriftClient {
497
500
  */
498
501
  openPosition(direction: PositionDirection, amount: BN, marketIndex: number, limitPrice?: BN, subAccountId?: number): Promise<TransactionSignature>;
499
502
  sendSignedTx(tx: Transaction | VersionedTransaction, opts?: ConfirmOptions): Promise<TransactionSignature>;
500
- prepareMarketOrderTxs(orderParams: OptionalOrderParams, userAccountPublicKey: PublicKey, userAccount: UserAccount, makerInfo?: MakerInfo | MakerInfo[], txParams?: TxParams, bracketOrdersParams?: OptionalOrderParams[], referrerInfo?: ReferrerInfo, cancelExistingOrders?: boolean, settlePnl?: boolean, positionMaxLev?: number): Promise<{
503
+ prepareMarketOrderTxs(orderParams: OptionalOrderParams, userAccountPublicKey: PublicKey, userAccount: UserAccount, makerInfo?: MakerInfo | MakerInfo[], txParams?: TxParams, bracketOrdersParams?: OptionalOrderParams[], referrerInfo?: ReferrerInfo, cancelExistingOrders?: boolean, settlePnl?: boolean, positionMaxLev?: number, isolatedPositionDepositAmount?: BN): Promise<{
501
504
  cancelExistingOrdersTx?: Transaction | VersionedTransaction;
502
505
  settlePnlTx?: Transaction | VersionedTransaction;
503
506
  fillTx?: Transaction | VersionedTransaction;
@@ -520,7 +523,7 @@ export declare class DriftClient {
520
523
  signedCancelExistingOrdersTx?: Transaction;
521
524
  signedSettlePnlTx?: Transaction;
522
525
  }>;
523
- placePerpOrder(orderParams: OptionalOrderParams, txParams?: TxParams, subAccountId?: number): Promise<TransactionSignature>;
526
+ placePerpOrder(orderParams: OptionalOrderParams, txParams?: TxParams, subAccountId?: number, isolatedPositionDepositAmount?: BN): Promise<TransactionSignature>;
524
527
  getPlacePerpOrderIx(orderParams: OptionalOrderParams, subAccountId?: number, depositToTradeArgs?: {
525
528
  isMakingNewAccount: boolean;
526
529
  depositMarketIndex: number;
@@ -531,7 +534,9 @@ export declare class DriftClient {
531
534
  getSettleExpiredMarketIx(marketIndex: number): Promise<TransactionInstruction>;
532
535
  settleExpiredMarketPoolsToRevenuePool(marketIndex: number, txParams?: TxParams): Promise<TransactionSignature>;
533
536
  getSettleExpiredMarketPoolsToRevenuePoolIx(perpMarketIndex: number): Promise<TransactionInstruction>;
534
- cancelOrder(orderId?: number, txParams?: TxParams, subAccountId?: number): Promise<TransactionSignature>;
537
+ cancelOrder(orderId?: number, txParams?: TxParams, subAccountId?: number, overrides?: {
538
+ withdrawIsolatedDepositAmount?: BN;
539
+ }): Promise<TransactionSignature>;
535
540
  getCancelOrderIx(orderId?: number, subAccountId?: number): Promise<TransactionInstruction>;
536
541
  cancelOrderByUserId(userOrderId: number, txParams?: TxParams, subAccountId?: number): Promise<TransactionSignature>;
537
542
  getCancelOrderByUserIdIx(userOrderId: number, subAccountId?: number): Promise<TransactionInstruction>;
@@ -565,8 +570,8 @@ export declare class DriftClient {
565
570
  marketIndex?: number;
566
571
  direction?: PositionDirection;
567
572
  }, placeOrderParams: OrderParams[], txParams?: TxParams, subAccountId?: number): Promise<TransactionSignature>;
568
- placeOrders(params: OrderParams[], txParams?: TxParams, subAccountId?: number, optionalIxs?: TransactionInstruction[]): Promise<TransactionSignature>;
569
- preparePlaceOrdersTx(params: OrderParams[], txParams?: TxParams, subAccountId?: number, optionalIxs?: TransactionInstruction[]): Promise<{
573
+ placeOrders(params: OrderParams[], txParams?: TxParams, subAccountId?: number, optionalIxs?: TransactionInstruction[], isolatedPositionDepositAmount?: BN): Promise<TransactionSignature>;
574
+ preparePlaceOrdersTx(params: OrderParams[], txParams?: TxParams, subAccountId?: number, optionalIxs?: TransactionInstruction[], isolatedPositionDepositAmount?: BN): Promise<{
570
575
  placeOrdersTx: anchor.web3.Transaction | anchor.web3.VersionedTransaction;
571
576
  }>;
572
577
  getPlaceOrdersIx(params: OptionalOrderParams[], subAccountId?: number, overrides?: {
@@ -723,7 +728,7 @@ export declare class DriftClient {
723
728
  updateUserOpenOrdersCount(userAccountPublicKey: PublicKey, user: UserAccount, txParams?: TxParams, fillerPublicKey?: PublicKey): Promise<TransactionSignature>;
724
729
  getUpdateUserOpenOrdersCountIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, fillerPublicKey?: PublicKey): Promise<TransactionInstruction>;
725
730
  placeAndTakePerpOrder(orderParams: OptionalOrderParams, makerInfo?: MakerInfo | MakerInfo[], referrerInfo?: ReferrerInfo, successCondition?: PlaceAndTakeOrderSuccessCondition, auctionDurationPercentage?: number, txParams?: TxParams, subAccountId?: number): Promise<TransactionSignature>;
726
- preparePlaceAndTakePerpOrderWithAdditionalOrders(orderParams: OptionalOrderParams, makerInfo?: MakerInfo | MakerInfo[], referrerInfo?: ReferrerInfo, bracketOrdersParams?: OptionalOrderParams[], txParams?: TxParams, subAccountId?: number, cancelExistingOrders?: boolean, settlePnl?: boolean, exitEarlyIfSimFails?: boolean, auctionDurationPercentage?: number, optionalIxs?: TransactionInstruction[]): Promise<{
731
+ preparePlaceAndTakePerpOrderWithAdditionalOrders(orderParams: OptionalOrderParams, makerInfo?: MakerInfo | MakerInfo[], referrerInfo?: ReferrerInfo, bracketOrdersParams?: OptionalOrderParams[], txParams?: TxParams, subAccountId?: number, cancelExistingOrders?: boolean, settlePnl?: boolean, exitEarlyIfSimFails?: boolean, auctionDurationPercentage?: number, optionalIxs?: TransactionInstruction[], isolatedPositionDepositAmount?: BN): Promise<{
727
732
  placeAndTakeTx: Transaction | VersionedTransaction;
728
733
  cancelExistingOrdersTx: Transaction | VersionedTransaction;
729
734
  settlePnlTx: Transaction | VersionedTransaction;
@@ -922,7 +927,6 @@ export declare class DriftClient {
922
927
  bitFlags?: number;
923
928
  policy?: ModifyOrderPolicy;
924
929
  maxTs?: BN;
925
- txParams?: TxParams;
926
930
  }, subAccountId?: number): Promise<TransactionInstruction>;
927
931
  settlePNLs(users: {
928
932
  settleeUserAccountPublicKey: PublicKey;
@@ -1263,5 +1267,6 @@ export declare class DriftClient {
1263
1267
  signedTxMap: MappedRecord<Record<string, anchor.web3.TransactionInstruction | anchor.web3.TransactionInstruction[]>, anchor.web3.Transaction | anchor.web3.VersionedTransaction>;
1264
1268
  signedTxData: SignedTxData[];
1265
1269
  }>;
1270
+ isOrderIncreasingPosition(orderParams: OptionalOrderParams, subAccountId: number): boolean;
1266
1271
  }
1267
1272
  export {};
@@ -69,6 +69,7 @@ const on_demand_1 = require("@switchboard-xyz/on-demand");
69
69
  const grpcDriftClientAccountSubscriber_1 = require("./accounts/grpcDriftClientAccountSubscriber");
70
70
  const tweetnacl_1 = __importDefault(require("tweetnacl"));
71
71
  const oracleId_1 = require("./oracles/oracleId");
72
+ // BN is already imported globally in this file via other imports
72
73
  const sha256_1 = require("@noble/hashes/sha256");
73
74
  const utils_3 = require("./oracles/utils");
74
75
  const orders_1 = require("./math/orders");
@@ -84,6 +85,22 @@ class DriftClient {
84
85
  get isSubscribed() {
85
86
  return this._isSubscribed && this.accountSubscriber.isSubscribed;
86
87
  }
88
+ async getPrePlaceOrderIxs(orderParams, userAccount, options) {
89
+ var _a;
90
+ const preIxs = [];
91
+ if ((0, types_1.isVariant)(orderParams.marketType, 'perp')) {
92
+ const { positionMaxLev, isolatedPositionDepositAmount } = options !== null && options !== void 0 ? options : {};
93
+ if (((_a = isolatedPositionDepositAmount === null || isolatedPositionDepositAmount === void 0 ? void 0 : isolatedPositionDepositAmount.gt) === null || _a === void 0 ? void 0 : _a.call(isolatedPositionDepositAmount, numericConstants_1.ZERO)) &&
94
+ this.isOrderIncreasingPosition(orderParams, userAccount.subAccountId)) {
95
+ preIxs.push(await this.getTransferIsolatedPerpPositionDepositIx(isolatedPositionDepositAmount, orderParams.marketIndex, userAccount.subAccountId));
96
+ }
97
+ if (positionMaxLev) {
98
+ const marginRatio = Math.floor((1 / positionMaxLev) * numericConstants_1.MARGIN_PRECISION.toNumber());
99
+ preIxs.push(await this.getUpdateUserPerpPositionCustomMarginRatioIx(orderParams.marketIndex, marginRatio, userAccount.subAccountId));
100
+ }
101
+ }
102
+ return preIxs;
103
+ }
87
104
  set isSubscribed(val) {
88
105
  this._isSubscribed = val;
89
106
  }
@@ -2203,11 +2220,24 @@ class DriftClient {
2203
2220
  remainingAccounts,
2204
2221
  });
2205
2222
  }
2206
- async transferIsolatedPerpPositionDeposit(amount, perpMarketIndex, subAccountId, txParams) {
2207
- const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.getTransferIsolatedPerpPositionDepositIx(amount, perpMarketIndex, subAccountId), txParams), [], this.opts);
2223
+ async transferIsolatedPerpPositionDeposit(amount, perpMarketIndex, subAccountId, txParams, trySettle, noBuffer) {
2224
+ const ixs = [];
2225
+ const tokenAmountDeposited = this.getIsolatedPerpPositionTokenAmount(perpMarketIndex);
2226
+ const transferIx = await this.getTransferIsolatedPerpPositionDepositIx(amount, perpMarketIndex, subAccountId, noBuffer);
2227
+ const needsToSettle = amount.lt(tokenAmountDeposited.neg()) || amount.eq(numericConstants_1.MIN_I64) || trySettle;
2228
+ if (needsToSettle) {
2229
+ const settleIx = await this.settleMultiplePNLsIx(await (0, pda_1.getUserAccountPublicKey)(this.program.programId, this.authority, subAccountId !== null && subAccountId !== void 0 ? subAccountId : this.activeSubAccountId), this.getUserAccount(subAccountId), [perpMarketIndex], types_1.SettlePnlMode.TRY_SETTLE);
2230
+ ixs.push(settleIx);
2231
+ }
2232
+ ixs.push(transferIx);
2233
+ const tx = await this.buildTransaction(ixs, txParams);
2234
+ const { txSig } = await this.sendTransaction(tx, [], {
2235
+ ...this.opts,
2236
+ skipPreflight: true,
2237
+ });
2208
2238
  return txSig;
2209
2239
  }
2210
- async getTransferIsolatedPerpPositionDepositIx(amount, perpMarketIndex, subAccountId) {
2240
+ async getTransferIsolatedPerpPositionDepositIx(amount, perpMarketIndex, subAccountId, noAmountBuffer, signingAuthority) {
2211
2241
  const userAccountPublicKey = await (0, pda_1.getUserAccountPublicKey)(this.program.programId, this.authority, subAccountId !== null && subAccountId !== void 0 ? subAccountId : this.activeSubAccountId);
2212
2242
  const perpMarketAccount = this.getPerpMarketAccount(perpMarketIndex);
2213
2243
  const spotMarketIndex = perpMarketAccount.quoteSpotMarketIndex;
@@ -2218,21 +2248,49 @@ class DriftClient {
2218
2248
  writableSpotMarketIndexes: [spotMarketIndex],
2219
2249
  readablePerpMarketIndex: [perpMarketIndex],
2220
2250
  });
2221
- return await this.program.instruction.transferIsolatedPerpPositionDeposit(spotMarketIndex, perpMarketIndex, amount, {
2251
+ const amountWithBuffer = noAmountBuffer || amount.eq(numericConstants_1.MIN_I64)
2252
+ ? amount
2253
+ : amount.add(amount.div(new anchor_1.BN(200))); // .5% buffer
2254
+ return await this.program.instruction.transferIsolatedPerpPositionDeposit(spotMarketIndex, perpMarketIndex, amountWithBuffer, {
2222
2255
  accounts: {
2223
2256
  state: await this.getStatePublicKey(),
2224
2257
  spotMarketVault: spotMarketAccount.vault,
2225
2258
  user: userAccountPublicKey,
2226
2259
  userStats: this.getUserStatsAccountPublicKey(),
2227
- authority: this.wallet.publicKey,
2260
+ authority: signingAuthority !== null && signingAuthority !== void 0 ? signingAuthority : this.wallet.publicKey,
2228
2261
  },
2229
2262
  remainingAccounts,
2230
2263
  });
2231
2264
  }
2232
2265
  async withdrawFromIsolatedPerpPosition(amount, perpMarketIndex, userTokenAccount, subAccountId, txParams) {
2233
- const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.getWithdrawFromIsolatedPerpPositionIx(amount, perpMarketIndex, userTokenAccount, subAccountId), txParams));
2266
+ const instructions = await this.getWithdrawFromIsolatedPerpPositionIxsBundle(amount, perpMarketIndex, subAccountId, userTokenAccount);
2267
+ const { txSig } = await this.sendTransaction(await this.buildTransaction(instructions, txParams));
2234
2268
  return txSig;
2235
2269
  }
2270
+ async getWithdrawFromIsolatedPerpPositionIxsBundle(amount, perpMarketIndex, subAccountId, userTokenAccount) {
2271
+ const userAccountPublicKey = await (0, pda_1.getUserAccountPublicKey)(this.program.programId, this.authority, subAccountId !== null && subAccountId !== void 0 ? subAccountId : this.activeSubAccountId);
2272
+ const userAccount = this.getUserAccount(subAccountId);
2273
+ const tokenAmountDeposited = this.getIsolatedPerpPositionTokenAmount(perpMarketIndex);
2274
+ const isolatedPositionUnrealizedPnl = (0, position_1.calculateClaimablePnl)(this.getPerpMarketAccount(perpMarketIndex), this.getSpotMarketAccount(this.getPerpMarketAccount(perpMarketIndex).quoteSpotMarketIndex), userAccount.perpPositions.find((p) => p.marketIndex === perpMarketIndex), this.getOracleDataForSpotMarket(this.getPerpMarketAccount(perpMarketIndex).quoteSpotMarketIndex));
2275
+ const depositAmountPlusUnrealizedPnl = tokenAmountDeposited.add(isolatedPositionUnrealizedPnl);
2276
+ const amountToWithdraw = amount.gt(depositAmountPlusUnrealizedPnl)
2277
+ ? numericConstants_1.MIN_I64 // min i64
2278
+ : amount;
2279
+ let associatedTokenAccount = userTokenAccount;
2280
+ if (!associatedTokenAccount) {
2281
+ const perpMarketAccount = this.getPerpMarketAccount(perpMarketIndex);
2282
+ const quoteSpotMarketIndex = perpMarketAccount.quoteSpotMarketIndex;
2283
+ associatedTokenAccount = await this.getAssociatedTokenAccount(quoteSpotMarketIndex);
2284
+ }
2285
+ const withdrawIx = await this.getWithdrawFromIsolatedPerpPositionIx(amountToWithdraw, perpMarketIndex, associatedTokenAccount, subAccountId);
2286
+ const ixs = [withdrawIx];
2287
+ const needsToSettle = amount.gt(tokenAmountDeposited) && isolatedPositionUnrealizedPnl.gt(numericConstants_1.ZERO);
2288
+ if (needsToSettle) {
2289
+ const settleIx = await this.settleMultiplePNLsIx(userAccountPublicKey, userAccount, [perpMarketIndex], types_1.SettlePnlMode.TRY_SETTLE);
2290
+ ixs.push(settleIx);
2291
+ }
2292
+ return ixs;
2293
+ }
2236
2294
  async getWithdrawFromIsolatedPerpPositionIx(amount, perpMarketIndex, userTokenAccount, subAccountId) {
2237
2295
  const userAccountPublicKey = await (0, pda_1.getUserAccountPublicKey)(this.program.programId, this.authority, subAccountId !== null && subAccountId !== void 0 ? subAccountId : this.activeSubAccountId);
2238
2296
  const perpMarketAccount = this.getPerpMarketAccount(perpMarketIndex);
@@ -2389,7 +2447,7 @@ class DriftClient {
2389
2447
  const { txSig } = await this.sendTransaction(tx, undefined, opts !== null && opts !== void 0 ? opts : this.opts, true);
2390
2448
  return txSig;
2391
2449
  }
2392
- async prepareMarketOrderTxs(orderParams, userAccountPublicKey, userAccount, makerInfo, txParams, bracketOrdersParams = new Array(), referrerInfo, cancelExistingOrders, settlePnl, positionMaxLev) {
2450
+ async prepareMarketOrderTxs(orderParams, userAccountPublicKey, userAccount, makerInfo, txParams, bracketOrdersParams = new Array(), referrerInfo, cancelExistingOrders, settlePnl, positionMaxLev, isolatedPositionDepositAmount) {
2393
2451
  const marketIndex = orderParams.marketIndex;
2394
2452
  const orderId = userAccount.nextOrderId;
2395
2453
  const ixPromisesForTxs = {
@@ -2399,10 +2457,17 @@ class DriftClient {
2399
2457
  marketOrderTx: undefined,
2400
2458
  };
2401
2459
  const txKeys = Object.keys(ixPromisesForTxs);
2402
- const marketOrderTxIxs = positionMaxLev
2403
- ? this.getPlaceOrdersAndSetPositionMaxLevIx([orderParams, ...bracketOrdersParams], positionMaxLev, userAccount.subAccountId)
2404
- : this.getPlaceOrdersIx([orderParams, ...bracketOrdersParams], userAccount.subAccountId);
2405
- ixPromisesForTxs.marketOrderTx = marketOrderTxIxs;
2460
+ const preIxs = await this.getPrePlaceOrderIxs(orderParams, userAccount, {
2461
+ positionMaxLev,
2462
+ isolatedPositionDepositAmount,
2463
+ });
2464
+ ixPromisesForTxs.marketOrderTx = (async () => {
2465
+ const placeOrdersIx = await this.getPlaceOrdersIx([orderParams, ...bracketOrdersParams], userAccount.subAccountId);
2466
+ if (preIxs.length) {
2467
+ return [...preIxs, placeOrdersIx];
2468
+ }
2469
+ return placeOrdersIx;
2470
+ })();
2406
2471
  /* Cancel open orders in market if requested */
2407
2472
  if (cancelExistingOrders && (0, types_1.isVariant)(orderParams.marketType, 'perp')) {
2408
2473
  ixPromisesForTxs.cancelExistingOrdersTx = this.getCancelOrdersIx(orderParams.marketType, orderParams.marketIndex, null, userAccount.subAccountId);
@@ -2449,8 +2514,14 @@ class DriftClient {
2449
2514
  signedSettlePnlTx: signedTxs.settlePnlTx,
2450
2515
  };
2451
2516
  }
2452
- async placePerpOrder(orderParams, txParams, subAccountId) {
2453
- const { txSig, slot } = await this.sendTransaction(await this.buildTransaction(await this.getPlacePerpOrderIx(orderParams, subAccountId), txParams), [], this.opts);
2517
+ async placePerpOrder(orderParams, txParams, subAccountId, isolatedPositionDepositAmount) {
2518
+ var _a;
2519
+ const preIxs = [];
2520
+ if (((_a = isolatedPositionDepositAmount === null || isolatedPositionDepositAmount === void 0 ? void 0 : isolatedPositionDepositAmount.gt) === null || _a === void 0 ? void 0 : _a.call(isolatedPositionDepositAmount, numericConstants_1.ZERO)) &&
2521
+ this.isOrderIncreasingPosition(orderParams, subAccountId)) {
2522
+ preIxs.push(await this.getTransferIsolatedPerpPositionDepositIx(isolatedPositionDepositAmount, orderParams.marketIndex, subAccountId));
2523
+ }
2524
+ const { txSig, slot } = await this.sendTransaction(await this.buildTransaction(await this.getPlacePerpOrderIx(orderParams, subAccountId), txParams, undefined, undefined, undefined, undefined, preIxs), [], this.opts);
2454
2525
  this.perpMarketLastSlotCache.set(orderParams.marketIndex, slot);
2455
2526
  return txSig;
2456
2527
  }
@@ -2556,8 +2627,19 @@ class DriftClient {
2556
2627
  },
2557
2628
  });
2558
2629
  }
2559
- async cancelOrder(orderId, txParams, subAccountId) {
2560
- const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.getCancelOrderIx(orderId, subAccountId), txParams), [], this.opts);
2630
+ async cancelOrder(orderId, txParams, subAccountId, overrides) {
2631
+ const cancelIx = await this.getCancelOrderIx(orderId, subAccountId);
2632
+ const instructions = [cancelIx];
2633
+ if ((overrides === null || overrides === void 0 ? void 0 : overrides.withdrawIsolatedDepositAmount) !== undefined) {
2634
+ const order = this.getOrder(orderId, subAccountId);
2635
+ const perpMarketIndex = order === null || order === void 0 ? void 0 : order.marketIndex;
2636
+ const withdrawAmount = overrides.withdrawIsolatedDepositAmount;
2637
+ if (withdrawAmount.gt(numericConstants_1.ZERO)) {
2638
+ const withdrawIxs = await this.getWithdrawFromIsolatedPerpPositionIxsBundle(withdrawAmount, perpMarketIndex, subAccountId);
2639
+ instructions.push(...withdrawIxs);
2640
+ }
2641
+ }
2642
+ const { txSig } = await this.sendTransaction(await this.buildTransaction(instructions, txParams), [], this.opts);
2561
2643
  return txSig;
2562
2644
  }
2563
2645
  async getCancelOrderIx(orderId, subAccountId) {
@@ -2676,13 +2758,23 @@ class DriftClient {
2676
2758
  const { txSig } = await this.sendTransaction(tx, [], this.opts);
2677
2759
  return txSig;
2678
2760
  }
2679
- async placeOrders(params, txParams, subAccountId, optionalIxs) {
2680
- const { txSig } = await this.sendTransaction((await this.preparePlaceOrdersTx(params, txParams, subAccountId, optionalIxs)).placeOrdersTx, [], this.opts, false);
2761
+ async placeOrders(params, txParams, subAccountId, optionalIxs, isolatedPositionDepositAmount) {
2762
+ const { txSig } = await this.sendTransaction((await this.preparePlaceOrdersTx(params, txParams, subAccountId, optionalIxs, isolatedPositionDepositAmount)).placeOrdersTx, [], this.opts, false);
2681
2763
  return txSig;
2682
2764
  }
2683
- async preparePlaceOrdersTx(params, txParams, subAccountId, optionalIxs) {
2765
+ async preparePlaceOrdersTx(params, txParams, subAccountId, optionalIxs, isolatedPositionDepositAmount) {
2766
+ var _a;
2684
2767
  const lookupTableAccounts = await this.fetchAllLookupTableAccounts();
2685
- const tx = await this.buildTransaction(await this.getPlaceOrdersIx(params, subAccountId), txParams, undefined, lookupTableAccounts, undefined, undefined, optionalIxs);
2768
+ const preIxs = [];
2769
+ if ((params === null || params === void 0 ? void 0 : params.length) === 1) {
2770
+ const p = params[0];
2771
+ if ((0, types_1.isVariant)(p.marketType, 'perp') &&
2772
+ ((_a = isolatedPositionDepositAmount === null || isolatedPositionDepositAmount === void 0 ? void 0 : isolatedPositionDepositAmount.gt) === null || _a === void 0 ? void 0 : _a.call(isolatedPositionDepositAmount, numericConstants_1.ZERO)) &&
2773
+ this.isOrderIncreasingPosition(p, subAccountId)) {
2774
+ preIxs.push(await this.getTransferIsolatedPerpPositionDepositIx(isolatedPositionDepositAmount, p.marketIndex, subAccountId));
2775
+ }
2776
+ }
2777
+ const tx = await this.buildTransaction(await this.getPlaceOrdersIx(params, subAccountId), txParams, undefined, lookupTableAccounts, undefined, undefined, [...preIxs, ...(optionalIxs !== null && optionalIxs !== void 0 ? optionalIxs : [])]);
2686
2778
  return {
2687
2779
  placeOrdersTx: tx,
2688
2780
  };
@@ -2771,7 +2863,7 @@ class DriftClient {
2771
2863
  remainingAccounts,
2772
2864
  });
2773
2865
  const marginRatio = Math.floor((1 / positionMaxLev) * numericConstants_1.MARGIN_PRECISION.toNumber());
2774
- // TODO: Handle multiple markets?
2866
+ // Keep existing behavior but note: prefer using getPostPlaceOrderIxs path
2775
2867
  const setPositionMaxLevIxs = await this.getUpdateUserPerpPositionCustomMarginRatioIx(readablePerpMarketIndex[0], marginRatio, subAccountId);
2776
2868
  return [placeOrdersIxs, setPositionMaxLevIxs];
2777
2869
  }
@@ -3772,7 +3864,7 @@ class DriftClient {
3772
3864
  this.perpMarketLastSlotCache.set(orderParams.marketIndex, slot);
3773
3865
  return txSig;
3774
3866
  }
3775
- async preparePlaceAndTakePerpOrderWithAdditionalOrders(orderParams, makerInfo, referrerInfo, bracketOrdersParams = new Array(), txParams, subAccountId, cancelExistingOrders, settlePnl, exitEarlyIfSimFails, auctionDurationPercentage, optionalIxs) {
3867
+ async preparePlaceAndTakePerpOrderWithAdditionalOrders(orderParams, makerInfo, referrerInfo, bracketOrdersParams = new Array(), txParams, subAccountId, cancelExistingOrders, settlePnl, exitEarlyIfSimFails, auctionDurationPercentage, optionalIxs, isolatedPositionDepositAmount) {
3776
3868
  const placeAndTakeIxs = [];
3777
3869
  const txsToSign = {
3778
3870
  placeAndTakeTx: undefined,
@@ -3784,13 +3876,22 @@ class DriftClient {
3784
3876
  const lookupTableAccounts = await this.fetchAllLookupTableAccounts();
3785
3877
  let earlyExitFailedPlaceAndTakeSim = false;
3786
3878
  const prepPlaceAndTakeTx = async () => {
3787
- var _a;
3879
+ var _a, _b;
3788
3880
  const placeAndTakeIx = await this.getPlaceAndTakePerpOrderIx(orderParams, makerInfo, referrerInfo, undefined, auctionDurationPercentage, subAccountId);
3881
+ if ((0, types_1.isVariant)(orderParams.marketType, 'perp') &&
3882
+ ((_a = isolatedPositionDepositAmount === null || isolatedPositionDepositAmount === void 0 ? void 0 : isolatedPositionDepositAmount.gt) === null || _a === void 0 ? void 0 : _a.call(isolatedPositionDepositAmount, numericConstants_1.ZERO)) &&
3883
+ this.isOrderIncreasingPosition(orderParams, subAccountId)) {
3884
+ placeAndTakeIxs.push(await this.getTransferIsolatedPerpPositionDepositIx(isolatedPositionDepositAmount, orderParams.marketIndex, subAccountId));
3885
+ }
3789
3886
  placeAndTakeIxs.push(placeAndTakeIx);
3790
3887
  if (bracketOrdersParams.length > 0) {
3791
3888
  const bracketOrdersIx = await this.getPlaceOrdersIx(bracketOrdersParams, subAccountId);
3792
3889
  placeAndTakeIxs.push(bracketOrdersIx);
3793
3890
  }
3891
+ // Optional extra ixs can be appended at the front
3892
+ if (optionalIxs === null || optionalIxs === void 0 ? void 0 : optionalIxs.length) {
3893
+ placeAndTakeIxs.unshift(...optionalIxs);
3894
+ }
3794
3895
  const shouldUseSimulationComputeUnits = txParams === null || txParams === void 0 ? void 0 : txParams.useSimulatedComputeUnits;
3795
3896
  const shouldExitIfSimulationFails = exitEarlyIfSimFails;
3796
3897
  const txParamsWithoutImplicitSimulation = {
@@ -3799,7 +3900,7 @@ class DriftClient {
3799
3900
  };
3800
3901
  if (shouldUseSimulationComputeUnits || shouldExitIfSimulationFails) {
3801
3902
  const placeAndTakeTxToSim = (await this.buildTransaction(placeAndTakeIxs, txParams, undefined, lookupTableAccounts, true, recentBlockHash, optionalIxs));
3802
- const simulationResult = await txParamProcessor_1.TransactionParamProcessor.getTxSimComputeUnits(placeAndTakeTxToSim, this.connection, (_a = txParams.computeUnitsBufferMultiplier) !== null && _a !== void 0 ? _a : 1.2, txParams.lowerBoundCu);
3903
+ const simulationResult = await txParamProcessor_1.TransactionParamProcessor.getTxSimComputeUnits(placeAndTakeTxToSim, this.connection, (_b = txParams.computeUnitsBufferMultiplier) !== null && _b !== void 0 ? _b : 1.2, txParams.lowerBoundCu);
3803
3904
  if (shouldExitIfSimulationFails && !simulationResult.success) {
3804
3905
  earlyExitFailedPlaceAndTakeSim = true;
3805
3906
  return;
@@ -6604,5 +6705,18 @@ class DriftClient {
6604
6705
  forceVersionedTransaction,
6605
6706
  });
6606
6707
  }
6708
+ isOrderIncreasingPosition(orderParams, subAccountId) {
6709
+ const userAccount = this.getUserAccount(subAccountId);
6710
+ const perpPosition = userAccount.perpPositions.find((p) => p.marketIndex === orderParams.marketIndex);
6711
+ if (!perpPosition)
6712
+ return true;
6713
+ const currentBase = perpPosition.baseAssetAmount;
6714
+ if (currentBase.eq(numericConstants_1.ZERO))
6715
+ return true;
6716
+ const orderBaseAmount = (0, types_1.isVariant)(orderParams.direction, 'long')
6717
+ ? orderParams.baseAssetAmount
6718
+ : orderParams.baseAssetAmount.neg();
6719
+ return currentBase.add(orderBaseAmount).abs().gt(currentBase.abs());
6720
+ }
6607
6721
  }
6608
6722
  exports.DriftClient = DriftClient;
@@ -49,24 +49,12 @@ export declare class MarginCalculation {
49
49
  marginRequirement: BN;
50
50
  marginRequirementPlusBuffer: BN;
51
51
  isolatedMarginCalculations: Map<number, IsolatedMarginCalculation>;
52
- allDepositOraclesValid: boolean;
53
- allLiabilityOraclesValid: boolean;
54
- withPerpIsolatedLiability: boolean;
55
- withSpotIsolatedLiability: boolean;
56
52
  totalPerpLiabilityValue: BN;
57
- trackedMarketMarginRequirement: BN;
58
- fuelDeposits: number;
59
- fuelBorrows: number;
60
- fuelPositions: number;
61
53
  constructor(context: MarginContext);
62
54
  addCrossMarginTotalCollateral(delta: BN): void;
63
55
  addCrossMarginRequirement(marginRequirement: BN, liabilityValue: BN): void;
64
56
  addIsolatedMarginCalculation(marketIndex: number, depositValue: BN, pnl: BN, liabilityValue: BN, marginRequirement: BN): void;
65
57
  addPerpLiabilityValue(perpLiabilityValue: BN): void;
66
- updateAllDepositOraclesValid(valid: boolean): void;
67
- updateAllLiabilityOraclesValid(valid: boolean): void;
68
- updateWithSpotIsolatedLiability(isolated: boolean): void;
69
- updateWithPerpIsolatedLiability(isolated: boolean): void;
70
58
  getCrossTotalCollateralPlusBuffer(): BN;
71
59
  meetsCrossMarginRequirement(): boolean;
72
60
  meetsCrossMarginRequirementWithBuffer(): boolean;
@@ -91,15 +91,7 @@ class MarginCalculation {
91
91
  this.marginRequirement = numericConstants_1.ZERO;
92
92
  this.marginRequirementPlusBuffer = numericConstants_1.ZERO;
93
93
  this.isolatedMarginCalculations = new Map();
94
- this.allDepositOraclesValid = true;
95
- this.allLiabilityOraclesValid = true;
96
- this.withPerpIsolatedLiability = false;
97
- this.withSpotIsolatedLiability = false;
98
94
  this.totalPerpLiabilityValue = numericConstants_1.ZERO;
99
- this.trackedMarketMarginRequirement = numericConstants_1.ZERO;
100
- this.fuelDeposits = 0;
101
- this.fuelBorrows = 0;
102
- this.fuelPositions = 0;
103
95
  }
104
96
  addCrossMarginTotalCollateral(delta) {
105
97
  const crossMarginBuffer = this.context.crossMarginBuffer;
@@ -136,18 +128,6 @@ class MarginCalculation {
136
128
  this.totalPerpLiabilityValue =
137
129
  this.totalPerpLiabilityValue.add(perpLiabilityValue);
138
130
  }
139
- updateAllDepositOraclesValid(valid) {
140
- this.allDepositOraclesValid = this.allDepositOraclesValid && valid;
141
- }
142
- updateAllLiabilityOraclesValid(valid) {
143
- this.allLiabilityOraclesValid = this.allLiabilityOraclesValid && valid;
144
- }
145
- updateWithSpotIsolatedLiability(isolated) {
146
- this.withSpotIsolatedLiability = this.withSpotIsolatedLiability || isolated;
147
- }
148
- updateWithPerpIsolatedLiability(isolated) {
149
- this.withPerpIsolatedLiability = this.withPerpIsolatedLiability || isolated;
150
- }
151
131
  getCrossTotalCollateralPlusBuffer() {
152
132
  return this.totalCollateral.add(this.totalCollateralBuffer);
153
133
  }
@@ -91,6 +91,7 @@ function calculateWorstCaseBaseAssetAmount(perpPosition, perpMarket, oraclePrice
91
91
  exports.calculateWorstCaseBaseAssetAmount = calculateWorstCaseBaseAssetAmount;
92
92
  function calculateWorstCasePerpLiabilityValue(perpPosition, perpMarket, oraclePrice, includeOpenOrders = true) {
93
93
  const isPredictionMarket = (0, types_1.isVariant)(perpMarket.contractType, 'prediction');
94
+ // return early if no open orders required
94
95
  if (!includeOpenOrders) {
95
96
  return {
96
97
  worstCaseBaseAssetAmount: perpPosition.baseAssetAmount,
@@ -46,6 +46,7 @@ export declare function calculateUnsettledFundingPnl(market: PerpMarketAccount,
46
46
  */
47
47
  export declare function calculatePositionFundingPNL(market: PerpMarketAccount, perpPosition: PerpPosition): BN;
48
48
  export declare function positionIsAvailable(position: PerpPosition): boolean;
49
+ export declare function positionIsBeingLiquidated(position: PerpPosition): boolean;
49
50
  /**
50
51
  *
51
52
  * @param userPosition