@drift-labs/sdk 0.2.0-master.4 → 0.2.0-master.40

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 (234) hide show
  1. package/README.md +27 -27
  2. package/lib/accounts/bulkAccountLoader.d.ts +2 -0
  3. package/lib/accounts/bulkAccountLoader.js +36 -29
  4. package/lib/accounts/bulkUserStatsSubscription.d.ts +7 -0
  5. package/lib/accounts/bulkUserStatsSubscription.js +21 -0
  6. package/lib/accounts/bulkUserSubscription.d.ts +2 -2
  7. package/lib/accounts/bulkUserSubscription.js +0 -1
  8. package/lib/accounts/fetch.d.ts +2 -1
  9. package/lib/accounts/fetch.js +9 -1
  10. package/lib/accounts/{pollingClearingHouseAccountSubscriber.d.ts → pollingDriftClientAccountSubscriber.d.ts} +20 -25
  11. package/lib/accounts/{pollingClearingHouseAccountSubscriber.js → pollingDriftClientAccountSubscriber.js} +45 -49
  12. package/lib/accounts/{pollingOracleSubscriber.d.ts → pollingOracleAccountSubscriber.d.ts} +2 -2
  13. package/lib/accounts/{pollingOracleSubscriber.js → pollingOracleAccountSubscriber.js} +3 -3
  14. package/lib/accounts/pollingUserStatsAccountSubscriber.d.ts +27 -0
  15. package/lib/accounts/pollingUserStatsAccountSubscriber.js +113 -0
  16. package/lib/accounts/types.d.ts +26 -15
  17. package/lib/accounts/webSocketDriftClientAccountSubscriber.d.ts +49 -0
  18. package/lib/accounts/{webSocketClearingHouseAccountSubscriber.js → webSocketDriftClientAccountSubscriber.js} +47 -45
  19. package/lib/accounts/webSocketUserStatsAccountSubsriber.d.ts +20 -0
  20. package/lib/accounts/webSocketUserStatsAccountSubsriber.js +47 -0
  21. package/lib/addresses/marketAddresses.d.ts +1 -3
  22. package/lib/addresses/marketAddresses.js +1 -1
  23. package/lib/addresses/pda.d.ts +15 -9
  24. package/lib/addresses/pda.js +73 -35
  25. package/lib/adminClient.d.ts +65 -0
  26. package/lib/adminClient.js +637 -0
  27. package/lib/config.d.ts +9 -9
  28. package/lib/config.js +25 -21
  29. package/lib/constants/numericConstants.d.ts +30 -12
  30. package/lib/constants/numericConstants.js +41 -21
  31. package/lib/constants/perpMarkets.d.ts +18 -0
  32. package/lib/constants/{markets.js → perpMarkets.js} +7 -7
  33. package/lib/constants/spotMarkets.d.ts +19 -0
  34. package/lib/constants/spotMarkets.js +53 -0
  35. package/lib/dlob/DLOB.d.ts +82 -0
  36. package/lib/dlob/DLOB.js +696 -0
  37. package/lib/dlob/DLOBNode.d.ts +54 -0
  38. package/lib/dlob/DLOBNode.js +77 -0
  39. package/lib/dlob/NodeList.d.ts +27 -0
  40. package/lib/dlob/NodeList.js +144 -0
  41. package/lib/driftClient.d.ts +233 -0
  42. package/lib/driftClient.js +2096 -0
  43. package/lib/{clearingHouseConfig.d.ts → driftClientConfig.d.ts} +9 -9
  44. package/lib/{clearingHouseConfig.js → driftClientConfig.js} +0 -0
  45. package/lib/events/eventList.js +3 -0
  46. package/lib/events/eventSubscriber.d.ts +5 -2
  47. package/lib/events/eventSubscriber.js +25 -11
  48. package/lib/events/fetchLogs.d.ts +13 -2
  49. package/lib/events/fetchLogs.js +40 -12
  50. package/lib/events/pollingLogProvider.d.ts +2 -1
  51. package/lib/events/pollingLogProvider.js +7 -3
  52. package/lib/events/sort.js +8 -11
  53. package/lib/events/types.d.ts +9 -3
  54. package/lib/events/types.js +6 -0
  55. package/lib/events/webSocketLogProvider.js +1 -1
  56. package/lib/examples/makeTradeExample.js +30 -18
  57. package/lib/factory/bigNum.d.ts +8 -4
  58. package/lib/factory/bigNum.js +109 -19
  59. package/lib/idl/drift.json +8250 -0
  60. package/lib/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
  61. package/lib/index.d.ts +30 -13
  62. package/lib/index.js +30 -13
  63. package/lib/math/amm.d.ts +9 -6
  64. package/lib/math/amm.js +91 -38
  65. package/lib/math/conversion.js +1 -1
  66. package/lib/math/exchangeStatus.d.ts +4 -0
  67. package/lib/math/exchangeStatus.js +18 -0
  68. package/lib/math/funding.d.ts +6 -6
  69. package/lib/math/funding.js +23 -21
  70. package/lib/math/insurance.d.ts +4 -0
  71. package/lib/math/insurance.js +27 -0
  72. package/lib/math/margin.d.ts +11 -0
  73. package/lib/math/margin.js +82 -0
  74. package/lib/math/market.d.ts +14 -9
  75. package/lib/math/market.js +70 -10
  76. package/lib/math/oracles.d.ts +4 -0
  77. package/lib/math/oracles.js +36 -8
  78. package/lib/math/orders.d.ts +14 -6
  79. package/lib/math/orders.js +90 -17
  80. package/lib/math/position.d.ts +27 -13
  81. package/lib/math/position.js +92 -36
  82. package/lib/math/repeg.js +17 -8
  83. package/lib/math/spotBalance.d.ts +22 -0
  84. package/lib/math/spotBalance.js +192 -0
  85. package/lib/math/spotMarket.d.ts +4 -0
  86. package/lib/math/spotMarket.js +8 -0
  87. package/lib/math/spotPosition.d.ts +6 -0
  88. package/lib/math/spotPosition.js +23 -0
  89. package/lib/math/trade.d.ts +10 -10
  90. package/lib/math/trade.js +27 -31
  91. package/lib/oracles/pythClient.js +1 -1
  92. package/lib/oracles/quoteAssetOracleClient.js +1 -1
  93. package/lib/oracles/switchboardClient.js +1 -1
  94. package/lib/orderParams.d.ts +4 -4
  95. package/lib/orderParams.js +12 -4
  96. package/lib/serum/serumFulfillmentConfigMap.d.ts +10 -0
  97. package/lib/serum/serumFulfillmentConfigMap.js +17 -0
  98. package/lib/serum/serumSubscriber.d.ts +27 -0
  99. package/lib/serum/serumSubscriber.js +56 -0
  100. package/lib/serum/types.d.ts +11 -0
  101. package/lib/{clearingHouseUserConfig.js → serum/types.js} +0 -0
  102. package/lib/slot/SlotSubscriber.d.ts +7 -0
  103. package/lib/slot/SlotSubscriber.js +3 -0
  104. package/lib/{mockUSDCFaucet.d.ts → tokenFaucet.d.ts} +8 -5
  105. package/lib/{mockUSDCFaucet.js → tokenFaucet.js} +63 -51
  106. package/lib/tx/retryTxSender.d.ts +1 -1
  107. package/lib/tx/retryTxSender.js +13 -4
  108. package/lib/tx/types.d.ts +1 -1
  109. package/lib/tx/utils.js +1 -1
  110. package/lib/types.d.ts +589 -196
  111. package/lib/types.js +108 -17
  112. package/lib/user.d.ts +226 -0
  113. package/lib/user.js +949 -0
  114. package/lib/userConfig.d.ts +14 -0
  115. package/lib/userConfig.js +2 -0
  116. package/lib/userMap/userMap.d.ts +41 -0
  117. package/lib/userMap/userMap.js +85 -0
  118. package/lib/userMap/userStatsMap.d.ts +19 -0
  119. package/lib/userMap/userStatsMap.js +68 -0
  120. package/lib/userName.d.ts +1 -0
  121. package/lib/userName.js +3 -2
  122. package/lib/userStats.d.ts +18 -0
  123. package/lib/userStats.js +49 -0
  124. package/lib/userStatsConfig.d.ts +14 -0
  125. package/lib/userStatsConfig.js +2 -0
  126. package/lib/util/computeUnits.js +1 -1
  127. package/lib/util/getTokenAddress.d.ts +2 -0
  128. package/lib/util/getTokenAddress.js +9 -0
  129. package/package.json +10 -3
  130. package/src/accounts/bulkAccountLoader.ts +44 -34
  131. package/src/accounts/bulkUserStatsSubscription.ts +33 -0
  132. package/src/accounts/bulkUserSubscription.ts +2 -3
  133. package/src/accounts/fetch.ts +27 -2
  134. package/src/accounts/{pollingClearingHouseAccountSubscriber.ts → pollingDriftClientAccountSubscriber.ts} +65 -75
  135. package/src/accounts/{pollingOracleSubscriber.ts → pollingOracleAccountSubscriber.ts} +2 -2
  136. package/src/accounts/pollingUserStatsAccountSubscriber.ts +172 -0
  137. package/src/accounts/types.ts +35 -15
  138. package/src/accounts/{webSocketClearingHouseAccountSubscriber.ts → webSocketDriftClientAccountSubscriber.ts} +78 -73
  139. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +80 -0
  140. package/src/addresses/marketAddresses.ts +3 -4
  141. package/src/addresses/pda.ts +105 -33
  142. package/src/adminClient.ts +1207 -0
  143. package/src/config.ts +37 -31
  144. package/src/constants/numericConstants.ts +58 -24
  145. package/src/constants/{markets.ts → perpMarkets.ts} +10 -10
  146. package/src/constants/spotMarkets.ts +73 -0
  147. package/src/dlob/DLOB.ts +1123 -0
  148. package/src/dlob/DLOBNode.ts +155 -0
  149. package/src/dlob/NodeList.ts +195 -0
  150. package/src/driftClient.ts +3564 -0
  151. package/src/{clearingHouseConfig.ts → driftClientConfig.ts} +9 -8
  152. package/src/events/eventList.ts +3 -0
  153. package/src/events/eventSubscriber.ts +36 -14
  154. package/src/events/fetchLogs.ts +55 -13
  155. package/src/events/pollingLogProvider.ts +11 -3
  156. package/src/events/sort.ts +11 -15
  157. package/src/events/types.ts +21 -2
  158. package/src/events/webSocketLogProvider.ts +1 -1
  159. package/src/examples/makeTradeExample.ts +44 -28
  160. package/src/factory/bigNum.ts +150 -22
  161. package/src/idl/drift.json +8250 -0
  162. package/src/idl/pyth.json +98 -2
  163. package/src/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
  164. package/src/index.ts +30 -13
  165. package/src/math/amm.ts +161 -48
  166. package/src/math/conversion.ts +2 -2
  167. package/src/math/exchangeStatus.ts +31 -0
  168. package/src/math/funding.ts +41 -31
  169. package/src/math/insurance.ts +35 -0
  170. package/src/math/margin.ts +133 -0
  171. package/src/math/market.ts +143 -14
  172. package/src/math/oracles.ts +63 -9
  173. package/src/math/orders.ts +163 -26
  174. package/src/math/position.ts +136 -58
  175. package/src/math/repeg.ts +19 -9
  176. package/src/math/spotBalance.ts +319 -0
  177. package/src/math/spotMarket.ts +9 -0
  178. package/src/math/spotPosition.ts +47 -0
  179. package/src/math/trade.ts +33 -37
  180. package/src/oracles/pythClient.ts +2 -2
  181. package/src/oracles/quoteAssetOracleClient.ts +2 -2
  182. package/src/oracles/switchboardClient.ts +2 -2
  183. package/src/orderParams.ts +16 -8
  184. package/src/serum/serumFulfillmentConfigMap.ts +26 -0
  185. package/src/serum/serumSubscriber.ts +99 -0
  186. package/src/serum/types.ts +13 -0
  187. package/src/slot/SlotSubscriber.ts +11 -1
  188. package/src/{mockUSDCFaucet.ts → tokenFaucet.ts} +82 -70
  189. package/src/tx/retryTxSender.ts +16 -5
  190. package/src/tx/types.ts +2 -1
  191. package/src/tx/utils.ts +1 -1
  192. package/src/types.ts +572 -178
  193. package/src/user.ts +1582 -0
  194. package/src/{clearingHouseUserConfig.ts → userConfig.ts} +5 -5
  195. package/src/userMap/userMap.ts +124 -0
  196. package/src/userMap/userStatsMap.ts +108 -0
  197. package/src/userName.ts +2 -1
  198. package/src/userStats.ts +75 -0
  199. package/src/userStatsConfig.ts +18 -0
  200. package/src/util/computeUnits.ts +1 -1
  201. package/src/util/getTokenAddress.ts +18 -0
  202. package/tests/bn/test.ts +46 -11
  203. package/tests/dlob/helpers.ts +611 -0
  204. package/tests/dlob/test.ts +4588 -0
  205. package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +0 -49
  206. package/lib/admin.d.ts +0 -44
  207. package/lib/admin.js +0 -433
  208. package/lib/clearingHouse.d.ts +0 -133
  209. package/lib/clearingHouse.js +0 -931
  210. package/lib/clearingHouseUser.d.ts +0 -187
  211. package/lib/clearingHouseUser.js +0 -643
  212. package/lib/clearingHouseUserConfig.d.ts +0 -14
  213. package/lib/constants/banks.d.ts +0 -16
  214. package/lib/constants/banks.js +0 -34
  215. package/lib/constants/markets.d.ts +0 -19
  216. package/lib/idl/clearing_house.json +0 -3998
  217. package/lib/math/bankBalance.d.ts +0 -9
  218. package/lib/math/bankBalance.js +0 -75
  219. package/lib/math/state.d.ts +0 -8
  220. package/lib/math/state.js +0 -15
  221. package/lib/orders.d.ts +0 -8
  222. package/lib/orders.js +0 -134
  223. package/src/admin.ts +0 -722
  224. package/src/clearingHouse.ts +0 -1451
  225. package/src/clearingHouseUser.ts +0 -989
  226. package/src/constants/banks.ts +0 -43
  227. package/src/idl/clearing_house.json +0 -3998
  228. package/src/math/bankBalance.ts +0 -112
  229. package/src/math/state.ts +0 -14
  230. package/src/math/utils.js +0 -27
  231. package/src/math/utils.js.map +0 -1
  232. package/src/orders.ts +0 -244
  233. package/src/util/computeUnits.js +0 -17
  234. package/src/util/computeUnits.js.map +0 -1
