@drift-labs/sdk 2.82.0-beta.2 → 2.82.0-beta.20

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 (127) hide show
  1. package/README.md +65 -47
  2. package/VERSION +1 -1
  3. package/lib/accounts/types.d.ts +4 -3
  4. package/lib/accounts/webSocketAccountSubscriber.d.ts +3 -3
  5. package/lib/accounts/webSocketAccountSubscriber.js +16 -9
  6. package/lib/accounts/webSocketDriftClientAccountSubscriber.d.ts +3 -3
  7. package/lib/accounts/webSocketDriftClientAccountSubscriber.js +5 -5
  8. package/lib/accounts/webSocketInsuranceFundStakeAccountSubscriber.d.ts +2 -2
  9. package/lib/accounts/webSocketInsuranceFundStakeAccountSubscriber.js +5 -3
  10. package/lib/accounts/webSocketProgramAccountSubscriber.d.ts +3 -3
  11. package/lib/accounts/webSocketProgramAccountSubscriber.js +15 -9
  12. package/lib/accounts/webSocketUserAccountSubscriber.d.ts +3 -3
  13. package/lib/accounts/webSocketUserAccountSubscriber.js +3 -3
  14. package/lib/accounts/webSocketUserStatsAccountSubsriber.d.ts +3 -3
  15. package/lib/accounts/webSocketUserStatsAccountSubsriber.js +3 -3
  16. package/lib/auctionSubscriber/auctionSubscriber.d.ts +2 -2
  17. package/lib/auctionSubscriber/auctionSubscriber.js +3 -3
  18. package/lib/auctionSubscriber/types.d.ts +1 -0
  19. package/lib/clock/clockSubscriber.d.ts +29 -0
  20. package/lib/clock/clockSubscriber.js +74 -0
  21. package/lib/constants/perpMarkets.js +2 -2
  22. package/lib/constants/spotMarkets.js +11 -0
  23. package/lib/dlob/DLOB.js +2 -2
  24. package/lib/dlob/orderBookLevels.js +1 -0
  25. package/lib/driftClient.d.ts +21 -14
  26. package/lib/driftClient.js +192 -255
  27. package/lib/driftClientConfig.d.ts +3 -0
  28. package/lib/index.d.ts +2 -0
  29. package/lib/index.js +2 -0
  30. package/lib/jupiter/jupiterClient.d.ts +2 -1
  31. package/lib/jupiter/jupiterClient.js +10 -6
  32. package/lib/math/exchangeStatus.d.ts +2 -2
  33. package/lib/math/orders.d.ts +1 -1
  34. package/lib/math/orders.js +2 -2
  35. package/lib/orderSubscriber/OrderSubscriber.js +6 -3
  36. package/lib/orderSubscriber/WebsocketSubscription.d.ts +4 -3
  37. package/lib/orderSubscriber/WebsocketSubscription.js +3 -3
  38. package/lib/orderSubscriber/types.d.ts +1 -0
  39. package/lib/priorityFee/driftPriorityFeeMethod.d.ts +13 -3
  40. package/lib/priorityFee/driftPriorityFeeMethod.js +2 -2
  41. package/lib/priorityFee/index.d.ts +2 -0
  42. package/lib/priorityFee/index.js +2 -0
  43. package/lib/priorityFee/priorityFeeSubscriber.d.ts +1 -4
  44. package/lib/priorityFee/priorityFeeSubscriber.js +5 -4
  45. package/lib/priorityFee/priorityFeeSubscriberMap.d.ts +48 -0
  46. package/lib/priorityFee/priorityFeeSubscriberMap.js +88 -0
  47. package/lib/priorityFee/types.d.ts +8 -3
  48. package/lib/priorityFee/types.js +2 -1
  49. package/lib/tx/baseTxSender.d.ts +8 -6
  50. package/lib/tx/baseTxSender.js +9 -51
  51. package/lib/tx/fastSingleTxSender.d.ts +6 -6
  52. package/lib/tx/fastSingleTxSender.js +3 -31
  53. package/lib/tx/forwardOnlyTxSender.d.ts +4 -2
  54. package/lib/tx/forwardOnlyTxSender.js +2 -1
  55. package/lib/tx/retryTxSender.d.ts +4 -2
  56. package/lib/tx/retryTxSender.js +2 -1
  57. package/lib/tx/txHandler.d.ts +138 -0
  58. package/lib/tx/txHandler.js +396 -0
  59. package/lib/tx/txParamProcessor.d.ts +6 -10
  60. package/lib/tx/txParamProcessor.js +13 -17
  61. package/lib/tx/types.d.ts +8 -7
  62. package/lib/tx/types.js +12 -1
  63. package/lib/tx/whileValidTxSender.d.ts +7 -6
  64. package/lib/tx/whileValidTxSender.js +7 -28
  65. package/lib/types.d.ts +24 -4
  66. package/lib/types.js +10 -1
  67. package/lib/user.d.ts +0 -10
  68. package/lib/user.js +6 -29
  69. package/lib/userConfig.d.ts +1 -0
  70. package/lib/userMap/WebsocketSubscription.d.ts +4 -3
  71. package/lib/userMap/WebsocketSubscription.js +3 -3
  72. package/lib/userMap/userMap.js +4 -1
  73. package/lib/userMap/userMapConfig.d.ts +1 -0
  74. package/lib/userStats.js +6 -3
  75. package/lib/userStatsConfig.d.ts +1 -0
  76. package/lib/util/chainClock.d.ts +17 -0
  77. package/lib/util/chainClock.js +29 -0
  78. package/package.json +3 -3
  79. package/src/accounts/types.ts +5 -4
  80. package/src/accounts/webSocketAccountSubscriber.ts +35 -23
  81. package/src/accounts/webSocketDriftClientAccountSubscriber.ts +7 -6
  82. package/src/accounts/webSocketInsuranceFundStakeAccountSubscriber.ts +6 -4
  83. package/src/accounts/webSocketProgramAccountSubscriber.ts +32 -22
  84. package/src/accounts/webSocketUserAccountSubscriber.ts +5 -4
  85. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +5 -4
  86. package/src/auctionSubscriber/auctionSubscriber.ts +10 -4
  87. package/src/auctionSubscriber/types.ts +1 -0
  88. package/src/clock/clockSubscriber.ts +113 -0
  89. package/src/constants/perpMarkets.ts +2 -2
  90. package/src/constants/spotMarkets.ts +13 -0
  91. package/src/dlob/DLOB.ts +2 -2
  92. package/src/dlob/orderBookLevels.ts +2 -0
  93. package/src/driftClient.ts +295 -386
  94. package/src/driftClientConfig.ts +3 -0
  95. package/src/index.ts +2 -0
  96. package/src/jupiter/jupiterClient.ts +15 -6
  97. package/src/math/exchangeStatus.ts +2 -1
  98. package/src/math/orders.ts +3 -2
  99. package/src/orderSubscriber/OrderSubscriber.ts +4 -1
  100. package/src/orderSubscriber/WebsocketSubscription.ts +6 -5
  101. package/src/orderSubscriber/types.ts +1 -0
  102. package/src/priorityFee/driftPriorityFeeMethod.ts +16 -4
  103. package/src/priorityFee/index.ts +2 -0
  104. package/src/priorityFee/priorityFeeSubscriber.ts +7 -7
  105. package/src/priorityFee/priorityFeeSubscriberMap.ts +112 -0
  106. package/src/priorityFee/types.ts +16 -3
  107. package/src/tx/baseTxSender.ts +29 -79
  108. package/src/tx/fastSingleTxSender.ts +10 -55
  109. package/src/tx/forwardOnlyTxSender.ts +5 -1
  110. package/src/tx/retryTxSender.ts +5 -1
  111. package/src/tx/txHandler.ts +625 -0
  112. package/src/tx/txParamProcessor.ts +16 -28
  113. package/src/tx/types.ts +14 -18
  114. package/src/tx/whileValidTxSender.ts +24 -48
  115. package/src/types.ts +26 -2
  116. package/src/user.ts +7 -32
  117. package/src/userConfig.ts +1 -0
  118. package/src/userMap/WebsocketSubscription.ts +6 -5
  119. package/src/userMap/userMap.ts +4 -1
  120. package/src/userMap/userMapConfig.ts +1 -0
  121. package/src/userStats.ts +4 -1
  122. package/src/userStatsConfig.ts +1 -0
  123. package/src/util/chainClock.ts +41 -0
  124. package/tests/dlob/helpers.ts +3 -0
  125. package/lib/tx/utils.d.ts +0 -6
  126. package/lib/tx/utils.js +0 -39
  127. package/src/tx/utils.ts +0 -64
