@drift-labs/sdk 2.95.0-beta.12 → 2.95.0-beta.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.95.0-beta.12
1
+ 2.95.0-beta.14
@@ -24,8 +24,10 @@ export declare class PollingDriftClientAccountSubscriber implements DriftClientA
24
24
  state?: DataAndSlot<StateAccount>;
25
25
  perpMarket: Map<number, DataAndSlot<PerpMarketAccount>>;
26
26
  perpOracleMap: Map<number, PublicKey>;
27
+ perpOracleStringMap: Map<number, string>;
27
28
  spotMarket: Map<number, DataAndSlot<SpotMarketAccount>>;
28
29
  spotOracleMap: Map<number, PublicKey>;
30
+ spotOracleStringMap: Map<number, string>;
29
31
  oracles: Map<string, DataAndSlot<OraclePriceData>>;
30
32
  user?: DataAndSlot<UserAccount>;
31
33
  private isSubscribing;
@@ -58,7 +60,7 @@ export declare class PollingDriftClientAccountSubscriber implements DriftClientA
58
60
  getMarketAccountsAndSlots(): DataAndSlot<PerpMarketAccount>[];
59
61
  getSpotMarketAccountAndSlot(marketIndex: number): DataAndSlot<SpotMarketAccount> | undefined;
60
62
  getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[];
61
- getOraclePriceDataAndSlot(oraclePublicKey: PublicKey): DataAndSlot<OraclePriceData> | undefined;
63
+ getOraclePriceDataAndSlot(oraclePublicKey: PublicKey | string): DataAndSlot<OraclePriceData> | undefined;
62
64
  getOraclePriceDataAndSlotForPerpMarket(marketIndex: number): DataAndSlot<OraclePriceData> | undefined;
63
65
  getOraclePriceDataAndSlotForSpotMarket(marketIndex: number): DataAndSlot<OraclePriceData> | undefined;
64
66
  updateAccountLoaderPollingFrequency(pollingFrequency: number): void;
@@ -9,6 +9,7 @@ const web3_js_1 = require("@solana/web3.js");
9
9
  const oracleClientCache_1 = require("../oracles/oracleClientCache");
10
10
  const quoteAssetOracleClient_1 = require("../oracles/quoteAssetOracleClient");
11
11
  const config_1 = require("../config");
12
+ const ORACLE_DEFAULT_KEY = web3_js_1.PublicKey.default.toBase58();
12
13
  class PollingDriftClientAccountSubscriber {
13
14
  constructor(program, accountLoader, perpMarketIndexes, spotMarketIndexes, oracleInfos, shouldFindAllMarketsAndOracles) {
14
15
  this.oracleClientCache = new oracleClientCache_1.OracleClientCache();
@@ -16,8 +17,10 @@ class PollingDriftClientAccountSubscriber {
16
17
  this.oraclesToPoll = new Map();
17
18
  this.perpMarket = new Map();
18
19
  this.perpOracleMap = new Map();
20
+ this.perpOracleStringMap = new Map();
19
21
  this.spotMarket = new Map();
20
22
  this.spotOracleMap = new Map();
23
+ this.spotOracleStringMap = new Map();
21
24
  this.oracles = new Map();
22
25
  this.isSubscribing = false;
23
26
  this.isSubscribed = false;
@@ -300,6 +303,7 @@ class PollingDriftClientAccountSubscriber {
300
303
  }));
301
304
  }
302
305
  this.perpOracleMap.set(perpMarketIndex, oracle);
306
+ this.perpOracleStringMap.set(perpMarketIndex, oracle.toBase58());
303
307
  }
304
308
  await Promise.all(oraclePromises);
305
309
  }
@@ -317,6 +321,7 @@ class PollingDriftClientAccountSubscriber {
317
321
  }));
318
322
  }
319
323
  this.spotOracleMap.set(spotMarketIndex, oracle);
324
+ this.spotOracleStringMap.set(spotMarketIndex, oracle.toBase58());
320
325
  }
321
326
  await Promise.all(oraclePromises);
322
327
  }
@@ -343,17 +348,21 @@ class PollingDriftClientAccountSubscriber {
343
348
  }
