@drift-labs/sdk 2.49.0-beta.1 → 2.49.0-beta.11

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 (54) hide show
  1. package/VERSION +1 -1
  2. package/lib/accounts/{mockUserAccountSubscriber.d.ts → basicUserAccountSubscriber.d.ts} +2 -2
  3. package/lib/accounts/{mockUserAccountSubscriber.js → basicUserAccountSubscriber.js} +9 -6
  4. package/lib/accounts/pollingInsuranceFundStakeAccountSubscriber.d.ts +29 -0
  5. package/lib/accounts/pollingInsuranceFundStakeAccountSubscriber.js +110 -0
  6. package/lib/accounts/types.d.ts +14 -1
  7. package/lib/accounts/webSocketInsuranceFundStakeAccountSubscriber.d.ts +23 -0
  8. package/lib/accounts/webSocketInsuranceFundStakeAccountSubscriber.js +65 -0
  9. package/lib/dlob/DLOB.d.ts +6 -2
  10. package/lib/dlob/DLOB.js +37 -12
  11. package/lib/driftClient.d.ts +66 -66
  12. package/lib/driftClient.js +208 -194
  13. package/lib/events/eventSubscriber.js +2 -1
  14. package/lib/events/sort.d.ts +2 -2
  15. package/lib/events/sort.js +6 -23
  16. package/lib/examples/loadDlob.js +10 -5
  17. package/lib/index.d.ts +3 -1
  18. package/lib/index.js +3 -1
  19. package/lib/math/superStake.d.ts +43 -0
  20. package/lib/math/superStake.js +64 -22
  21. package/lib/orderSubscriber/OrderSubscriber.js +4 -0
  22. package/lib/orderSubscriber/WebsocketSubscription.d.ts +1 -1
  23. package/lib/orderSubscriber/WebsocketSubscription.js +8 -6
  24. package/lib/types.d.ts +0 -2
  25. package/lib/userMap/PollingSubscription.d.ts +15 -0
  26. package/lib/userMap/PollingSubscription.js +26 -0
  27. package/lib/userMap/WebsocketSubscription.d.ts +19 -0
  28. package/lib/userMap/WebsocketSubscription.js +40 -0
  29. package/lib/userMap/userMap.d.ts +15 -18
  30. package/lib/userMap/userMap.js +62 -31
  31. package/lib/userMap/userMapConfig.d.ts +20 -0
  32. package/lib/userMap/userMapConfig.js +2 -0
  33. package/package.json +1 -1
  34. package/src/accounts/{mockUserAccountSubscriber.ts → basicUserAccountSubscriber.ts} +8 -6
  35. package/src/accounts/pollingInsuranceFundStakeAccountSubscriber.ts +185 -0
  36. package/src/accounts/types.ts +21 -0
  37. package/src/accounts/webSocketInsuranceFundStakeAccountSubscriber.ts +127 -0
  38. package/src/dlob/DLOB.ts +55 -15
  39. package/src/driftClient.ts +429 -272
  40. package/src/events/eventSubscriber.ts +2 -1
  41. package/src/events/sort.ts +7 -29
  42. package/src/examples/loadDlob.ts +11 -6
  43. package/src/index.ts +3 -1
  44. package/src/math/superStake.ts +108 -20
  45. package/src/orderSubscriber/OrderSubscriber.ts +4 -0
  46. package/src/orderSubscriber/WebsocketSubscription.ts +19 -16
  47. package/src/types.ts +0 -2
  48. package/src/userMap/PollingSubscription.ts +46 -0
  49. package/src/userMap/WebsocketSubscription.ts +74 -0
  50. package/src/userMap/userMap.ts +88 -60
  51. package/src/userMap/userMapConfig.ts +31 -0
  52. package/tests/amm/test.ts +6 -3
  53. package/tests/dlob/helpers.ts +2 -6
  54. package/tests/dlob/test.ts +194 -0
@@ -5,33 +5,46 @@ const __1 = require("..");
5
5
  const web3_js_1 = require("@solana/web3.js");
6
6
  const buffer_1 = require("buffer");
7
7
  const memcmp_1 = require("../memcmp");
