@drift-labs/sdk 2.26.0-beta.1 → 2.26.0-beta.3

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 (42) hide show
  1. package/lib/config.d.ts +1 -0
  2. package/lib/config.js +2 -0
  3. package/lib/constants/spotMarkets.d.ts +1 -0
  4. package/lib/constants/spotMarkets.js +1 -0
  5. package/lib/dlob/DLOB.d.ts +38 -2
  6. package/lib/dlob/DLOB.js +69 -0
  7. package/lib/dlob/DLOBApiClient.js +1 -1
  8. package/lib/dlob/DLOBSubscriber.d.ts +34 -0
  9. package/lib/dlob/DLOBSubscriber.js +100 -0
  10. package/lib/dlob/orderBookLevels.d.ts +44 -0
  11. package/lib/dlob/orderBookLevels.js +137 -0
  12. package/lib/dlob/types.d.ts +2 -0
  13. package/lib/driftClient.d.ts +28 -10
  14. package/lib/driftClient.js +158 -55
  15. package/lib/driftClientConfig.d.ts +3 -0
  16. package/lib/idl/drift.json +1 -1
  17. package/lib/index.d.ts +1 -0
  18. package/lib/index.js +1 -0
  19. package/lib/serum/serumSubscriber.d.ts +5 -1
  20. package/lib/serum/serumSubscriber.js +22 -0
  21. package/lib/types.d.ts +1 -0
  22. package/package.json +1 -1
  23. package/src/assert/assert.js +9 -0
  24. package/src/config.ts +3 -0
  25. package/src/constants/spotMarkets.ts +4 -0
  26. package/src/dlob/DLOB.ts +177 -17
  27. package/src/dlob/DLOBApiClient.ts +3 -1
  28. package/src/dlob/DLOBSubscriber.ts +141 -0
  29. package/src/dlob/orderBookLevels.ts +243 -0
  30. package/src/dlob/types.ts +2 -0
  31. package/src/driftClient.ts +231 -66
  32. package/src/driftClientConfig.ts +3 -0
  33. package/src/idl/drift.json +1 -1
  34. package/src/index.ts +1 -0
  35. package/src/serum/serumSubscriber.ts +29 -1
  36. package/src/token/index.js +38 -0
  37. package/src/types.ts +1 -0
  38. package/src/util/computeUnits.js +27 -0
  39. package/src/util/getTokenAddress.js +9 -0
  40. package/src/util/promiseTimeout.js +14 -0
  41. package/src/util/tps.js +27 -0
  42. package/tests/dlob/helpers.ts +3 -0
@@ -61,7 +61,7 @@ class DriftClient {
61
61
  this._isSubscribed = val;
62
62
  }