344
349
  getOraclePriceDataAndSlot(oraclePublicKey) {
345
350
  this.assertIsSubscribed();
346
- if (oraclePublicKey.equals(web3_js_1.PublicKey.default)) {
351
+ const oracleString = typeof oraclePublicKey === 'string'
352
+ ? oraclePublicKey
353
+ : oraclePublicKey.toBase58();
354
+ if (oracleString === ORACLE_DEFAULT_KEY) {
347
355
  return {
348
356
  data: quoteAssetOracleClient_1.QUOTE_ORACLE_PRICE_DATA,
349
357
  slot: 0,
350
358
  };
351
359
  }
352
- return this.oracles.get(oraclePublicKey.toString());
360
+ return this.oracles.get(oracleString);
353
361
  }
354
362
  getOraclePriceDataAndSlotForPerpMarket(marketIndex) {
355
363
  const perpMarketAccount = this.getMarketAccountAndSlot(marketIndex);
356
364
  const oracle = this.perpOracleMap.get(marketIndex);
365
+ const oracleString = this.perpOracleStringMap.get(marketIndex);
357
366
  if (!perpMarketAccount || !oracle) {
358
367
  return undefined;
359
368
  }
@@ -361,11 +370,12 @@ class PollingDriftClientAccountSubscriber {
361
370
  // If the oracle has changed, we need to update the oracle map in background
362
371
  this.setPerpOracleMap();
363
372
  }
364
- return this.getOraclePriceDataAndSlot(oracle);
373
+ return this.getOraclePriceDataAndSlot(oracleString);
365
374
  }
366
375
  getOraclePriceDataAndSlotForSpotMarket(marketIndex) {
367
376
  const spotMarketAccount = this.getSpotMarketAccountAndSlot(marketIndex);
368
377
  const oracle = this.spotOracleMap.get(marketIndex);
378
+ const oracleString = this.spotOracleStringMap.get(marketIndex);
369
379
  if (!spotMarketAccount || !oracle) {
370
380
  return undefined;
371
381
  }
@@ -373,7 +383,7 @@ class PollingDriftClientAccountSubscriber {
373
383
  // If the oracle has changed, we need to update the oracle map in background
374
384
  this.setSpotOracleMap();
375
385
  }
376
- return this.getOraclePriceDataAndSlot(oracle);
386
+ return this.getOraclePriceDataAndSlot(oracleString);
377
387
  }
378
388
  updateAccountLoaderPollingFrequency(pollingFrequency) {
379
389
  this.accountLoader.updatePollingFrequency(pollingFrequency);
@@ -45,7 +45,7 @@ export interface DriftClientAccountSubscriber {
45
45
  getMarketAccountsAndSlots(): DataAndSlot<PerpMarketAccount>[];
46
46
  getSpotMarketAccountAndSlot(marketIndex: number): DataAndSlot<SpotMarketAccount> | undefined;
47
47
  getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[];
48
- getOraclePriceDataAndSlot(oraclePublicKey: PublicKey): DataAndSlot<OraclePriceData> | undefined;
48
+ getOraclePriceDataAndSlot(oraclePublicKey: PublicKey | string): DataAndSlot<OraclePriceData> | undefined;
49
49
  getOraclePriceDataAndSlotForPerpMarket(marketIndex: number): DataAndSlot<OraclePriceData> | undefined;
50
50
  getOraclePriceDataAndSlotForSpotMarket(marketIndex: number): DataAndSlot<OraclePriceData> | undefined;
51
51
  updateAccountLoaderPollingFrequency?: (pollingFrequency: number) => void;
@@ -22,14 +22,21 @@ export declare class WebSocketDriftClientAccountSubscriber implements DriftClien
22
22
  stateAccountSubscriber?: AccountSubscriber<StateAccount>;
23
23
  perpMarketAccountSubscribers: Map<number, AccountSubscriber<PerpMarketAccount>>;
24
24
  perpOracleMap: Map<number, PublicKey>;
25
+ perpOracleStringMap: Map<number, string>;
25
26
  spotMarketAccountSubscribers: Map<number, AccountSubscriber<SpotMarketAccount>>;
26
27
  spotOracleMap: Map<number, PublicKey>;
28
+ spotOracleStringMap: Map<number, string>;
27
29
  oracleSubscribers: Map<string, AccountSubscriber<OraclePriceData>>;
30
+ initialPerpMarketAccountData: Map<number, PerpMarketAccount>;
31
+ initialSpotMarketAccountData: Map<number, SpotMarketAccount>;
32
+ initialOraclePriceData: Map<string, OraclePriceData>;
28
33
  private isSubscribing;
29
34
  private subscriptionPromise;
30
35
  private subscriptionPromiseResolver;
31
36
  constructor(program: Program, perpMarketIndexes: number[], spotMarketIndexes: number[], oracleInfos: OracleInfo[], shouldFindAllMarketsAndOracles: boolean, resubOpts?: ResubOpts, commitment?: Commitment);
32
37
  subscribe(): Promise<boolean>;
38
+ setInitialData(): Promise<void>;
39
+ removeInitialData(): void;
33
40
  subscribeToPerpMarketAccounts(): Promise<boolean>;
34
41
  subscribeToPerpMarketAccount(marketIndex: number): Promise<boolean>;
35
42
  subscribeToSpotMarketAccounts(): Promise<boolean>;
@@ -52,7 +59,7 @@ export declare class WebSocketDriftClientAccountSubscriber implements DriftClien
52
59
  getMarketAccountsAndSlots(): DataAndSlot<PerpMarketAccount>[];
53
60
  getSpotMarketAccountAndSlot(marketIndex: number): DataAndSlot<SpotMarketAccount> | undefined;
54
61
  getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[];
55
- getOraclePriceDataAndSlot(oraclePublicKey: PublicKey): DataAndSlot<OraclePriceData> | undefined;
62
+ getOraclePriceDataAndSlot(oraclePublicKey: PublicKey | string): DataAndSlot<OraclePriceData> | undefined;
56
63
  getOraclePriceDataAndSlotForPerpMarket(marketIndex: number): DataAndSlot<OraclePriceData> | undefined;
57
64
  getOraclePriceDataAndSlotForSpotMarket(marketIndex: number): DataAndSlot<OraclePriceData> | undefined;
58
65
  }
@@ -9,13 +9,16 @@ const web3_js_1 = require("@solana/web3.js");
9
9
  const oracleClientCache_1 = require("../oracles/oracleClientCache");
10
10
  const quoteAssetOracleClient_1 = require("../oracles/quoteAssetOracleClient");
11
11
  const config_1 = require("../config");
12
+ const ORACLE_DEFAULT_KEY = web3_js_1.PublicKey.default.toBase58();
12
13
  class WebSocketDriftClientAccountSubscriber {
13
14
  constructor(program, perpMarketIndexes, spotMarketIndexes, oracleInfos, shouldFindAllMarketsAndOracles, resubOpts, commitment) {
14
15
  this.oracleClientCache = new oracleClientCache_1.OracleClientCache();
15
16
  this.perpMarketAccountSubscribers = new Map();
16
17
  this.perpOracleMap = new Map();
18
+ this.perpOracleStringMap = new Map();
17
19
  this.spotMarketAccountSubscribers = new Map();
18
20
  this.spotOracleMap = new Map();
21
+ this.spotOracleStringMap = new Map();
19
22
  this.oracleSubscribers = new Map();
20
23
  this.isSubscribing = false;
21
24
  this.isSubscribed = false;
@@ -40,10 +43,13 @@ class WebSocketDriftClientAccountSubscriber {
40
43
  this.subscriptionPromiseResolver = res;
41
44
  });
42
45
  if (this.shouldFindAllMarketsAndOracles) {
43
- const { perpMarketIndexes, spotMarketIndexes, oracleInfos } = await (0, config_1.findAllMarketAndOracles)(this.program);
46
+ const { perpMarketIndexes, perpMarketAccounts, spotMarketIndexes, spotMarketAccounts, oracleInfos, } = await (0, config_1.findAllMarketAndOracles)(this.program);
44
47
  this.perpMarketIndexes = perpMarketIndexes;
45
48
  this.spotMarketIndexes = spotMarketIndexes;
46
49
  this.oracleInfos = oracleInfos;
50
+ // front run and set the initial data here to save extra gma call in set initial data
51
+ this.initialPerpMarketAccountData = new Map(perpMarketAccounts.map((market) => [market.marketIndex, market]));
52
+ this.initialSpotMarketAccountData = new Map(spotMarketAccounts.map((market) => [market.marketIndex, market]));
47
53
  }
48
54
  const statePublicKey = await (0, pda_1.getDriftStateAccountPublicKey)(this.program.programId);
49
55
  // create and activate main state account subscription
@@ -52,6 +58,8 @@ class WebSocketDriftClientAccountSubscriber {
52
58
  this.eventEmitter.emit('stateAccountUpdate', data);
53
59
  this.eventEmitter.emit('update');
54
60
  });
61
+ // set initial data to avoid spamming getAccountInfo calls in webSocketAccountSubscriber
62
+ await this.setInitialData();
55
63
  await Promise.all([
56
64
  // subscribe to market accounts
57
65
  this.subscribeToPerpMarketAccounts(),
@@ -65,8 +73,40 @@ class WebSocketDriftClientAccountSubscriber {
65
73
  this.isSubscribing = false;
66
74
  this.isSubscribed = true;
67
75
  this.subscriptionPromiseResolver(true);
76
+ // delete initial data
77
+ this.removeInitialData();
68
78
  return true;
69
79
  }
80
+ async setInitialData() {
81
+ const connection = this.program.provider.connection;
82
+ if (!this.initialPerpMarketAccountData) {
83
+ const perpMarketPublicKeys = this.perpMarketIndexes.map((marketIndex) => (0, pda_1.getPerpMarketPublicKeySync)(this.program.programId, marketIndex));
84
+ const perpMarketAccountInfos = await connection.getMultipleAccountsInfo(perpMarketPublicKeys);
85
+ this.initialPerpMarketAccountData = new Map(perpMarketAccountInfos.map((accountInfo) => {
86
+ const perpMarket = this.program.coder.accounts.decode('PerpMarket', accountInfo.data);
87
+ return [perpMarket.marketIndex, perpMarket];
88
+ }));
89
+ }
90
+ if (!this.initialSpotMarketAccountData) {
91
+ const spotMarketPublicKeys = this.spotMarketIndexes.map((marketIndex) => (0, pda_1.getSpotMarketPublicKeySync)(this.program.programId, marketIndex));
92
+ const spotMarketAccountInfos = await connection.getMultipleAccountsInfo(spotMarketPublicKeys);
93
+ this.initialSpotMarketAccountData = new Map(spotMarketAccountInfos.map((accountInfo) => {
94
+ const spotMarket = this.program.coder.accounts.decode('SpotMarket', accountInfo.data);
95
+ return [spotMarket.marketIndex, spotMarket];
96
+ }));
97
+ }
98
+ const oracleAccountInfos = await connection.getMultipleAccountsInfo(this.oracleInfos.map((oracleInfo) => oracleInfo.publicKey));
99
+ this.initialOraclePriceData = new Map(this.oracleInfos.map((oracleInfo, i) => {
100
+ const oracleClient = this.oracleClientCache.get(oracleInfo.source, connection, this.program);
101
+ const oraclePriceData = oracleClient.getOraclePriceDataFromBuffer(oracleAccountInfos[i].data);
102
+ return [oracleInfo.publicKey.toString(), oraclePriceData];
103
+ }));
104
+ }
105
+ removeInitialData() {
106
+ this.initialPerpMarketAccountData = new Map();
107
+ this.initialSpotMarketAccountData = new Map();
108
+ this.initialOraclePriceData = new Map();
109
+ }
70
110
  async subscribeToPerpMarketAccounts() {
71
111
  await Promise.all(this.perpMarketIndexes.map((marketIndex) => this.subscribeToPerpMarketAccount(marketIndex)));
72
112
  return true;
@@ -74,6 +114,7 @@ class WebSocketDriftClientAccountSubscriber {
74
114
  async subscribeToPerpMarketAccount(marketIndex) {
75
115
  const perpMarketPublicKey = await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, marketIndex);
76
116
  const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('perpMarket', this.program, perpMarketPublicKey, undefined, this.resubOpts, this.commitment);
117
+ accountSubscriber.setData(this.initialPerpMarketAccountData.get(marketIndex));
77
118
  await accountSubscriber.subscribe((data) => {
78
119
  this.eventEmitter.emit('perpMarketAccountUpdate', data);
79
120
  this.eventEmitter.emit('update');
@@ -88,6 +129,7 @@ class WebSocketDriftClientAccountSubscriber {
88
129
  async subscribeToSpotMarketAccount(marketIndex) {
89
130
  const marketPublicKey = await (0, pda_1.getSpotMarketPublicKey)(this.program.programId, marketIndex);
90
131
  const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('spotMarket', this.program, marketPublicKey, undefined, this.resubOpts, this.commitment);
132
+ accountSubscriber.setData(this.initialSpotMarketAccountData.get(marketIndex));
91
133
  await accountSubscriber.subscribe((data) => {
92
134
  this.eventEmitter.emit('spotMarketAccountUpdate', data);
93
135
  this.eventEmitter.emit('update');
@@ -102,15 +144,17 @@ class WebSocketDriftClientAccountSubscriber {
102
144
  return true;
103
145
  }
104
146
  async subscribeToOracle(oracleInfo) {
147
+ const oracleString = oracleInfo.publicKey.toString();
105
148
  const client = this.oracleClientCache.get(oracleInfo.source, this.program.provider.connection, this.program);
106
149
  const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('oracle', this.program, oracleInfo.publicKey, (buffer) => {
107
150
  return client.getOraclePriceDataFromBuffer(buffer);
108
151
  }, this.resubOpts, this.commitment);
152
+ accountSubscriber.setData(this.initialOraclePriceData.get(oracleString));
109
153
  await accountSubscriber.subscribe((data) => {
110
154
  this.eventEmitter.emit('oraclePriceUpdate', oracleInfo.publicKey, data);
111
155
  this.eventEmitter.emit('update');
112
156
  });
113
- this.oracleSubscribers.set(oracleInfo.publicKey.toString(), accountSubscriber);
157
+ this.oracleSubscribers.set(oracleString, accountSubscriber);
114
158
  return true;
115
159
  }
116
160
  async unsubscribeFromMarketAccounts() {
@@ -183,6 +227,7 @@ class WebSocketDriftClientAccountSubscriber {
183
227
  }));
184
228
  }
185
229
  this.perpOracleMap.set(perpMarketIndex, oracle);
230
+ this.perpOracleStringMap.set(perpMarketIndex, oracle.toBase58());
186
231
  }
187
232
  await Promise.all(addOraclePromises);
188
233
  }
@@ -203,6 +248,7 @@ class WebSocketDriftClientAccountSubscriber {
203
248
  }));
204
249
  }
205
250
  this.spotOracleMap.set(spotMarketIndex, oracle);
251
+ this.spotOracleStringMap.set(spotMarketIndex, oracle.toBase58());
206
252
  }
207
253
  await Promise.all(addOraclePromises);
208
254
  }
@@ -231,17 +277,21 @@ class WebSocketDriftClientAccountSubscriber {
231
277
  }
232
278
  getOraclePriceDataAndSlot(oraclePublicKey) {
233
279
  this.assertIsSubscribed();
234
- if (oraclePublicKey.equals(web3_js_1.PublicKey.default)) {
280
+ const oracleString = typeof oraclePublicKey === 'string'
281
+ ? oraclePublicKey
282
+ : oraclePublicKey.toBase58();
283
+ if (oracleString === ORACLE_DEFAULT_KEY) {
235
284
  return {
236
285
  data: quoteAssetOracleClient_1.QUOTE_ORACLE_PRICE_DATA,
237
286
  slot: 0,
238
287
  };
239
288
  }
240
- return this.oracleSubscribers.get(oraclePublicKey.toString()).dataAndSlot;
289
+ return this.oracleSubscribers.get(oracleString).dataAndSlot;
241
290
  }
242
291
  getOraclePriceDataAndSlotForPerpMarket(marketIndex) {
243
292
  const perpMarketAccount = this.getMarketAccountAndSlot(marketIndex);
244
293
  const oracle = this.perpOracleMap.get(marketIndex);
294
+ const oracleString = this.perpOracleStringMap.get(marketIndex);
245
295
  if (!perpMarketAccount || !oracle) {
246
296
  return undefined;
247
297
  }
@@ -249,11 +299,12 @@ class WebSocketDriftClientAccountSubscriber {
249
299
  // If the oracle has changed, we need to update the oracle map in background
250
300
  this.setPerpOracleMap();
251
301
  }
252
- return this.getOraclePriceDataAndSlot(oracle);
302
+ return this.getOraclePriceDataAndSlot(oracleString);
253
303
  }
254
304
  getOraclePriceDataAndSlotForSpotMarket(marketIndex) {
255
305
  const spotMarketAccount = this.getSpotMarketAccountAndSlot(marketIndex);
256
306
  const oracle = this.spotOracleMap.get(marketIndex);
307
+ const oracleString = this.spotOracleStringMap.get(marketIndex);
257
308
  if (!spotMarketAccount || !oracle) {
258
309
  return undefined;
259
310
  }
@@ -261,7 +312,7 @@ class WebSocketDriftClientAccountSubscriber {
261
312
  // If the oracle has changed, we need to update the oracle map in background
262
313
  this.setSpotOracleMap();
263
314
  }
264
- return this.getOraclePriceDataAndSlot(oracle);
315
+ return this.getOraclePriceDataAndSlot(oracleString);
265
316
  }
266
317
  }
267
318
  exports.WebSocketDriftClientAccountSubscriber = WebSocketDriftClientAccountSubscriber;
@@ -9,7 +9,9 @@ export declare function getUserAccountPublicKey(programId: PublicKey, authority:
9
9
  export declare function getUserAccountPublicKeySync(programId: PublicKey, authority: PublicKey, subAccountId?: number): PublicKey;
10
10
  export declare function getUserStatsAccountPublicKey(programId: PublicKey, authority: PublicKey): PublicKey;
11
11
  export declare function getPerpMarketPublicKey(programId: PublicKey, marketIndex: number): Promise<PublicKey>;
12
+ export declare function getPerpMarketPublicKeySync(programId: PublicKey, marketIndex: number): PublicKey;
12
13
  export declare function getSpotMarketPublicKey(programId: PublicKey, marketIndex: number): Promise<PublicKey>;
14
+ export declare function getSpotMarketPublicKeySync(programId: PublicKey, marketIndex: number): PublicKey;
13
15
  export declare function getSpotMarketVaultPublicKey(programId: PublicKey, marketIndex: number): Promise<PublicKey>;
14
16
  export declare function getInsuranceFundVaultPublicKey(programId: PublicKey, marketIndex: number): Promise<PublicKey>;
15
17
  export declare function getInsuranceFundStakeAccountPublicKey(programId: PublicKey, authority: PublicKey, marketIndex: number): PublicKey;
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.getTokenProgramForSpotMarket = exports.getPythPullOraclePublicKey = exports.getPrelaunchOraclePublicKey = exports.getProtocolIfSharesTransferConfigPublicKey = exports.getReferrerNamePublicKeySync = exports.getOpenbookV2FulfillmentConfigPublicKey = exports.getPhoenixFulfillmentConfigPublicKey = exports.getSerumFulfillmentConfigPublicKey = exports.getSerumSignerPublicKey = exports.getSerumOpenOrdersPublicKey = exports.getDriftSignerPublicKey = exports.getInsuranceFundStakeAccountPublicKey = exports.getInsuranceFundVaultPublicKey = exports.getSpotMarketVaultPublicKey = exports.getSpotMarketPublicKey = exports.getPerpMarketPublicKey = exports.getUserStatsAccountPublicKey = exports.getUserAccountPublicKeySync = exports.getUserAccountPublicKey = exports.getUserAccountPublicKeyAndNonce = exports.getDriftStateAccountPublicKey = exports.getDriftStateAccountPublicKeyAndNonce = void 0;
26
+ exports.getTokenProgramForSpotMarket = exports.getPythPullOraclePublicKey = exports.getPrelaunchOraclePublicKey = exports.getProtocolIfSharesTransferConfigPublicKey = exports.getReferrerNamePublicKeySync = exports.getOpenbookV2FulfillmentConfigPublicKey = exports.getPhoenixFulfillmentConfigPublicKey = exports.getSerumFulfillmentConfigPublicKey = exports.getSerumSignerPublicKey = exports.getSerumOpenOrdersPublicKey = exports.getDriftSignerPublicKey = exports.getInsuranceFundStakeAccountPublicKey = exports.getInsuranceFundVaultPublicKey = exports.getSpotMarketVaultPublicKey = exports.getSpotMarketPublicKeySync = exports.getSpotMarketPublicKey = exports.getPerpMarketPublicKeySync = exports.getPerpMarketPublicKey = exports.getUserStatsAccountPublicKey = exports.getUserAccountPublicKeySync = exports.getUserAccountPublicKey = exports.getUserAccountPublicKeyAndNonce = exports.getDriftStateAccountPublicKey = exports.getDriftStateAccountPublicKeyAndNonce = void 0;
27
27
  const web3_js_1 = require("@solana/web3.js");
28
28
  const anchor = __importStar(require("@coral-xyz/anchor"));
29
29
  const spl_token_1 = require("@solana/spl-token");
@@ -69,6 +69,13 @@ async function getPerpMarketPublicKey(programId, marketIndex) {
69
69
  ], programId))[0];
70
70
  }
71
71
  exports.getPerpMarketPublicKey = getPerpMarketPublicKey;
72
+ function getPerpMarketPublicKeySync(programId, marketIndex) {
73
+ return web3_js_1.PublicKey.findProgramAddressSync([
74
+ Buffer.from(anchor.utils.bytes.utf8.encode('perp_market')),
75
+ new anchor.BN(marketIndex).toArrayLike(Buffer, 'le', 2),
76
+ ], programId)[0];
77
+ }
78
+ exports.getPerpMarketPublicKeySync = getPerpMarketPublicKeySync;
72
79
  async function getSpotMarketPublicKey(programId, marketIndex) {
73
80
  return (await web3_js_1.PublicKey.findProgramAddress([
74
81
  Buffer.from(anchor.utils.bytes.utf8.encode('spot_market')),
@@ -76,6 +83,13 @@ async function getSpotMarketPublicKey(programId, marketIndex) {
76
83
  ], programId))[0];
77
84
  }
78
85
  exports.getSpotMarketPublicKey = getSpotMarketPublicKey;
86
+ function getSpotMarketPublicKeySync(programId, marketIndex) {
87
+ return web3_js_1.PublicKey.findProgramAddressSync([
88
+ Buffer.from(anchor.utils.bytes.utf8.encode('spot_market')),
89
+ new anchor.BN(marketIndex).toArrayLike(Buffer, 'le', 2),
90
+ ], programId)[0];
91
+ }
92
+ exports.getSpotMarketPublicKeySync = getSpotMarketPublicKeySync;
79
93
  async function getSpotMarketVaultPublicKey(programId, marketIndex) {
80
94
  return (await web3_js_1.PublicKey.findProgramAddress([
81
95
  Buffer.from(anchor.utils.bytes.utf8.encode('spot_market_vault')),
package/lib/config.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { PerpMarketAccount, SpotMarketAccount } from '.';
1
2
  import { PerpMarketConfig } from './constants/perpMarkets';
2
3
  import { SpotMarketConfig } from './constants/spotMarkets';
3
4
  import { OracleInfo } from './oracles/types';
@@ -44,7 +45,9 @@ export declare function getMarketsAndOraclesForSubscription(env: DriftEnv): {
44
45
  };
45
46
  export declare function findAllMarketAndOracles(program: Program): Promise<{
46
47
  perpMarketIndexes: number[];
48
+ perpMarketAccounts: PerpMarketAccount[];
47
49
  spotMarketIndexes: number[];
48
50
  oracleInfos: OracleInfo[];
51
+ spotMarketAccounts: SpotMarketAccount[];
49
52
  }>;
50
53
  export {};
package/lib/config.js CHANGED
@@ -106,7 +106,9 @@ async function findAllMarketAndOracles(program) {
106
106
  }
107
107
  return {
108
108
  perpMarketIndexes,
109
+ perpMarketAccounts: perpMarketProgramAccounts.map((account) => account.account),
109
110
  spotMarketIndexes,
111
+ spotMarketAccounts: spotMarketProgramAccounts.map((account) => account.account),
110
112
  oracleInfos: Array.from(oracleInfos.values()),
111
113
  };
112
114
  }
@@ -309,7 +309,7 @@ class DriftClient {
309
309
  return this.accountSubscriber.getSpotMarketAccountAndSlot(numericConstants_1.QUOTE_SPOT_MARKET_INDEX).data;
310
310
  }
311
311
  getOraclePriceDataAndSlot(oraclePublicKey) {
312
- return this.accountSubscriber.getOraclePriceDataAndSlot(oraclePublicKey);
312
+ return this.accountSubscriber.getOraclePriceDataAndSlot(oraclePublicKey.toBase58());
313
313
  }
314
314
  async getSerumV3FulfillmentConfig(serumMarket) {
315
315
  const address = await (0, pda_1.getSerumFulfillmentConfigPublicKey)(this.program.programId, serumMarket);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.95.0-beta.12",
3
+ "version": "2.95.0-beta.14",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -28,6 +28,8 @@ import { OracleClientCache } from '../oracles/oracleClientCache';
28
28
  import { QUOTE_ORACLE_PRICE_DATA } from '../oracles/quoteAssetOracleClient';
29
29
  import { findAllMarketAndOracles } from '../config';
30
30
 
31
+ const ORACLE_DEFAULT_KEY = PublicKey.default.toBase58();
32
+
31
33
  export class PollingDriftClientAccountSubscriber
32
34
  implements DriftClientAccountSubscriber
33
35
  {
@@ -50,8 +52,10 @@ export class PollingDriftClientAccountSubscriber
50
52
  state?: DataAndSlot<StateAccount>;
51
53
  perpMarket = new Map<number, DataAndSlot<PerpMarketAccount>>();
52
54
  perpOracleMap = new Map<number, PublicKey>();
55
+ perpOracleStringMap = new Map<number, string>();
53
56
  spotMarket = new Map<number, DataAndSlot<SpotMarketAccount>>();
54
57
  spotOracleMap = new Map<number, PublicKey>();
58
+ spotOracleStringMap = new Map<number, string>();
55
59
  oracles = new Map<string, DataAndSlot<OraclePriceData>>();
56
60
  user?: DataAndSlot<UserAccount>;
57
61
 
@@ -470,6 +474,7 @@ export class PollingDriftClientAccountSubscriber
470
474
  );
471
475
  }
472
476
  this.perpOracleMap.set(perpMarketIndex, oracle);
477
+ this.perpOracleStringMap.set(perpMarketIndex, oracle.toBase58());
473
478
  }
474
479
  await Promise.all(oraclePromises);
475
480
  }
@@ -490,6 +495,7 @@ export class PollingDriftClientAccountSubscriber
490
495
  );
491
496
  }
492
497
  this.spotOracleMap.set(spotMarketIndex, oracle);
498
+ this.spotOracleStringMap.set(spotMarketIndex, oracle.toBase58());
493
499
  }