8
+ const WebsocketSubscription_1 = require("./WebsocketSubscription");
9
+ const PollingSubscription_1 = require("./PollingSubscription");
8
10
  class UserMap {
9
11
  /**
10
12
  * Constructs a new UserMap instance.
11
- *
12
- * @param {DriftClient} driftClient - The DriftClient instance.
13
- * @param {UserSubscriptionConfig} accountSubscription - The UserSubscriptionConfig instance.
14
- * @param {boolean} includeIdle - Whether idle users are subscribed to. Defaults to false to decrease # of user subscriptions.
15
- * @param {(authorities: PublicKey[]) => Promise<void>} syncCallback - Called after `sync` completes, will pas in unique list of authorities. Useful for using it to sync UserStatsMap.
16
- * @param {SyncCallbackCriteria} syncCallbackCriteria - The criteria for the sync callback. Defaults to having no filters
17
13
  */
18
- constructor(driftClient, accountSubscription, includeIdle = false, syncCallback, syncCallbackCriteria = { hasOpenOrders: false }) {
14
+ constructor(config) {
15
+ var _a, _b;
19
16
  this.userMap = new Map();
20
17
  this.stateAccountUpdateCallback = async (state) => {
21
- if (state.numberOfSubAccounts !== this.lastNumberOfSubAccounts) {
18
+ if (!state.numberOfSubAccounts.eq(this.lastNumberOfSubAccounts)) {
22
19
  await this.sync();
23
20
  this.lastNumberOfSubAccounts = state.numberOfSubAccounts;
24
21
  }
25
22
  };
26
- this.driftClient = driftClient;
27
- this.accountSubscription = accountSubscription;
28
- this.includeIdle = includeIdle;
29
- this.syncCallback = syncCallback;
30
- this.syncCallbackCriteria = syncCallbackCriteria;
31
- }
32
- addSyncCallback(syncCallback, syncCallbackCriteria = { hasOpenOrders: false }) {
33
- this.syncCallback = syncCallback;
34
- this.syncCallbackCriteria = syncCallbackCriteria;
23
+ this.driftClient = config.driftClient;
24
+ if (config.connection) {
25
+ this.connection = config.connection;
26
+ }
27
+ else {
28
+ this.connection = this.driftClient.connection;
29
+ }
30
+ this.commitment =
31
+ (_a = config.subscriptionConfig.commitment) !== null && _a !== void 0 ? _a : this.driftClient.opts.commitment;
32
+ this.includeIdle = (_b = config.includeIdle) !== null && _b !== void 0 ? _b : false;
33
+ if (config.subscriptionConfig.type === 'polling') {
34
+ this.subscription = new PollingSubscription_1.PollingSubscription({
35
+ userMap: this,
36
+ frequency: config.subscriptionConfig.frequency,
37
+ skipInitialLoad: config.skipInitialLoad,
38
+ });
39
+ }
40
+ else {
41
+ this.subscription = new WebsocketSubscription_1.WebsocketSubscription({
42
+ userMap: this,
43
+ commitment: this.commitment,
44
+ resubTimeoutMs: config.subscriptionConfig.resubTimeoutMs,
45
+ skipInitialLoad: config.skipInitialLoad,
46
+ });
47
+ }
35
48
  }
36
49
  async subscribe() {
37
50
  if (this.size() > 0) {
@@ -41,13 +54,16 @@ class UserMap {
41
54
  this.lastNumberOfSubAccounts =
42
55
  this.driftClient.getStateAccount().numberOfSubAccounts;
43
56
  this.driftClient.eventEmitter.on('stateAccountUpdate', this.stateAccountUpdateCallback);
44
- await this.sync();
57
+ await this.subscription.subscribe();
45
58
  }
46
- async addPubkey(userAccountPublicKey, userAccount) {
59
+ async addPubkey(userAccountPublicKey, userAccount, slot) {
47
60
  const user = new __1.User({
48
61
  driftClient: this.driftClient,
49
62
  userAccountPublicKey,
50
- accountSubscription: this.accountSubscription,
63
+ accountSubscription: {
64
+ type: 'custom',
65
+ userAccountSubscriber: new __1.BasicUserAccountSubscriber(userAccountPublicKey, userAccount, slot),
66
+ },
51
67
  });
52
68
  await user.subscribe(userAccount);
53
69
  this.userMap.set(userAccountPublicKey.toString(), user);
@@ -148,11 +164,15 @@ class UserMap {
148
164
  size() {
149
165
  return this.userMap.size;
150
166
  }
151
- getUniqueAuthorities(useSyncCallbackCriteria = true) {
167
+ /**
168
+ * Returns a unique list of authorities for all users in the UserMap that meet the filter criteria
169
+ * @param filterCriteria: Users must meet these criteria to be included
170
+ * @returns
171
+ */
172
+ getUniqueAuthorities(filterCriteria) {
152
173
  const usersMeetingCriteria = Array.from(this.userMap.values()).filter((user) => {
153
174
  let pass = true;
154
- if (useSyncCallbackCriteria &&
155
- this.syncCallbackCriteria.hasOpenOrders) {
175
+ if (filterCriteria && filterCriteria.hasOpenOrders) {
156
176
  pass = pass && user.getUserAccount().hasOpenOrder;
157
177
  }
158
178
  return pass;
@@ -176,7 +196,7 @@ class UserMap {
176
196
  const rpcRequestArgs = [
177
197
  this.driftClient.program.programId.toBase58(),
178
198
  {
179
- commitment: this.driftClient.connection.commitment,
199
+ commitment: this.commitment,
180
200
  filters,
181
201
  encoding: 'base64',
182
202
  withContext: true,
@@ -184,7 +204,7 @@ class UserMap {
184
204
  ];
185
205
  const rpcJSONResponse =
186
206
  // @ts-ignore
187
- await this.driftClient.connection._rpcRequest('getProgramAccounts', rpcRequestArgs);
207
+ await this.connection._rpcRequest('getProgramAccounts', rpcRequestArgs);
188
208
  const rpcResponseAndContext = rpcJSONResponse.result;
189
209
  const slot = rpcResponseAndContext.context.slot;
190
210
  const programAccountBufferMap = new Map();
@@ -195,9 +215,11 @@ class UserMap {
195
215
  }
196
216
  for (const [key, buffer] of programAccountBufferMap.entries()) {
197
217
  if (!this.has(key)) {
198
- const userAccount = this.driftClient.program.account.user.coder.accounts.decode('User', buffer);
218
+ const userAccount = this.driftClient.program.account.user.coder.accounts.decodeUnchecked('User', buffer);
199
219
  await this.addPubkey(new web3_js_1.PublicKey(key), userAccount);
200
220
  }
221
+ // give event loop a chance to breathe
222
+ await new Promise((resolve) => setTimeout(resolve, 0));
201
223
  }
202
224
  for (const [key, user] of this.userMap.entries()) {
203
225
  if (!programAccountBufferMap.has(key)) {
@@ -205,16 +227,15 @@ class UserMap {
205
227
  this.userMap.delete(key);
206
228
  }
207
229
  else {
208
- const userAccount = this.driftClient.program.account.user.coder.accounts.decode('User', programAccountBufferMap.get(key));
230
+ const userAccount = this.driftClient.program.account.user.coder.accounts.decodeUnchecked('User', programAccountBufferMap.get(key));
209
231
  user.accountSubscriber.updateData(userAccount, slot);
210
232
  }
211
- }
212
- if (this.syncCallback) {
213
- await this.syncCallback(this.getUniqueAuthorities());
233
+ // give event loop a chance to breathe
234
+ await new Promise((resolve) => setTimeout(resolve, 0));
214
235
  }
215
236
  }
216
237
  catch (e) {
217
- console.error(`Error in UserMap.sync()`);
238
+ console.error(`Error in UserMap.sync():`);
218
239
  console.error(e);
219
240
  }
220
241
  finally {
@@ -223,6 +244,7 @@ class UserMap {
223
244
  }
224
245
  }
225
246
  async unsubscribe() {
247
+ await this.subscription.unsubscribe();
226
248
  for (const [key, user] of this.userMap.entries()) {
227
249
  await user.unsubscribe();
228
250
  this.userMap.delete(key);
@@ -232,5 +254,14 @@ class UserMap {
232
254
  this.lastNumberOfSubAccounts = undefined;
233
255
  }
234
256
  }
257
+ async updateUserAccount(key, userAccount, slot) {
258
+ if (!this.userMap.has(key)) {
259
+ this.addPubkey(new web3_js_1.PublicKey(key), userAccount, slot);
260
+ }
261
+ else {
262
+ const user = this.userMap.get(key);
263
+ user.accountSubscriber.updateData(userAccount, slot);
264
+ }
265
+ }
235
266
  }
236
267
  exports.UserMap = UserMap;
@@ -0,0 +1,20 @@
1
+ import { Commitment, Connection } from '@solana/web3.js';
2
+ import { DriftClient } from '../driftClient';
3
+ export type UserAccountFilterCriteria = {
4
+ hasOpenOrders: boolean;
5
+ };
6
+ export type UserMapConfig = {
7
+ driftClient: DriftClient;
8
+ connection?: Connection;
9
+ subscriptionConfig: {
10
+ type: 'polling';
11
+ frequency: number;
12
+ commitment?: Commitment;
13
+ } | {
14
+ type: 'websocket';
15
+ resubTimeoutMs?: number;
16
+ commitment?: Commitment;
17
+ };
18
+ skipInitialLoad?: boolean;
19
+ includeIdle?: boolean;
20
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.49.0-beta.1",
3
+ "version": "2.49.0-beta.11",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -4,7 +4,7 @@ import StrictEventEmitter from 'strict-event-emitter-types';
4
4
  import { EventEmitter } from 'events';
5
5
  import { UserAccount } from '../types';
6
6
 
7
- export class MockUserAccountSubscriber implements UserAccountSubscriber {
7
+ export class BasicUserAccountSubscriber implements UserAccountSubscriber {
8
8
  isSubscribed: boolean;
9
9
  eventEmitter: StrictEventEmitter<EventEmitter, UserAccountEvents>;
10
10
  userAccountPublicKey: PublicKey;
@@ -16,8 +16,8 @@ export class MockUserAccountSubscriber implements UserAccountSubscriber {
16
16
 
17
17
  public constructor(
18
18
  userAccountPublicKey: PublicKey,
19
- data: UserAccount,
20
- slot: number
19
+ data?: UserAccount,
20
+ slot?: number
21
21
  ) {
22
22
  this.isSubscribed = true;
23
23
  this.eventEmitter = new EventEmitter();
@@ -46,8 +46,10 @@ export class MockUserAccountSubscriber implements UserAccountSubscriber {
46
46
  }
47
47
 
48
48
  public updateData(userAccount: UserAccount, slot: number): void {
49
- this.user = { data: userAccount, slot };
50
- this.eventEmitter.emit('userAccountUpdate', userAccount);
51
- this.eventEmitter.emit('update');
49
+ if (!this.user || slot >= (this.user.slot ?? 0)) {
50
+ this.user = { data: userAccount, slot };
51
+ this.eventEmitter.emit('userAccountUpdate', userAccount);
52
+ this.eventEmitter.emit('update');
53
+ }
52
54
  }
53
55
  }
@@ -0,0 +1,185 @@
1
+ import {
2
+ DataAndSlot,
3
+ NotSubscribedError,
4
+ InsuranceFundStakeAccountEvents,
5
+ InsuranceFundStakeAccountSubscriber,
6
+ } from './types';
7
+ import { Program } from '@coral-xyz/anchor';
8
+ import StrictEventEmitter from 'strict-event-emitter-types';
9
+ import { EventEmitter } from 'events';
10
+ import { PublicKey } from '@solana/web3.js';
11
+ import { BulkAccountLoader } from './bulkAccountLoader';
12
+ import { InsuranceFundStake } from '../types';
13
+
14
+ export class PollingInsuranceFundStakeAccountSubscriber
15
+ implements InsuranceFundStakeAccountSubscriber
16
+ {
17
+ isSubscribed: boolean;
18
+ program: Program;
19
+ eventEmitter: StrictEventEmitter<
20
+ EventEmitter,
21
+ InsuranceFundStakeAccountEvents
22
+ >;
23
+ insuranceFundStakeAccountPublicKey: PublicKey;
24
+
25
+ accountLoader: BulkAccountLoader;
26
+ callbackId?: string;
27
+ errorCallbackId?: string;
28
+
29
+ insuranceFundStakeAccountAndSlot?: DataAndSlot<InsuranceFundStake>;
30
+
31
+ public constructor(
32
+ program: Program,
33
+ publicKey: PublicKey,
34
+ accountLoader: BulkAccountLoader
35
+ ) {
36
+ this.isSubscribed = false;
37
+ this.program = program;
38
+ this.insuranceFundStakeAccountPublicKey = publicKey;
39
+ this.accountLoader = accountLoader;
40
+ this.eventEmitter = new EventEmitter();
41
+ }
42
+
43
+ async subscribe(insuranceFundStake?: InsuranceFundStake): Promise<boolean> {
44
+ if (this.isSubscribed) {
45
+ return true;
46
+ }
47
+
48
+ if (insuranceFundStake) {
49
+ this.insuranceFundStakeAccountAndSlot = {
50
+ data: insuranceFundStake,
51
+ slot: undefined,
52
+ };
53
+ }
54
+
55
+ await this.addToAccountLoader();
56
+
57
+ if (this.doesAccountExist()) {
58
+ this.eventEmitter.emit('update');
59
+ }
60
+
61
+ this.isSubscribed = true;
62
+ return true;
63
+ }
64
+
65
+ async addToAccountLoader(): Promise<void> {
66
+ if (this.callbackId) {
67
+ return;
68
+ }
69
+
70
+ this.callbackId = await this.accountLoader.addAccount(
71
+ this.insuranceFundStakeAccountPublicKey,
72
+ (buffer, slot: number) => {
73
+ if (!buffer) {
74
+ return;
75
+ }
76
+
77
+ if (
78
+ this.insuranceFundStakeAccountAndSlot &&
79
+ this.insuranceFundStakeAccountAndSlot.slot > slot
80
+ ) {
81
+ return;
82
+ }
83
+
84
+ const account = this.program.account.user.coder.accounts.decode(
85
+ 'InsuranceFundStake',
86
+ buffer
87
+ );
88
+ this.insuranceFundStakeAccountAndSlot = { data: account, slot };
89
+ this.eventEmitter.emit('insuranceFundStakeAccountUpdate', account);
90
+ this.eventEmitter.emit('update');
91
+ }
92
+ );
93
+
94
+ this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
95
+ this.eventEmitter.emit('error', error);
96
+ });
97
+ }
98
+
99
+ async fetchIfUnloaded(): Promise<void> {
100
+ if (this.insuranceFundStakeAccountAndSlot === undefined) {
101
+ await this.fetch();
102
+ }
103
+ }
104
+
105
+ async fetch(): Promise<void> {
106
+ try {
107
+ const dataAndContext =
108
+ await this.program.account.insuranceFundStake.fetchAndContext(
109
+ this.insuranceFundStakeAccountPublicKey,
110
+ this.accountLoader.commitment
111
+ );
112
+ if (
113
+ dataAndContext.context.slot >
114
+ (this.insuranceFundStakeAccountAndSlot?.slot ?? 0)
115
+ ) {
116
+ this.insuranceFundStakeAccountAndSlot = {
117
+ data: dataAndContext.data as InsuranceFundStake,
118
+ slot: dataAndContext.context.slot,
119
+ };
120
+ }
121
+ } catch (e) {
122
+ console.log(
123
+ `PollingInsuranceFundStakeAccountSubscriber.fetch() InsuranceFundStake does not exist: ${e.message}`
124
+ );
125
+ }
126
+ }
127
+
128
+ doesAccountExist(): boolean {
129
+ return this.insuranceFundStakeAccountAndSlot !== undefined;
130
+ }
131
+
132
+ async unsubscribe(): Promise<void> {
133
+ if (!this.isSubscribed) {
134
+ return;
135
+ }
136
+
137
+ this.accountLoader.removeAccount(
138
+ this.insuranceFundStakeAccountPublicKey,
139
+ this.callbackId
140
+ );
141
+ this.callbackId = undefined;
142
+
143
+ this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
144
+ this.errorCallbackId = undefined;
145
+
146
+ this.isSubscribed = false;
147
+ }
148
+
149
+ assertIsSubscribed(): void {
150
+ if (!this.isSubscribed) {
151
+ throw new NotSubscribedError(
152
+ 'You must call `subscribe` before using this function'
153
+ );
154
+ }
155
+ }
156
+
157
+ public getInsuranceFundStakeAccountAndSlot(): DataAndSlot<InsuranceFundStake> {
158
+ this.assertIsSubscribed();
159
+ return this.insuranceFundStakeAccountAndSlot;
160
+ }
161
+
162
+ didSubscriptionSucceed(): boolean {
163
+ return !!this.insuranceFundStakeAccountAndSlot;
164
+ }
165
+
166
+ public updateData(
167
+ insuranceFundStake: InsuranceFundStake,
168
+ slot: number
169
+ ): void {
170
+ if (
171
+ !this.insuranceFundStakeAccountAndSlot ||
172
+ this.insuranceFundStakeAccountAndSlot.slot < slot
173
+ ) {
174
+ this.insuranceFundStakeAccountAndSlot = {
175
+ data: insuranceFundStake,
176
+ slot,
177
+ };
178
+ this.eventEmitter.emit(
179
+ 'insuranceFundStakeAccountUpdate',
180
+ insuranceFundStake
181
+ );
182
+ this.eventEmitter.emit('update');
183
+ }
184
+ }
185
+ }
@@ -5,6 +5,7 @@ import {
5
5
  StateAccount,
6
6
  UserAccount,
7
7
  UserStatsAccount,
8
+ InsuranceFundStake,
8
9
  } from '../types';
9
10
  import StrictEventEmitter from 'strict-event-emitter-types';
10
11
  import { EventEmitter } from 'events';
@@ -105,6 +106,26 @@ export interface TokenAccountSubscriber {
105
106
  getTokenAccountAndSlot(): DataAndSlot<Account>;
106
107
  }
107
108
 
109
+ export interface InsuranceFundStakeAccountSubscriber {
110
+ eventEmitter: StrictEventEmitter<
111
+ EventEmitter,
112
+ InsuranceFundStakeAccountEvents
113
+ >;
114
+ isSubscribed: boolean;
115
+
116
+ subscribe(): Promise<boolean>;
117
+ fetch(): Promise<void>;
118
+ unsubscribe(): Promise<void>;
119
+
120
+ getInsuranceFundStakeAccountAndSlot(): DataAndSlot<InsuranceFundStake>;
121
+ }
122
+
123
+ export interface InsuranceFundStakeAccountEvents {
124
+ insuranceFundStakeAccountUpdate: (payload: InsuranceFundStake) => void;
125
+ update: void;
126
+ error: (e: Error) => void;
127
+ }
128
+
108
129
  export interface OracleEvents {
109
130
  oracleUpdate: (payload: OraclePriceData) => void;
110
131
  update: void;
@@ -0,0 +1,127 @@
1
+ import {
2
+ DataAndSlot,
3
+ AccountSubscriber,
4
+ NotSubscribedError,
5
+ InsuranceFundStakeAccountEvents,
6
+ InsuranceFundStakeAccountSubscriber,
7
+ } from './types';
8
+ import { Program } from '@coral-xyz/anchor';
9
+ import StrictEventEmitter from 'strict-event-emitter-types';
10
+ import { EventEmitter } from 'events';
11
+ import { Commitment, PublicKey } from '@solana/web3.js';
12
+ import { WebSocketAccountSubscriber } from './webSocketAccountSubscriber';
13
+ import { InsuranceFundStake } from '../types';
14
+
15
+ export class WebSocketInsuranceFundStakeAccountSubscriber
16
+ implements InsuranceFundStakeAccountSubscriber
17
+ {
18
+ isSubscribed: boolean;
19
+ reconnectTimeoutMs?: number;
20
+ commitment?: Commitment;
21
+ program: Program;
22
+ eventEmitter: StrictEventEmitter<
23
+ EventEmitter,
24
+ InsuranceFundStakeAccountEvents
25
+ >;
26
+ insuranceFundStakeAccountPublicKey: PublicKey;
27
+
28
+ insuranceFundStakeDataAccountSubscriber: AccountSubscriber<InsuranceFundStake>;
29
+
30
+ public constructor(
31
+ program: Program,
32
+ insuranceFundStakeAccountPublicKey: PublicKey,
33
+ reconnectTimeoutMs?: number,
34
+ commitment?: Commitment
35
+ ) {
36
+ this.isSubscribed = false;
37
+ this.program = program;
38
+ this.insuranceFundStakeAccountPublicKey =
39
+ insuranceFundStakeAccountPublicKey;
40
+ this.eventEmitter = new EventEmitter();
41
+ this.reconnectTimeoutMs = reconnectTimeoutMs;
42
+ this.commitment = commitment;
43
+ }
44
+
45
+ async subscribe(
46
+ insuranceFundStakeAccount?: InsuranceFundStake
47
+ ): Promise<boolean> {
48
+ if (this.isSubscribed) {
49
+ return true;
50
+ }
51
+
52
+ this.insuranceFundStakeDataAccountSubscriber =
53
+ new WebSocketAccountSubscriber(
54
+ 'insuranceFundStake',
55
+ this.program,
56
+ this.insuranceFundStakeAccountPublicKey,
57
+ undefined,
58
+ this.reconnectTimeoutMs,
59
+ this.commitment
60
+ );
61
+
62
+ if (insuranceFundStakeAccount) {
63
+ this.insuranceFundStakeDataAccountSubscriber.setData(
64
+ insuranceFundStakeAccount
65
+ );
66
+ }
67
+
68
+ await this.insuranceFundStakeDataAccountSubscriber.subscribe(
69
+ (data: InsuranceFundStake) => {
70
+ this.eventEmitter.emit('insuranceFundStakeAccountUpdate', data);
71
+ this.eventEmitter.emit('update');
72
+ }
73
+ );
74
+
75
+ this.eventEmitter.emit('update');
76
+ this.isSubscribed = true;
77
+ return true;
78
+ }
79
+
80
+ async fetch(): Promise<void> {
81
+ await Promise.all([this.insuranceFundStakeDataAccountSubscriber.fetch()]);
82
+ }
83
+
84
+ async unsubscribe(): Promise<void> {
85
+ if (!this.isSubscribed) {
86
+ return;
87
+ }
88
+
89
+ await Promise.all([
90
+ this.insuranceFundStakeDataAccountSubscriber.unsubscribe(),
91
+ ]);
92
+
93
+ this.isSubscribed = false;
94
+ }
95
+
96
+ assertIsSubscribed(): void {
97
+ if (!this.isSubscribed) {
98
+ throw new NotSubscribedError(
99
+ 'You must call `subscribe` before using this function'
100
+ );
101
+ }
102
+ }
103
+
104
+ public getInsuranceFundStakeAccountAndSlot(): DataAndSlot<InsuranceFundStake> {
105
+ this.assertIsSubscribed();
106
+ return this.insuranceFundStakeDataAccountSubscriber.dataAndSlot;
107
+ }
108
+
109
+ public updateData(
110
+ insuranceFundStake: InsuranceFundStake,
111
+ slot: number
112
+ ): void {
113
+ const currentDataSlot =
114
+ this.insuranceFundStakeDataAccountSubscriber.dataAndSlot?.slot || 0;
115
+ if (currentDataSlot <= slot) {
116
+ this.insuranceFundStakeDataAccountSubscriber.setData(
117
+ insuranceFundStake,
118
+ slot
119
+ );
120
+ this.eventEmitter.emit(
121
+ 'insuranceFundStakeAccountUpdate',
122
+ insuranceFundStake
123
+ );
124
+ this.eventEmitter.emit('update');
125
+ }
126
+ }
127
+ }