@drift-labs/sdk 2.43.0-beta.9 → 2.45.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.43.0-beta.9
1
+ 2.45.0-beta.0
@@ -13,6 +13,7 @@ export declare class WebSocketAccountSubscriber<T> implements AccountSubscriber<
13
13
  onChange: (data: T) => void;
14
14
  listenerId?: number;
15
15
  resubTimeoutMs?: number;
16
+ isUnsubscribing: boolean;
16
17
  timeoutId?: NodeJS.Timeout;
17
18
  receivingData: boolean;
18
19
  constructor(accountName: string, program: Program, accountPublicKey: PublicKey, decodeBuffer?: (buffer: Buffer) => T, resubTimeoutMs?: number);
@@ -4,6 +4,7 @@ exports.WebSocketAccountSubscriber = void 0;
4
4
  const utils_1 = require("./utils");
5
5
  class WebSocketAccountSubscriber {
6
6
  constructor(accountName, program, accountPublicKey, decodeBuffer, resubTimeoutMs) {
7
+ this.isUnsubscribing = false;
7
8
  this.accountName = accountName;
8
9
  this.program = program;
9
10
  this.accountPublicKey = accountPublicKey;
@@ -12,7 +13,7 @@ class WebSocketAccountSubscriber {
12
13
  this.receivingData = false;
13
14
  }
14
15
  async subscribe(onChange) {
15
- if (this.listenerId) {
16
+ if (this.listenerId || this.isUnsubscribing) {
16
17
  return;
17
18
  }
18
19
  this.onChange = onChange;
@@ -49,6 +50,10 @@ class WebSocketAccountSubscriber {
49
50
  throw new Error('onChange callback function must be set');
50
51
  }
51
52
  this.timeoutId = setTimeout(async () => {
53
+ if (this.isUnsubscribing) {
54
+ // If we are in the process of unsubscribing, do not attempt to resubscribe
55
+ return;
56
+ }
52
57
  if (this.receivingData) {
53
58
  console.log(`No ws data from ${this.accountName} in ${this.resubTimeoutMs}ms, resubscribing`);
54
59
  await this.unsubscribe();
@@ -108,11 +113,21 @@ class WebSocketAccountSubscriber {
108
113
  }
109
114
  }
110
115
  unsubscribe() {
116
+ this.isUnsubscribing = true;
117
+ clearTimeout(this.timeoutId);
118
+ this.timeoutId = undefined;
111
119
  if (this.listenerId) {
112
- const promise = this.program.provider.connection.removeAccountChangeListener(this.listenerId);
113
- this.listenerId = undefined;
120
+ const promise = this.program.provider.connection
121
+ .removeAccountChangeListener(this.listenerId)
122
+ .then(() => {
123
+ this.listenerId = undefined;
124
+ this.isUnsubscribing = false;
125
+ });
114
126
  return promise;
115
127
  }
128
+ else {
129
+ this.isUnsubscribing = false;
130
+ }
116
131
  }
117
132
  }
118
133
  exports.WebSocketAccountSubscriber = WebSocketAccountSubscriber;
@@ -15,6 +15,7 @@ export declare class WebSocketProgramAccountSubscriber<T> implements ProgramAcco
15
15
  onChange: (accountId: PublicKey, data: T, context: Context) => void;
16
16
  listenerId?: number;
17
17
  resubTimeoutMs?: number;
18
+ isUnsubscribing: boolean;
18
19
  timeoutId?: NodeJS.Timeout;
19
20
  options: {
20
21
  filters: MemcmpFilter[];
@@ -5,6 +5,7 @@ class WebSocketProgramAccountSubscriber {
5
5
  constructor(subscriptionName, accountDiscriminator, program, decodeBufferFn, options = {
6
6
  filters: [],
7
7
  }, resubTimeoutMs) {
8
+ this.isUnsubscribing = false;
8
9
  this.receivingData = false;
9
10
  this.subscriptionName = subscriptionName;
10
11
  this.accountDiscriminator = accountDiscriminator;
@@ -16,7 +17,7 @@ class WebSocketProgramAccountSubscriber {
16
17
  }
17
18
  async subscribe(onChange) {
18
19
  var _a;
19
- if (this.listenerId) {
20
+ if (this.listenerId || this.isUnsubscribing) {
20
21
  return;
21
22
  }
22
23
  this.onChange = onChange;
@@ -40,6 +41,10 @@ class WebSocketProgramAccountSubscriber {
40
41
  throw new Error('onChange callback function must be set');
41
42
  }
42
43
  this.timeoutId = setTimeout(async () => {
44
+ if (this.isUnsubscribing) {
45
+ // If we are in the process of unsubscribing, do not attempt to resubscribe
46
+ return;
47
+ }
43
48
  if (this.receivingData) {
44
49
  console.log(`No ws data from ${this.subscriptionName} in ${this.resubTimeoutMs}ms, resubscribing`);
45
50
  await this.unsubscribe();
@@ -89,11 +94,21 @@ class WebSocketProgramAccountSubscriber {
89
94
  }
90
95
  }
91
96
  unsubscribe() {
97
+ this.isUnsubscribing = true;
98
+ clearTimeout(this.timeoutId);
99
+ this.timeoutId = undefined;
92
100
  if (this.listenerId) {
93
- const promise = this.program.provider.connection.removeAccountChangeListener(this.listenerId);
94
- this.listenerId = undefined;
101
+ const promise = this.program.provider.connection
102
+ .removeAccountChangeListener(this.listenerId)
103
+ .then(() => {
104
+ this.listenerId = undefined;
105
+ this.isUnsubscribing = false;
106
+ });
95
107
  return promise;
96
108
  }
109
+ else {
110
+ this.isUnsubscribing = false;
111
+ }
97
112
  }
98
113
  }
99
114
  exports.WebSocketProgramAccountSubscriber = WebSocketProgramAccountSubscriber;
@@ -33,6 +33,7 @@ export declare class AdminClient extends DriftClient {
33
33
  updateSpotFeeStructure(feeStructure: FeeStructure): Promise<TransactionSignature>;
34
34
  updateInitialPctToLiquidate(initialPctToLiquidate: number): Promise<TransactionSignature>;
35
35
  updateLiquidationDuration(liquidationDuration: number): Promise<TransactionSignature>;
36
+ updateLiquidationMarginBufferRatio(updateLiquidationMarginBufferRatio: number): Promise<TransactionSignature>;
36
37
  updateOracleGuardRails(oracleGuardRails: OracleGuardRails): Promise<TransactionSignature>;
37
38
  updateStateSettlementDuration(settlementDuration: number): Promise<TransactionSignature>;
38
39
  updateWithdrawGuardThreshold(spotMarketIndex: number, withdrawGuardThreshold: BN): Promise<TransactionSignature>;
@@ -421,6 +421,14 @@ class AdminClient extends driftClient_1.DriftClient {
421
421
  },
422
422
  });
423
423
  }
424
+ async updateLiquidationMarginBufferRatio(updateLiquidationMarginBufferRatio) {
425
+ return await this.program.rpc.updateLiquidationMarginBufferRatio(updateLiquidationMarginBufferRatio, {
426
+ accounts: {
427
+ admin: this.wallet.publicKey,
428
+ state: await this.getStatePublicKey(),
429
+ },
430
+ });
431
+ }
424
432
  async updateOracleGuardRails(oracleGuardRails) {
425
433
  const tx = await this.program.transaction.updateOracleGuardRails(oracleGuardRails, {
426
434
  accounts: {
@@ -87,10 +87,16 @@ export declare class DLOB {
87
87
  takerNode: DLOBNode;
88
88
  makerNode: DLOBNode;
89
89
  } | undefined;
90
- getBestAsk(marketIndex: number, fallbackAsk: BN | undefined, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData): BN;
91
- getBestBid(marketIndex: number, fallbackBid: BN | undefined, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData): BN;
90
+ getBestAsk(marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData): BN;
91
+ getBestBid(marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData): BN;
92
+ getStopLosses(marketIndex: number, marketType: MarketType, direction: PositionDirection): Generator<DLOBNode>;
93
+ getStopLossMarkets(marketIndex: number, marketType: MarketType, direction: PositionDirection): Generator<DLOBNode>;
94
+ getStopLossLimits(marketIndex: number, marketType: MarketType, direction: PositionDirection): Generator<DLOBNode>;
95
+ getTakeProfits(marketIndex: number, marketType: MarketType, direction: PositionDirection): Generator<DLOBNode>;
96
+ getTakeProfitMarkets(marketIndex: number, marketType: MarketType, direction: PositionDirection): Generator<DLOBNode>;
97
+ getTakeProfitLimits(marketIndex: number, marketType: MarketType, direction: PositionDirection): Generator<DLOBNode>;
92
98
  findNodesToTrigger(marketIndex: number, slot: number, oraclePrice: BN, marketType: MarketType, stateAccount: StateAccount): NodeToTrigger[];
93
- printTopOfOrderLists(sdkConfig: any, driftClient: DriftClient, slotSubscriber: SlotSubscriber, marketIndex: number, marketType: MarketType): void;
99
+ printTop(driftClient: DriftClient, slotSubscriber: SlotSubscriber, marketIndex: number, marketType: MarketType): void;
94
100
  getDLOBOrders(): DLOBOrders;
95
101
  getNodeLists(): Generator<NodeList<DLOBNodeType>>;
96
102
  /**
package/lib/dlob/DLOB.js CHANGED
@@ -796,16 +796,80 @@ class DLOB {
796
796
  };
797
797
  }
798
798
  }
799
- getBestAsk(marketIndex, fallbackAsk, slot, marketType, oraclePriceData) {
800
- return this.getAsks(marketIndex, fallbackAsk, slot, marketType, oraclePriceData)
799
+ getBestAsk(marketIndex, slot, marketType, oraclePriceData) {
800
+ return this.getRestingLimitAsks(marketIndex, slot, marketType, oraclePriceData)
801
801
  .next()
802
802
  .value.getPrice(oraclePriceData, slot);
803
803
  }
804
- getBestBid(marketIndex, fallbackBid, slot, marketType, oraclePriceData) {
805
- return this.getBids(marketIndex, fallbackBid, slot, marketType, oraclePriceData)
804
+ getBestBid(marketIndex, slot, marketType, oraclePriceData) {
805
+ return this.getRestingLimitBids(marketIndex, slot, marketType, oraclePriceData)
806
806
  .next()
807
807
  .value.getPrice(oraclePriceData, slot);
808
808
  }
809
+ *getStopLosses(marketIndex, marketType, direction) {
810
+ const marketTypeStr = (0, __1.getVariant)(marketType);
811
+ const marketNodeLists = this.orderLists.get(marketTypeStr).get(marketIndex);
812
+ if ((0, __1.isVariant)(direction, 'long') && marketNodeLists.trigger.below) {
813
+ for (const node of marketNodeLists.trigger.below.getGenerator()) {
814
+ if ((0, __1.isVariant)(node.order.direction, 'short')) {
815
+ yield node;
816
+ }
817
+ }
818
+ }
819
+ else if ((0, __1.isVariant)(direction, 'short') && marketNodeLists.trigger.above) {
820
+ for (const node of marketNodeLists.trigger.above.getGenerator()) {
821
+ if ((0, __1.isVariant)(node.order.direction, 'long')) {
822
+ yield node;
823
+ }
824
+ }
825
+ }
826
+ }
827
+ *getStopLossMarkets(marketIndex, marketType, direction) {
828
+ for (const node of this.getStopLosses(marketIndex, marketType, direction)) {
829
+ if ((0, __1.isVariant)(node.order.orderType, 'triggerMarket')) {
830
+ yield node;
831
+ }
832
+ }
833
+ }
834
+ *getStopLossLimits(marketIndex, marketType, direction) {
835
+ for (const node of this.getStopLosses(marketIndex, marketType, direction)) {
836
+ if ((0, __1.isVariant)(node.order.orderType, 'triggerLimit')) {
837
+ yield node;
838
+ }
839
+ }
840
+ }
841
+ *getTakeProfits(marketIndex, marketType, direction) {
842
+ const marketTypeStr = (0, __1.getVariant)(marketType);
843
+ const marketNodeLists = this.orderLists.get(marketTypeStr).get(marketIndex);
844
+ if ((0, __1.isVariant)(direction, 'long') && marketNodeLists.trigger.above) {
845
+ for (const node of marketNodeLists.trigger.above.getGenerator()) {
846
+ if ((0, __1.isVariant)(node.order.direction, 'short')) {
847
+ yield node;
848
+ }
849
+ }
850
+ }
851
+ else if ((0, __1.isVariant)(direction, 'short') && marketNodeLists.trigger.below) {
852
+ for (const node of marketNodeLists.trigger.below.getGenerator()) {
853
+ if ((0, __1.isVariant)(node.order.direction, 'long')) {
854
+ yield node;
855
+ }
856
+ }
857
+ }
858
+ }
859
+ *getTakeProfitMarkets(marketIndex, marketType, direction) {
860
+ for (const node of this.getTakeProfits(marketIndex, marketType, direction)) {
861
+ if ((0, __1.isVariant)(node.order.orderType, 'triggerMarket')) {
862
+ yield node;
863
+ }
864
+ }
865
+ }
866
+ *getTakeProfitLimits(marketIndex, marketType, direction) {
867
+ for (const node of this.getTakeProfits(marketIndex, marketType, direction)) {
868
+ if ((0, __1.isVariant)(node.order.orderType, 'triggerLimit')) {
869
+ yield node;
870
+ }
871
+ }
872
+ }
809
873
  findNodesToTrigger(marketIndex, slot, oraclePrice, marketType, stateAccount) {
810
874
  if ((0, exchangeStatus_1.exchangePaused)(stateAccount)) {
811
875
  return [];
@@ -845,15 +909,12 @@ class DLOB {
845
909
  }
846
910
  return nodesToTrigger;
847
911
  }
848
- printTopOfOrderLists(sdkConfig, driftClient, slotSubscriber, marketIndex, marketType) {
912
+ printTop(driftClient, slotSubscriber, marketIndex, marketType) {
849
913
  if ((0, __1.isVariant)(marketType, 'perp')) {
850
- const market = driftClient.getPerpMarketAccount(marketIndex);
851
914
  const slot = slotSubscriber.getSlot();
852
915
  const oraclePriceData = driftClient.getOracleDataForPerpMarket(marketIndex);
853
- const fallbackAsk = (0, __1.calculateAskPrice)(market, oraclePriceData);
854
- const fallbackBid = (0, __1.calculateBidPrice)(market, oraclePriceData);
855
- const bestAsk = this.getBestAsk(marketIndex, fallbackAsk, slot, marketType, oraclePriceData);
856
- const bestBid = this.getBestBid(marketIndex, fallbackBid, slot, marketType, oraclePriceData);
916
+ const bestAsk = this.getBestAsk(marketIndex, slot, marketType, oraclePriceData);
917
+ const bestBid = this.getBestBid(marketIndex, slot, marketType, oraclePriceData);
857
918
  const mid = bestAsk.add(bestBid).div(new __1.BN(2));
858
919
  const bidSpread = ((0, __1.convertToNumber)(bestBid, __1.PRICE_PRECISION) /
859
920
  (0, __1.convertToNumber)(oraclePriceData.price, __1.PRICE_PRECISION) -
@@ -863,7 +924,8 @@ class DLOB {
863
924
  (0, __1.convertToNumber)(oraclePriceData.price, __1.PRICE_PRECISION) -
864
925
  1) *
865
926
  100.0;
866
- console.log(`Market ${sdkConfig.MARKETS[marketIndex].symbol} Orders`);
927
+ const name = (0, __1.decodeName)(driftClient.getPerpMarketAccount(marketIndex).name);
928
+ console.log(`Market ${name} Orders`);
867
929
  console.log(` Ask`, (0, __1.convertToNumber)(bestAsk, __1.PRICE_PRECISION).toFixed(3), `(${askSpread.toFixed(4)}%)`);
868
930
  console.log(` Mid`, (0, __1.convertToNumber)(mid, __1.PRICE_PRECISION).toFixed(3));
869
931
  console.log(` Bid`, (0, __1.convertToNumber)(bestBid, __1.PRICE_PRECISION).toFixed(3), `(${bidSpread.toFixed(4)}%)`);
@@ -871,8 +933,8 @@ class DLOB {
871
933
  else if ((0, __1.isVariant)(marketType, 'spot')) {
872
934
  const slot = slotSubscriber.getSlot();
873
935
  const oraclePriceData = driftClient.getOracleDataForPerpMarket(marketIndex);
874
- const bestAsk = this.getBestAsk(marketIndex, undefined, slot, marketType, oraclePriceData);
875
- const bestBid = this.getBestBid(marketIndex, undefined, slot, marketType, oraclePriceData);
936
+ const bestAsk = this.getBestAsk(marketIndex, slot, marketType, oraclePriceData);
937
+ const bestBid = this.getBestBid(marketIndex, slot, marketType, oraclePriceData);
876
938
  const mid = bestAsk.add(bestBid).div(new __1.BN(2));
877
939
  const bidSpread = ((0, __1.convertToNumber)(bestBid, __1.PRICE_PRECISION) /
878
940
  (0, __1.convertToNumber)(oraclePriceData.price, __1.PRICE_PRECISION) -
@@ -882,7 +944,8 @@ class DLOB {
882
944
  (0, __1.convertToNumber)(oraclePriceData.price, __1.PRICE_PRECISION) -
883
945
  1) *
884
946
  100.0;
885
- console.log(`Market ${sdkConfig.MARKETS[marketIndex].symbol} Orders`);
947
+ const name = (0, __1.decodeName)(driftClient.getSpotMarketAccount(marketIndex).name);
948
+ console.log(`Market ${name} Orders`);
886
949
  console.log(` Ask`, (0, __1.convertToNumber)(bestAsk, __1.PRICE_PRECISION).toFixed(3), `(${askSpread.toFixed(4)}%)`);
887
950
  console.log(` Mid`, (0, __1.convertToNumber)(mid, __1.PRICE_PRECISION).toFixed(3));
888
951
  console.log(` Bid`, (0, __1.convertToNumber)(bestBid, __1.PRICE_PRECISION).toFixed(3), `(${bidSpread.toFixed(4)}%)`);
@@ -209,6 +209,7 @@ function groupL2(l2, grouping, depth) {
209
209
  return {
210
210
  bids: groupL2Levels(l2.bids, grouping, __1.PositionDirection.LONG, depth),
211
211
  asks: groupL2Levels(l2.asks, grouping, __1.PositionDirection.SHORT, depth),
212
+ slot: l2.slot,
212
213
  };
213
214
  }
214
215
  exports.groupL2 = groupL2;
@@ -275,11 +275,13 @@ export declare class DriftClient {
275
275
  * @param makerInfo
276
276
  * @param txParams
277
277
  * @param bracketOrdersParams
278
+ * @param cancelExistingOrders - Builds and returns an extra transaciton to cancel the existing orders in the same perp market. Intended use is to auto-cancel TP/SL orders when closing a position. Ignored if orderParams.marketType is not MarketType.PERP
278
279
  * @returns
279
280
  */
280
- sendMarketOrderAndGetSignedFillTx(orderParams: OptionalOrderParams, userAccountPublicKey: PublicKey, userAccount: UserAccount, makerInfo?: MakerInfo | MakerInfo[], txParams?: TxParams, bracketOrdersParams?: OptionalOrderParams[], referrerInfo?: ReferrerInfo): Promise<{
281
+ sendMarketOrderAndGetSignedFillTx(orderParams: OptionalOrderParams, userAccountPublicKey: PublicKey, userAccount: UserAccount, makerInfo?: MakerInfo | MakerInfo[], txParams?: TxParams, bracketOrdersParams?: OptionalOrderParams[], referrerInfo?: ReferrerInfo, cancelExistingOrders?: boolean): Promise<{
281
282
  txSig: TransactionSignature;
282
283
  signedFillTx: Transaction;
284
+ signedCancelExistingOrdersTx?: Transaction;
283
285
  }>;
284
286
  placePerpOrder(orderParams: OptionalOrderParams, txParams?: TxParams): Promise<TransactionSignature>;
285
287
  getPlacePerpOrderIx(orderParams: OptionalOrderParams): Promise<TransactionInstruction>;