494
500
  await Promise.all(oraclePromises);
495
501
  }
@@ -528,17 +534,21 @@ export class PollingDriftClientAccountSubscriber
528
534
  }
529
535
 
530
536
  public getOraclePriceDataAndSlot(
531
- oraclePublicKey: PublicKey
537
+ oraclePublicKey: PublicKey | string
532
538
  ): DataAndSlot<OraclePriceData> | undefined {
533
539
  this.assertIsSubscribed();
534
- if (oraclePublicKey.equals(PublicKey.default)) {
540
+ const oracleString =
541
+ typeof oraclePublicKey === 'string'
542
+ ? oraclePublicKey
543
+ : oraclePublicKey.toBase58();
544
+ if (oracleString === ORACLE_DEFAULT_KEY) {
535
545
  return {
536
546
  data: QUOTE_ORACLE_PRICE_DATA,
537
547
  slot: 0,
538
548
  };
539
549
  }
540
550
 
541
- return this.oracles.get(oraclePublicKey.toString());
551
+ return this.oracles.get(oracleString);
542
552
  }
543
553
 
544
554
  public getOraclePriceDataAndSlotForPerpMarket(
@@ -546,6 +556,7 @@ export class PollingDriftClientAccountSubscriber
546
556
  ): DataAndSlot<OraclePriceData> | undefined {
547
557
  const perpMarketAccount = this.getMarketAccountAndSlot(marketIndex);
548
558
  const oracle = this.perpOracleMap.get(marketIndex);
559
+ const oracleString = this.perpOracleStringMap.get(marketIndex);
549
560
 
550
561
  if (!perpMarketAccount || !oracle) {
551
562
  return undefined;
@@ -556,7 +567,7 @@ export class PollingDriftClientAccountSubscriber
556
567
  this.setPerpOracleMap();
557
568
  }
558
569
 
559
- return this.getOraclePriceDataAndSlot(oracle);
570
+ return this.getOraclePriceDataAndSlot(oracleString);
560
571
  }
561
572
 
562
573
  public getOraclePriceDataAndSlotForSpotMarket(
@@ -564,6 +575,7 @@ export class PollingDriftClientAccountSubscriber
564
575
  ): DataAndSlot<OraclePriceData> | undefined {
565
576
  const spotMarketAccount = this.getSpotMarketAccountAndSlot(marketIndex);
566
577
  const oracle = this.spotOracleMap.get(marketIndex);
578
+ const oracleString = this.spotOracleStringMap.get(marketIndex);
567
579
  if (!spotMarketAccount || !oracle) {
568
580
  return undefined;
569
581
  }
@@ -573,7 +585,7 @@ export class PollingDriftClientAccountSubscriber
573
585
  this.setSpotOracleMap();
574
586
  }
575
587
 
576
- return this.getOraclePriceDataAndSlot(oracle);
588
+ return this.getOraclePriceDataAndSlot(oracleString);
577
589
  }