package/README.md CHANGED
@@ -19,6 +19,13 @@ npm i @drift-labs/sdk
19
19
 
20
20
  ## Getting Started
21
21
 
22
+ Documentation:
23
+
24
+ - [API docs](https://drift-labs.github.io/v2-teacher/)
25
+ - [overview docs](https://docs.drift.trade/)
26
+
27
+ The below is a light overview of using solana and drift's typescript sdk, but not as comprehensive as the [API docs](https://drift-labs.github.io/v2-teacher/).
28
+
22
29
  ### Setting up a wallet for your program
23
30
 
24
31
  ```bash
@@ -77,8 +84,10 @@ convertToNumber(new BN(10500), new BN(1000)); // = 10.5
77
84
  ### Setting up an account and making a trade
78
85
 
79
86
  ```typescript
80
- import { AnchorProvider, BN } from '@coral-xyz/anchor';
81
- import { Token, TOKEN_PROGRAM_ID } from '@solana/spl-token';
87
+ import * as anchor from '@coral-xyz/anchor';
88
+ import { AnchorProvider } from '@coral-xyz/anchor';
89
+ import { getAssociatedTokenAddress, TOKEN_PROGRAM_ID } from '@solana/spl-token';
90
+
82
91
  import { Connection, Keypair, PublicKey } from '@solana/web3.js';
83
92
  import {
84
93
  calculateReservePrice,
@@ -95,16 +104,17 @@ import {
95
104
  BASE_PRECISION,
96
105
  getMarketOrderParams,
97
106
  BulkAccountLoader,
98
- getMarketsAndOraclesForSubscription
107
+ BN,
108
+ calculateBidAskPrice,
109
+ getMarketsAndOraclesForSubscription,
110
+ calculateEstimatedPerpEntryPrice,
99
111
  } from '../sdk';
100
112
 
101
113
  export const getTokenAddress = (
102
114
  mintAddress: string,
103
115
  userPubKey: string
104
116
  ): Promise<PublicKey> => {
105
- return Token.getAssociatedTokenAddress(
106
- new PublicKey(`ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL`),
107
- TOKEN_PROGRAM_ID,
117
+ return getAssociatedTokenAddress(
108
118
  new PublicKey(mintAddress),
109
119
  new PublicKey(userPubKey)
110
120
  );
@@ -112,49 +122,56 @@ export const getTokenAddress = (
112
122
 
113
123
  const main = async () => {
114
124
  const env = 'devnet';
125
+ // const env = 'mainnet-beta';
126
+
115
127
  // Initialize Drift SDK
116
128
  const sdkConfig = initialize({ env });
117
129
 
118
130
  // Set up the Wallet and Provider
119
- const privateKey = process.env.BOT_PRIVATE_KEY; // stored as an array string
120
- const keypair = Keypair.fromSecretKey(
121
- Uint8Array.from(JSON.parse(privateKey))
122
- );
123
- const wallet = new Wallet(keypair);
131
+ if (!process.env.ANCHOR_WALLET) {
132
+ throw new Error('ANCHOR_WALLET env var must be set.');
133
+ }
124
134
 
125
- // Set up the Connection
126
- const rpcAddress = process.env.RPC_ADDRESS; // can use: https://api.devnet.solana.com for devnet; https://api.mainnet-beta.solana.com for mainnet;
127
- const connection = new Connection(rpcAddress);
135
+ if (!process.env.ANCHOR_PROVIDER_URL) {
136
+ throw new Error('ANCHOR_PROVIDER_URL env var must be set.');
137
+ }
128
138
 
129
- // Set up the Provider
130
- const provider = new AnchorProvider(
131
- connection,
132
- wallet,
133
- AnchorProvider.defaultOptions()
139
+ const provider = anchor.AnchorProvider.local(
140
+ process.env.ANCHOR_PROVIDER_URL,
141
+ {
142
+ preflightCommitment: 'confirmed',
143
+ skipPreflight: false,
144
+ commitment: 'confirmed',
145
+ }
134
146
  );
135
-
136
147
  // Check SOL Balance
137
- const lamportsBalance = await connection.getBalance(wallet.publicKey);
138
- console.log('SOL balance:', lamportsBalance / 10 ** 9);
148
+ const lamportsBalance = await provider.connection.getBalance(
149
+ provider.wallet.publicKey
150
+ );
151
+ console.log(
152
+ provider.wallet.publicKey.toString(),
153
+ env,
154
+ 'SOL balance:',
155
+ lamportsBalance / 10 ** 9
156
+ );
139
157
 
140
158
  // Misc. other things to set up
141
159
  const usdcTokenAddress = await getTokenAddress(
142
160
  sdkConfig.USDC_MINT_ADDRESS,
143
- wallet.publicKey.toString()
161
+ provider.wallet.publicKey.toString()
144
162
  );
145
163
 
146
164
  // Set up the Drift Client
147
165
  const driftPublicKey = new PublicKey(sdkConfig.DRIFT_PROGRAM_ID);
148
166
  const bulkAccountLoader = new BulkAccountLoader(
149
- connection,
167
+ provider.connection,
150
168
  'confirmed',
151
169
  1000
152
170
  );
153
171
  const driftClient = new DriftClient({
154
- connection,
172
+ connection: provider.connection,
155
173
  wallet: provider.wallet,
156
174
  programID: driftPublicKey,
157
- ...getMarketsAndOraclesForSubscription(env),
158
175
  accountSubscription: {
159
176
  type: 'polling',
160
177
  accountLoader: bulkAccountLoader,
@@ -162,6 +179,8 @@ const main = async () => {
162
179
  });
163
180
  await driftClient.subscribe();
164
181
 
182
+ console.log('subscribed to driftClient');
183
+
165
184
  // Set up user client
166
185
  const user = new User({
167
186
  driftClient: driftClient,
@@ -176,13 +195,20 @@ const main = async () => {
176
195
  const userAccountExists = await user.exists();
177
196
 
178
197
  if (!userAccountExists) {
179
- //// Create a Clearing House account by Depositing some USDC ($10,000 in this case)
198
+ console.log(
199
+ 'initializing to',
200
+ env,
201
+ ' drift account for',
202
+ provider.wallet.publicKey.toString()
203
+ );
204
+
205
+ //// Create a Drift V2 account by Depositing some USDC ($10,000 in this case)
180
206
  const depositAmount = new BN(10000).mul(QUOTE_PRECISION);
181
207
  await driftClient.initializeUserAccountAndDepositCollateral(
182
208
  depositAmount,
183
209
  await getTokenAddress(
184
210
  usdcTokenAddress.toString(),
185
- wallet.publicKey.toString()
211
+ provider.wallet.publicKey.toString()
186
212
  )
187
213
  );
188
214
  }
@@ -194,6 +220,9 @@ const main = async () => {
194
220
  (market) => market.baseAssetSymbol === 'SOL'
195
221
  );
196
222
 
223
+ const marketIndex = solMarketInfo.marketIndex;
224
+
225
+ // Get vAMM bid and ask price
197
226
  const [bid, ask] = calculateBidAskPrice(
198
227
  driftClient.getPerpMarketAccount(marketIndex).amm,
199
228
  driftClient.getOracleDataForPerpMarket(marketIndex)
@@ -203,35 +232,26 @@ const main = async () => {
203
232
  const formattedAskPrice = convertToNumber(ask, PRICE_PRECISION);
204
233
 
205
234
  console.log(
206
- `Current amm bid and ask price are $${formattedBidPrice} and $${formattedAskPrice}`
235
+ env,
236
+ `vAMM bid: $${formattedBidPrice} and ask: $${formattedAskPrice}`
207
237
  );
208
238
 
209
- // Estimate the slippage for a $5000 LONG trade
210
239
  const solMarketAccount = driftClient.getPerpMarketAccount(
211
240
  solMarketInfo.marketIndex
212
241
  );
242
+ console.log(env, `Placing a 1 SOL-PERP LONG order`);
213
243
 
214
- const slippage = convertToNumber(
215
- calculateTradeSlippage(
216
- PositionDirection.LONG,
217
- new BN(1).mul(BASE_PRECISION),
218
- solMarketAccount,
219
- 'base',
220
- driftClient.getOracleDataForPerpMarket(solMarketInfo.marketIndex)
221
- )[0],
222
- PRICE_PRECISION
223
- );
224
-
225
- console.log(`Slippage for a 1 SOL-PERP would be $${slippage}`);
226
-
227
- await driftClient.placePerpOrder(
244
+ const txSig = await driftClient.placePerpOrder(
228
245
  getMarketOrderParams({
229
246
  baseAssetAmount: new BN(1).mul(BASE_PRECISION),
230
247
  direction: PositionDirection.LONG,
231
248
  marketIndex: solMarketAccount.marketIndex,
232
249
  })
233
250
  );
234
- console.log(`Placed a 1 SOL-PERP LONG order`);
251
+ console.log(
252
+ env,
253
+ `Placed a 1 SOL-PERP LONG order. Tranaction signature: ${txSig}`
254
+ );
235
255
  };
236
256
 
237
257
  main();
@@ -244,5 +264,3 @@ Drift Protocol v2 is licensed under [Apache 2.0](./LICENSE).
244
264
  Unless you explicitly state otherwise, any contribution intentionally submitted
245
265
  for inclusion in Drift SDK by you, as defined in the Apache-2.0 license, shall be
246
266
  licensed as above, without any additional terms or conditions.
247
-
248
-
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.82.0-beta.2
1
+ 2.82.0-beta.20
@@ -29,9 +29,6 @@ export interface DriftClientAccountEvents {
29
29
  update: void;
30
30
  error: (e: Error) => void;
31
31
  }
32
- export interface DriftClientMetricsEvents {
33
- txSigned: void;
34
- }
35
32
  export interface DriftClientAccountSubscriber {
36
33
  eventEmitter: StrictEventEmitter<EventEmitter, DriftClientAccountEvents>;
37
34
  isSubscribed: boolean;
@@ -126,6 +123,10 @@ export type DataAndSlot<T> = {
126
123
  data: T;
127
124
  slot: number;
128
125
  };
126
+ export type ResubOpts = {
127
+ resubTimeoutMs?: number;
128
+ logResubMessages?: boolean;
129
+ };
129
130
  export interface UserStatsAccountEvents {
130
131
  userStatsAccountUpdate: (payload: UserStatsAccount) => void;
131
132
  update: void;
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
- import { DataAndSlot, BufferAndSlot, AccountSubscriber } from './types';
3
+ import { DataAndSlot, BufferAndSlot, AccountSubscriber, ResubOpts } from './types';
4
4
  import { Program } from '@coral-xyz/anchor';
5
5
  import { AccountInfo, Commitment, Context, PublicKey } from '@solana/web3.js';
6
6
  export declare class WebSocketAccountSubscriber<T> implements AccountSubscriber<T> {
@@ -12,12 +12,12 @@ export declare class WebSocketAccountSubscriber<T> implements AccountSubscriber<
12
12
  decodeBufferFn: (buffer: Buffer) => T;
13
13
  onChange: (data: T) => void;
14
14
  listenerId?: number;
15
- resubTimeoutMs?: number;
15
+ resubOpts?: ResubOpts;
16
16
  commitment?: Commitment;
17
17
  isUnsubscribing: boolean;
18
18
  timeoutId?: NodeJS.Timeout;
19
19
  receivingData: boolean;
20
- constructor(accountName: string, program: Program, accountPublicKey: PublicKey, decodeBuffer?: (buffer: Buffer) => T, resubTimeoutMs?: number, commitment?: Commitment);
20
+ constructor(accountName: string, program: Program, accountPublicKey: PublicKey, decodeBuffer?: (buffer: Buffer) => T, resubOpts?: ResubOpts, commitment?: Commitment);
21
21
  subscribe(onChange: (data: T) => void): Promise<void>;
22
22
  setData(data: T, slot?: number): void;
23
23
  private setTimeout;
@@ -3,14 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.WebSocketAccountSubscriber = void 0;
4
4
  const utils_1 = require("./utils");
5
5
  class WebSocketAccountSubscriber {
6
- constructor(accountName, program, accountPublicKey, decodeBuffer, resubTimeoutMs, commitment) {
6
+ constructor(accountName, program, accountPublicKey, decodeBuffer, resubOpts, commitment) {
7
+ var _a;
7
8
  this.isUnsubscribing = false;
8
9
  this.accountName = accountName;
9
10
  this.program = program;
10
11
  this.accountPublicKey = accountPublicKey;
11
12
  this.decodeBufferFn = decodeBuffer;
12
- this.resubTimeoutMs = resubTimeoutMs;
13
- if (this.resubTimeoutMs < 1000) {
13
+ this.resubOpts = resubOpts;
14
+ if (((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.resubTimeoutMs) < 1000) {
14
15
  console.log('resubTimeoutMs should be at least 1000ms to avoid spamming resub');
15
16
  }
16
17
  this.receivingData = false;
@@ -18,6 +19,7 @@ class WebSocketAccountSubscriber {
18
19
  commitment !== null && commitment !== void 0 ? commitment : this.program.provider.opts.commitment;
19
20
  }
20
21
  async subscribe(onChange) {
22
+ var _a;
21
23
  if (this.listenerId != null || this.isUnsubscribing) {
22
24
  return;
23
25
  }
@@ -26,7 +28,8 @@ class WebSocketAccountSubscriber {
26
28
  await this.fetch();
27
29
  }
28
30
  this.listenerId = this.program.provider.connection.onAccountChange(this.accountPublicKey, (accountInfo, context) => {
29
- if (this.resubTimeoutMs) {
31
+ var _a;
32
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.resubTimeoutMs) {
30
33
  this.receivingData = true;
31
34
  clearTimeout(this.timeoutId);
32
35
  this.handleRpcResponse(context, accountInfo);
@@ -36,7 +39,7 @@ class WebSocketAccountSubscriber {
36
39
  this.handleRpcResponse(context, accountInfo);
37
40
  }
38
41
  }, this.commitment);
39
- if (this.resubTimeoutMs) {
42
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.resubTimeoutMs) {
40
43
  this.receivingData = true;
41
44
  this.setTimeout();
42
45
  }
@@ -52,21 +55,25 @@ class WebSocketAccountSubscriber {
52
55
  };
53
56
  }
54
57
  setTimeout() {
58
+ var _a;
55
59
  if (!this.onChange) {
56
60
  throw new Error('onChange callback function must be set');
57
61
  }
58
62
  this.timeoutId = setTimeout(async () => {
63
+ var _a;
59
64
  if (this.isUnsubscribing) {
60
65
  // If we are in the process of unsubscribing, do not attempt to resubscribe
61
66
  return;
62
67
  }
63
68
  if (this.receivingData) {
64
- console.log(`No ws data from ${this.accountName} in ${this.resubTimeoutMs}ms, resubscribing`);
69
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
70
+ console.log(`No ws data from ${this.accountName} in ${this.resubOpts.resubTimeoutMs}ms, resubscribing`);
71
+ }
65
72
  await this.unsubscribe(true);
66
73
  this.receivingData = false;
67
74
  await this.subscribe(this.onChange);
68
75
  }
69
- }, this.resubTimeoutMs);
76
+ }, (_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.resubTimeoutMs);
70
77
  }
71
78
  async fetch() {
72
79
  const rpcResponse = await this.program.provider.connection.getAccountInfoAndContext(this.accountPublicKey, this.program.provider.opts.commitment);
@@ -119,8 +126,8 @@ class WebSocketAccountSubscriber {
119
126
  }
120
127
  }
121
128
  unsubscribe(onResub = false) {
122
- if (!onResub) {
123
- this.resubTimeoutMs = undefined;
129
+ if (!onResub && this.resubOpts) {
130
+ this.resubOpts.resubTimeoutMs = undefined;
124
131
  }
125
132
  this.isUnsubscribing = true;
126
133
  clearTimeout(this.timeoutId);
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import { DriftClientAccountSubscriber, DriftClientAccountEvents, DataAndSlot } from './types';
2
+ import { DriftClientAccountSubscriber, DriftClientAccountEvents, DataAndSlot, ResubOpts } from './types';
3
3
  import { AccountSubscriber } from './types';
4
4
  import { SpotMarketAccount, PerpMarketAccount, StateAccount } from '../types';
5
5
  import { Program } from '@coral-xyz/anchor';
@@ -16,7 +16,7 @@ export declare class WebSocketDriftClientAccountSubscriber implements DriftClien
16
16
  spotMarketIndexes: number[];
17
17
  oracleInfos: OracleInfo[];
18
18
  oracleClientCache: OracleClientCache;
19
- resubTimeoutMs?: number;
19
+ resubOpts?: ResubOpts;
20
20
  shouldFindAllMarketsAndOracles: boolean;
21
21
  eventEmitter: StrictEventEmitter<EventEmitter, DriftClientAccountEvents>;
22
22
  stateAccountSubscriber?: AccountSubscriber<StateAccount>;
@@ -28,7 +28,7 @@ export declare class WebSocketDriftClientAccountSubscriber implements DriftClien
28
28
  private isSubscribing;
29
29
  private subscriptionPromise;
30
30
  private subscriptionPromiseResolver;
31
- constructor(program: Program, perpMarketIndexes: number[], spotMarketIndexes: number[], oracleInfos: OracleInfo[], shouldFindAllMarketsAndOracles: boolean, resubTimeoutMs?: number, commitment?: Commitment);
31
+ constructor(program: Program, perpMarketIndexes: number[], spotMarketIndexes: number[], oracleInfos: OracleInfo[], shouldFindAllMarketsAndOracles: boolean, resubOpts?: ResubOpts, commitment?: Commitment);
32
32
  subscribe(): Promise<boolean>;
33
33
  subscribeToPerpMarketAccounts(): Promise<boolean>;
34
34
  subscribeToPerpMarketAccount(marketIndex: number): Promise<boolean>;
@@ -10,7 +10,7 @@ const oracleClientCache_1 = require("../oracles/oracleClientCache");
10
10
  const quoteAssetOracleClient_1 = require("../oracles/quoteAssetOracleClient");
11
11
  const config_1 = require("../config");
12
12
  class WebSocketDriftClientAccountSubscriber {
13
- constructor(program, perpMarketIndexes, spotMarketIndexes, oracleInfos, shouldFindAllMarketsAndOracles, resubTimeoutMs, commitment) {
13
+ constructor(program, perpMarketIndexes, spotMarketIndexes, oracleInfos, shouldFindAllMarketsAndOracles, resubOpts, commitment) {
14
14
  this.oracleClientCache = new oracleClientCache_1.OracleClientCache();
15
15
  this.perpMarketAccountSubscribers = new Map();
16
16
  this.perpOracleMap = new Map();
@@ -25,7 +25,7 @@ class WebSocketDriftClientAccountSubscriber {
25
25
  this.spotMarketIndexes = spotMarketIndexes;
26
26
  this.oracleInfos = oracleInfos;
27
27
  this.shouldFindAllMarketsAndOracles = shouldFindAllMarketsAndOracles;
28
- this.resubTimeoutMs = resubTimeoutMs;
28
+ this.resubOpts = resubOpts;
29
29
  this.commitment = commitment;
30
30
  }
31
31
  async subscribe() {
@@ -74,7 +74,7 @@ class WebSocketDriftClientAccountSubscriber {
74
74
  }
75
75
  async subscribeToPerpMarketAccount(marketIndex) {
76
76
  const perpMarketPublicKey = await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, marketIndex);
77
- const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('perpMarket', this.program, perpMarketPublicKey, undefined, this.resubTimeoutMs, this.commitment);
77
+ const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('perpMarket', this.program, perpMarketPublicKey, undefined, this.resubOpts, this.commitment);
78
78
  await accountSubscriber.subscribe((data) => {
79
79
  this.eventEmitter.emit('perpMarketAccountUpdate', data);
80
80
  this.eventEmitter.emit('update');
@@ -90,7 +90,7 @@ class WebSocketDriftClientAccountSubscriber {
90
90
  }
91
91
  async subscribeToSpotMarketAccount(marketIndex) {
92
92
  const marketPublicKey = await (0, pda_1.getSpotMarketPublicKey)(this.program.programId, marketIndex);
93
- const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('spotMarket', this.program, marketPublicKey, undefined, this.resubTimeoutMs, this.commitment);
93
+ const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('spotMarket', this.program, marketPublicKey, undefined, this.resubOpts, this.commitment);
94
94
  await accountSubscriber.subscribe((data) => {
95
95
  this.eventEmitter.emit('spotMarketAccountUpdate', data);
96
96
  this.eventEmitter.emit('update');
@@ -110,7 +110,7 @@ class WebSocketDriftClientAccountSubscriber {
110
110
  const client = this.oracleClientCache.get(oracleInfo.source, this.program.provider.connection, this.program);
111
111
  const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('oracle', this.program, oracleInfo.publicKey, (buffer) => {
112
112
  return client.getOraclePriceDataFromBuffer(buffer);
113
- }, this.resubTimeoutMs, this.commitment);
113
+ }, this.resubOpts, this.commitment);
114
114
  await accountSubscriber.subscribe((data) => {
115
115
  this.eventEmitter.emit('oraclePriceUpdate', oracleInfo.publicKey, data);
116
116
  this.eventEmitter.emit('update');
@@ -7,13 +7,13 @@ import { Commitment, PublicKey } from '@solana/web3.js';
7
7
  import { InsuranceFundStake } from '../types';
8
8
  export declare class WebSocketInsuranceFundStakeAccountSubscriber implements InsuranceFundStakeAccountSubscriber {
9
9
  isSubscribed: boolean;
10
- reconnectTimeoutMs?: number;
10
+ resubTimeoutMs?: number;
11
11
  commitment?: Commitment;
12
12
  program: Program;
13
13
  eventEmitter: StrictEventEmitter<EventEmitter, InsuranceFundStakeAccountEvents>;
14
14
  insuranceFundStakeAccountPublicKey: PublicKey;
15
15
  insuranceFundStakeDataAccountSubscriber: AccountSubscriber<InsuranceFundStake>;
16
- constructor(program: Program, insuranceFundStakeAccountPublicKey: PublicKey, reconnectTimeoutMs?: number, commitment?: Commitment);
16
+ constructor(program: Program, insuranceFundStakeAccountPublicKey: PublicKey, resubTimeoutMs?: number, commitment?: Commitment);
17
17
  subscribe(insuranceFundStakeAccount?: InsuranceFundStake): Promise<boolean>;
18
18
  fetch(): Promise<void>;
19
19
  unsubscribe(): Promise<void>;
@@ -5,13 +5,13 @@ const types_1 = require("./types");
5
5
  const events_1 = require("events");
6
6
  const webSocketAccountSubscriber_1 = require("./webSocketAccountSubscriber");
7
7
  class WebSocketInsuranceFundStakeAccountSubscriber {
8
- constructor(program, insuranceFundStakeAccountPublicKey, reconnectTimeoutMs, commitment) {
8
+ constructor(program, insuranceFundStakeAccountPublicKey, resubTimeoutMs, commitment) {
9
9
  this.isSubscribed = false;
10
10
  this.program = program;
11
11
  this.insuranceFundStakeAccountPublicKey =
12
12
  insuranceFundStakeAccountPublicKey;
13
13
  this.eventEmitter = new events_1.EventEmitter();
14
- this.reconnectTimeoutMs = reconnectTimeoutMs;
14
+ this.resubTimeoutMs = resubTimeoutMs;
15
15
  this.commitment = commitment;
16
16
  }
17
17
  async subscribe(insuranceFundStakeAccount) {
@@ -19,7 +19,9 @@ class WebSocketInsuranceFundStakeAccountSubscriber {
19
19
  return true;
20
20
  }
21
21
  this.insuranceFundStakeDataAccountSubscriber =
22
- new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('insuranceFundStake', this.program, this.insuranceFundStakeAccountPublicKey, undefined, this.reconnectTimeoutMs, this.commitment);
22
+ new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('insuranceFundStake', this.program, this.insuranceFundStakeAccountPublicKey, undefined, {
23
+ resubTimeoutMs: this.resubTimeoutMs,
24
+ }, this.commitment);
23
25
  if (insuranceFundStakeAccount) {
24
26
  this.insuranceFundStakeDataAccountSubscriber.setData(insuranceFundStakeAccount);
25
27
  }
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
- import { DataAndSlot, BufferAndSlot, ProgramAccountSubscriber } from './types';
3
+ import { DataAndSlot, BufferAndSlot, ProgramAccountSubscriber, ResubOpts } from './types';
4
4
  import { Program } from '@coral-xyz/anchor';
5
5
  import { Commitment, Context, KeyedAccountInfo, MemcmpFilter, PublicKey } from '@solana/web3.js';
6
6
  export declare class WebSocketProgramAccountSubscriber<T> implements ProgramAccountSubscriber<T> {
@@ -14,7 +14,7 @@ export declare class WebSocketProgramAccountSubscriber<T> implements ProgramAcco
14
14
  decodeBuffer: (accountName: string, ix: Buffer) => T;
15
15
  onChange: (accountId: PublicKey, data: T, context: Context, buffer: Buffer) => void;
16
16
  listenerId?: number;
17
- resubTimeoutMs?: number;
17
+ resubOpts?: ResubOpts;
18
18
  isUnsubscribing: boolean;
19
19
  timeoutId?: NodeJS.Timeout;
20
20
  options: {
@@ -25,7 +25,7 @@ export declare class WebSocketProgramAccountSubscriber<T> implements ProgramAcco
25
25
  constructor(subscriptionName: string, accountDiscriminator: string, program: Program, decodeBufferFn: (accountName: string, ix: Buffer) => T, options?: {
26
26
  filters: MemcmpFilter[];
27
27
  commitment?: Commitment;
28
- }, resubTimeoutMs?: number);
28
+ }, resubOpts?: ResubOpts);
29
29
  subscribe(onChange: (accountId: PublicKey, data: T, context: Context, buffer: Buffer) => void): Promise<void>;
30
30
  private setTimeout;
31
31
  handleRpcResponse(context: Context, keyedAccountInfo: KeyedAccountInfo): void;
@@ -4,28 +4,30 @@ exports.WebSocketProgramAccountSubscriber = void 0;
4
4
  class WebSocketProgramAccountSubscriber {
5
5
  constructor(subscriptionName, accountDiscriminator, program, decodeBufferFn, options = {
6
6
  filters: [],
7
- }, resubTimeoutMs) {
7
+ }, resubOpts) {
8
+ var _a;
8
9
  this.isUnsubscribing = false;
9
10
  this.receivingData = false;
10
11
  this.subscriptionName = subscriptionName;
11
12
  this.accountDiscriminator = accountDiscriminator;
12
13
  this.program = program;
13
14
  this.decodeBuffer = decodeBufferFn;
14
- this.resubTimeoutMs = resubTimeoutMs;
15
- if (this.resubTimeoutMs < 1000) {
15
+ this.resubOpts = resubOpts;
16
+ if (((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.resubTimeoutMs) < 1000) {
16
17
  console.log('resubTimeoutMs should be at least 1000ms to avoid spamming resub');
17
18
  }
18
19
  this.options = options;
19
20
  this.receivingData = false;
20
21
  }
21
22
  async subscribe(onChange) {
22
- var _a;
23
+ var _a, _b;
23
24
  if (this.listenerId != null || this.isUnsubscribing) {
24
25
  return;
25
26
  }
26
27
  this.onChange = onChange;
27
28
  this.listenerId = this.program.provider.connection.onProgramAccountChange(this.program.programId, (keyedAccountInfo, context) => {
28
- if (this.resubTimeoutMs) {
29
+ var _a;
30
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.resubTimeoutMs) {
29
31
  this.receivingData = true;
30
32
  clearTimeout(this.timeoutId);
31
33
  this.handleRpcResponse(context, keyedAccountInfo);
@@ -35,27 +37,31 @@ class WebSocketProgramAccountSubscriber {
35
37
  this.handleRpcResponse(context, keyedAccountInfo);
36
38
  }
37
39
  }, (_a = this.options.commitment) !== null && _a !== void 0 ? _a : this.program.provider.opts.commitment, this.options.filters);
38
- if (this.resubTimeoutMs) {
40
+ if ((_b = this.resubOpts) === null || _b === void 0 ? void 0 : _b.resubTimeoutMs) {
39
41
  this.receivingData = true;
40
42
  this.setTimeout();
41
43
  }
42
44
  }
43
45
  setTimeout() {
46
+ var _a;
44
47
  if (!this.onChange) {
45
48
  throw new Error('onChange callback function must be set');
46
49
  }
47
50
  this.timeoutId = setTimeout(async () => {
51
+ var _a, _b;
48
52
  if (this.isUnsubscribing) {
49
53
  // If we are in the process of unsubscribing, do not attempt to resubscribe
50
54
  return;
51
55
  }
52
56
  if (this.receivingData) {
53
- console.log(`No ws data from ${this.subscriptionName} in ${this.resubTimeoutMs}ms, resubscribing`);
57
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
58
+ console.log(`No ws data from ${this.subscriptionName} in ${(_b = this.resubOpts) === null || _b === void 0 ? void 0 : _b.resubTimeoutMs}ms, resubscribing`);
59
+ }
54
60
  await this.unsubscribe(true);
55
61
  this.receivingData = false;
56
62
  await this.subscribe(this.onChange);
57
63
  }
58
- }, this.resubTimeoutMs);
64
+ }, (_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.resubTimeoutMs);
59
65
  }
60
66
  handleRpcResponse(context, keyedAccountInfo) {
61
67
  const newSlot = context.slot;
@@ -99,7 +105,7 @@ class WebSocketProgramAccountSubscriber {
99
105
  }
100
106
  unsubscribe(onResub = false) {
101
107
  if (!onResub) {
102
- this.resubTimeoutMs = undefined;
108
+ this.resubOpts.resubTimeoutMs = undefined;
103
109
  }
104
110
  this.isUnsubscribing = true;
105
111
  clearTimeout(this.timeoutId);
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import { DataAndSlot, AccountSubscriber, UserAccountEvents, UserAccountSubscriber } from './types';
2
+ import { DataAndSlot, AccountSubscriber, UserAccountEvents, UserAccountSubscriber, ResubOpts } from './types';
3
3
  import { Program } from '@coral-xyz/anchor';
4
4
  import StrictEventEmitter from 'strict-event-emitter-types';
5
5
  import { EventEmitter } from 'events';
@@ -7,13 +7,13 @@ import { Commitment, PublicKey } from '@solana/web3.js';
7
7
  import { UserAccount } from '../types';
8
8
  export declare class WebSocketUserAccountSubscriber implements UserAccountSubscriber {
9
9
  isSubscribed: boolean;
10
- reconnectTimeoutMs?: number;
10
+ resubOpts?: ResubOpts;
11
11
  commitment?: Commitment;
12
12
  program: Program;
13
13
  eventEmitter: StrictEventEmitter<EventEmitter, UserAccountEvents>;
14
14
  userAccountPublicKey: PublicKey;
15
15
  userDataAccountSubscriber: AccountSubscriber<UserAccount>;
16
- constructor(program: Program, userAccountPublicKey: PublicKey, reconnectTimeoutMs?: number, commitment?: Commitment);
16
+ constructor(program: Program, userAccountPublicKey: PublicKey, resubOpts?: ResubOpts, commitment?: Commitment);
17
17
  subscribe(userAccount?: UserAccount): Promise<boolean>;
18
18
  fetch(): Promise<void>;
19
19
  unsubscribe(): Promise<void>;
@@ -5,19 +5,19 @@ const types_1 = require("./types");
5
5
  const events_1 = require("events");
6
6
  const webSocketAccountSubscriber_1 = require("./webSocketAccountSubscriber");
7
7
  class WebSocketUserAccountSubscriber {
8
- constructor(program, userAccountPublicKey, reconnectTimeoutMs, commitment) {
8
+ constructor(program, userAccountPublicKey, resubOpts, commitment) {
9
9
  this.isSubscribed = false;
10
10
  this.program = program;
11
+ this.resubOpts = resubOpts;
11
12
  this.userAccountPublicKey = userAccountPublicKey;
12
13
  this.eventEmitter = new events_1.EventEmitter();
13
- this.reconnectTimeoutMs = reconnectTimeoutMs;
14
14
  this.commitment = commitment;
15
15
  }
16
16
  async subscribe(userAccount) {
17
17
  if (this.isSubscribed) {
18
18
  return true;
19
19
  }
20
- this.userDataAccountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('user', this.program, this.userAccountPublicKey, undefined, this.reconnectTimeoutMs, this.commitment);
20
+ this.userDataAccountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('user', this.program, this.userAccountPublicKey, undefined, this.resubOpts, this.commitment);
21
21
  if (userAccount) {
22
22
  this.userDataAccountSubscriber.setData(userAccount);
23
23
  }
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import { DataAndSlot, AccountSubscriber, UserStatsAccountSubscriber, UserStatsAccountEvents } from './types';
2
+ import { DataAndSlot, AccountSubscriber, UserStatsAccountSubscriber, UserStatsAccountEvents, ResubOpts } from './types';
3
3
  import { Program } from '@coral-xyz/anchor';
4
4
  import StrictEventEmitter from 'strict-event-emitter-types';
5
5
  import { EventEmitter } from 'events';
@@ -7,13 +7,13 @@ import { Commitment, PublicKey } from '@solana/web3.js';
7
7
  import { UserStatsAccount } from '../types';
8
8
  export declare class WebSocketUserStatsAccountSubscriber implements UserStatsAccountSubscriber {
9
9
  isSubscribed: boolean;
10
- reconnectTimeoutMs?: number;
10
+ resubOpts?: ResubOpts;
11
11
  commitment?: Commitment;
12
12
  program: Program;
13
13
  eventEmitter: StrictEventEmitter<EventEmitter, UserStatsAccountEvents>;
14
14
  userStatsAccountPublicKey: PublicKey;
15
15
  userStatsAccountSubscriber: AccountSubscriber<UserStatsAccount>;
16
- constructor(program: Program, userStatsAccountPublicKey: PublicKey, reconnectTimeoutMs?: number, commitment?: Commitment);
16
+ constructor(program: Program, userStatsAccountPublicKey: PublicKey, resubOpts?: ResubOpts, commitment?: Commitment);
17
17
  subscribe(userStatsAccount?: UserStatsAccount): Promise<boolean>;
18
18
  fetch(): Promise<void>;
19
19
  unsubscribe(): Promise<void>;