@drift-labs/sdk 2.142.0-beta.2 → 2.142.0-beta.21

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 (41) hide show
  1. package/VERSION +1 -1
  2. package/lib/browser/accounts/grpcDriftClientAccountSubscriberV2.d.ts +52 -4
  3. package/lib/browser/accounts/grpcDriftClientAccountSubscriberV2.js +315 -38
  4. package/lib/browser/accounts/grpcMultiAccountSubscriber.d.ts +11 -4
  5. package/lib/browser/accounts/grpcMultiAccountSubscriber.js +124 -18
  6. package/lib/browser/adminClient.d.ts +2 -0
  7. package/lib/browser/adminClient.js +17 -0
  8. package/lib/browser/constants/spotMarkets.js +4 -4
  9. package/lib/browser/driftClient.d.ts +25 -2
  10. package/lib/browser/driftClient.js +27 -4
  11. package/lib/browser/events/types.d.ts +3 -3
  12. package/lib/browser/idl/drift.json +72 -0
  13. package/lib/browser/types.d.ts +22 -1
  14. package/lib/node/accounts/grpcDriftClientAccountSubscriberV2.d.ts +52 -4
  15. package/lib/node/accounts/grpcDriftClientAccountSubscriberV2.d.ts.map +1 -1
  16. package/lib/node/accounts/grpcDriftClientAccountSubscriberV2.js +315 -38
  17. package/lib/node/accounts/grpcMultiAccountSubscriber.d.ts +11 -4
  18. package/lib/node/accounts/grpcMultiAccountSubscriber.d.ts.map +1 -1
  19. package/lib/node/accounts/grpcMultiAccountSubscriber.js +124 -18
  20. package/lib/node/adminClient.d.ts +2 -0
  21. package/lib/node/adminClient.d.ts.map +1 -1
  22. package/lib/node/adminClient.js +17 -0
  23. package/lib/node/constants/spotMarkets.js +4 -4
  24. package/lib/node/driftClient.d.ts +25 -2
  25. package/lib/node/driftClient.d.ts.map +1 -1
  26. package/lib/node/driftClient.js +27 -4
  27. package/lib/node/events/types.d.ts +3 -3
  28. package/lib/node/events/types.d.ts.map +1 -1
  29. package/lib/node/idl/drift.json +72 -0
  30. package/lib/node/types.d.ts +22 -1
  31. package/lib/node/types.d.ts.map +1 -1
  32. package/package.json +8 -2
  33. package/scripts/client-test.ts +361 -75
  34. package/src/accounts/grpcDriftClientAccountSubscriberV2.ts +517 -77
  35. package/src/accounts/grpcMultiAccountSubscriber.ts +179 -32
  36. package/src/adminClient.ts +34 -0
  37. package/src/constants/spotMarkets.ts +4 -4
  38. package/src/driftClient.ts +32 -4
  39. package/src/events/types.ts +4 -2
  40. package/src/idl/drift.json +72 -0
  41. package/src/types.ts +25 -2
@@ -1,17 +1,116 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.grpcDriftClientAccountSubscriberV2 = void 0;
4
- const webSocketDriftClientAccountSubscriber_1 = require("./webSocketDriftClientAccountSubscriber");
4
+ const events_1 = require("events");
5
5
  const web3_js_1 = require("@solana/web3.js");
6
6
  const config_1 = require("../config");
7
7
  const pda_1 = require("../addresses/pda");
8
+ const types_1 = require("./types");
8
9
  const grpcAccountSubscriber_1 = require("./grpcAccountSubscriber");
9
10
  const grpcMultiAccountSubscriber_1 = require("./grpcMultiAccountSubscriber");
10
11
  const oracleId_1 = require("../oracles/oracleId");