578
590
 
579
591
  public updateAccountLoaderPollingFrequency(pollingFrequency: number): void {
@@ -72,7 +72,7 @@ export interface DriftClientAccountSubscriber {
72
72
  ): DataAndSlot<SpotMarketAccount> | undefined;
73
73
  getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[];
74
74
  getOraclePriceDataAndSlot(
75
- oraclePublicKey: PublicKey
75
+ oraclePublicKey: PublicKey | string
76
76
  ): DataAndSlot<OraclePriceData> | undefined;
77
77
  getOraclePriceDataAndSlotForPerpMarket(
78
78
  marketIndex: number
@@ -13,6 +13,8 @@ import {
13
13
  getDriftStateAccountPublicKey,
14
14
  getSpotMarketPublicKey,
15
15
  getPerpMarketPublicKey,
16
+ getPerpMarketPublicKeySync,
17
+ getSpotMarketPublicKeySync,
16
18
  } from '../addresses/pda';
17
19
  import { WebSocketAccountSubscriber } from './webSocketAccountSubscriber';
18
20
  import { Commitment, PublicKey } from '@solana/web3.js';
@@ -22,6 +24,8 @@ import * as Buffer from 'buffer';
22
24
  import { QUOTE_ORACLE_PRICE_DATA } from '../oracles/quoteAssetOracleClient';
23
25
  import { findAllMarketAndOracles } from '../config';
24
26
 
27
+ const ORACLE_DEFAULT_KEY = PublicKey.default.toBase58();
28
+
25
29
  export class WebSocketDriftClientAccountSubscriber
26
30
  implements DriftClientAccountSubscriber
27
31
  {
@@ -43,13 +47,19 @@ export class WebSocketDriftClientAccountSubscriber
43
47
  AccountSubscriber<PerpMarketAccount>
44
48
  >();
45
49
  perpOracleMap = new Map<number, PublicKey>();
50
+ perpOracleStringMap = new Map<number, string>();
46
51
  spotMarketAccountSubscribers = new Map<
47
52
  number,
48
53
  AccountSubscriber<SpotMarketAccount>
49
54
  >();
50
55
  spotOracleMap = new Map<number, PublicKey>();
56
+ spotOracleStringMap = new Map<number, string>();
51
57
  oracleSubscribers = new Map<string, AccountSubscriber<OraclePriceData>>();
52
58
 
59
+ initialPerpMarketAccountData: Map<number, PerpMarketAccount>;
60
+ initialSpotMarketAccountData: Map<number, SpotMarketAccount>;
61
+ initialOraclePriceData: Map<string, OraclePriceData>;
62
+
53
63
  private isSubscribing = false;
54
64
  private subscriptionPromise: Promise<boolean>;
55
65
  private subscriptionPromiseResolver: (val: boolean) => void;
@@ -90,11 +100,23 @@ export class WebSocketDriftClientAccountSubscriber
90
100
  });
91
101
 
92
102
  if (this.shouldFindAllMarketsAndOracles) {
93
- const { perpMarketIndexes, spotMarketIndexes, oracleInfos } =
94
- await findAllMarketAndOracles(this.program);
103
+ const {
104
+ perpMarketIndexes,
105
+ perpMarketAccounts,
106
+ spotMarketIndexes,
107
+ spotMarketAccounts,
108
+ oracleInfos,
109
+ } = await findAllMarketAndOracles(this.program);
95
110
  this.perpMarketIndexes = perpMarketIndexes;
96
111
  this.spotMarketIndexes = spotMarketIndexes;
97
112
  this.oracleInfos = oracleInfos;
113
+ // front run and set the initial data here to save extra gma call in set initial data
114
+ this.initialPerpMarketAccountData = new Map(
115
+ perpMarketAccounts.map((market) => [market.marketIndex, market])
116
+ );
117
+ this.initialSpotMarketAccountData = new Map(
118
+ spotMarketAccounts.map((market) => [market.marketIndex, market])
119
+ );
98
120
  }
99
121
 
100
122
  const statePublicKey = await getDriftStateAccountPublicKey(
@@ -115,6 +137,9 @@ export class WebSocketDriftClientAccountSubscriber
115
137
  this.eventEmitter.emit('update');
116
138
  });