63
63
  constructor(config) {
64
- var _a, _b, _c, _d, _e, _f, _g, _h;
64
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
65
65
  this.users = new Map();
66
66
  this._isSubscribed = false;
67
67
  this.perpMarketLastSlotCache = new Map();
@@ -72,10 +72,26 @@ class DriftClient {
72
72
  this.provider = new anchor_1.AnchorProvider(config.connection, config.wallet, this.opts);
73
73
  this.program = new anchor_1.Program(drift_json_1.default, config.programID, this.provider);
74
74
  this.authority = (_a = config.authority) !== null && _a !== void 0 ? _a : this.wallet.publicKey;
75
- const subAccountIds = (_b = config.subAccountIds) !== null && _b !== void 0 ? _b : [0];
76
- this.activeSubAccountId = (_c = config.activeSubAccountId) !== null && _c !== void 0 ? _c : subAccountIds[0];
75
+ this.activeSubAccountId = (_b = config.activeSubAccountId) !== null && _b !== void 0 ? _b : 0;
76
+ this.skipLoadUsers = (_c = config.skipLoadUsers) !== null && _c !== void 0 ? _c : false;
77
+ if (config.includeDelegates && config.subAccountIds) {
78
+ throw new Error('Can only pass one of includeDelegates or subAccountIds. If you want to specify subaccount ids for multiple authorities, pass authoritySubaccountMap instead');
79
+ }
80
+ if (config.authoritySubaccountMap && config.subAccountIds) {
81
+ throw new Error('Can only pass one of authoritySubaccountMap or subAccountIds');
82
+ }
83
+ if (config.authoritySubaccountMap && config.includeDelegates) {
84
+ throw new Error('Can only pass one of authoritySubaccountMap or includeDelegates');
85
+ }
86
+ this.authoritySubaccountMap = config.authoritySubaccountMap
87
+ ? config.authoritySubaccountMap
88
+ : config.subAccountIds
89
+ ? new Map([[this.authority.toString(), config.subAccountIds]])
90
+ : new Map();
91
+ this.includeDelegates = (_d = config.includeDelegates) !== null && _d !== void 0 ? _d : false;
92
+ this.activeAuthority = this.authority;
77
93
  this.userAccountSubscriptionConfig =
78
- ((_d = config.accountSubscription) === null || _d === void 0 ? void 0 : _d.type) === 'polling'
94
+ ((_e = config.accountSubscription) === null || _e === void 0 ? void 0 : _e.type) === 'polling'
79
95
  ? {
80
96
  type: 'polling',
81
97
  accountLoader: config.accountSubscription.accountLoader,
@@ -83,7 +99,6 @@ class DriftClient {
83
99
  : {
84
100
  type: 'websocket',
85
101
  };
86
- this.createUsers(subAccountIds, this.userAccountSubscriptionConfig);
87
102
  if (config.userStats) {
88
103
  this.userStats = new userStats_1.UserStats({
89
104
  driftClient: this,
@@ -108,23 +123,20 @@ class DriftClient {
108
123
  if (config.env && !this.marketLookupTable) {
109
124
  this.marketLookupTable = new web3_js_1.PublicKey(config_1.configs[config.env].MARKET_LOOKUP_TABLE);
110
125
  }
111
- if (((_e = config.accountSubscription) === null || _e === void 0 ? void 0 : _e.type) === 'polling') {
126
+ if (((_f = config.accountSubscription) === null || _f === void 0 ? void 0 : _f.type) === 'polling') {
112
127
  this.accountSubscriber = new pollingDriftClientAccountSubscriber_1.PollingDriftClientAccountSubscriber(this.program, config.accountSubscription.accountLoader, perpMarketIndexes !== null && perpMarketIndexes !== void 0 ? perpMarketIndexes : [], spotMarketIndexes !== null && spotMarketIndexes !== void 0 ? spotMarketIndexes : [], oracleInfos !== null && oracleInfos !== void 0 ? oracleInfos : []);
113
128
  }
114
129
  else {
115
130
  this.accountSubscriber = new webSocketDriftClientAccountSubscriber_1.WebSocketDriftClientAccountSubscriber(this.program, perpMarketIndexes !== null && perpMarketIndexes !== void 0 ? perpMarketIndexes : [], spotMarketIndexes !== null && spotMarketIndexes !== void 0 ? spotMarketIndexes : [], oracleInfos !== null && oracleInfos !== void 0 ? oracleInfos : []);
116
131
  }
117
132
  this.eventEmitter = this.accountSubscriber.eventEmitter;
118
- this.txSender = new retryTxSender_1.RetryTxSender(this.provider, (_f = config.txSenderConfig) === null || _f === void 0 ? void 0 : _f.timeout, (_g = config.txSenderConfig) === null || _g === void 0 ? void 0 : _g.retrySleep, (_h = config.txSenderConfig) === null || _h === void 0 ? void 0 : _h.additionalConnections);
133
+ this.txSender = new retryTxSender_1.RetryTxSender(this.provider, (_g = config.txSenderConfig) === null || _g === void 0 ? void 0 : _g.timeout, (_h = config.txSenderConfig) === null || _h === void 0 ? void 0 : _h.retrySleep, (_j = config.txSenderConfig) === null || _j === void 0 ? void 0 : _j.additionalConnections);
119
134
  }
120
- createUsers(subAccountIds, accountSubscriptionConfig) {
121
- for (const subAccountId of subAccountIds) {
122
- const user = this.createUser(subAccountId, accountSubscriptionConfig);
123
- this.users.set(subAccountId, user);
124
- }
135
+ getUserMapKey(subAccountId, authority) {
136
+ return `${subAccountId}_${authority.toString()}`;
125
137
  }
126
- createUser(subAccountId, accountSubscriptionConfig) {
127
- const userAccountPublicKey = (0, pda_1.getUserAccountPublicKeySync)(this.program.programId, this.authority, subAccountId);
138
+ createUser(subAccountId, accountSubscriptionConfig, authority) {
139
+ const userAccountPublicKey = (0, pda_1.getUserAccountPublicKeySync)(this.program.programId, authority !== null && authority !== void 0 ? authority : this.authority, subAccountId);
128
140
  return new user_1.User({
129
141
  driftClient: this,
130
142
  userAccountPublicKey,
@@ -132,7 +144,7 @@ class DriftClient {
132
144
  });
133
145
  }
134
146
  async subscribe() {
135
- let subscribePromises = this.subscribeUsers().concat(this.accountSubscriber.subscribe());
147
+ let subscribePromises = [this.addAndSubscribeToUsers()].concat(this.accountSubscriber.subscribe());
136
148
  if (this.userStats !== undefined) {
137
149
  subscribePromises = subscribePromises.concat(this.userStats.subscribe());
138
150
  }
@@ -262,54 +274,109 @@ class DriftClient {
262
274
  * @param newWallet
263
275
  * @param subAccountIds
264
276
  * @param activeSubAccountId
277
+ * @param includeDelegates
265
278
  */
266
- async updateWallet(newWallet, subAccountIds = [0], activeSubAccountId = 0) {
279
+ async updateWallet(newWallet, subAccountIds, activeSubAccountId, includeDelegates, authoritySubaccountMap) {
267
280
  const newProvider = new anchor_1.AnchorProvider(this.connection, newWallet, this.opts);
268
281
  const newProgram = new anchor_1.Program(drift_json_1.default, this.program.programId, newProvider);
282
+ this.skipLoadUsers = false;
269
283
  // Update provider for txSender with new wallet details
270
284
  this.txSender.provider = newProvider;
271
285
  this.wallet = newWallet;
272
286
  this.provider = newProvider;
273
287
  this.program = newProgram;
274
288
  this.authority = newWallet.publicKey;
289
+ this.activeSubAccountId = activeSubAccountId;
290
+ this.userStatsAccountPublicKey = undefined;
291
+ this.includeDelegates = includeDelegates !== null && includeDelegates !== void 0 ? includeDelegates : false;
292
+ if (includeDelegates && subAccountIds) {
293
+ throw new Error('Can only pass one of includeDelegates or subAccountIds. If you want to specify subaccount ids for multiple authorities, pass authoritySubaccountMap instead');
294
+ }
295
+ if (authoritySubaccountMap && subAccountIds) {
296
+ throw new Error('Can only pass one of authoritySubaccountMap or subAccountIds');
297
+ }
298
+ if (authoritySubaccountMap && includeDelegates) {
299
+ throw new Error('Can only pass one of authoritySubaccountMap or includeDelegates');
300
+ }
301
+ this.authoritySubaccountMap = authoritySubaccountMap
302
+ ? authoritySubaccountMap
303
+ : subAccountIds
304
+ ? new Map([[this.authority.toString(), subAccountIds]])
305
+ : new Map();
306
+ let success = true;
275
307
  if (this.isSubscribed) {
276
308
  await Promise.all(this.unsubscribeUsers());
277
309
  if (this.userStats) {
278
310
  await this.userStats.unsubscribe();
279
311
  this.userStats = new userStats_1.UserStats({
280
312
  driftClient: this,
281
- userStatsAccountPublicKey: (0, pda_1.getUserStatsAccountPublicKey)(this.program.programId, this.authority),
313
+ userStatsAccountPublicKey: this.getUserStatsAccountPublicKey(),
282
314
  accountSubscription: this.userAccountSubscriptionConfig,
283
315
  });
284
- }
285
- }
286
- this.users.clear();
287
- this.createUsers(subAccountIds, this.userAccountSubscriptionConfig);
288
- if (this.isSubscribed) {
289
- await Promise.all(this.subscribeUsers());
290
- if (this.userStats) {
291
316
  await this.userStats.subscribe();
292
317
  }
318
+ this.users.clear();
319
+ success = await this.addAndSubscribeToUsers();
293
320
  }
294
- this.activeSubAccountId = activeSubAccountId;
295
- this.userStatsAccountPublicKey = undefined;
321
+ return success;
296
322
  }
297
- switchActiveUser(subAccountId) {
323
+ switchActiveUser(subAccountId, authority) {
298
324
  this.activeSubAccountId = subAccountId;
325
+ this.activeAuthority = authority !== null && authority !== void 0 ? authority : this.authority;
299
326
  }
300
- async addUser(subAccountId) {
301
- if (this.users.has(subAccountId)) {
302
- return;
327
+ async addUser(subAccountId, authority) {
328
+ authority = authority !== null && authority !== void 0 ? authority : this.authority;
329
+ const userKey = this.getUserMapKey(subAccountId, authority);
330
+ if (this.users.has(userKey) && this.users.get(userKey).isSubscribed) {
331
+ return true;
332
+ }
333
+ const user = this.createUser(subAccountId, this.userAccountSubscriptionConfig, authority);
334
+ const result = await user.subscribe();
335
+ if (result) {
336
+ this.users.set(userKey, user);
337
+ return true;
338
+ }
339
+ else {
340
+ return false;
303
341
  }
304
- const user = this.createUser(subAccountId, this.userAccountSubscriptionConfig);
305
- await user.subscribe();
306
- this.users.set(subAccountId, user);
307
342
  }
308
- async addAllUsers() {
309
- const userAccounts = await this.getUserAccountsForAuthority(this.authority);
310
- for (const userAccount of userAccounts) {
311
- await this.addUser(userAccount.subAccountId);
343
+ /**
344
+ * Adds and subscribes to users based on params set by the constructor or by updateWallet.
345
+ */
346
+ async addAndSubscribeToUsers() {
347
+ var _a, _b, _c, _d, _e, _f, _g, _h;
348
+ // save the rpc calls if driftclient is initialized without a real wallet
349
+ if (this.skipLoadUsers)
350
+ return true;
351
+ let result = true;
352
+ if (this.authoritySubaccountMap && this.authoritySubaccountMap.size > 0) {
353
+ this.authoritySubaccountMap.forEach(async (value, key) => {
354
+ for (const subAccountId of value) {
355
+ result =
356
+ result && (await this.addUser(subAccountId, new web3_js_1.PublicKey(key)));
357
+ }
358
+ });
359
+ if (this.activeSubAccountId == undefined) {
360
+ this.switchActiveUser((_a = [...this.authoritySubaccountMap.values()][0][0]) !== null && _a !== void 0 ? _a : 0, new web3_js_1.PublicKey((_b = [...this.authoritySubaccountMap.keys()][0]) !== null && _b !== void 0 ? _b : this.authority.toString()));
361
+ }
362
+ }
363
+ else {
364
+ const userAccounts = (_c = (await this.getUserAccountsForAuthority(this.authority))) !== null && _c !== void 0 ? _c : [];
365
+ let delegatedAccounts = [];
366
+ if (this.includeDelegates) {
367
+ delegatedAccounts =
368
+ (_d = (await this.getUserAccountsForDelegate(this.authority))) !== null && _d !== void 0 ? _d : [];
369
+ }
370
+ for (const account of userAccounts.concat(delegatedAccounts)) {
371
+ result =
372
+ result &&
373
+ (await this.addUser(account.subAccountId, account.authority));
374
+ }
375
+ if (this.activeSubAccountId == undefined) {
376
+ this.switchActiveUser((_f = (_e = userAccounts.concat(delegatedAccounts)[0]) === null || _e === void 0 ? void 0 : _e.subAccountId) !== null && _f !== void 0 ? _f : 0, (_h = (_g = userAccounts.concat(delegatedAccounts)[0]) === null || _g === void 0 ? void 0 : _g.authority) !== null && _h !== void 0 ? _h : this.authority);
377
+ }
312
378
  }
379
+ return result;
313
380
  }
314
381
  async initializeUserAccount(subAccountId = 0, name = userName_1.DEFAULT_USER_NAME, referrerInfo) {
315
382
  const [userAccountPublicKey, initializeUserAccountIx] = await this.getInitializeUserInstructions(subAccountId, name, referrerInfo);
@@ -416,7 +483,7 @@ class DriftClient {
416
483
  }
417
484
  async updateUserMarginTradingEnabled(marginTradingEnabled, subAccountId = 0) {
418
485
  const userAccountPublicKey = (0, pda_1.getUserAccountPublicKeySync)(this.program.programId, this.wallet.publicKey, subAccountId);
419
- await this.addUser(subAccountId);
486
+ await this.addUser(subAccountId, this.wallet.publicKey);
420
487
  const remainingAccounts = this.getRemainingAccounts({
421
488
  userAccounts: [this.getUserAccount(subAccountId)],
422
489
  });
@@ -464,7 +531,9 @@ class DriftClient {
464
531
  },
465
532
  },
466
533
  ]);
467
- return programAccounts.map((programAccount) => programAccount.account);
534
+ return programAccounts
535
+ .map((programAccount) => programAccount.account)
536
+ .sort((a, b) => a.subAccountId - b.subAccountId);
468
537
  }
469
538
  async getUserAccountsAndAddressesForAuthority(authority) {
470
539
  const programAccounts = await this.program.account.user.all([
@@ -488,7 +557,9 @@ class DriftClient {
488
557
  },
489
558
  },
490
559
  ]);
491
- return programAccounts.map((programAccount) => programAccount.account);
560
+ return programAccounts
561
+ .map((programAccount) => programAccount.account)
562
+ .sort((a, b) => a.subAccountId - b.subAccountId);
492
563
  }
493
564
  async getReferredUserStatsAccountsByReferrer(referrer) {
494
565
  const programAccounts = await this.program.account.userStats.all([
@@ -526,19 +597,25 @@ class DriftClient {
526
597
  },
527
598
  });
528
599
  const { txSig } = await this.sendTransaction((0, utils_1.wrapInTx)(ix, txParams === null || txParams === void 0 ? void 0 : txParams.computeUnits, txParams === null || txParams === void 0 ? void 0 : txParams.computeUnitsPrice), [], this.opts);
529
- await ((_a = this.users.get(subAccountId)) === null || _a === void 0 ? void 0 : _a.unsubscribe());
530
- this.users.delete(subAccountId);
600
+ const userMapKey = this.getUserMapKey(subAccountId, this.wallet.publicKey);
601
+ await ((_a = this.users.get(userMapKey)) === null || _a === void 0 ? void 0 : _a.unsubscribe());
602
+ this.users.delete(userMapKey);
531
603
  return txSig;
532
604
  }
533
- getUser(subAccountId) {
605
+ getUser(subAccountId, authority) {
534
606
  subAccountId = subAccountId !== null && subAccountId !== void 0 ? subAccountId : this.activeSubAccountId;
535
- if (!this.users.has(subAccountId)) {
607
+ authority = authority !== null && authority !== void 0 ? authority : this.activeAuthority;
608
+ const userMapKey = this.getUserMapKey(subAccountId, authority);
609
+ if (!this.users.has(userMapKey)) {
536
610
  throw new Error(`Clearing House has no user for user id ${subAccountId}`);
537
611
  }
538
- return this.users.get(subAccountId);
612
+ return this.users.get(userMapKey);
539
613
  }
540
614
  getUsers() {
541
- return [...this.users.values()];
615
+ // delegate users get added to the end
616
+ return [...this.users.values()]
617
+ .filter((acct) => acct.getUserAccount().authority.equals(this.authority))
618
+ .concat([...this.users.values()].filter((acct) => !acct.getUserAccount().authority.equals(this.authority)));
542
619
  }
543
620
  getUserStats() {
544
621
  return this.userStats;
@@ -552,14 +629,14 @@ class DriftClient {
552
629
  if (this.userStatsAccountPublicKey) {
553
630
  return this.userStatsAccountPublicKey;
554
631
  }
555
- this.userStatsAccountPublicKey = (0, pda_1.getUserStatsAccountPublicKey)(this.program.programId, this.authority);
632
+ this.userStatsAccountPublicKey = (0, pda_1.getUserStatsAccountPublicKey)(this.program.programId, this.activeAuthority);
556
633
  return this.userStatsAccountPublicKey;
557
634
  }
558
- async getUserAccountPublicKey() {
559
- return this.getUser().userAccountPublicKey;
635
+ async getUserAccountPublicKey(subAccountId, authority) {
636
+ return this.getUser(subAccountId, authority).userAccountPublicKey;
560
637
  }
561
- getUserAccount(subAccountId) {
562
- return this.getUser(subAccountId).getUserAccount();
638
+ getUserAccount(subAccountId, authority) {
639
+ return this.getUser(subAccountId, authority).getUserAccount();
563
640
  }
564
641
  /**
565
642
  * Forces a fetch to rpc before returning accounts. Useful for anchor tests.
@@ -1059,9 +1136,10 @@ class DriftClient {
1059
1136
  const fromUser = await (0, pda_1.getUserAccountPublicKey)(this.program.programId, this.wallet.publicKey, fromSubAccountId);
1060
1137
  const toUser = await (0, pda_1.getUserAccountPublicKey)(this.program.programId, this.wallet.publicKey, toSubAccountId);
1061
1138
  let remainingAccounts;
1062
- if (this.users.has(fromSubAccountId)) {
1139
+ const userMapKey = this.getUserMapKey(fromSubAccountId, this.wallet.publicKey);
1140
+ if (this.users.has(userMapKey)) {
1063
1141
  remainingAccounts = this.getRemainingAccounts({
1064
- userAccounts: [this.users.get(fromSubAccountId).getUserAccount()],
1142
+ userAccounts: [this.users.get(userMapKey).getUserAccount()],
1065
1143
  useMarketLastSlotCache: true,
1066
1144
  writableSpotMarketIndexes: [marketIndex],
1067
1145
  });
@@ -1799,7 +1877,7 @@ class DriftClient {
1799
1877
  });
1800
1878
  }
1801
1879
  async forceCancelOrders(userAccountPublicKey, user, txParams) {
1802
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getForceCancelOrdersIx(userAccountPublicKey, user), txParams === null || txParams === void 0 ? void 0 : txParams.computeUnits, txParams === null || txParams === void 0 ? void 0 : txParams.computeUnitsPrice), [], this.opts);
1880
+ const { txSig } = await this.sendTransaction((0, utils_1.wrapInTx)(await this.getForceCancelOrdersIx(userAccountPublicKey, user), txParams === null || txParams === void 0 ? void 0 : txParams.computeUnits, txParams === null || txParams === void 0 ? void 0 : txParams.computeUnitsPrice), [], this.opts);
1803
1881
  return txSig;
1804
1882
  }
1805
1883
  async getForceCancelOrdersIx(userAccountPublicKey, userAccount) {
@@ -1819,7 +1897,7 @@ class DriftClient {
1819
1897
  });
1820
1898
  }
1821
1899
  async updateUserIdle(userAccountPublicKey, user, txParams) {
1822
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getUpdateUserIdleIx(userAccountPublicKey, user), txParams === null || txParams === void 0 ? void 0 : txParams.computeUnits, txParams === null || txParams === void 0 ? void 0 : txParams.computeUnitsPrice), [], this.opts);
1900
+ const { txSig } = await this.sendTransaction((0, utils_1.wrapInTx)(await this.getUpdateUserIdleIx(userAccountPublicKey, user), txParams === null || txParams === void 0 ? void 0 : txParams.computeUnits, txParams === null || txParams === void 0 ? void 0 : txParams.computeUnitsPrice), [], this.opts);
1823
1901
  return txSig;
1824
1902
  }
1825
1903
  async getUpdateUserIdleIx(userAccountPublicKey, userAccount) {
@@ -2679,6 +2757,31 @@ class DriftClient {
2679
2757
  };
2680
2758
  return extendedInfo;
2681
2759
  }
2760
+ /**
2761
+ * Returns the market index and type for a given market name
2762
+ * E.g. "SOL-PERP" -> { marketIndex: 0, marketType: MarketType.PERP }
2763
+ *
2764
+ * @param name
2765
+ */
2766
+ getMarketIndexAndType(name) {
2767
+ for (const perpMarketAccount of this.getPerpMarketAccounts()) {
2768
+ if ((0, userName_1.decodeName)(perpMarketAccount.name) === name) {
2769
+ return {
2770
+ marketIndex: perpMarketAccount.marketIndex,
2771
+ marketType: types_1.MarketType.PERP,
2772
+ };
2773
+ }
2774
+ }
2775
+ for (const spotMarketAccount of this.getSpotMarketAccounts()) {
2776
+ if ((0, userName_1.decodeName)(spotMarketAccount.name) === name) {
2777
+ return {
2778
+ marketIndex: spotMarketAccount.marketIndex,
2779
+ marketType: types_1.MarketType.SPOT,
2780
+ };
2781
+ }
2782
+ }
2783
+ return undefined;
2784
+ }
2682
2785
  sendTransaction(tx, additionalSigners, opts, preSigned) {
2683
2786
  return this.txSender.send(tx, additionalSigners, opts, preSigned);
2684
2787
  }
@@ -19,6 +19,9 @@ export type DriftClientConfig = {
19
19
  env?: DriftEnv;
20
20
  userStats?: boolean;
21
21
  authority?: PublicKey;
22
+ includeDelegates?: boolean;
23
+ authoritySubaccountMap?: Map<string, number[]>;
24
+ skipLoadUsers?: boolean;
22
25
  };
23
26
  export type DriftClientSubscriptionConfig = {
24
27
  type: 'websocket';
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.26.0-beta.1",
2
+ "version": "2.26.0-beta.3",
3
3
  "name": "drift",
4
4
  "instructions": [
5
5
  {
package/lib/index.d.ts CHANGED
@@ -68,6 +68,7 @@ export * from './dlob/DLOBOrders';
68
68
  export * from './dlob/NodeList';
69
69
  export * from './dlob/DLOBSubscriber';
70
70
  export * from './dlob/types';
71
+ export * from './dlob/orderBookLevels';
71
72
  export * from './userMap/userMap';
72
73
  export * from './userMap/userStatsMap';
73
74
  export * from './math/bankruptcy';
package/lib/index.js CHANGED
@@ -92,6 +92,7 @@ __exportStar(require("./dlob/DLOBOrders"), exports);
92
92
  __exportStar(require("./dlob/NodeList"), exports);
93
93
  __exportStar(require("./dlob/DLOBSubscriber"), exports);
94
94
  __exportStar(require("./dlob/types"), exports);
95
+ __exportStar(require("./dlob/orderBookLevels"), exports);
95
96
  __exportStar(require("./userMap/userMap"), exports);
96
97
  __exportStar(require("./userMap/userStatsMap"), exports);
97
98
  __exportStar(require("./math/bankruptcy"), exports);
@@ -3,7 +3,8 @@ import { BulkAccountLoader } from '../accounts/bulkAccountLoader';
3
3
  import { Market, Orderbook } from '@project-serum/serum';
4
4
  import { SerumMarketSubscriberConfig } from './types';
5
5
  import { BN } from '@coral-xyz/anchor';
6
- export declare class SerumSubscriber {
6
+ import { L2Level, L2OrderBookGenerator } from '../dlob/orderBookLevels';
7
+ export declare class SerumSubscriber implements L2OrderBookGenerator {
7
8
  connection: Connection;
8
9
  programId: PublicKey;
9
10
  marketAddress: PublicKey;
@@ -23,5 +24,8 @@ export declare class SerumSubscriber {
23
24
  subscribe(): Promise<void>;
24
25
  getBestBid(): BN | undefined;
25
26
  getBestAsk(): BN | undefined;
27
+ getL2Bids(): Generator<L2Level>;
28
+ getL2Asks(): Generator<L2Level>;
29
+ getL2Levels(side: 'bids' | 'asks'): Generator<L2Level>;
26
30
  unsubscribe(): Promise<void>;
27
31
  }
@@ -66,6 +66,28 @@ class SerumSubscriber {
66
66
  }
67
67
  return new anchor_1.BN(bestAsk[0] * numericConstants_1.PRICE_PRECISION.toNumber());
68
68
  }
69
+ getL2Bids() {
70
+ return this.getL2Levels('bids');
71
+ }
72
+ getL2Asks() {
73
+ return this.getL2Levels('asks');
74
+ }
75
+ *getL2Levels(side) {
76
+ // @ts-ignore
77
+ const basePrecision = Math.pow(10, this.market._baseSplTokenDecimals);
78
+ const pricePrecision = numericConstants_1.PRICE_PRECISION.toNumber();
79
+ for (const { price: priceNum, size: sizeNum } of this[side].items(side === 'bids')) {
80
+ const price = new anchor_1.BN(priceNum * pricePrecision);
81
+ const size = new anchor_1.BN(sizeNum * basePrecision);
82
+ yield {
83
+ price,
84
+ size,
85
+ sources: {
86
+ serum: size,
87
+ },
88
+ };
89
+ }
90
+ }
69
91
  async unsubscribe() {
70
92
  if (!this.subscribed) {
71
93
  return;
package/lib/types.d.ts CHANGED
@@ -660,6 +660,7 @@ export type HistoricalIndexData = {
660
660
  export type SpotMarketAccount = {
661
661
  status: MarketStatus;
662
662
  assetTier: AssetTier;
663
+ name: number[];
663
664
  marketIndex: number;
664
665
  pubkey: PublicKey;
665
666
  mint: PublicKey;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.26.0-beta.1",
3
+ "version": "2.26.0-beta.3",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.assert = void 0;
4
+ function assert(condition, error) {
5
+ if (!condition) {
6
+ throw new Error(error || 'Unspecified AssertionError');
7
+ }
8
+ }
9
+ exports.assert = assert;
package/src/config.ts CHANGED
@@ -18,6 +18,7 @@ type DriftConfig = {
18
18
  DRIFT_PROGRAM_ID: string;
19
19
  USDC_MINT_ADDRESS: string;
20
20
  SERUM_V3: string;
21
+ PHOENIX: string;
21
22
  V2_ALPHA_TICKET_MINT_ADDRESS: string;
22
23
  PERP_MARKETS: PerpMarketConfig[];
23
24
  SPOT_MARKETS: SpotMarketConfig[];
@@ -33,6 +34,7 @@ export const configs: { [key in DriftEnv]: DriftConfig } = {
33
34
  DRIFT_PROGRAM_ID: 'dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH',
34
35
  USDC_MINT_ADDRESS: '8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2',
35
36
  SERUM_V3: 'DESVgJVGajEgKGXhb6XmqDHGz3VjdgP7rEVESBgxmroY',
37
+ PHOENIX: 'PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY',
36
38
  V2_ALPHA_TICKET_MINT_ADDRESS:
37
39
  'DeEiGWfCMP9psnLGkxGrBBMEAW5Jv8bBGMN8DCtFRCyB',
38
40
  PERP_MARKETS: DevnetPerpMarkets,
@@ -45,6 +47,7 @@ export const configs: { [key in DriftEnv]: DriftConfig } = {
45
47
  DRIFT_PROGRAM_ID: 'dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH',
46
48
  USDC_MINT_ADDRESS: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
47
49
  SERUM_V3: 'srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX',
50
+ PHOENIX: 'PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY',
48
51
  V2_ALPHA_TICKET_MINT_ADDRESS:
49
52
  'Cmvhycb6LQvvzaShGw4iDHRLzeSSryioAsU98DSSkMNa',
50
53
  PERP_MARKETS: MainnetPerpMarkets,
@@ -17,6 +17,7 @@ export type SpotMarketConfig = {
17
17
  precision: BN;
18
18
  precisionExp: BN;
19
19
  serumMarket?: PublicKey;
20
+ phoenixMarket?: PublicKey;
20
21
  };
21
22
 
22
23
  export const WRAPPED_SOL_MINT = new PublicKey(
@@ -42,6 +43,9 @@ export const DevnetSpotMarkets: SpotMarketConfig[] = [
42
43
  precision: LAMPORTS_PRECISION,
43
44
  precisionExp: LAMPORTS_EXP,
44
45
  serumMarket: new PublicKey('8N37SsnTu8RYxtjrV9SStjkkwVhmU8aCWhLvwduAPEKW'),
46
+ phoenixMarket: new PublicKey(
47
+ '78ehDnHgbkFxqXZwdFxa8HK7saX58GymeX2wNGdkqYLp'
48
+ ),
45
49
  },
46
50
  {
47
51
  symbol: 'BTC',