11
- class grpcDriftClientAccountSubscriberV2 extends webSocketDriftClientAccountSubscriber_1.WebSocketDriftClientAccountSubscriber {
12
+ const oracleClientCache_1 = require("../oracles/oracleClientCache");
13
+ const utils_1 = require("./utils");
14
+ class grpcDriftClientAccountSubscriberV2 {
12
15
  constructor(grpcConfigs, program, perpMarketIndexes, spotMarketIndexes, oracleInfos, shouldFindAllMarketsAndOracles, delistedMarketSetting, resubOpts) {
13
- super(program, perpMarketIndexes, spotMarketIndexes, oracleInfos, shouldFindAllMarketsAndOracles, delistedMarketSetting, resubOpts);
16
+ this.perpMarketIndexToAccountPubkeyMap = new Map();
17
+ this.spotMarketIndexToAccountPubkeyMap = new Map();
18
+ this.perpOracleMap = new Map();
19
+ this.perpOracleStringMap = new Map();
20
+ this.spotOracleMap = new Map();
21
+ this.spotOracleStringMap = new Map();
22
+ this.oracleIdToOracleDataMap = new Map();
23
+ this.oracleClientCache = new oracleClientCache_1.OracleClientCache();
24
+ this.chunks = (array, size) => {
25
+ return new Array(Math.ceil(array.length / size))
26
+ .fill(null)
27
+ .map((_, index) => index * size)
28
+ .map((begin) => array.slice(begin, begin + size));
29
+ };
30
+ this.eventEmitter = new events_1.EventEmitter();
31
+ this.isSubscribed = false;
32
+ this.isSubscribing = false;
33
+ this.program = program;
34
+ this.perpMarketIndexes = perpMarketIndexes;
35
+ this.spotMarketIndexes = spotMarketIndexes;
36
+ this.shouldFindAllMarketsAndOracles = shouldFindAllMarketsAndOracles;
37
+ this.oracleInfos = oracleInfos;
38
+ this.initialPerpMarketAccountData = new Map();
39
+ this.initialSpotMarketAccountData = new Map();
40
+ this.initialOraclePriceData = new Map();
41
+ this.perpOracleMap = new Map();
42
+ this.perpOracleStringMap = new Map();
43
+ this.spotOracleMap = new Map();
44
+ this.spotOracleStringMap = new Map();
14
45
  this.grpcConfigs = grpcConfigs;
46
+ this.resubOpts = resubOpts;
47
+ this.delistedMarketSetting = delistedMarketSetting;
48
+ }
49
+ async setInitialData() {
50
+ const connection = this.program.provider.connection;
51
+ if (!this.initialPerpMarketAccountData ||
52
+ this.initialPerpMarketAccountData.size === 0) {
53
+ const perpMarketPublicKeys = this.perpMarketIndexes.map((marketIndex) => (0, pda_1.getPerpMarketPublicKeySync)(this.program.programId, marketIndex));
54
+ const perpMarketPublicKeysChunks = this.chunks(perpMarketPublicKeys, 75);
55
+ const perpMarketAccountInfos = (await Promise.all(perpMarketPublicKeysChunks.map((perpMarketPublicKeysChunk) => connection.getMultipleAccountsInfo(perpMarketPublicKeysChunk)))).flat();
56
+ this.initialPerpMarketAccountData = new Map(perpMarketAccountInfos
57
+ .filter((accountInfo) => !!accountInfo)
58
+ .map((accountInfo) => {
59
+ const perpMarket = this.program.coder.accounts.decode('PerpMarket', accountInfo.data);
60
+ return [perpMarket.marketIndex, perpMarket];
61
+ }));
62
+ }
63
+ if (!this.initialSpotMarketAccountData ||
64
+ this.initialSpotMarketAccountData.size === 0) {
65
+ const spotMarketPublicKeys = this.spotMarketIndexes.map((marketIndex) => (0, pda_1.getSpotMarketPublicKeySync)(this.program.programId, marketIndex));
66
+ const spotMarketPublicKeysChunks = this.chunks(spotMarketPublicKeys, 75);
67
+ const spotMarketAccountInfos = (await Promise.all(spotMarketPublicKeysChunks.map((spotMarketPublicKeysChunk) => connection.getMultipleAccountsInfo(spotMarketPublicKeysChunk)))).flat();
68
+ this.initialSpotMarketAccountData = new Map(spotMarketAccountInfos
69
+ .filter((accountInfo) => !!accountInfo)
70
+ .map((accountInfo) => {
71
+ const spotMarket = this.program.coder.accounts.decode('SpotMarket', accountInfo.data);
72
+ return [spotMarket.marketIndex, spotMarket];
73
+ }));
74
+ }
75
+ const oracleAccountPubkeyChunks = this.chunks(this.oracleInfos.map((oracleInfo) => oracleInfo.publicKey), 75);
76
+ const oracleAccountInfos = (await Promise.all(oracleAccountPubkeyChunks.map((oracleAccountPublicKeysChunk) => connection.getMultipleAccountsInfo(oracleAccountPublicKeysChunk)))).flat();
77
+ this.initialOraclePriceData = new Map(this.oracleInfos.reduce((result, oracleInfo, i) => {
78
+ if (!oracleAccountInfos[i]) {
79
+ return result;
80
+ }
81
+ const oracleClient = this.oracleClientCache.get(oracleInfo.source, connection, this.program);
82
+ const oraclePriceData = oracleClient.getOraclePriceDataFromBuffer(oracleAccountInfos[i].data);
83
+ result.push([
84
+ (0, oracleId_1.getOracleId)(oracleInfo.publicKey, oracleInfo.source),
85
+ oraclePriceData,
86
+ ]);
87
+ return result;
88
+ }, []));
89
+ }
90
+ async addPerpMarket(_marketIndex) {
91
+ if (!this.perpMarketIndexes.includes(_marketIndex)) {
92
+ this.perpMarketIndexes = this.perpMarketIndexes.concat(_marketIndex);
93
+ }
94
+ return true;
95
+ }
96
+ async addSpotMarket(_marketIndex) {
97
+ return true;
98
+ }
99
+ async addOracle(oracleInfo) {
100
+ var _a, _c;
101
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
102
+ console.log('[grpcDriftClientAccountSubscriberV2] addOracle');
103
+ }
104
+ if (oracleInfo.publicKey.equals(web3_js_1.PublicKey.default)) {
105
+ return true;
106
+ }
107
+ const exists = this.oracleInfos.some((o) => o.source === oracleInfo.source &&
108
+ o.publicKey.equals(oracleInfo.publicKey));
109
+ if (!exists) {
110
+ this.oracleInfos = this.oracleInfos.concat(oracleInfo);
111
+ }
112
+ (_c = this.oracleMultiSubscriber) === null || _c === void 0 ? void 0 : _c.addAccounts([oracleInfo.publicKey]);
113
+ return true;
15
114
  }
16
115
  async subscribe() {
17
116
  if (this.isSubscribed) {
@@ -59,8 +158,133 @@ class grpcDriftClientAccountSubscriberV2 extends webSocketDriftClientAccountSubs
59
158
  this.removeInitialData();
60
159
  return true;
61
160
  }
161
+ async fetch() {
162
+ var _a, _c, _d, _e;
163
+ await ((_a = this.stateAccountSubscriber) === null || _a === void 0 ? void 0 : _a.fetch());
164
+ await ((_c = this.perpMarketsSubscriber) === null || _c === void 0 ? void 0 : _c.fetch());
165
+ await ((_d = this.spotMarketsSubscriber) === null || _d === void 0 ? void 0 : _d.fetch());
166
+ await ((_e = this.oracleMultiSubscriber) === null || _e === void 0 ? void 0 : _e.fetch());
167
+ }
168
+ assertIsSubscribed() {
169
+ if (!this.isSubscribed) {
170
+ throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
171
+ }
172
+ }
173
+ getStateAccountAndSlot() {
174
+ this.assertIsSubscribed();
175
+ return this.stateAccountSubscriber.dataAndSlot;
176
+ }
177
+ getMarketAccountsAndSlots() {
178
+ var _a, _c;
179
+ const map = (_a = this.perpMarketsSubscriber) === null || _a === void 0 ? void 0 : _a.getAccountDataMap();
180
+ return Array.from((_c = map === null || map === void 0 ? void 0 : map.values()) !== null && _c !== void 0 ? _c : []);
181
+ }
182
+ getSpotMarketAccountsAndSlots() {
183
+ var _a, _c;
184
+ const map = (_a = this.spotMarketsSubscriber) === null || _a === void 0 ? void 0 : _a.getAccountDataMap();
185
+ return Array.from((_c = map === null || map === void 0 ? void 0 : map.values()) !== null && _c !== void 0 ? _c : []);
186
+ }
187
+ getMarketAccountAndSlot(marketIndex) {
188
+ var _a;
189
+ return (_a = this.perpMarketsSubscriber) === null || _a === void 0 ? void 0 : _a.getAccountData(this.perpMarketIndexToAccountPubkeyMap.get(marketIndex));
190
+ }
191
+ getSpotMarketAccountAndSlot(marketIndex) {
192
+ var _a;
193
+ return (_a = this.spotMarketsSubscriber) === null || _a === void 0 ? void 0 : _a.getAccountData(this.spotMarketIndexToAccountPubkeyMap.get(marketIndex));
194
+ }
195
+ getOraclePriceDataAndSlot(oracleId) {
196
+ this.assertIsSubscribed();
197
+ // we need to rely on a map we store in this class because the grpcMultiAccountSubscriber does not track a mapping or oracle ID.
198
+ // DO NOT call getAccountData on the oracleMultiSubscriber, it will not return the correct data in certain cases(BONK spot and perp market subscribed too at once).
199
+ return this.oracleIdToOracleDataMap.get(oracleId);
200
+ }
201
+ getOraclePriceDataAndSlotForPerpMarket(marketIndex) {
202
+ const perpMarketAccount = this.getMarketAccountAndSlot(marketIndex);
203
+ const oracle = this.perpOracleMap.get(marketIndex);
204
+ const oracleId = this.perpOracleStringMap.get(marketIndex);
205
+ if (!perpMarketAccount || !oracleId) {
206
+ return undefined;
207
+ }
208
+ if (!perpMarketAccount.data.amm.oracle.equals(oracle)) {
209
+ // If the oracle has changed, we need to update the oracle map in background
210
+ this.setPerpOracleMap();
211
+ }
212
+ return this.getOraclePriceDataAndSlot(oracleId);
213
+ }
214
+ getOraclePriceDataAndSlotForSpotMarket(marketIndex) {
215
+ const spotMarketAccount = this.getSpotMarketAccountAndSlot(marketIndex);
216
+ const oracle = this.spotOracleMap.get(marketIndex);
217
+ const oracleId = this.spotOracleStringMap.get(marketIndex);
218
+ if (!spotMarketAccount || !oracleId) {
219
+ return undefined;
220
+ }
221
+ if (!spotMarketAccount.data.oracle.equals(oracle)) {
222
+ // If the oracle has changed, we need to update the oracle map in background
223
+ this.setSpotOracleMap();
224
+ }
225
+ return this.getOraclePriceDataAndSlot(oracleId);
226
+ }
227
+ async setPerpOracleMap() {
228
+ var _a, _c;
229
+ const perpMarketsMap = (_a = this.perpMarketsSubscriber) === null || _a === void 0 ? void 0 : _a.getAccountDataMap();
230
+ const perpMarkets = Array.from(perpMarketsMap.values());
231
+ const addOraclePromises = [];
232
+ for (const perpMarket of perpMarkets) {
233
+ if (!perpMarket || !perpMarket.data) {
234
+ continue;
235
+ }
236
+ const perpMarketAccount = perpMarket.data;
237
+ const perpMarketIndex = perpMarketAccount.marketIndex;
238
+ const oracle = perpMarketAccount.amm.oracle;
239
+ const oracleId = (0, oracleId_1.getOracleId)(oracle, perpMarket.data.amm.oracleSource);
240
+ if (!((_c = this.oracleMultiSubscriber) === null || _c === void 0 ? void 0 : _c.getAccountDataMap().has(oracleId))) {
241
+ addOraclePromises.push(this.addOracle({
242
+ publicKey: oracle,
243
+ source: perpMarket.data.amm.oracleSource,
244
+ }));
245
+ }
246
+ this.perpOracleMap.set(perpMarketIndex, oracle);
247
+ this.perpOracleStringMap.set(perpMarketIndex, oracleId);
248
+ }
249
+ await Promise.all(addOraclePromises);
250
+ }
251
+ async setSpotOracleMap() {
252
+ var _a, _c;
253
+ const spotMarketsMap = (_a = this.spotMarketsSubscriber) === null || _a === void 0 ? void 0 : _a.getAccountDataMap();
254
+ const spotMarkets = Array.from(spotMarketsMap.values());
255
+ const addOraclePromises = [];
256
+ for (const spotMarket of spotMarkets) {
257
+ if (!spotMarket || !spotMarket.data) {
258
+ continue;
259
+ }
260
+ const spotMarketAccount = spotMarket.data;
261
+ const spotMarketIndex = spotMarketAccount.marketIndex;
262
+ const oracle = spotMarketAccount.oracle;
263
+ const oracleId = (0, oracleId_1.getOracleId)(oracle, spotMarketAccount.oracleSource);
264
+ if (!((_c = this.oracleMultiSubscriber) === null || _c === void 0 ? void 0 : _c.getAccountDataMap().has(oracleId))) {
265
+ addOraclePromises.push(this.addOracle({
266
+ publicKey: oracle,
267
+ source: spotMarketAccount.oracleSource,
268
+ }));
269
+ }
270
+ this.spotOracleMap.set(spotMarketIndex, oracle);
271
+ this.spotOracleStringMap.set(spotMarketIndex, oracleId);
272
+ }
273
+ await Promise.all(addOraclePromises);
274
+ }
62
275
  async subscribeToPerpMarketAccounts() {
63
- const perpMarketPubkeys = await Promise.all(this.perpMarketIndexes.map((marketIndex) => (0, pda_1.getPerpMarketPublicKey)(this.program.programId, marketIndex)));
276
+ var _a;
277
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
278
+ console.log('[grpcDriftClientAccountSubscriberV2] subscribeToPerpMarketAccounts');
279
+ }
280
+ const perpMarketIndexToAccountPubkeys = await Promise.all(this.perpMarketIndexes.map(async (marketIndex) => [
281
+ marketIndex,
282
+ await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, marketIndex),
283
+ ]));
284
+ for (const [marketIndex, accountPubkey,] of perpMarketIndexToAccountPubkeys) {
285
+ this.perpMarketIndexToAccountPubkeyMap.set(marketIndex, accountPubkey.toBase58());
286
+ }
287
+ const perpMarketPubkeys = perpMarketIndexToAccountPubkeys.map(([_, accountPubkey]) => accountPubkey);
64
288
  this.perpMarketsSubscriber =
65
289
  await grpcMultiAccountSubscriber_1.grpcMultiAccountSubscriber.create(this.grpcConfigs, 'perpMarket', this.program, undefined, this.resubOpts, undefined, async () => {
66
290
  var _a;
@@ -74,6 +298,9 @@ class grpcDriftClientAccountSubscriberV2 extends webSocketDriftClientAccountSubs
74
298
  console.error('Perp markets resubscribe failed:', e);
75
299
  }
76
300
  });