117
139
 
140
+ // set initial data to avoid spamming getAccountInfo calls in webSocketAccountSubscriber
141
+ await this.setInitialData();
142
+
118
143
  await Promise.all([
119
144
  // subscribe to market accounts
120
145
  this.subscribeToPerpMarketAccounts(),
@@ -132,9 +157,75 @@ export class WebSocketDriftClientAccountSubscriber
132
157
  this.isSubscribed = true;
133
158
  this.subscriptionPromiseResolver(true);
134
159
 
160
+ // delete initial data
161
+ this.removeInitialData();
162
+
135
163
  return true;
136
164
  }
137
165
 
166
+ async setInitialData(): Promise<void> {
167
+ const connection = this.program.provider.connection;
168
+
169
+ if (!this.initialPerpMarketAccountData) {
170
+ const perpMarketPublicKeys = this.perpMarketIndexes.map((marketIndex) =>
171
+ getPerpMarketPublicKeySync(this.program.programId, marketIndex)
172
+ );
173
+ const perpMarketAccountInfos = await connection.getMultipleAccountsInfo(
174
+ perpMarketPublicKeys
175
+ );
176
+ this.initialPerpMarketAccountData = new Map(
177
+ perpMarketAccountInfos.map((accountInfo) => {
178
+ const perpMarket = this.program.coder.accounts.decode(
179
+ 'PerpMarket',
180
+ accountInfo.data
181
+ );
182
+ return [perpMarket.marketIndex, perpMarket];
183
+ })
184
+ );
185
+ }
186
+
187
+ if (!this.initialSpotMarketAccountData) {
188
+ const spotMarketPublicKeys = this.spotMarketIndexes.map((marketIndex) =>
189
+ getSpotMarketPublicKeySync(this.program.programId, marketIndex)
190
+ );
191
+ const spotMarketAccountInfos = await connection.getMultipleAccountsInfo(
192
+ spotMarketPublicKeys
193
+ );
194
+ this.initialSpotMarketAccountData = new Map(
195
+ spotMarketAccountInfos.map((accountInfo) => {
196
+ const spotMarket = this.program.coder.accounts.decode(
197
+ 'SpotMarket',
198
+ accountInfo.data
199
+ );
200
+ return [spotMarket.marketIndex, spotMarket];
201
+ })
202
+ );
203
+ }
204
+
205
+ const oracleAccountInfos = await connection.getMultipleAccountsInfo(
206
+ this.oracleInfos.map((oracleInfo) => oracleInfo.publicKey)
207
+ );
208
+ this.initialOraclePriceData = new Map(
209
+ this.oracleInfos.map((oracleInfo, i) => {
210
+ const oracleClient = this.oracleClientCache.get(
211
+ oracleInfo.source,
212
+ connection,
213
+ this.program
214
+ );
215
+ const oraclePriceData = oracleClient.getOraclePriceDataFromBuffer(
216
+ oracleAccountInfos[i].data
217
+ );
218
+ return [oracleInfo.publicKey.toString(), oraclePriceData];
219
+ })
220
+ );
221
+ }
222
+
223
+ removeInitialData() {
224
+ this.initialPerpMarketAccountData = new Map();
225
+ this.initialSpotMarketAccountData = new Map();
226
+ this.initialOraclePriceData = new Map();
227
+ }
228
+
138
229
  async subscribeToPerpMarketAccounts(): Promise<boolean> {
139
230
  await Promise.all(
140
231
  this.perpMarketIndexes.map((marketIndex) =>
@@ -157,6 +248,9 @@ export class WebSocketDriftClientAccountSubscriber
157
248
  this.resubOpts,
158
249
  this.commitment
159
250
  );
251
+ accountSubscriber.setData(
252
+ this.initialPerpMarketAccountData.get(marketIndex)
253
+ );
160
254
  await accountSubscriber.subscribe((data: PerpMarketAccount) => {
161
255
  this.eventEmitter.emit('perpMarketAccountUpdate', data);
162
256
  this.eventEmitter.emit('update');
@@ -187,6 +281,9 @@ export class WebSocketDriftClientAccountSubscriber
187
281
  this.resubOpts,
188
282
  this.commitment
189
283
  );
284
+ accountSubscriber.setData(
285
+ this.initialSpotMarketAccountData.get(marketIndex)
286
+ );
190
287
  await accountSubscriber.subscribe((data: SpotMarketAccount) => {
191
288
  this.eventEmitter.emit('spotMarketAccountUpdate', data);
192
289
  this.eventEmitter.emit('update');
@@ -206,6 +303,7 @@ export class WebSocketDriftClientAccountSubscriber
206
303
  }
207
304
 
208
305
  async subscribeToOracle(oracleInfo: OracleInfo): Promise<boolean> {
306
+ const oracleString = oracleInfo.publicKey.toString();
209
307
  const client = this.oracleClientCache.get(
210
308
  oracleInfo.source,
211
309
  this.program.provider.connection,
@@ -221,16 +319,13 @@ export class WebSocketDriftClientAccountSubscriber
221
319
  this.resubOpts,
222
320
  this.commitment
223
321
  );
224
-
322
+ accountSubscriber.setData(this.initialOraclePriceData.get(oracleString));
225
323
  await accountSubscriber.subscribe((data: OraclePriceData) => {
226
324
  this.eventEmitter.emit('oraclePriceUpdate', oracleInfo.publicKey, data);
227
325
  this.eventEmitter.emit('update');
228
326
  });
229
327
 
230
- this.oracleSubscribers.set(
231
- oracleInfo.publicKey.toString(),
232
- accountSubscriber
233
- );
328
+ this.oracleSubscribers.set(oracleString, accountSubscriber);
234
329
  return true;
235
330
  }
236
331
 
@@ -341,6 +436,7 @@ export class WebSocketDriftClientAccountSubscriber
341
436
  );
342
437
  }
343
438
  this.perpOracleMap.set(perpMarketIndex, oracle);
439
+ this.perpOracleStringMap.set(perpMarketIndex, oracle.toBase58());
344
440
  }
345
441
  await Promise.all(addOraclePromises);
346
442
  }
@@ -364,6 +460,7 @@ export class WebSocketDriftClientAccountSubscriber
364
460
  );
