@drift-labs/sdk 2.95.0-beta.2 → 2.95.0-beta.20

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 (36) hide show
  1. package/VERSION +1 -1
  2. package/lib/accounts/pollingDriftClientAccountSubscriber.d.ts +3 -1
  3. package/lib/accounts/pollingDriftClientAccountSubscriber.js +14 -4
  4. package/lib/accounts/types.d.ts +1 -1
  5. package/lib/accounts/webSocketDriftClientAccountSubscriber.d.ts +8 -1
  6. package/lib/accounts/webSocketDriftClientAccountSubscriber.js +66 -6
  7. package/lib/addresses/pda.d.ts +2 -0
  8. package/lib/addresses/pda.js +15 -1
  9. package/lib/config.d.ts +3 -0
  10. package/lib/config.js +2 -0
  11. package/lib/constants/perpMarkets.js +25 -4
  12. package/lib/constants/spotMarkets.js +10 -0
  13. package/lib/driftClient.js +6 -2
  14. package/lib/events/parse.d.ts +4 -0
  15. package/lib/events/parse.js +10 -3
  16. package/lib/idl/drift.json +8 -3
  17. package/lib/math/auction.d.ts +5 -1
  18. package/lib/math/auction.js +5 -1
  19. package/lib/math/insurance.d.ts +3 -1
  20. package/lib/math/insurance.js +31 -1
  21. package/lib/math/spotBalance.d.ts +3 -3
  22. package/lib/math/spotBalance.js +7 -7
  23. package/package.json +1 -1
  24. package/src/accounts/pollingDriftClientAccountSubscriber.ts +17 -5
  25. package/src/accounts/types.ts +1 -1
  26. package/src/accounts/webSocketDriftClientAccountSubscriber.ts +125 -12
  27. package/src/addresses/pda.ts +26 -0
  28. package/src/config.ts +8 -0
  29. package/src/constants/perpMarkets.ts +26 -4
  30. package/src/constants/spotMarkets.ts +11 -0
  31. package/src/driftClient.ts +11 -2
  32. package/src/events/parse.ts +12 -1
  33. package/src/idl/drift.json +8 -3
  34. package/src/math/auction.ts +16 -0
  35. package/src/math/insurance.ts +48 -2
  36. package/src/math/spotBalance.ts +13 -7
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.95.0-beta.2
1
+ 2.95.0-beta.20
@@ -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,46 @@ 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
86
+ .filter((accountInfo) => !!accountInfo)
87
+ .map((accountInfo) => {
88
+ const perpMarket = this.program.coder.accounts.decode('PerpMarket', accountInfo.data);
89
+ return [perpMarket.marketIndex, perpMarket];
90
+ }));
91
+ }
92
+ if (!this.initialSpotMarketAccountData) {
93
+ const spotMarketPublicKeys = this.spotMarketIndexes.map((marketIndex) => (0, pda_1.getSpotMarketPublicKeySync)(this.program.programId, marketIndex));
94
+ const spotMarketAccountInfos = await connection.getMultipleAccountsInfo(spotMarketPublicKeys);
95
+ this.initialSpotMarketAccountData = new Map(spotMarketAccountInfos
96
+ .filter((accountInfo) => !!accountInfo)
97
+ .map((accountInfo) => {
98
+ const spotMarket = this.program.coder.accounts.decode('SpotMarket', accountInfo.data);
99
+ return [spotMarket.marketIndex, spotMarket];
100
+ }));
101
+ }
102
+ const oracleAccountInfos = await connection.getMultipleAccountsInfo(this.oracleInfos.map((oracleInfo) => oracleInfo.publicKey));
103
+ this.initialOraclePriceData = new Map(this.oracleInfos
104
+ .filter((_, i) => !!oracleAccountInfos[i])
105
+ .map((oracleInfo, i) => {
106
+ const oracleClient = this.oracleClientCache.get(oracleInfo.source, connection, this.program);
107
+ const oraclePriceData = oracleClient.getOraclePriceDataFromBuffer(oracleAccountInfos[i].data);
108
+ return [oracleInfo.publicKey.toString(), oraclePriceData];
109
+ }));
110
+ }
111
+ removeInitialData() {
112
+ this.initialPerpMarketAccountData = new Map();
113
+ this.initialSpotMarketAccountData = new Map();
114
+ this.initialOraclePriceData = new Map();
115
+ }
70
116
  async subscribeToPerpMarketAccounts() {
71
117
  await Promise.all(this.perpMarketIndexes.map((marketIndex) => this.subscribeToPerpMarketAccount(marketIndex)));
72
118
  return true;
@@ -74,6 +120,7 @@ class WebSocketDriftClientAccountSubscriber {
74
120
  async subscribeToPerpMarketAccount(marketIndex) {
75
121
  const perpMarketPublicKey = await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, marketIndex);
76
122
  const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('perpMarket', this.program, perpMarketPublicKey, undefined, this.resubOpts, this.commitment);
123
+ accountSubscriber.setData(this.initialPerpMarketAccountData.get(marketIndex));
77
124
  await accountSubscriber.subscribe((data) => {
78
125
  this.eventEmitter.emit('perpMarketAccountUpdate', data);
79
126
  this.eventEmitter.emit('update');
@@ -88,6 +135,7 @@ class WebSocketDriftClientAccountSubscriber {
88
135
  async subscribeToSpotMarketAccount(marketIndex) {
89
136
  const marketPublicKey = await (0, pda_1.getSpotMarketPublicKey)(this.program.programId, marketIndex);
90
137
  const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('spotMarket', this.program, marketPublicKey, undefined, this.resubOpts, this.commitment);
138
+ accountSubscriber.setData(this.initialSpotMarketAccountData.get(marketIndex));
91
139
  await accountSubscriber.subscribe((data) => {
92
140
  this.eventEmitter.emit('spotMarketAccountUpdate', data);
93
141
  this.eventEmitter.emit('update');
@@ -102,15 +150,20 @@ class WebSocketDriftClientAccountSubscriber {
102
150
  return true;
103
151
  }
104
152
  async subscribeToOracle(oracleInfo) {
153
+ const oracleString = oracleInfo.publicKey.toString();
105
154
  const client = this.oracleClientCache.get(oracleInfo.source, this.program.provider.connection, this.program);
106
155
  const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('oracle', this.program, oracleInfo.publicKey, (buffer) => {
107
156
  return client.getOraclePriceDataFromBuffer(buffer);
108
157
  }, this.resubOpts, this.commitment);
158
+ const initialOraclePriceData = this.initialOraclePriceData.get(oracleString);
159
+ if (initialOraclePriceData) {
160
+ accountSubscriber.setData(initialOraclePriceData);
161
+ }
109
162
  await accountSubscriber.subscribe((data) => {
110
163
  this.eventEmitter.emit('oraclePriceUpdate', oracleInfo.publicKey, data);
111
164
  this.eventEmitter.emit('update');
112
165
  });
113
- this.oracleSubscribers.set(oracleInfo.publicKey.toString(), accountSubscriber);
166
+ this.oracleSubscribers.set(oracleString, accountSubscriber);
114
167
  return true;
115
168
  }
116
169
  async unsubscribeFromMarketAccounts() {
@@ -183,6 +236,7 @@ class WebSocketDriftClientAccountSubscriber {
183
236
  }));
184
237
  }
185
238
  this.perpOracleMap.set(perpMarketIndex, oracle);
239
+ this.perpOracleStringMap.set(perpMarketIndex, oracle.toBase58());
186
240
  }
187
241
  await Promise.all(addOraclePromises);
188
242
  }
@@ -203,6 +257,7 @@ class WebSocketDriftClientAccountSubscriber {
203
257
  }));
204
258
  }
205
259
  this.spotOracleMap.set(spotMarketIndex, oracle);
260
+ this.spotOracleStringMap.set(spotMarketIndex, oracle.toBase58());
206
261
  }