@@ -1,24 +1,24 @@
1
1
  import {
2
2
  DataAndSlot,
3
3
  AccountToPoll,
4
- ClearingHouseAccountEvents,
5
- ClearingHouseAccountSubscriber,
4
+ DriftClientAccountEvents,
5
+ DriftClientAccountSubscriber,
6
6
  NotSubscribedError,
7
7
  OraclesToPoll,
8
8
  } from './types';
9
- import { BN, Program } from '@project-serum/anchor';
9
+ import { Program } from '@project-serum/anchor';
10
10
  import StrictEventEmitter from 'strict-event-emitter-types';
11
11
  import { EventEmitter } from 'events';
12
12
  import {
13
- BankAccount,
14
- MarketAccount,
13
+ SpotMarketAccount,
14
+ PerpMarketAccount,
15
15
  StateAccount,
16
16
  UserAccount,
17
17
  } from '../types';
18
18
  import {
19
- getClearingHouseStateAccountPublicKey,
20
- getBankPublicKey,
21
- getMarketPublicKey,
19
+ getDriftStateAccountPublicKey,
20
+ getSpotMarketPublicKey,
21
+ getPerpMarketPublicKey,
22
22
  } from '../addresses/pda';
23
23
  import { BulkAccountLoader } from './bulkAccountLoader';