365
461
  }
366
462
  this.spotOracleMap.set(spotMarketIndex, oracle);
463
+ this.spotOracleStringMap.set(spotMarketIndex, oracle.toBase58());
367
464
  }
368
465
  await Promise.all(addOraclePromises);
369
466
  }
@@ -408,16 +505,20 @@ export class WebSocketDriftClientAccountSubscriber
408
505
  }
409
506
 
410
507
  public getOraclePriceDataAndSlot(
411
- oraclePublicKey: PublicKey
508
+ oraclePublicKey: PublicKey | string
412
509
  ): DataAndSlot<OraclePriceData> | undefined {
413
510
  this.assertIsSubscribed();
414
- if (oraclePublicKey.equals(PublicKey.default)) {
511
+ const oracleString =
512
+ typeof oraclePublicKey === 'string'
513
+ ? oraclePublicKey
514
+ : oraclePublicKey.toBase58();
515
+ if (oracleString === ORACLE_DEFAULT_KEY) {
415
516
  return {
416
517
  data: QUOTE_ORACLE_PRICE_DATA,
417
518
  slot: 0,
418
519
  };
419
520
  }
420
- return this.oracleSubscribers.get(oraclePublicKey.toString()).dataAndSlot;
521
+ return this.oracleSubscribers.get(oracleString).dataAndSlot;
421
522
  }
422
523
 
423
524
  public getOraclePriceDataAndSlotForPerpMarket(
@@ -425,6 +526,7 @@ export class WebSocketDriftClientAccountSubscriber
425
526
  ): DataAndSlot<OraclePriceData> | undefined {
426
527
  const perpMarketAccount = this.getMarketAccountAndSlot(marketIndex);
427
528
  const oracle = this.perpOracleMap.get(marketIndex);
529
+ const oracleString = this.perpOracleStringMap.get(marketIndex);
428
530
  if (!perpMarketAccount || !oracle) {
429
531
  return undefined;
430
532
  }
@@ -434,7 +536,7 @@ export class WebSocketDriftClientAccountSubscriber
434
536
  this.setPerpOracleMap();
435
537
  }
436
538
 
437
- return this.getOraclePriceDataAndSlot(oracle);
539
+ return this.getOraclePriceDataAndSlot(oracleString);
438
540
  }