207
262
  await Promise.all(addOraclePromises);
208
263
  }
@@ -231,17 +286,21 @@ class WebSocketDriftClientAccountSubscriber {
231
286
  }
232
287
  getOraclePriceDataAndSlot(oraclePublicKey) {
233
288
  this.assertIsSubscribed();
234
- if (oraclePublicKey.equals(web3_js_1.PublicKey.default)) {
289
+ const oracleString = typeof oraclePublicKey === 'string'
290
+ ? oraclePublicKey
291
+ : oraclePublicKey.toBase58();
292
+ if (oracleString === ORACLE_DEFAULT_KEY) {
235
293
  return {
236
294
  data: quoteAssetOracleClient_1.QUOTE_ORACLE_PRICE_DATA,
237
295
  slot: 0,
238
296
  };
239
297
  }
240
- return this.oracleSubscribers.get(oraclePublicKey.toString()).dataAndSlot;
298
+ return this.oracleSubscribers.get(oracleString).dataAndSlot;
241
299
  }
242
300
  getOraclePriceDataAndSlotForPerpMarket(marketIndex) {
243
301
  const perpMarketAccount = this.getMarketAccountAndSlot(marketIndex);
244
302
  const oracle = this.perpOracleMap.get(marketIndex);
303
+ const oracleString = this.perpOracleStringMap.get(marketIndex);
245
304
  if (!perpMarketAccount || !oracle) {
246
305
  return undefined;
247
306
  }
@@ -249,11 +308,12 @@ class WebSocketDriftClientAccountSubscriber {
249
308
  // If the oracle has changed, we need to update the oracle map in background
250
309
  this.setPerpOracleMap();
251
310
  }
252
- return this.getOraclePriceDataAndSlot(oracle);
311
+ return this.getOraclePriceDataAndSlot(oracleString);
253
312
  }
254
313
  getOraclePriceDataAndSlotForSpotMarket(marketIndex) {
255
314
  const spotMarketAccount = this.getSpotMarketAccountAndSlot(marketIndex);
256
315
  const oracle = this.spotOracleMap.get(marketIndex);
316
+ const oracleString = this.spotOracleStringMap.get(marketIndex);
257
317
  if (!spotMarketAccount || !oracle) {
258
318
  return undefined;
259
319
  }
@@ -261,7 +321,7 @@ class WebSocketDriftClientAccountSubscriber {
261
321
  // If the oracle has changed, we need to update the oracle map in background
262
322
  this.setSpotOracleMap();
263
323
  }
264
- return this.getOraclePriceDataAndSlot(oracle);
324
+ return this.getOraclePriceDataAndSlot(oracleString);
265
325
  }
266
326
  }