24
24
  import { capitalize } from './utils';
@@ -27,17 +27,17 @@ import { OracleInfo, OraclePriceData } from '../oracles/types';
27
27
  import { OracleClientCache } from '../oracles/oracleClientCache';
28
28
  import { QUOTE_ORACLE_PRICE_DATA } from '../oracles/quoteAssetOracleClient';
29
29
 
30
- export class PollingClearingHouseAccountSubscriber
31
- implements ClearingHouseAccountSubscriber
30
+ export class PollingDriftClientAccountSubscriber
31
+ implements DriftClientAccountSubscriber
32
32
  {
33
33
  isSubscribed: boolean;
34
34
  program: Program;
35
- marketIndexes: BN[];
36
- bankIndexes: BN[];
35
+ perpMarketIndexes: number[];
36
+ spotMarketIndexes: number[];
37
37
  oracleInfos: OracleInfo[];
38
38
  oracleClientCache = new OracleClientCache();
39
39
 
40
- eventEmitter: StrictEventEmitter<EventEmitter, ClearingHouseAccountEvents>;
40
+ eventEmitter: StrictEventEmitter<EventEmitter, DriftClientAccountEvents>;
41
41
 
42
42
  accountLoader: BulkAccountLoader;
43
43
  accountsToPoll = new Map<string, AccountToPoll>();
@@ -45,8 +45,8 @@ export class PollingClearingHouseAccountSubscriber
45
45
  errorCallbackId?: string;
46
46
 
47
47
  state?: DataAndSlot<StateAccount>;
48
- market = new Map<number, DataAndSlot<MarketAccount>>();
49
- bank = new Map<number, DataAndSlot<BankAccount>>();
48
+ perpMarket = new Map<number, DataAndSlot<PerpMarketAccount>>();
49
+ spotMarket = new Map<number, DataAndSlot<SpotMarketAccount>>();
50
50
  oracles = new Map<string, DataAndSlot<OraclePriceData>>();
51
51
  user?: DataAndSlot<UserAccount>;
52
52
 
@@ -57,16 +57,16 @@ export class PollingClearingHouseAccountSubscriber
57
57
  public constructor(
58
58
  program: Program,
59
59
  accountLoader: BulkAccountLoader,
60
- marketIndexes: BN[],
61
- bankIndexes: BN[],
60
+ perpMarketIndexes: number[],
61
+ spotMarketIndexes: number[],
62
62
  oracleInfos: OracleInfo[]
63
63
  ) {
64
64
  this.isSubscribed = false;
65
65
  this.program = program;
66
66
  this.eventEmitter = new EventEmitter();
67
67
  this.accountLoader = accountLoader;
68
- this.marketIndexes = marketIndexes;
69
- this.bankIndexes = bankIndexes;
68
+ this.perpMarketIndexes = perpMarketIndexes;
69
+ this.spotMarketIndexes = spotMarketIndexes;
70
70
  this.oracleInfos = oracleInfos;
71
71
  }
72
72
 
@@ -113,60 +113,62 @@ export class PollingClearingHouseAccountSubscriber
113
113
  return;
114
114
  }
