@drift-labs/sdk 0.1.18-orders.1 → 0.1.18-orders.2

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 (71) hide show
  1. package/README.md +2 -1
  2. package/lib/accounts/bulkAccountLoader.d.ts +32 -0
  3. package/lib/accounts/bulkAccountLoader.js +156 -0
  4. package/lib/accounts/bulkUserSubscription.d.ts +7 -0
  5. package/lib/accounts/bulkUserSubscription.js +28 -0
  6. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +49 -0
  7. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +228 -0
  8. package/lib/accounts/pollingTokenAccountSubscriber.d.ts +25 -0
  9. package/lib/accounts/pollingTokenAccountSubscriber.js +79 -0
  10. package/lib/accounts/pollingUserAccountSubscriber.d.ts +32 -0
  11. package/lib/accounts/pollingUserAccountSubscriber.js +133 -0
  12. package/lib/accounts/types.d.ts +30 -25
  13. package/lib/accounts/utils.d.ts +1 -0
  14. package/lib/accounts/utils.js +7 -0
  15. package/lib/accounts/{defaultClearingHouseAccountSubscriber.d.ts → webSocketClearingHouseAccountSubscriber.d.ts} +6 -4
  16. package/lib/accounts/{defaultClearingHouseAccountSubscriber.js → webSocketClearingHouseAccountSubscriber.js} +5 -4
  17. package/lib/accounts/{defaultUserAccountSubscriber.d.ts → webSocketUserAccountSubscriber.d.ts} +3 -1
  18. package/lib/accounts/{defaultUserAccountSubscriber.js → webSocketUserAccountSubscriber.js} +10 -7
  19. package/lib/addresses.d.ts +2 -2
  20. package/lib/addresses.js +4 -4
  21. package/lib/admin.d.ts +3 -0
  22. package/lib/admin.js +61 -13
  23. package/lib/clearingHouse.d.ts +16 -4
  24. package/lib/clearingHouse.js +50 -10
  25. package/lib/clearingHouseUser.d.ts +9 -1
  26. package/lib/clearingHouseUser.js +19 -5
  27. package/lib/config.js +1 -1
  28. package/lib/constants/markets.js +16 -0
  29. package/lib/factory/clearingHouse.d.ts +25 -0
  30. package/lib/factory/clearingHouse.js +64 -0
  31. package/lib/factory/clearingHouseUser.d.ts +19 -0
  32. package/lib/factory/clearingHouseUser.js +34 -0
  33. package/lib/idl/clearing_house.json +360 -15
  34. package/lib/index.d.ts +9 -4
  35. package/lib/index.js +14 -5
  36. package/lib/math/funding.js +4 -1
  37. package/lib/math/utils.d.ts +2 -2
  38. package/lib/math/utils.js +6 -3
  39. package/lib/orderParams.d.ts +3 -3
  40. package/lib/orderParams.js +23 -3
  41. package/lib/token/index.d.ts +3 -0
  42. package/lib/token/index.js +38 -0
  43. package/lib/types.d.ts +13 -3
  44. package/package.json +3 -3
  45. package/src/accounts/bulkAccountLoader.ts +195 -0
  46. package/src/accounts/bulkUserSubscription.ts +28 -0
  47. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +326 -0
  48. package/src/accounts/pollingTokenAccountSubscriber.ts +99 -0
  49. package/src/accounts/pollingUserAccountSubscriber.ts +186 -0
  50. package/src/accounts/types.ts +35 -30
  51. package/src/accounts/utils.ts +3 -0
  52. package/src/accounts/{defaultClearingHouseAccountSubscriber.ts → webSocketClearingHouseAccountSubscriber.ts} +9 -6
  53. package/src/accounts/{defaultUserAccountSubscriber.ts → webSocketUserAccountSubscriber.ts} +10 -5
  54. package/src/addresses.ts +6 -4
  55. package/src/admin.ts +73 -20
  56. package/src/clearingHouse.ts +69 -25
  57. package/src/clearingHouseUser.ts +26 -6
  58. package/src/config.ts +1 -1
  59. package/src/constants/markets.ts +16 -0
  60. package/src/factory/clearingHouse.ts +125 -0
  61. package/src/factory/clearingHouseUser.ts +73 -0
  62. package/src/idl/clearing_house.json +360 -15
  63. package/src/index.ts +9 -4
  64. package/src/math/funding.ts +5 -1
  65. package/src/math/utils.ts +1 -1
  66. package/src/orderParams.ts +26 -3
  67. package/src/token/index.ts +37 -0
  68. package/src/types.ts +13 -3
  69. package/lib/accounts/defaultHistoryAccountSubscriber.d.ts +0 -28
  70. package/lib/accounts/defaultHistoryAccountSubscriber.js +0 -110
  71. package/src/accounts/defaultHistoryAccountSubscriber.ts +0 -176