267
327
  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
  }
@@ -65,10 +65,10 @@ exports.DevnetPerpMarkets = [
65
65
  symbol: 'MATIC-PERP',
66
66
  baseAssetSymbol: 'MATIC',
67
67
  marketIndex: 5,
68
- oracle: new web3_js_1.PublicKey('5Wf1WrXLeNJghU8WRo5odvwAjpjSSF4THbjdxbKmwVsi'),
68
+ oracle: new web3_js_1.PublicKey('BrzyDgwELy4jjjsqLQpBeUxzrsueYyMhuWpYBaUYcXvi'),
69
69
  launchTs: 1677690149000,
70
70
  oracleSource: __1.OracleSource.PYTH_PULL,
71
- pythFeedId: '0x5de33a9112c2b700b8d30b8a3402c103578ccfa2765696471cc672bd5cf6ac52',
71
+ pythFeedId: '0xffd11c5a1cfd42f80afb2df4d9f264c15f956d68153335374ec10722edd70472',
72
72
  },
73
73
  {
74
74
  fullName: 'Arbitrum',
@@ -373,10 +373,10 @@ exports.MainnetPerpMarkets = [
373
373
  symbol: 'MATIC-PERP',
374
374
  baseAssetSymbol: 'MATIC',
375
375
  marketIndex: 5,
376
- oracle: new web3_js_1.PublicKey('5Wf1WrXLeNJghU8WRo5odvwAjpjSSF4THbjdxbKmwVsi'),
376
+ oracle: new web3_js_1.PublicKey('BrzyDgwELy4jjjsqLQpBeUxzrsueYyMhuWpYBaUYcXvi'),
377
377
  launchTs: 1677690149000,
378
378
  oracleSource: __1.OracleSource.PYTH_PULL,
379
- pythFeedId: '0x5de33a9112c2b700b8d30b8a3402c103578ccfa2765696471cc672bd5cf6ac52',
379
+ pythFeedId: '0xffd11c5a1cfd42f80afb2df4d9f264c15f956d68153335374ec10722edd70472',
380
380
  },
381
381
  {
382
382
  fullName: 'Arbitrum',
@@ -757,6 +757,27 @@ exports.MainnetPerpMarkets = [
757
757
  launchTs: 1724250126000,
758
758
  oracleSource: __1.OracleSource.Prelaunch,
759
759
  },
760
+ {
761
+ fullName: 'DEMOCRATS-WIN-MICHIGAN-BET',
762
+ category: ['Prediction', 'Election'],
763
+ symbol: 'DEMOCRATS-WIN-MICHIGAN-BET',
764
+ baseAssetSymbol: 'DEMOCRATS-WIN-MICHIGAN',
765
+ marketIndex: 41,
766
+ oracle: new web3_js_1.PublicKey('8HTDLjhb2esGU5mu11v3pq3eWeFqmvKPkQNCnTTwKAyB'),
767
+ launchTs: 1725551484000,
768
+ oracleSource: __1.OracleSource.Prelaunch,
769
+ },
770
+ {
771
+ fullName: 'TON',
772
+ category: ['L1'],
773
+ symbol: 'TON-PERP',
774
+ baseAssetSymbol: 'TON',
775
+ marketIndex: 42,
776
+ oracle: new web3_js_1.PublicKey('BNjCXrpEqjdBnuRy2SAUgm5Pq8B73wGFwsf6RYFJiLPY'),
777
+ launchTs: 1725551484000,
778
+ oracleSource: __1.OracleSource.PYTH_PULL,
779
+ pythFeedId: '0x8963217838ab4cf5cadc172203c1f0b763fbaa45f346d8ee50ba994bbcac3026',
780
+ },
760
781
  ];
761
782
  exports.PerpMarkets = {
762
783
  devnet: exports.DevnetPerpMarkets,
@@ -333,6 +333,16 @@ exports.MainnetSpotMarkets = [
333
333
  precisionExp: numericConstants_1.NINE,
334
334
  pythFeedId: '0xca3ba9a619a4b3755c10ac7d5e760275aa95e9823d38a84fedd416856cdba37c',
335
335
  },
336
+ {
337
+ symbol: 'BNSOL',
338
+ marketIndex: 25,
339
+ oracle: new web3_js_1.PublicKey('BAtFj4kQttZRVep3UZS2aZRDixkGYgWsbqTBVDbnSsPF'),
340
+ oracleSource: __1.OracleSource.PYTH_PULL,
341
+ mint: new web3_js_1.PublicKey('BNso1VUJnh4zcfpZa6986Ea66P6TCp59hvtNJ8b1X85'),
342
+ precision: numericConstants_1.LAMPORTS_PRECISION,
343
+ precisionExp: numericConstants_1.LAMPORTS_EXP,
344
+ pythFeedId: '0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d',
345
+ },
336
346
  ];
337
347
  exports.SpotMarkets = {
338
348
  devnet: exports.DevnetSpotMarkets,
@@ -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);
@@ -1725,10 +1725,14 @@ class DriftClient {
1725
1725
  writablePerpMarketIndexes: [marketIndex],
1726
1726
  writableSpotMarketIndexes: [numericConstants_1.QUOTE_SPOT_MARKET_INDEX],
1727
1727
  });