115
115
 
116
- const accounts = await this.getClearingHouseAccounts();
116
+ const statePublicKey = await getDriftStateAccountPublicKey(
117
+ this.program.programId
118
+ );
117
119
 
118
- this.accountsToPoll.set(accounts.state.toString(), {
120
+ this.accountsToPoll.set(statePublicKey.toString(), {
119
121
  key: 'state',
120
- publicKey: accounts.state,
122
+ publicKey: statePublicKey,
121
123
  eventType: 'stateAccountUpdate',
122
124
  });
123
125
 
124
- await this.updateMarketAccountsToPoll();
125
- await this.updateBankAccountsToPoll();
126
+ await this.updatePerpMarketAccountsToPoll();
127
+ await this.updateSpotMarketAccountsToPoll();
126
128
  }
127
129
 
128
- async updateMarketAccountsToPoll(): Promise<boolean> {
129
- for (const marketIndex of this.marketIndexes) {
130
- await this.addMarketAccountToPoll(marketIndex);
130
+ async updatePerpMarketAccountsToPoll(): Promise<boolean> {
131
+ for (const marketIndex of this.perpMarketIndexes) {
132
+ await this.addPerpMarketAccountToPoll(marketIndex);
131
133
  }
132
134
  return true;
133
135
  }
134
136
 
135
- async addMarketAccountToPoll(marketIndex: BN): Promise<boolean> {
136
- const marketPublicKey = await getMarketPublicKey(
137
+ async addPerpMarketAccountToPoll(marketIndex: number): Promise<boolean> {
138
+ const perpMarketPublicKey = await getPerpMarketPublicKey(
137
139
  this.program.programId,
138
140
  marketIndex
139
141
  );
140
142
 
141
- this.accountsToPoll.set(marketPublicKey.toString(), {
142
- key: 'market',
143
- publicKey: marketPublicKey,
144
- eventType: 'marketAccountUpdate',
145
- mapKey: marketIndex.toNumber(),
143
+ this.accountsToPoll.set(perpMarketPublicKey.toString(), {
144
+ key: 'perpMarket',
145
+ publicKey: perpMarketPublicKey,
146
+ eventType: 'perpMarketAccountUpdate',
147
+ mapKey: marketIndex,
146
148
  });
147
149
 
148
150
  return true;
149
151
  }
150
152
 
151
- async updateBankAccountsToPoll(): Promise<boolean> {
152
- for (const bankIndex of this.bankIndexes) {
153
- await this.addBankAccountToPoll(bankIndex);
153
+ async updateSpotMarketAccountsToPoll(): Promise<boolean> {
154
+ for (const marketIndex of this.spotMarketIndexes) {
155
+ await this.addSpotMarketAccountToPoll(marketIndex);
154
156
  }
155
157
 
156
158
  return true;
157
159
  }
158
160
 
159
- async addBankAccountToPoll(bankIndex: BN): Promise<boolean> {
160
- const bankPublicKey = await getBankPublicKey(
161
+ async addSpotMarketAccountToPoll(marketIndex: number): Promise<boolean> {
162
+ const marketPublicKey = await getSpotMarketPublicKey(
161
163
  this.program.programId,
162
- bankIndex
164
+ marketIndex
163
165
  );
164
166
 
165
- this.accountsToPoll.set(bankPublicKey.toString(), {
166
- key: 'bank',
167
- publicKey: bankPublicKey,
168
- eventType: 'bankAccountUpdate',
169
- mapKey: bankIndex.toNumber(),
167
+ this.accountsToPoll.set(marketPublicKey.toString(), {
168
+ key: 'spotMarket',
169
+ publicKey: marketPublicKey,
170
+ eventType: 'spotMarketAccountUpdate',
171
+ mapKey: marketIndex,
170
172
  });
171
173
  return true;
172
174
  }
@@ -190,18 +192,6 @@ export class PollingClearingHouseAccountSubscriber
190
192
  return true;
191
193
  }
192
194
 
193
- async getClearingHouseAccounts(): Promise<ClearingHouseAccounts> {
194
- const statePublicKey = await getClearingHouseStateAccountPublicKey(
195
- this.program.programId
196
- );
197
-
198
- const accounts = {
199
- state: statePublicKey,
200
- };
201
-
202
- return accounts;
203
- }
204
-
205
195
  async addToAccountLoader(): Promise<void> {
206
196
  for (const [_, accountToPoll] of this.accountsToPoll) {
207
197
  this.addAccountToAccountLoader(accountToPoll);
@@ -353,15 +343,15 @@ export class PollingClearingHouseAccountSubscriber
353
343
  this.isSubscribed = false;
354
344
  }
355
345
 
356
- async addBank(bankIndex: BN): Promise<boolean> {
357
- await this.addBankAccountToPoll(bankIndex);
358
- const accountToPoll = this.accountsToPoll.get(bankIndex.toString());
346
+ async addSpotMarket(marketIndex: number): Promise<boolean> {
347
+ await this.addSpotMarketAccountToPoll(marketIndex);
348
+ const accountToPoll = this.accountsToPoll.get(marketIndex.toString());
359
349
  this.addAccountToAccountLoader(accountToPoll);
360
350
  return true;
361
351
  }
362
352
 
363
- async addMarket(marketIndex: BN): Promise<boolean> {
364
- await this.addMarketAccountToPoll(marketIndex);
353
+ async addPerpMarket(marketIndex: number): Promise<boolean> {
354
+ await this.addPerpMarketAccountToPoll(marketIndex);
365
355
  const accountToPoll = this.accountsToPoll.get(marketIndex.toString());
366
356
  this.addAccountToAccountLoader(accountToPoll);
367
357
  return true;
@@ -394,19 +384,23 @@ export class PollingClearingHouseAccountSubscriber
394
384
  }
395
385
 
396
386
  public getMarketAccountAndSlot(
397
- marketIndex: BN
398
- ): DataAndSlot<MarketAccount> | undefined {
399
- return this.market.get(marketIndex.toNumber());
387
+ marketIndex: number
388
+ ): DataAndSlot<PerpMarketAccount> | undefined {
389
+ return this.perpMarket.get(marketIndex);
390
+ }
391
+
392
+ public getMarketAccountsAndSlots(): DataAndSlot<PerpMarketAccount>[] {
393
+ return Array.from(this.perpMarket.values());
400
394
  }
401
395
 
402
- public getMarketAccountsAndSlots(): DataAndSlot<MarketAccount>[] {
403
- return Array.from(this.market.values());
396
+ public getSpotMarketAccountAndSlot(
397
+ marketIndex: number
398
+ ): DataAndSlot<SpotMarketAccount> | undefined {
399
+ return this.spotMarket.get(marketIndex);
404
400
  }
405
401
 
406
- public getBankAccountAndSlot(
407
- bankIndex: BN
408
- ): DataAndSlot<BankAccount> | undefined {
409
- return this.bank.get(bankIndex.toNumber());
402
+ public getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[] {
403
+ return Array.from(this.spotMarket.values());
410
404
  }
411
405
 
412
406
  public getOraclePriceDataAndSlot(
@@ -423,7 +417,3 @@ export class PollingClearingHouseAccountSubscriber
423
417
  return this.oracles.get(oraclePublicKey.toString());
424
418
  }
425
419
  }
426
-
427
- type ClearingHouseAccounts = {
428
- state: PublicKey;
429
- };
@@ -2,7 +2,7 @@ import {
2
2
  DataAndSlot,
3
3
  NotSubscribedError,
4
4
  OracleEvents,
5
- OracleSubscriber,
5
+ OracleAccountSubscriber,
6
6
  } from './types';
7
7
  import { Program } from '@project-serum/anchor';
8
8
  import StrictEventEmitter from 'strict-event-emitter-types';
@@ -11,7 +11,7 @@ import { PublicKey } from '@solana/web3.js';
11
11
  import { BulkAccountLoader } from './bulkAccountLoader';
12
12
  import { OracleClient, OraclePriceData } from '../oracles/types';
13
13
 
14
- export class PollingOracleSubscriber implements OracleSubscriber {
14
+ export class PollingOracleAccountSubscriber implements OracleAccountSubscriber {
15
15
  isSubscribed: boolean;
16
16
  program: Program;
17
17
  eventEmitter: StrictEventEmitter<EventEmitter, OracleEvents>;
@@ -0,0 +1,172 @@
1
+ import {
2
+ DataAndSlot,
3
+ AccountToPoll,
4
+ NotSubscribedError,
5
+ UserStatsAccountSubscriber,
6
+ UserStatsAccountEvents,
7
+ } from './types';
8
+ import { Program } from '@project-serum/anchor';
9
+ import StrictEventEmitter from 'strict-event-emitter-types';
10
+ import { EventEmitter } from 'events';
11
+ import { PublicKey } from '@solana/web3.js';
12
+ import { UserStatsAccount } from '../types';
13
+ import { BulkAccountLoader } from './bulkAccountLoader';
14
+ import { capitalize } from './utils';
15
+
16
+ export class PollingUserStatsAccountSubscriber
17
+ implements UserStatsAccountSubscriber
18
+ {
19
+ isSubscribed: boolean;
20
+ program: Program;
21
+ eventEmitter: StrictEventEmitter<EventEmitter, UserStatsAccountEvents>;
22
+ userStatsAccountPublicKey: PublicKey;
23
+
24
+ accountLoader: BulkAccountLoader;
25
+ accountsToPoll = new Map<string, AccountToPoll>();
26
+ errorCallbackId?: string;
27
+
28
+ userStats?: DataAndSlot<UserStatsAccount>;
29
+
30
+ public constructor(
31
+ program: Program,
32
+ userStatsAccountPublicKey: PublicKey,
33
+ accountLoader: BulkAccountLoader
34
+ ) {
35
+ this.isSubscribed = false;
36
+ this.program = program;
37
+ this.accountLoader = accountLoader;
38
+ this.eventEmitter = new EventEmitter();
39
+ this.userStatsAccountPublicKey = userStatsAccountPublicKey;
40
+ }
41
+
42
+ async subscribe(): Promise<boolean> {
43
+ if (this.isSubscribed) {
44
+ return true;
45
+ }
46
+
47
+ await this.addToAccountLoader();
48
+
49
+ let subscriptionSucceeded = false;
50
+ let retries = 0;
51
+ while (!subscriptionSucceeded && retries < 5) {
52
+ await this.fetchIfUnloaded();
53
+ subscriptionSucceeded = this.didSubscriptionSucceed();
54
+ retries++;
55
+ }
56
+
57
+ if (subscriptionSucceeded) {
58
+ this.eventEmitter.emit('update');
59
+ }
60
+
61
+ this.isSubscribed = subscriptionSucceeded;
62
+ return subscriptionSucceeded;
63
+ }
64
+
65
+ async addToAccountLoader(): Promise<void> {
66
+ if (this.accountsToPoll.size > 0) {
67
+ return;
68
+ }
69
+
70
+ this.accountsToPoll.set(this.userStatsAccountPublicKey.toString(), {
71
+ key: 'userStats',
72
+ publicKey: this.userStatsAccountPublicKey,
73
+ eventType: 'userStatsAccountUpdate',
74
+ });
75
+
76
+ for (const [_, accountToPoll] of this.accountsToPoll) {
77
+ accountToPoll.callbackId = this.accountLoader.addAccount(
78
+ accountToPoll.publicKey,
79
+ (buffer, slot) => {
80
+ if (!buffer) {
81
+ return;
82
+ }
83
+
84
+ const account = this.program.account[
85
+ accountToPoll.key
86
+ ].coder.accounts.decode(capitalize(accountToPoll.key), buffer);
87
+ this[accountToPoll.key] = { data: account, slot };
88
+ // @ts-ignore
89
+ this.eventEmitter.emit(accountToPoll.eventType, account);
90
+ this.eventEmitter.emit('update');
91
+ }
92
+ );
93
+ }
94
+
95
+ this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
96
+ this.eventEmitter.emit('error', error);
97
+ });
98
+ }
99
+
100
+ async fetchIfUnloaded(): Promise<void> {
101
+ let shouldFetch = false;
102
+ for (const [_, accountToPoll] of this.accountsToPoll) {
103
+ if (this[accountToPoll.key] === undefined) {
104
+ shouldFetch = true;
105
+ break;
106
+ }
107
+ }
108
+
109
+ if (shouldFetch) {
110
+ await this.fetch();
111
+ }
112
+ }
113
+
114
+ async fetch(): Promise<void> {
115
+ await this.accountLoader.load();
116
+ for (const [_, accountToPoll] of this.accountsToPoll) {
117
+ const { buffer, slot } = this.accountLoader.getBufferAndSlot(
118
+ accountToPoll.publicKey
119
+ );
120
+ if (buffer) {
121
+ const account = this.program.account[
122
+ accountToPoll.key
123
+ ].coder.accounts.decode(capitalize(accountToPoll.key), buffer);
124
+ this[accountToPoll.key] = { data: account, slot };
125
+ }
126
+ }
127
+ }
128
+
129
+ didSubscriptionSucceed(): boolean {
130
+ let success = true;
131
+ for (const [_, accountToPoll] of this.accountsToPoll) {
132
+ if (!this[accountToPoll.key]) {
133
+ success = false;
134
+ break;
135
+ }
136
+ }
137
+ return success;
138
+ }
139
+
140
+ async unsubscribe(): Promise<void> {
141
+ if (!this.isSubscribed) {
142
+ return;
143
+ }
144
+
145
+ for (const [_, accountToPoll] of this.accountsToPoll) {
146
+ this.accountLoader.removeAccount(
147
+ accountToPoll.publicKey,
148
+ accountToPoll.callbackId
149
+ );
150
+ }
151
+
152
+ this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
153
+ this.errorCallbackId = undefined;
154
+
155
+ this.accountsToPoll.clear();
156
+
157
+ this.isSubscribed = false;
158
+ }
159
+
160
+ assertIsSubscribed(): void {
161
+ if (!this.isSubscribed) {
162
+ throw new NotSubscribedError(
163
+ 'You must call `subscribe` before using this function'
164
+ );
165
+ }
166
+ }
167
+
168
+ public getUserStatsAccountAndSlot(): DataAndSlot<UserStatsAccount> {
169
+ this.assertIsSubscribed();
170
+ return this.userStats;
171
+ }
172
+ }
@@ -1,16 +1,16 @@
1
1
  import {
2
- BankAccount,
3
- MarketAccount,
2
+ SpotMarketAccount,
3
+ PerpMarketAccount,
4
4
  OracleSource,
5
5
  StateAccount,
6
6
  UserAccount,
7
+ UserStatsAccount,
7
8
  } from '../types';
8
9
  import StrictEventEmitter from 'strict-event-emitter-types';
9
10
  import { EventEmitter } from 'events';
10
11
  import { PublicKey } from '@solana/web3.js';
11
12
  import { AccountInfo } from '@solana/spl-token';
12
13
  import { OracleInfo, OraclePriceData } from '..';
13
- import { BN } from '@project-serum/anchor';
14
14
 
15
15
  export interface AccountSubscriber<T> {
16
16
  dataAndSlot?: DataAndSlot<T>;
@@ -23,34 +23,37 @@ export class NotSubscribedError extends Error {
23
23
  name = 'NotSubscribedError';
24
24
  }
25
25
 
26
- export interface ClearingHouseAccountEvents {
26
+ export interface DriftClientAccountEvents {
27
27
  stateAccountUpdate: (payload: StateAccount) => void;
28
- marketAccountUpdate: (payload: MarketAccount) => void;
29
- bankAccountUpdate: (payload: BankAccount) => void;
28
+ perpMarketAccountUpdate: (payload: PerpMarketAccount) => void;
29
+ spotMarketAccountUpdate: (payload: SpotMarketAccount) => void;
30
30
  oraclePriceUpdate: (publicKey: PublicKey, data: OraclePriceData) => void;
31
31
  userAccountUpdate: (payload: UserAccount) => void;
32
32
  update: void;
33
33
  error: (e: Error) => void;
34
34
  }
35
35
 
36
- export interface ClearingHouseAccountSubscriber {
37
- eventEmitter: StrictEventEmitter<EventEmitter, ClearingHouseAccountEvents>;
36
+ export interface DriftClientAccountSubscriber {
37
+ eventEmitter: StrictEventEmitter<EventEmitter, DriftClientAccountEvents>;
38
38
  isSubscribed: boolean;
39
39
 
40
40
  subscribe(): Promise<boolean>;
41
41
  fetch(): Promise<void>;
42
42
  unsubscribe(): Promise<void>;
43
43
 
44
- addMarket(marketIndex: BN): Promise<boolean>;
45
- addBank(bankIndex: BN): Promise<boolean>;
44
+ addPerpMarket(marketIndex: number): Promise<boolean>;
45
+ addSpotMarket(marketIndex: number): Promise<boolean>;
46
46
  addOracle(oracleInfo: OracleInfo): Promise<boolean>;
47
47
 
48
48
  getStateAccountAndSlot(): DataAndSlot<StateAccount>;
49
49
  getMarketAccountAndSlot(
50
- marketIndex: BN
51
- ): DataAndSlot<MarketAccount> | undefined;
52
- getMarketAccountsAndSlots(): DataAndSlot<MarketAccount>[];
53
- getBankAccountAndSlot(bankIndex: BN): DataAndSlot<BankAccount> | undefined;
50
+ marketIndex: number
51
+ ): DataAndSlot<PerpMarketAccount> | undefined;
52
+ getMarketAccountsAndSlots(): DataAndSlot<PerpMarketAccount>[];
53
+ getSpotMarketAccountAndSlot(
54
+ marketIndex: number
55
+ ): DataAndSlot<SpotMarketAccount> | undefined;
56
+ getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[];
54
57
  getOraclePriceDataAndSlot(
55
58
  oraclePublicKey: PublicKey
56
59
  ): DataAndSlot<OraclePriceData> | undefined;
@@ -96,7 +99,7 @@ export interface OracleEvents {
96
99
  error: (e: Error) => void;
97
100
  }
98
101
 
99
- export interface OracleSubscriber {
102
+ export interface OracleAccountSubscriber {
100
103
  eventEmitter: StrictEventEmitter<EventEmitter, OracleEvents>;
101
104
  isSubscribed: boolean;
102
105
 
@@ -130,3 +133,20 @@ export type DataAndSlot<T> = {
130
133
  data: T;
131
134
  slot: number;
132
135
  };
136
+
137
+ export interface UserStatsAccountEvents {
138
+ userStatsAccountUpdate: (payload: UserStatsAccount) => void;
139
+ update: void;
140
+ error: (e: Error) => void;
141
+ }
142
+
143
+ export interface UserStatsAccountSubscriber {
144
+ eventEmitter: StrictEventEmitter<EventEmitter, UserStatsAccountEvents>;
145
+ isSubscribed: boolean;
146
+
147
+ subscribe(): Promise<boolean>;
148
+ fetch(): Promise<void>;
149
+ unsubscribe(): Promise<void>;
150
+
151
+ getUserStatsAccountAndSlot(): DataAndSlot<UserStatsAccount>;
152
+ }