@drift-labs/sdk 2.67.0-beta.0 → 2.67.0-beta.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.
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.67.0-beta.0
1
+ 2.67.0-beta.2
@@ -23,7 +23,9 @@ export declare class PollingDriftClientAccountSubscriber implements DriftClientA
23
23
  errorCallbackId?: string;
24
24
  state?: DataAndSlot<StateAccount>;
25
25
  perpMarket: Map<number, DataAndSlot<PerpMarketAccount>>;
26
+ perpOracleMap: Map<number, PublicKey>;
26
27
  spotMarket: Map<number, DataAndSlot<SpotMarketAccount>>;
28
+ spotOracleMap: Map<number, PublicKey>;
27
29
  oracles: Map<string, DataAndSlot<OraclePriceData>>;
28
30
  user?: DataAndSlot<UserAccount>;
29
31
  private isSubscribing;
@@ -47,6 +49,8 @@ export declare class PollingDriftClientAccountSubscriber implements DriftClientA
47
49
  addSpotMarket(marketIndex: number): Promise<boolean>;
48
50
  addPerpMarket(marketIndex: number): Promise<boolean>;
49
51
  addOracle(oracleInfo: OracleInfo): Promise<boolean>;
52
+ private setPerpOracleMap;
53
+ private setSpotOracleMap;
50
54
  assertIsSubscribed(): void;
51
55
  getStateAccountAndSlot(): DataAndSlot<StateAccount>;
52
56
  getMarketAccountAndSlot(marketIndex: number): DataAndSlot<PerpMarketAccount> | undefined;
@@ -54,5 +58,7 @@ export declare class PollingDriftClientAccountSubscriber implements DriftClientA
54
58
  getSpotMarketAccountAndSlot(marketIndex: number): DataAndSlot<SpotMarketAccount> | undefined;
55
59
  getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[];
56
60
  getOraclePriceDataAndSlot(oraclePublicKey: PublicKey): DataAndSlot<OraclePriceData> | undefined;
61
+ getOraclePriceDataAndSlotForPerpMarket(marketIndex: number): DataAndSlot<OraclePriceData> | undefined;
62
+ getOraclePriceDataAndSlotForSpotMarket(marketIndex: number): DataAndSlot<OraclePriceData> | undefined;
57
63
  updateAccountLoaderPollingFrequency(pollingFrequency: number): void;
58
64
  }