1728
+ const perpMarketPublicKey = await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, marketIndex);
1728
1729
  return await this.program.instruction.settleExpiredMarket(marketIndex, {
1729
1730
  accounts: {
1730
1731
  state: await this.getStatePublicKey(),
1731
- authority: this.wallet.publicKey,
1732
+ admin: this.isSubscribed
1733
+ ? this.getStateAccount().admin
1734
+ : this.wallet.publicKey,
1735
+ perpMarket: perpMarketPublicKey,
1732
1736
  },
1733
1737
  remainingAccounts,
1734
1738
  });
@@ -1,2 +1,6 @@
1
1
  import { Program, Event } from '@coral-xyz/anchor';
2
2
  export declare function parseLogs(program: Program, logs: string[], programId?: string): Event[];
3
+ export declare function parseLogsWithRaw(program: Program, logs: string[], programId?: string): {
4
+ events: Event[];
5
+ rawLogs: string[];
6
+ };
@@ -1,13 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseLogs = void 0;
3
+ exports.parseLogsWithRaw = exports.parseLogs = void 0;
4
4
  const driftProgramId = 'dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH';
5
5
  const PROGRAM_LOG = 'Program log: ';
6
6
  const PROGRAM_DATA = 'Program data: ';
7
7
  const PROGRAM_LOG_START_INDEX = PROGRAM_LOG.length;