439
541
 
440
542
  public getOraclePriceDataAndSlotForSpotMarket(
@@ -442,6 +544,7 @@ export class WebSocketDriftClientAccountSubscriber
442
544
  ): DataAndSlot<OraclePriceData> | undefined {
443
545
  const spotMarketAccount = this.getSpotMarketAccountAndSlot(marketIndex);
444
546
  const oracle = this.spotOracleMap.get(marketIndex);
547
+ const oracleString = this.spotOracleStringMap.get(marketIndex);
445
548
  if (!spotMarketAccount || !oracle) {
446
549
  return undefined;
447
550
  }
@@ -451,6 +554,6 @@ export class WebSocketDriftClientAccountSubscriber
451
554
  this.setSpotOracleMap();
452
555
  }
453
556
 
454
- return this.getOraclePriceDataAndSlot(oracle);
557
+ return this.getOraclePriceDataAndSlot(oracleString);
455
558
  }
456
559
  }
@@ -87,6 +87,19 @@ export async function getPerpMarketPublicKey(
87
87
  )[0];
88
88
  }
89
89
 
90
+ export function getPerpMarketPublicKeySync(
91
+ programId: PublicKey,
92
+ marketIndex: number
93
+ ): PublicKey {
94
+ return PublicKey.findProgramAddressSync(
95
+ [
96
+ Buffer.from(anchor.utils.bytes.utf8.encode('perp_market')),
97
+ new anchor.BN(marketIndex).toArrayLike(Buffer, 'le', 2),
98
+ ],
99
+ programId
100
+ )[0];
101
+ }
102
+
90
103
  export async function getSpotMarketPublicKey(
91
104
  programId: PublicKey,
92
105
  marketIndex: number
@@ -102,6 +115,19 @@ export async function getSpotMarketPublicKey(
102
115
  )[0];
103
116
  }