@@ -15,7 +15,9 @@ class PollingDriftClientAccountSubscriber {
15
15
  this.accountsToPoll = new Map();
16
16
  this.oraclesToPoll = new Map();
17
17
  this.perpMarket = new Map();
18
+ this.perpOracleMap = new Map();
18
19
  this.spotMarket = new Map();
20
+ this.spotOracleMap = new Map();
19
21
  this.oracles = new Map();
20
22
  this.isSubscribing = false;
21
23
  this.isSubscribed = false;
@@ -57,6 +59,8 @@ class PollingDriftClientAccountSubscriber {
57
59
  if (subscriptionSucceeded) {
58
60
  this.eventEmitter.emit('update');
59
61
  }
62
+ this.setPerpOracleMap();
63
+ this.setSpotOracleMap();
60
64
  this.isSubscribing = false;
61
65
  this.isSubscribed = subscriptionSucceeded;
62
66
  this.subscriptionPromiseResolver(subscriptionSucceeded);
@@ -229,6 +233,7 @@ class PollingDriftClientAccountSubscriber {
229
233
  await this.addSpotMarketAccountToPoll(marketIndex);
230
234
  const accountToPoll = this.accountsToPoll.get(marketPublicKey.toString());
231
235
  await this.addAccountToAccountLoader(accountToPoll);
236
+ this.setSpotOracleMap();
232
237
  return true;
233
238
  }
234
239
  async addPerpMarket(marketIndex) {
@@ -239,6 +244,7 @@ class PollingDriftClientAccountSubscriber {
239
244
  await this.addPerpMarketAccountToPoll(marketIndex);
240
245
  const accountToPoll = this.accountsToPoll.get(marketPublicKey.toString());
241
246
  await this.addAccountToAccountLoader(accountToPoll);
247
+ this.setPerpOracleMap();
242
248
  return true;
243
249
  }
244
250
  async addOracle(oracleInfo) {
@@ -251,6 +257,24 @@ class PollingDriftClientAccountSubscriber {
251
257
  await this.addOracleToAccountLoader(oracleToPoll);
252
258
  return true;
253
259
  }
260
+ setPerpOracleMap() {
261
+ const perpMarkets = this.getMarketAccountsAndSlots();
262
+ for (const perpMarket of perpMarkets) {
263
+ const perpMarketAccount = perpMarket.data;
264
+ const perpMarketIndex = perpMarketAccount.marketIndex;
265
+ const oracle = perpMarketAccount.amm.oracle;
266
+ this.perpOracleMap.set(perpMarketIndex, oracle);
267
+ }
268
+ }
269
+ setSpotOracleMap() {
270
+ const spotMarkets = this.getSpotMarketAccountsAndSlots();
271
+ for (const spotMarket of spotMarkets) {
272
+ const spotMarketAccount = spotMarket.data;
273
+ const spotMarketIndex = spotMarketAccount.marketIndex;
274
+ const oracle = spotMarketAccount.oracle;
275
+ this.spotOracleMap.set(spotMarketIndex, oracle);
276
+ }
277
+ }
254
278
  assertIsSubscribed() {
255
279
  if (!this.isSubscribed) {
256
280
  throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
@@ -282,6 +306,40 @@ class PollingDriftClientAccountSubscriber {
282
306
  }
283
307
  return this.oracles.get(oraclePublicKey.toString());
284
308
  }
309
+ getOraclePriceDataAndSlotForPerpMarket(marketIndex) {
310
+ const perpMarketAccount = this.getMarketAccountAndSlot(marketIndex);
311
+ const oracle = this.perpOracleMap.get(marketIndex);
312
+ if (!perpMarketAccount || !oracle) {
313
+ return undefined;
314
+ }
315
+ if (!perpMarketAccount.data.amm.oracle.equals(oracle)) {
316
+ // If the oracle has changed, we need to update the oracle map in background
317
+ this.addOracle({
318
+ source: perpMarketAccount.data.amm.oracleSource,
319
+ publicKey: perpMarketAccount.data.amm.oracle,
320
+ }).then(() => {
321
+ this.setPerpOracleMap();
322
+ });
323
+ }
324
+ return this.getOraclePriceDataAndSlot(oracle);
325
+ }
326
+ getOraclePriceDataAndSlotForSpotMarket(marketIndex) {
327
+ const spotMarketAccount = this.getSpotMarketAccountAndSlot(marketIndex);
328
+ const oracle = this.spotOracleMap.get(marketIndex);
329
+ if (!spotMarketAccount || !oracle) {
330
+ return undefined;
331
+ }
332
+ if (!spotMarketAccount.data.oracle.equals(oracle)) {
333
+ // If the oracle has changed, we need to update the oracle map in background
334
+ this.addOracle({
335
+ source: spotMarketAccount.data.oracleSource,
336
+ publicKey: spotMarketAccount.data.oracle,
337
+ }).then(() => {
338
+ this.setSpotOracleMap();
339
+ });
340
+ }
341
+ return this.getOraclePriceDataAndSlot(oracle);
342
+ }
285
343
  updateAccountLoaderPollingFrequency(pollingFrequency) {
286
344
  this.accountLoader.updatePollingFrequency(pollingFrequency);
287
345
  }
@@ -47,6 +47,8 @@ export interface DriftClientAccountSubscriber {
47
47
  getSpotMarketAccountAndSlot(marketIndex: number): DataAndSlot<SpotMarketAccount> | undefined;
48
48
  getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[];
49
49
  getOraclePriceDataAndSlot(oraclePublicKey: PublicKey): DataAndSlot<OraclePriceData> | undefined;
50
+ getOraclePriceDataAndSlotForPerpMarket(marketIndex: number): DataAndSlot<OraclePriceData> | undefined;
51
+ getOraclePriceDataAndSlotForSpotMarket(marketIndex: number): DataAndSlot<OraclePriceData> | undefined;
50
52
  updateAccountLoaderPollingFrequency?: (pollingFrequency: number) => void;
51
53
  }
52
54
  export interface UserAccountEvents {
@@ -21,7 +21,9 @@ export declare class WebSocketDriftClientAccountSubscriber implements DriftClien
21
21
  eventEmitter: StrictEventEmitter<EventEmitter, DriftClientAccountEvents>;
22
22
  stateAccountSubscriber?: AccountSubscriber<StateAccount>;
23
23
  perpMarketAccountSubscribers: Map<number, AccountSubscriber<PerpMarketAccount>>;
24
+ perpOracleMap: Map<number, PublicKey>;
24
25
  spotMarketAccountSubscribers: Map<number, AccountSubscriber<SpotMarketAccount>>;
26
+ spotOracleMap: Map<number, PublicKey>;
25
27
  oracleSubscribers: Map<string, AccountSubscriber<OraclePriceData>>;
26
28
  private isSubscribing;
27
29
  private subscriptionPromise;
@@ -42,6 +44,8 @@ export declare class WebSocketDriftClientAccountSubscriber implements DriftClien
42
44
  addSpotMarket(marketIndex: number): Promise<boolean>;
43
45
  addPerpMarket(marketIndex: number): Promise<boolean>;
44
46
  addOracle(oracleInfo: OracleInfo): Promise<boolean>;
47
+ private setPerpOracleMap;
48
+ private setSpotOracleMap;
45
49
  assertIsSubscribed(): void;
46
50
  getStateAccountAndSlot(): DataAndSlot<StateAccount>;
47
51
  getMarketAccountAndSlot(marketIndex: number): DataAndSlot<PerpMarketAccount> | undefined;
@@ -49,4 +53,6 @@ export declare class WebSocketDriftClientAccountSubscriber implements DriftClien
49
53
  getSpotMarketAccountAndSlot(marketIndex: number): DataAndSlot<SpotMarketAccount> | undefined;
50
54
  getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[];
51
55
  getOraclePriceDataAndSlot(oraclePublicKey: PublicKey): DataAndSlot<OraclePriceData> | undefined;
56
+ getOraclePriceDataAndSlotForPerpMarket(marketIndex: number): DataAndSlot<OraclePriceData> | undefined;
57
+ getOraclePriceDataAndSlotForSpotMarket(marketIndex: number): DataAndSlot<OraclePriceData> | undefined;
52
58
  }
@@ -13,7 +13,9 @@ class WebSocketDriftClientAccountSubscriber {
13
13
  constructor(program, perpMarketIndexes, spotMarketIndexes, oracleInfos, shouldFindAllMarketsAndOracles, resubTimeoutMs, commitment) {
14
14
  this.oracleClientCache = new oracleClientCache_1.OracleClientCache();
15
15
  this.perpMarketAccountSubscribers = new Map();
16
+ this.perpOracleMap = new Map();
16
17
  this.spotMarketAccountSubscribers = new Map();
18
+ this.spotOracleMap = new Map();
17
19
  this.oracleSubscribers = new Map();
18
20
  this.isSubscribing = false;
19
21
  this.isSubscribed = false;
@@ -57,6 +59,8 @@ class WebSocketDriftClientAccountSubscriber {
57
59
  // subscribe to oracles
58
60
  await this.subscribeToOracles();
59
61
  this.eventEmitter.emit('update');
62
+ this.setPerpOracleMap();
63
+ this.setSpotOracleMap();
60
64
  this.isSubscribing = false;
61
65
  this.isSubscribed = true;
62
66
  this.subscriptionPromiseResolver(true);
@@ -152,13 +156,17 @@ class WebSocketDriftClientAccountSubscriber {
152
156
  if (this.spotMarketAccountSubscribers.has(marketIndex)) {
153
157
  return true;
154
158
  }
155
- return this.subscribeToSpotMarketAccount(marketIndex);
159
+ const subscriptionSuccess = this.subscribeToSpotMarketAccount(marketIndex);
160
+ this.setSpotOracleMap();
161
+ return subscriptionSuccess;
156
162
  }
157
163
  async addPerpMarket(marketIndex) {
158
164
  if (this.perpMarketAccountSubscribers.has(marketIndex)) {
159
165
  return true;
160
166
  }
161
- return this.subscribeToPerpMarketAccount(marketIndex);
167
+ const subscriptionSuccess = this.subscribeToPerpMarketAccount(marketIndex);
168
+ this.setPerpOracleMap();
169
+ return subscriptionSuccess;
162
170
  }
163
171
  async addOracle(oracleInfo) {
164
172
  if (this.oracleSubscribers.has(oracleInfo.publicKey.toString())) {
@@ -169,6 +177,30 @@ class WebSocketDriftClientAccountSubscriber {
169
177
  }
170
178
  return this.subscribeToOracle(oracleInfo);
171
179
  }
180
+ setPerpOracleMap() {
181
+ const perpMarkets = this.getMarketAccountsAndSlots();
182
+ for (const perpMarket of perpMarkets) {
183
+ if (!perpMarket) {
184
+ continue;
185
+ }
186
+ const perpMarketAccount = perpMarket.data;
187
+ const perpMarketIndex = perpMarketAccount.marketIndex;
188
+ const oracle = perpMarketAccount.amm.oracle;
189
+ this.perpOracleMap.set(perpMarketIndex, oracle);
190
+ }
191
+ }
192
+ setSpotOracleMap() {
193
+ const spotMarkets = this.getSpotMarketAccountsAndSlots();
194
+ for (const spotMarket of spotMarkets) {
195
+ if (!spotMarket) {
196
+ continue;
197
+ }
198
+ const spotMarketAccount = spotMarket.data;
199
+ const spotMarketIndex = spotMarketAccount.marketIndex;
200
+ const oracle = spotMarketAccount.oracle;
201
+ this.spotOracleMap.set(spotMarketIndex, oracle);
202
+ }
203
+ }
172
204
  assertIsSubscribed() {
173
205
  if (!this.isSubscribed) {
174
206
  throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
@@ -202,5 +234,39 @@ class WebSocketDriftClientAccountSubscriber {
202
234
  }
203
235
  return this.oracleSubscribers.get(oraclePublicKey.toString()).dataAndSlot;
204
236
  }
237
+ getOraclePriceDataAndSlotForPerpMarket(marketIndex) {
238
+ const perpMarketAccount = this.getMarketAccountAndSlot(marketIndex);
239
+ const oracle = this.perpOracleMap.get(marketIndex);
240
+ if (!perpMarketAccount || !oracle) {
241
+ return undefined;
242
+ }
243
+ if (!perpMarketAccount.data.amm.oracle.equals(oracle)) {
244
+ // If the oracle has changed, we need to update the oracle map in background
245
+ this.addOracle({
246
+ source: perpMarketAccount.data.amm.oracleSource,
247
+ publicKey: perpMarketAccount.data.amm.oracle,
248
+ }).then(() => {
249
+ this.setPerpOracleMap();
250
+ });
251
+ }
252
+ return this.getOraclePriceDataAndSlot(oracle);
253
+ }
254
+ getOraclePriceDataAndSlotForSpotMarket(marketIndex) {
255
+ const spotMarketAccount = this.getSpotMarketAccountAndSlot(marketIndex);
256
+ const oracle = this.spotOracleMap.get(marketIndex);
257
+ if (!spotMarketAccount || !oracle) {
258
+ return undefined;
259
+ }
260
+ if (!spotMarketAccount.data.oracle.equals(oracle)) {
261
+ // If the oracle has changed, we need to update the oracle map in background
262
+ this.addOracle({
263
+ source: spotMarketAccount.data.oracleSource,
264
+ publicKey: spotMarketAccount.data.oracle,
265
+ }).then(() => {
266
+ this.setSpotOracleMap();
267
+ });
268
+ }
269
+ return this.getOraclePriceDataAndSlot(oracle);
270
+ }
205
271
  }
206
272
  exports.WebSocketDriftClientAccountSubscriber = WebSocketDriftClientAccountSubscriber;
@@ -3169,14 +3169,10 @@ class DriftClient {
3169
3169
  this.eventEmitter.emit(eventName, data);
3170
3170
  }
3171
3171
  getOracleDataForPerpMarket(marketIndex) {
3172
- const oracleKey = this.getPerpMarketAccount(marketIndex).amm.oracle;
3173
- const oracleData = this.getOraclePriceDataAndSlot(oracleKey).data;
3174
- return oracleData;
3172
+ return this.accountSubscriber.getOraclePriceDataAndSlotForPerpMarket(marketIndex).data;
3175
3173
  }
3176
3174
  getOracleDataForSpotMarket(marketIndex) {
3177
- const oracleKey = this.getSpotMarketAccount(marketIndex).oracle;
3178
- const oracleData = this.getOraclePriceDataAndSlot(oracleKey).data;
3179
- return oracleData;
3175
+ return this.accountSubscriber.getOraclePriceDataAndSlotForSpotMarket(marketIndex).data;
3180
3176
  }
3181
3177
  async initializeInsuranceFundStake(marketIndex, txParams) {
3182
3178
  const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.getInitializeInsuranceFundStakeIx(marketIndex), txParams), [], this.opts);
@@ -3306,6 +3302,7 @@ class DriftClient {
3306
3302
  return txSig;
3307
3303
  }
3308
3304
  async removeInsuranceFundStake(marketIndex, collateralAccountPublicKey) {
3305
+ var _a, _b;
3309
3306
  const removeIfStakeIxs = [];
3310
3307
  const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
3311
3308
  const ifStakeAccountPublicKey = (0, pda_1.getInsuranceFundStakeAccountPublicKey)(this.program.programId, this.wallet.publicKey, marketIndex);
@@ -3328,9 +3325,11 @@ class DriftClient {
3328
3325
  removeIfStakeIxs.push(createTokenAccountIx);
3329
3326
  }
3330
3327
  }
3328
+ const userAccountExists = !!((_b = (_a = this.getUser()) === null || _a === void 0 ? void 0 : _a.accountSubscriber) === null || _b === void 0 ? void 0 : _b.isSubscribed) &&
3329
+ (await this.checkIfAccountExists(this.getUser().userAccountPublicKey));
3331
3330
  const remainingAccounts = this.getRemainingAccounts({
3332
- userAccounts: [this.getUserAccount()],
3333
- useMarketLastSlotCache: true,
3331
+ userAccounts: userAccountExists ? [this.getUserAccount()] : [],
3332
+ useMarketLastSlotCache: false,
3334
3333
  writableSpotMarketIndexes: [marketIndex],
3335
3334
  });
3336
3335
  const removeStakeIx = await this.program.instruction.removeInsuranceFundStake(marketIndex, {
@@ -6,6 +6,7 @@ const pythClient_1 = require("../oracles/pythClient");
6
6
  // import { SwitchboardClient } from '../oracles/switchboardClient';
7
7
  const quoteAssetOracleClient_1 = require("../oracles/quoteAssetOracleClient");
8
8
  const anchor_1 = require("@coral-xyz/anchor");
9
+ const switchboardClient_1 = require("../oracles/switchboardClient");
9
10
  function getOracleClient(oracleSource, connection) {
10
11
  if ((0, types_1.isVariant)(oracleSource, 'pyth')) {
11
12
  return new pythClient_1.PythClient(connection);
@@ -19,9 +20,9 @@ function getOracleClient(oracleSource, connection) {
19
20
  if ((0, types_1.isVariant)(oracleSource, 'pythStableCoin')) {
20
21
  return new pythClient_1.PythClient(connection, undefined, true);
21
22
  }
22
- // if (isVariant(oracleSource, 'switchboard')) {
23
- // return new SwitchboardClient(connection);
24
- // }
23
+ if ((0, types_1.isVariant)(oracleSource, 'switchboard')) {
24
+ return new switchboardClient_1.SwitchboardClient(connection);
25
+ }
25
26
  if ((0, types_1.isVariant)(oracleSource, 'quoteAsset')) {
26
27
  return new quoteAssetOracleClient_1.QuoteAssetOracleClient();
27
28
  }