301
+ for (const data of this.initialPerpMarketAccountData.values()) {
302
+ this.perpMarketsSubscriber.setAccountData(data.pubkey.toBase58(), data);
303
+ }
77
304
  await this.perpMarketsSubscriber.subscribe(perpMarketPubkeys, (_accountId, data) => {
78
305
  this.eventEmitter.emit('perpMarketAccountUpdate', data);
79
306
  this.eventEmitter.emit('update');
@@ -81,7 +308,18 @@ class grpcDriftClientAccountSubscriberV2 extends webSocketDriftClientAccountSubs
81
308
  return true;
82
309
  }
83
310
  async subscribeToSpotMarketAccounts() {
84
- const spotMarketPubkeys = await Promise.all(this.spotMarketIndexes.map((marketIndex) => (0, pda_1.getSpotMarketPublicKey)(this.program.programId, marketIndex)));
311
+ var _a;
312
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
313
+ console.log('[grpcDriftClientAccountSubscriberV2] subscribeToSpotMarketAccounts');
314
+ }
315
+ const spotMarketIndexToAccountPubkeys = await Promise.all(this.spotMarketIndexes.map(async (marketIndex) => [
316
+ marketIndex,
317
+ await (0, pda_1.getSpotMarketPublicKey)(this.program.programId, marketIndex),
318
+ ]));
319
+ for (const [marketIndex, accountPubkey,] of spotMarketIndexToAccountPubkeys) {
320
+ this.spotMarketIndexToAccountPubkeyMap.set(marketIndex, accountPubkey.toBase58());
321
+ }
322
+ const spotMarketPubkeys = spotMarketIndexToAccountPubkeys.map(([_, accountPubkey]) => accountPubkey);
85
323
  this.spotMarketsSubscriber =
86
324
  await grpcMultiAccountSubscriber_1.grpcMultiAccountSubscriber.create(this.grpcConfigs, 'spotMarket', this.program, undefined, this.resubOpts, undefined, async () => {
87
325
  var _a;
@@ -95,6 +333,9 @@ class grpcDriftClientAccountSubscriberV2 extends webSocketDriftClientAccountSubs
95
333
  console.error('Spot markets resubscribe failed:', e);
96
334
  }
97
335
  });