8
8
  const PROGRAM_DATA_START_INDEX = PROGRAM_DATA.length;
9
9
  function parseLogs(program, logs, programId = driftProgramId) {
10
+ const { events } = parseLogsWithRaw(program, logs, programId);
11
+ return events;
12
+ }
13
+ exports.parseLogs = parseLogs;
14
+ function parseLogsWithRaw(program, logs, programId = driftProgramId) {
10
15
  const events = [];
16
+ const rawLogs = [];
11
17
  const execution = new ExecutionContext();
12
18
  for (const log of logs) {
13
19
  if (log.startsWith('Log truncated')) {
@@ -16,6 +22,7 @@ function parseLogs(program, logs, programId = driftProgramId) {
16
22
  const [event, newProgram, didPop] = handleLog(execution, log, program, programId);
17
23
  if (event) {
18
24
  events.push(event);
25
+ rawLogs.push(log);
19
26
  }
20
27
  if (newProgram) {
21
28
  execution.push(newProgram);
@@ -24,9 +31,9 @@ function parseLogs(program, logs, programId = driftProgramId) {
24
31
  execution.pop();
25
32
  }
26
33
  }
27
- return events;
34
+ return { events, rawLogs };
28
35
  }
29
- exports.parseLogs = parseLogs;
36
+ exports.parseLogsWithRaw = parseLogsWithRaw;
30
37
  function handleLog(execution, log, program, programId = driftProgramId) {
31
38
  // Executing program is drift program.
32
39
  if (execution.stack.length > 0 && execution.program() === programId) {
@@ -1606,15 +1606,20 @@
1606
1606
  {
1607
1607
  "name": "settleExpiredMarket",
1608
1608
  "accounts": [
1609
+ {
1610
+ "name": "admin",
1611
+ "isMut": false,
1612
+ "isSigner": true
1613
+ },
1609
1614
  {
1610
1615
  "name": "state",
1611
1616
  "isMut": false,
1612
1617
  "isSigner": false
1613
1618
  },
1614
1619
  {
1615
- "name": "authority",
1616
- "isMut": false,
1617
- "isSigner": true
1620
+ "name": "perpMarket",
1621
+ "isMut": true,
1622
+ "isSigner": false
1618
1623
  }
1619
1624
  ],
1620
1625
  "args": [
@@ -6,12 +6,16 @@ export declare function isFallbackAvailableLiquiditySource(order: Order, minAuct
6
6
  export declare function getAuctionPrice(order: Order, slot: number, oraclePrice: BN): BN;
7
7
  export declare function getAuctionPriceForFixedAuction(order: Order, slot: number): BN;
8
8
  export declare function getAuctionPriceForOracleOffsetAuction(order: Order, slot: number, oraclePrice: BN): BN;
9
- export declare function deriveOracleAuctionParams({ direction, oraclePrice, auctionStartPrice, auctionEndPrice, limitPrice, }: {
9
+ export declare function deriveOracleAuctionParams({ direction, oraclePrice, auctionStartPrice, auctionEndPrice, limitPrice, auctionPriceCaps, }: {
10
10
  direction: PositionDirection;
11
11
  oraclePrice: BN;
12
12
  auctionStartPrice: BN;
13
13
  auctionEndPrice: BN;
14
14
  limitPrice: BN;
15
+ auctionPriceCaps?: {
16
+ min: BN;
17
+ max: BN;
18
+ };
15
19
  }): {
16
20
  auctionStartPrice: BN;
17
21
  auctionEndPrice: BN;
@@ -94,7 +94,7 @@ function getAuctionPriceForOracleOffsetAuction(order, slot, oraclePrice) {
94
94
  return _1.BN.max(oraclePrice.add(priceOffset), _1.ONE);
95
95
  }
96
96
  exports.getAuctionPriceForOracleOffsetAuction = getAuctionPriceForOracleOffsetAuction;
97
- function deriveOracleAuctionParams({ direction, oraclePrice, auctionStartPrice, auctionEndPrice, limitPrice, }) {
97
+ function deriveOracleAuctionParams({ direction, oraclePrice, auctionStartPrice, auctionEndPrice, limitPrice, auctionPriceCaps, }) {
98
98
  let oraclePriceOffset;
99
99
  if (limitPrice.eq(_1.ZERO) || oraclePrice.eq(_1.ZERO)) {
100
100
  oraclePriceOffset = _1.ZERO;
@@ -114,6 +114,10 @@ function deriveOracleAuctionParams({ direction, oraclePrice, auctionStartPrice,
114
114
  catch (e) {
115
115
  oraclePriceOffsetNum = 0;
116
116
  }
117
+ if (auctionPriceCaps) {
118
+ auctionStartPrice = _1.BN.min(_1.BN.max(auctionStartPrice, auctionPriceCaps.min), auctionPriceCaps.max);
119
+ auctionEndPrice = _1.BN.min(_1.BN.max(auctionEndPrice, auctionPriceCaps.min), auctionPriceCaps.max);
120
+ }
117
121
  return {
118
122
  auctionStartPrice: auctionStartPrice.sub(oraclePrice),
119
123
  auctionEndPrice: auctionEndPrice.sub(oraclePrice),
@@ -1,5 +1,7 @@
1
1
  /// <reference types="bn.js" />
2
- import { BN } from '../index';
2
+ import { BN, SpotMarketAccount } from '../index';
3
+ export declare function nextRevenuePoolSettleApr(spotMarket: SpotMarketAccount, vaultBalance: BN, // vault token amount
4
+ amount?: BN): number;
3
5
  export declare function stakeAmountToShares(amount: BN, totalIfShares: BN, insuranceFundVaultBalance: BN): BN;
4
6
  export declare function unstakeSharesToAmount(nShares: BN, totalIfShares: BN, insuranceFundVaultBalance: BN): BN;
5
7
  export declare function unstakeSharesToAmountWithOpenRequest(nShares: BN, withdrawRequestShares: BN, withdrawRequestAmount: BN, totalIfShares: BN, insuranceFundVaultBalance: BN): BN;