104
117
 
118
+ export function getSpotMarketPublicKeySync(
119
+ programId: PublicKey,
120
+ marketIndex: number
121
+ ): PublicKey {
122
+ return PublicKey.findProgramAddressSync(
123
+ [
124
+ Buffer.from(anchor.utils.bytes.utf8.encode('spot_market')),
125
+ new anchor.BN(marketIndex).toArrayLike(Buffer, 'le', 2),
126
+ ],
127
+ programId
128
+ )[0];
129
+ }
130
+
105
131
  export async function getSpotMarketVaultPublicKey(
106
132
  programId: PublicKey,
107
133
  marketIndex: number
package/src/config.ts CHANGED
@@ -132,8 +132,10 @@ export function getMarketsAndOraclesForSubscription(env: DriftEnv): {
132
132
 
133
133
  export async function findAllMarketAndOracles(program: Program): Promise<{
134
134
  perpMarketIndexes: number[];
135
+ perpMarketAccounts: PerpMarketAccount[];
135
136
  spotMarketIndexes: number[];
136
137
  oracleInfos: OracleInfo[];
138
+ spotMarketAccounts: SpotMarketAccount[];
137
139
  }> {
138
140
  const perpMarketIndexes = [];
139
141
  const spotMarketIndexes = [];
@@ -164,7 +166,13 @@ export async function findAllMarketAndOracles(program: Program): Promise<{
164
166
 
165
167
  return {
166
168
  perpMarketIndexes,
169
+ perpMarketAccounts: perpMarketProgramAccounts.map(
170
+ (account) => account.account
171
+ ),
167
172
  spotMarketIndexes,
173
+ spotMarketAccounts: spotMarketProgramAccounts.map(
174
+ (account) => account.account
175
+ ),
168
176
  oracleInfos: Array.from(oracleInfos.values()),
169
177
  };
170
178
  }
@@ -538,7 +538,9 @@ export class DriftClient {
538
538
  public getOraclePriceDataAndSlot(
539
539
  oraclePublicKey: PublicKey
540
540
  ): DataAndSlot<OraclePriceData> | undefined {
541
- return this.accountSubscriber.getOraclePriceDataAndSlot(oraclePublicKey);
541
+ return this.accountSubscriber.getOraclePriceDataAndSlot(
542
+ oraclePublicKey.toBase58()
543
+ );
542
544
  }
543
545
 
544
546
  public async getSerumV3FulfillmentConfig(