336
+ for (const data of this.initialSpotMarketAccountData.values()) {
337
+ this.spotMarketsSubscriber.setAccountData(data.pubkey.toBase58(), data);
338
+ }
98
339
  await this.spotMarketsSubscriber.subscribe(spotMarketPubkeys, (_accountId, data) => {
99
340
  this.eventEmitter.emit('spotMarketAccountUpdate', data);
100
341
  this.eventEmitter.emit('update');
@@ -102,60 +343,96 @@ class grpcDriftClientAccountSubscriberV2 extends webSocketDriftClientAccountSubs
102
343
  return true;
103
344
  }
104
345
  async subscribeToOracles() {
105
- // Build list of unique oracle pubkeys and a lookup for sources
106
- const uniqueOraclePubkeys = new Map();
346
+ var _a;
347
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
348
+ console.log('grpcDriftClientAccountSubscriberV2 subscribeToOracles');
349
+ }
350
+ const oraclePubkeyToInfosMap = new Map();
107
351
  for (const info of this.oracleInfos) {
108
- const id = (0, oracleId_1.getOracleId)(info.publicKey, info.source);
109
- if (!uniqueOraclePubkeys.has(id) &&
110
- !info.publicKey.equals(web3_js_1.PublicKey.default)) {
111
- uniqueOraclePubkeys.set(id, info);
352
+ const pubkey = info.publicKey.toBase58();
353
+ if (!oraclePubkeyToInfosMap.has(pubkey)) {
354
+ oraclePubkeyToInfosMap.set(pubkey, []);
112
355
  }
356
+ oraclePubkeyToInfosMap.get(pubkey).push(info);
113
357
  }
114
- const oraclePubkeys = Array.from(uniqueOraclePubkeys.values()).map((i) => i.publicKey);
115
- const pubkeyToSource = new Map(Array.from(uniqueOraclePubkeys.values()).map((i) => [
116
- i.publicKey.toBase58(),
117
- i.source,
118
- ]));
119
- this.oracleMultiSubscriber =
120
- await grpcMultiAccountSubscriber_1.grpcMultiAccountSubscriber.create(this.grpcConfigs, 'oracle', this.program, (buffer, pubkey) => {
121
- if (!pubkey) {
122
- throw new Error('Oracle pubkey missing in decode');
123
- }
124
- const source = pubkeyToSource.get(pubkey);
125
- const client = this.oracleClientCache.get(source, this.program.provider.connection, this.program);
126
- return client.getOraclePriceDataFromBuffer(buffer);
127
- }, this.resubOpts, undefined, async () => {
128
- var _a;
129
- try {
130
- if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
131
- console.log('[grpcDriftClientAccountSubscriberV2] oracle subscriber unsubscribed; resubscribing');
132
- }
133
- await this.subscribeToOracles();
134
- }
135
- catch (e) {
136
- console.error('Oracle resubscribe failed:', e);
358
+ const oraclePubkeys = Array.from(new Set(this.oracleInfos.map((info) => info.publicKey)));
359
+ this.oracleMultiSubscriber = await grpcMultiAccountSubscriber_1.grpcMultiAccountSubscriber.create(this.grpcConfigs, 'oracle', this.program, (buffer, pubkey, accountProps) => {
360
+ if (!pubkey) {
361
+ throw new Error('Oracle pubkey missing in decode');
362
+ }
363
+ const client = this.oracleClientCache.get(accountProps.source, this.program.provider.connection, this.program);
364
+ const price = client.getOraclePriceDataFromBuffer(buffer);
365
+ return price;
366
+ }, this.resubOpts, undefined, async () => {
367
+ var _a;
368
+ try {
369
+ if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
370
+ console.log('[grpcDriftClientAccountSubscriberV2] oracle subscriber unsubscribed; resubscribing');
137
371
  }
372
+ await this.subscribeToOracles();
373
+ }
374
+ catch (e) {
375
+ console.error('Oracle resubscribe failed:', e);
376
+ }
377
+ }, oraclePubkeyToInfosMap);
378
+ for (const data of this.initialOraclePriceData.entries()) {
379
+ const { publicKey } = (0, oracleId_1.getPublicKeyAndSourceFromOracleId)(data[0]);
380
+ this.oracleMultiSubscriber.setAccountData(publicKey.toBase58(), data[1]);
381
+ this.oracleIdToOracleDataMap.set(data[0], {
382
+ data: data[1],
383
+ slot: 0,
138
384
  });
139
- await this.oracleMultiSubscriber.subscribe(oraclePubkeys, (accountId, data) => {
140
- const source = pubkeyToSource.get(accountId.toBase58());
141
- this.eventEmitter.emit('oraclePriceUpdate', accountId, source, data);
385
+ }
386
+ await this.oracleMultiSubscriber.subscribe(oraclePubkeys, (accountId, data, context, _b, accountProps) => {
387
+ const oracleId = (0, oracleId_1.getOracleId)(accountId, accountProps.source);
388
+ this.oracleIdToOracleDataMap.set(oracleId, {
389
+ data,
390
+ slot: context.slot,
391
+ });
392
+ this.eventEmitter.emit('oraclePriceUpdate', accountId, accountProps.source, data);
142
393
  this.eventEmitter.emit('update');
143
394
  });
144
395
  return true;
145
396
  }
397
+ async handleDelistedMarkets() {
398
+ var _a, _c;
399
+ if (this.delistedMarketSetting === types_1.DelistedMarketSetting.Subscribe) {
400
+ return;
401
+ }
402
+ const { perpMarketIndexes, oracles } = (0, utils_1.findDelistedPerpMarketsAndOracles)(Array.from(((_a = this.perpMarketsSubscriber) === null || _a === void 0 ? void 0 : _a.getAccountDataMap().values()) || []), Array.from(((_c = this.spotMarketsSubscriber) === null || _c === void 0 ? void 0 : _c.getAccountDataMap().values()) || []));
403
+ for (const perpMarketIndex of perpMarketIndexes) {
404
+ await this.perpMarketsSubscriber.removeAccounts([
405
+ new web3_js_1.PublicKey(this.perpMarketIndexToAccountPubkeyMap.get(perpMarketIndex) || ''),
406
+ ]);
407
+ if (this.delistedMarketSetting === types_1.DelistedMarketSetting.Discard) {
408
+ this.perpMarketIndexToAccountPubkeyMap.delete(perpMarketIndex);
409
+ }
410
+ }
411
+ for (const oracle of oracles) {
412
+ await this.oracleMultiSubscriber.removeAccounts([oracle.publicKey]);
413
+ }
414
+ }
415
+ removeInitialData() {
416
+ this.initialPerpMarketAccountData = new Map();
417
+ this.initialSpotMarketAccountData = new Map();
418
+ this.initialOraclePriceData = new Map();
419
+ }
146
420
  async unsubscribeFromOracles() {
147
421
  if (this.oracleMultiSubscriber) {
148
422
  await this.oracleMultiSubscriber.unsubscribe();
149
423
  this.oracleMultiSubscriber = undefined;
150
424
  return;
151
425
  }
152
- await super.unsubscribeFromOracles();
153
426
  }
154
427
  async unsubscribe() {
428
+ var _a, _c;
155
429
  if (this.isSubscribed) {
156
430
  return;
157
431
  }
158
432
  await this.stateAccountSubscriber.unsubscribe();
433
+ await this.unsubscribeFromOracles();
434
+ await ((_a = this.perpMarketsSubscriber) === null || _a === void 0 ? void 0 : _a.unsubscribe());
435
+ await ((_c = this.spotMarketsSubscriber) === null || _c === void 0 ? void 0 : _c.unsubscribe());
159
436
  }
160
437
  }
161
438
  exports.grpcDriftClientAccountSubscriberV2 = grpcDriftClientAccountSubscriberV2;
@@ -3,8 +3,8 @@
3
3
  import { Program } from '@coral-xyz/anchor';
4
4
  import { Context, PublicKey } from '@solana/web3.js';
5
5
  import { Client } from '../isomorphic/grpc';
6
- import { GrpcConfigs, ResubOpts } from './types';
7
- export declare class grpcMultiAccountSubscriber<T> {
6
+ import { DataAndSlot, GrpcConfigs, ResubOpts } from './types';
7
+ export declare class grpcMultiAccountSubscriber<T, U = undefined> {
8
8
  private client;
9
9
  private stream;
10
10
  private commitmentLevel;
@@ -19,9 +19,16 @@ export declare class grpcMultiAccountSubscriber<T> {
19
19
  private receivingData;
20
20
  private subscribedAccounts;
21
21
  private onChangeMap;
22
+ private dataMap;
23
+ private accountPropsMap;
24
+ private bufferMap;
22
25
  private constructor();
23
- static create<U>(grpcConfigs: GrpcConfigs, accountName: string, program: Program, decodeBuffer?: (buffer: Buffer, pubkey?: string) => U, resubOpts?: ResubOpts, clientProp?: Client, onUnsubscribe?: () => Promise<void>): Promise<grpcMultiAccountSubscriber<U>>;
24
- subscribe(accounts: PublicKey[], onChange: (accountId: PublicKey, data: T, context: Context, buffer: Buffer) => void): Promise<void>;
26
+ static create<T, U = undefined>(grpcConfigs: GrpcConfigs, accountName: string, program: Program, decodeBuffer?: (buffer: Buffer, pubkey?: string, accountProps?: U) => T, resubOpts?: ResubOpts, clientProp?: Client, onUnsubscribe?: () => Promise<void>, accountPropsMap?: Map<string, U | Array<U>>): Promise<grpcMultiAccountSubscriber<T, U>>;
27
+ setAccountData(accountPubkey: string, data: T, slot?: number): void;
28
+ getAccountData(accountPubkey: string): DataAndSlot<T> | undefined;
29
+ getAccountDataMap(): Map<string, DataAndSlot<T>>;
30
+ fetch(): Promise<void>;
31
+ subscribe(accounts: PublicKey[], onChange: (accountId: PublicKey, data: T, context: Context, buffer: Buffer, accountProps: U) => void): Promise<void>;
25
32
  addAccounts(accounts: PublicKey[]): Promise<void>;
26
33
  removeAccounts(accounts: PublicKey[]): Promise<void>;
27
34
  unsubscribe(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"grpcMultiAccountSubscriber.d.ts","sourceRoot":"","sources":["../../../src/accounts/grpcMultiAccountSubscriber.ts"],"names":[],"mappings":";;AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIrD,OAAO,EACN,MAAM,EAMN,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAUjD,qBAAa,0BAA0B,CAAC,CAAC;IACxC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAwD;IACtE,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,cAAc,CAAC,CAAyC;IAChE,OAAO,CAAC,SAAS,CAAC,CAAY;IAC9B,OAAO,CAAC,aAAa,CAAC,CAAsB;IAErC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,UAAS;IAC/B,OAAO,CAAC,SAAS,CAAC,CAAgC;IAClD,OAAO,CAAC,aAAa,CAAS;IAE9B,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,WAAW,CAGf;IAEJ,OAAO;WAkBa,MAAM,CAAC,CAAC,EAC3B,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,OAAO,EAChB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,CAAC,EACrD,SAAS,CAAC,EAAE,SAAS,EACrB,UAAU,CAAC,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GACjC,OAAO,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC;IAuBnC,SAAS,CACd,QAAQ,EAAE,SAAS,EAAE,EACrB,QAAQ,EAAE,CACT,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,KACV,IAAI,GACP,OAAO,CAAC,IAAI,CAAC;IA+FV,WAAW,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAiCjD,cAAc,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAmCpD,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IA4ClC,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,UAAU;CAIlB"}
1
+ {"version":3,"file":"grpcMultiAccountSubscriber.d.ts","sourceRoot":"","sources":["../../../src/accounts/grpcMultiAccountSubscriber.ts"],"names":[],"mappings":";;AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAc,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIjE,OAAO,EACN,MAAM,EAMN,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAiB,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAyB7E,qBAAa,0BAA0B,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS;IACvD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAwD;IACtE,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,cAAc,CAAC,CAIhB;IACP,OAAO,CAAC,SAAS,CAAC,CAAY;IAC9B,OAAO,CAAC,aAAa,CAAC,CAAsB;IAErC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,UAAS;IAC/B,OAAO,CAAC,SAAS,CAAC,CAAgC;IAClD,OAAO,CAAC,aAAa,CAAS;IAE9B,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,WAAW,CAGf;IAEJ,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,eAAe,CAAmC;IAC1D,OAAO,CAAC,SAAS,CAAoC;IAErD,OAAO;WAoBa,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,EAC1C,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,OAAO,EAChB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,CAAC,KAAK,CAAC,EACvE,SAAS,CAAC,EAAE,SAAS,EACrB,UAAU,CAAC,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EACnC,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,GACzC,OAAO,CAAC,0BAA0B,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAwB5C,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAInE,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,SAAS;IAIjE,iBAAiB,IAAI,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IAI1C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoEtB,SAAS,CACd,QAAQ,EAAE,SAAS,EAAE,EACrB,QAAQ,EAAE,CACT,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,CAAC,KACX,IAAI,GACP,OAAO,CAAC,IAAI,CAAC;IAsIV,WAAW,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAiCjD,cAAc,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAmCpD,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IA4ClC,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,UAAU;CAIlB"}