@@ -0,0 +1,326 @@
1
+ import {
2
+ AccountToPoll,
3
+ ClearingHouseAccountEvents,
4
+ ClearingHouseAccountSubscriber,
5
+ ClearingHouseAccountTypes,
6
+ NotSubscribedError,
7
+ } from './types';
8
+ import { Program } from '@project-serum/anchor';
9
+ import StrictEventEmitter from 'strict-event-emitter-types';
10
+ import { EventEmitter } from 'events';
11
+ import {
12
+ DepositHistoryAccount,
13
+ ExtendedCurveHistoryAccount,
14
+ FundingPaymentHistoryAccount,
15
+ FundingRateHistoryAccount,
16
+ LiquidationHistoryAccount,
17
+ MarketsAccount,
18
+ OrderHistoryAccount,
19
+ OrderStateAccount,
20
+ StateAccount,
21
+ TradeHistoryAccount,
22
+ } from '../types';
23
+ import { getClearingHouseStateAccountPublicKey } from '../addresses';
24
+ import { BulkAccountLoader } from './bulkAccountLoader';
25
+ import { capitalize } from './utils';
26
+ import { ClearingHouseConfigType } from '../factory/clearingHouse';
27
+
28
+ export class PollingClearingHouseAccountSubscriber
29
+ implements ClearingHouseAccountSubscriber
30
+ {
31
+ isSubscribed: boolean;
32
+ program: Program;
33
+ eventEmitter: StrictEventEmitter<EventEmitter, ClearingHouseAccountEvents>;
34
+
35
+ accountLoader: BulkAccountLoader;
36
+ accountsToPoll = new Map<string, AccountToPoll>();
37
+ errorCallbackId?: string;
38
+
39
+ state?: StateAccount;
40
+ markets?: MarketsAccount;
41
+ orderState?: OrderStateAccount;
42
+ tradeHistory?: TradeHistoryAccount;
43
+ depositHistory?: DepositHistoryAccount;
44
+ fundingPaymentHistory?: FundingPaymentHistoryAccount;
45
+ fundingRateHistory?: FundingRateHistoryAccount;
46
+ liquidationHistory?: LiquidationHistoryAccount;
47
+ extendedCurveHistory: ExtendedCurveHistoryAccount;
48
+ orderHistory?: OrderHistoryAccount;
49
+
50
+ optionalExtraSubscriptions: ClearingHouseAccountTypes[] = [];
51
+
52
+ type: ClearingHouseConfigType = 'polling';
53
+
54
+ private isSubscribing = false;
55
+ private subscriptionPromise: Promise<boolean>;
56
+ private subscriptionPromiseResolver: (val: boolean) => void;
57
+
58
+ public constructor(program: Program, accountLoader: BulkAccountLoader) {
59
+ this.isSubscribed = false;
60
+ this.program = program;
61
+ this.eventEmitter = new EventEmitter();
62
+ this.accountLoader = accountLoader;
63
+ }
64
+
65
+ public async subscribe(
66
+ optionalSubscriptions?: ClearingHouseAccountTypes[]
67
+ ): Promise<boolean> {
68
+ if (this.isSubscribed) {
69
+ return true;
70
+ }
71
+
72
+ if (this.isSubscribing) {
73
+ return await this.subscriptionPromise;
74
+ }
75
+
76
+ this.optionalExtraSubscriptions = optionalSubscriptions;
77
+
78
+ this.isSubscribing = true;
79
+
80
+ this.subscriptionPromise = new Promise((res) => {
81
+ this.subscriptionPromiseResolver = res;
82
+ });
83
+
84
+ await this.updateAccountsToPoll();
85
+ await this.addToAccountLoader();
86
+ await this.fetch();
87
+ this.eventEmitter.emit('update');
88
+
89
+ this.isSubscribing = false;
90
+ this.isSubscribed = true;
91
+ this.subscriptionPromiseResolver(true);
92
+
93
+ return true;
94
+ }
95
+
96
+ async updateAccountsToPoll(): Promise<void> {
97
+ if (this.accountsToPoll.size > 0) {
98
+ return;
99
+ }
100
+
101
+ const statePublicKey = await getClearingHouseStateAccountPublicKey(
102
+ this.program.programId
103
+ );
104
+
105
+ const state = (await this.program.account.state.fetch(
106
+ statePublicKey
107
+ )) as StateAccount;
108
+
109
+ this.accountsToPoll.set(statePublicKey.toString(), {
110
+ key: 'state',
111
+ publicKey: statePublicKey,
112
+ eventType: 'stateAccountUpdate',
113
+ });
114
+
115
+ this.accountsToPoll.set(state.markets.toString(), {
116
+ key: 'markets',
117
+ publicKey: state.markets,
118
+ eventType: 'marketsAccountUpdate',
119
+ });
120
+
121
+ this.accountsToPoll.set(state.orderState.toString(), {
122
+ key: 'orderState',
123
+ publicKey: state.orderState,
124
+ eventType: 'orderStateAccountUpdate',
125
+ });
126
+
127
+ if (this.optionalExtraSubscriptions?.includes('tradeHistoryAccount')) {
128
+ this.accountsToPoll.set(state.tradeHistory.toString(), {
129
+ key: 'tradeHistory',
130
+ publicKey: state.tradeHistory,
131
+ eventType: 'tradeHistoryAccountUpdate',
132
+ });
133
+ }
134
+
135
+ if (this.optionalExtraSubscriptions?.includes('depositHistoryAccount')) {
136
+ this.accountsToPoll.set(state.depositHistory.toString(), {
137
+ key: 'depositHistory',
138
+ publicKey: state.depositHistory,
139
+ eventType: 'depositHistoryAccountUpdate',
140
+ });
141
+ }
142
+
143
+ if (
144
+ this.optionalExtraSubscriptions?.includes('fundingPaymentHistoryAccount')
145
+ ) {
146
+ this.accountsToPoll.set(state.fundingPaymentHistory.toString(), {
147
+ key: 'fundingPaymentHistory',
148
+ publicKey: state.fundingPaymentHistory,
149
+ eventType: 'fundingPaymentHistoryAccountUpdate',
150
+ });
151
+ }
152
+
153
+ if (
154
+ this.optionalExtraSubscriptions?.includes('fundingRateHistoryAccount')
155
+ ) {
156
+ this.accountsToPoll.set(state.fundingRateHistory.toString(), {
157
+ key: 'fundingRateHistory',
158
+ publicKey: state.fundingRateHistory,
159
+ eventType: 'fundingRateHistoryAccountUpdate',
160
+ });
161
+ }
162
+
163
+ if (this.optionalExtraSubscriptions?.includes('curveHistoryAccount')) {
164
+ this.accountsToPoll.set(state.extendedCurveHistory.toString(), {
165
+ key: 'extendedCurveHistory',
166
+ publicKey: state.extendedCurveHistory,
167
+ eventType: 'curveHistoryAccountUpdate',
168
+ });
169
+ }
170
+
171
+ if (
172
+ this.optionalExtraSubscriptions?.includes('liquidationHistoryAccount')
173
+ ) {
174
+ this.accountsToPoll.set(state.liquidationHistory.toString(), {
175
+ key: 'liquidationHistory',
176
+ publicKey: state.liquidationHistory,
177
+ eventType: 'liquidationHistoryAccountUpdate',
178
+ });
179
+ }
180
+
181
+ if (this.optionalExtraSubscriptions?.includes('orderHistoryAccount')) {
182
+ const orderState = (await this.program.account.orderState.fetch(
183
+ state.orderState
184
+ )) as OrderStateAccount;
185
+
186
+ this.accountsToPoll.set(orderState.orderHistory.toString(), {
187
+ key: 'orderHistory',
188
+ publicKey: orderState.orderHistory,
189
+ eventType: 'orderHistoryAccountUpdate',
190
+ });
191
+ }
192
+ }
193
+
194
+ async addToAccountLoader(): Promise<void> {
195
+ for (const [_, accountToPoll] of this.accountsToPoll) {
196
+ accountToPoll.callbackId = this.accountLoader.addAccount(
197
+ accountToPoll.publicKey,
198
+ (buffer) => {
199
+ const account = this.program.account[
200
+ accountToPoll.key
201
+ ].coder.accounts.decode(capitalize(accountToPoll.key), buffer);
202
+ this[accountToPoll.key] = account;
203
+ // @ts-ignore
204
+ this.eventEmitter.emit(accountToPoll.eventType, account);
205
+ this.eventEmitter.emit('update');
206
+ }
207
+ );
208
+ }
209
+
210
+ this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
211
+ this.eventEmitter.emit('error', error);
212
+ });
213
+ }
214
+
215
+ public async fetch(): Promise<void> {
216
+ await this.accountLoader.load();
217
+ for (const [_, accountToPoll] of this.accountsToPoll) {
218
+ const buffer = this.accountLoader.getAccountData(accountToPoll.publicKey);
219
+ if (buffer) {
220
+ this[accountToPoll.key] = this.program.account[
221
+ accountToPoll.key
222
+ ].coder.accounts.decode(capitalize(accountToPoll.key), buffer);
223
+ }
224
+ }
225
+ }
226
+
227
+ public async unsubscribe(): Promise<void> {
228
+ if (!this.isSubscribed) {
229
+ return;
230
+ }
231
+
232
+ for (const [_, accountToPoll] of this.accountsToPoll) {
233
+ this.accountLoader.removeAccount(
234
+ accountToPoll.publicKey,
235
+ accountToPoll.callbackId
236
+ );
237
+ }
238
+
239
+ this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
240
+ this.errorCallbackId = undefined;
241
+
242
+ this.accountsToPoll.clear();
243
+ this.isSubscribed = false;
244
+ }
245
+
246
+ assertIsSubscribed(): void {
247
+ if (!this.isSubscribed) {
248
+ throw new NotSubscribedError(
249
+ 'You must call `subscribe` before using this function'
250
+ );
251
+ }
252
+ }
253
+
254
+ assertOptionalIsSubscribed(
255
+ optionalSubscription: ClearingHouseAccountTypes
256
+ ): void {
257
+ if (!this.isSubscribed) {
258
+ throw new NotSubscribedError(
259
+ 'You must call `subscribe` before using this function'
260
+ );
261
+ }
262
+
263
+ if (!this.optionalExtraSubscriptions.includes(optionalSubscription)) {
264
+ throw new NotSubscribedError(
265
+ `You need to subscribe to the optional Clearing House account "${optionalSubscription}" to use this method`
266
+ );
267
+ }
268
+ }
269
+
270
+ public getStateAccount(): StateAccount {
271
+ this.assertIsSubscribed();
272
+ return this.state;
273
+ }
274
+
275
+ public getMarketsAccount(): MarketsAccount {
276
+ this.assertIsSubscribed();
277
+ return this.markets;
278
+ }
279
+
280
+ public getOrderStateAccount(): OrderStateAccount {
281
+ this.assertIsSubscribed();
282
+ return this.orderState;
283
+ }
284
+
285
+ public getTradeHistoryAccount(): TradeHistoryAccount {
286
+ this.assertIsSubscribed();
287
+ this.assertOptionalIsSubscribed('tradeHistoryAccount');
288
+ return this.tradeHistory;
289
+ }
290
+
291
+ public getDepositHistoryAccount(): DepositHistoryAccount {
292
+ this.assertIsSubscribed();
293
+ this.assertOptionalIsSubscribed('depositHistoryAccount');
294
+ return this.depositHistory;
295
+ }
296
+
297
+ public getFundingPaymentHistoryAccount(): FundingPaymentHistoryAccount {
298
+ this.assertIsSubscribed();
299
+ this.assertOptionalIsSubscribed('fundingPaymentHistoryAccount');
300
+ return this.fundingPaymentHistory;
301
+ }
302
+
303
+ public getFundingRateHistoryAccount(): FundingRateHistoryAccount {
304
+ this.assertIsSubscribed();
305
+ this.assertOptionalIsSubscribed('fundingRateHistoryAccount');
306
+ return this.fundingRateHistory;
307
+ }
308
+
309
+ public getCurveHistoryAccount(): ExtendedCurveHistoryAccount {
310
+ this.assertIsSubscribed();
311
+ this.assertOptionalIsSubscribed('curveHistoryAccount');
312
+ return this.extendedCurveHistory;
313
+ }
314
+
315
+ public getLiquidationHistoryAccount(): LiquidationHistoryAccount {
316
+ this.assertIsSubscribed();
317
+ this.assertOptionalIsSubscribed('liquidationHistoryAccount');
318
+ return this.liquidationHistory;
319
+ }
320
+
321
+ public getOrderHistoryAccount(): OrderHistoryAccount {
322
+ this.assertIsSubscribed();
323
+ this.assertOptionalIsSubscribed('orderHistoryAccount');
324
+ return this.orderHistory;
325
+ }
326
+ }
@@ -0,0 +1,99 @@
1
+ import {
2
+ NotSubscribedError,
3
+ TokenAccountEvents,
4
+ TokenAccountSubscriber,
5
+ } from './types';
6
+ import { Program } from '@project-serum/anchor';
7
+ import StrictEventEmitter from 'strict-event-emitter-types';
8
+ import { EventEmitter } from 'events';
9
+ import { PublicKey } from '@solana/web3.js';
10
+ import { BulkAccountLoader } from './bulkAccountLoader';
11
+ import { AccountInfo } from '@solana/spl-token';
12
+ import { parseTokenAccount } from '../token';
13
+
14
+ export class PollingTokenAccountSubscriber implements TokenAccountSubscriber {
15
+ isSubscribed: boolean;
16
+ program: Program;
17
+ eventEmitter: StrictEventEmitter<EventEmitter, TokenAccountEvents>;
18
+ publicKey: PublicKey;
19
+
20
+ accountLoader: BulkAccountLoader;
21
+ callbackId?: string;
22
+ errorCallbackId?: string;
23
+
24
+ tokenAccount?: AccountInfo;
25
+
26
+ public constructor(publicKey: PublicKey, accountLoader: BulkAccountLoader) {
27
+ this.isSubscribed = false;
28
+ this.publicKey = publicKey;
29
+ this.accountLoader = accountLoader;
30
+ this.eventEmitter = new EventEmitter();
31
+ }
32
+
33
+ async subscribe(): Promise<boolean> {
34
+ if (this.isSubscribed) {
35
+ return true;
36
+ }
37
+
38
+ this.addToAccountLoader();
39
+ await this.fetch();
40
+ this.eventEmitter.emit('update');
41
+
42
+ this.isSubscribed = true;
43
+ return true;
44
+ }
45
+
46
+ addToAccountLoader(): void {
47
+ if (this.callbackId) {
48
+ return;
49
+ }
50
+
51
+ this.callbackId = this.accountLoader.addAccount(
52
+ this.publicKey,
53
+ (buffer) => {
54
+ const tokenAccount = parseTokenAccount(buffer);
55
+ this.tokenAccount = tokenAccount;
56
+ // @ts-ignore
57
+ this.eventEmitter.emit('tokenAccountUpdate', tokenAccount);
58
+ this.eventEmitter.emit('update');
59
+ }
60
+ );
61
+
62
+ this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
63
+ this.eventEmitter.emit('error', error);
64
+ });
65
+ }
66
+
67
+ async fetch(): Promise<void> {
68
+ await this.accountLoader.load();
69
+ const buffer = this.accountLoader.getAccountData(this.publicKey);
70
+ this.tokenAccount = parseTokenAccount(buffer);
71
+ }
72
+
73
+ async unsubscribe(): Promise<void> {
74
+ if (!this.isSubscribed) {
75
+ return;
76
+ }
77
+
78
+ this.accountLoader.removeAccount(this.publicKey, this.callbackId);
79
+ this.callbackId = undefined;
80
+
81
+ this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
82
+ this.errorCallbackId = undefined;
83
+
84
+ this.isSubscribed = false;
85
+ }
86
+
87
+ assertIsSubscribed(): void {
88
+ if (!this.isSubscribed) {
89
+ throw new NotSubscribedError(
90
+ 'You must call `subscribe` before using this function'
91
+ );
92
+ }
93
+ }
94
+
95
+ public getTokenAccount(): AccountInfo {
96
+ this.assertIsSubscribed();
97
+ return this.tokenAccount;
98
+ }
99
+ }
@@ -0,0 +1,186 @@
1
+ import {
2
+ AccountToPoll,
3
+ NotSubscribedError,
4
+ UserAccountEvents,
5
+ UserAccountSubscriber,
6
+ } from './types';
7
+ import { Program } from '@project-serum/anchor';
8
+ import StrictEventEmitter from 'strict-event-emitter-types';
9
+ import { EventEmitter } from 'events';
10
+ import { PublicKey } from '@solana/web3.js';
11
+ import {
12
+ getUserAccountPublicKey,
13
+ getUserOrdersAccountPublicKey,
14
+ } from '../addresses';
15
+ import { UserAccount, UserOrdersAccount, UserPositionsAccount } from '../types';
16
+ import { BulkAccountLoader } from './bulkAccountLoader';
17
+ import { capitalize } from './utils';
18
+ import { ClearingHouseConfigType } from '../factory/clearingHouse';
19
+
20
+ export class PollingUserAccountSubscriber implements UserAccountSubscriber {
21
+ isSubscribed: boolean;
22
+ program: Program;
23
+ eventEmitter: StrictEventEmitter<EventEmitter, UserAccountEvents>;
24
+ authority: PublicKey;
25
+
26
+ accountLoader: BulkAccountLoader;
27
+ accountsToPoll = new Map<string, AccountToPoll>();
28
+ errorCallbackId?: string;
29
+
30
+ user?: UserAccount;
31
+ userPositions?: UserPositionsAccount;
32
+ userOrders?: UserOrdersAccount;
33
+
34
+ type: ClearingHouseConfigType = 'polling';
35
+
36
+ public constructor(
37
+ program: Program,
38
+ authority: PublicKey,
39
+ accountLoader: BulkAccountLoader
40
+ ) {
41
+ this.isSubscribed = false;
42
+ this.program = program;
43
+ this.authority = authority;
44
+ this.accountLoader = accountLoader;
45
+ this.eventEmitter = new EventEmitter();
46
+ }
47
+
48
+ async subscribe(): Promise<boolean> {
49
+ if (this.isSubscribed) {
50
+ return true;
51
+ }
52
+
53
+ await this.addToAccountLoader();
54
+ await this.fetchIfUnloaded();
55
+ this.eventEmitter.emit('update');
56
+
57
+ this.isSubscribed = true;
58
+ return true;
59
+ }
60
+
61
+ async addToAccountLoader(): Promise<void> {
62
+ if (this.accountsToPoll.size > 0) {
63
+ return;
64
+ }
65
+
66
+ const userPublicKey = await getUserAccountPublicKey(
67
+ this.program.programId,
68
+ this.authority
69
+ );
70
+
71
+ const userAccount = (await this.program.account.user.fetch(
72
+ userPublicKey
73
+ )) as UserAccount;
74
+
75
+ this.accountsToPoll.set(userPublicKey.toString(), {
76
+ key: 'user',
77
+ publicKey: userPublicKey,
78
+ eventType: 'userAccountData',
79
+ });
80
+
81
+ this.accountsToPoll.set(userAccount.positions.toString(), {
82
+ key: 'userPositions',
83
+ publicKey: userAccount.positions,
84
+ eventType: 'userPositionsData',
85
+ });
86
+
87
+ const userOrdersPublicKey = await getUserOrdersAccountPublicKey(
88
+ this.program.programId,
89
+ userPublicKey
90
+ );
91
+
92
+ this.accountsToPoll.set(userOrdersPublicKey.toString(), {
93
+ key: 'userOrders',
94
+ publicKey: userOrdersPublicKey,
95
+ eventType: 'userOrdersData',
96
+ });
97
+
98
+ for (const [_, accountToPoll] of this.accountsToPoll) {
99
+ accountToPoll.callbackId = this.accountLoader.addAccount(
100
+ accountToPoll.publicKey,
101
+ (buffer) => {
102
+ const account = this.program.account[
103
+ accountToPoll.key
104
+ ].coder.accounts.decode(capitalize(accountToPoll.key), buffer);
105
+ this[accountToPoll.key] = account;
106
+ // @ts-ignore
107
+ this.eventEmitter.emit(accountToPoll.eventType, account);
108
+ this.eventEmitter.emit('update');
109
+ }
110
+ );
111
+ }
112
+
113
+ this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
114
+ this.eventEmitter.emit('error', error);
115
+ });
116
+ }
117
+
118
+ async fetchIfUnloaded(): Promise<void> {
119
+ let shouldFetch = false;
120
+ for (const [_, accountToPoll] of this.accountsToPoll) {
121
+ if (this[accountToPoll.key] === undefined) {
122
+ shouldFetch = true;
123
+ break;
124
+ }
125
+ }
126
+
127
+ if (shouldFetch) {
128
+ await this.fetch();
129
+ }
130
+ }
131
+
132
+ async fetch(): Promise<void> {
133
+ await this.accountLoader.load();
134
+ for (const [_, accountToPoll] of this.accountsToPoll) {
135
+ const buffer = this.accountLoader.getAccountData(accountToPoll.publicKey);
136
+ if (buffer) {
137
+ this[accountToPoll.key] = this.program.account[
138
+ accountToPoll.key
139
+ ].coder.accounts.decode(capitalize(accountToPoll.key), buffer);
140
+ }
141
+ }
142
+ }
143
+
144
+ async unsubscribe(): Promise<void> {
145
+ if (!this.isSubscribed) {
146
+ return;
147
+ }
148
+
149
+ for (const [_, accountToPoll] of this.accountsToPoll) {
150
+ this.accountLoader.removeAccount(
151
+ accountToPoll.publicKey,
152
+ accountToPoll.callbackId
153
+ );
154
+ }
155
+
156
+ this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
157
+ this.errorCallbackId = undefined;
158
+
159
+ this.accountsToPoll.clear();
160
+
161
+ this.isSubscribed = false;
162
+ }
163
+
164
+ assertIsSubscribed(): void {
165
+ if (!this.isSubscribed) {
166
+ throw new NotSubscribedError(
167
+ 'You must call `subscribe` before using this function'
168
+ );
169
+ }
170
+ }
171
+
172
+ public getUserAccount(): UserAccount {
173
+ this.assertIsSubscribed();
174
+ return this.user;
175
+ }
176
+
177
+ public getUserPositionsAccount(): UserPositionsAccount {
178
+ this.assertIsSubscribed();
179
+ return this.userPositions;
180
+ }
181
+
182
+ public getUserOrdersAccount(): UserOrdersAccount {
183
+ this.assertIsSubscribed();
184
+ return this.userOrders;
185
+ }
186
+ }