@drift-labs/sdk 0.1.36-master.7 → 0.2.0-master.10

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 (254) hide show
  1. package/lib/accounts/bulkAccountLoader.d.ts +6 -6
  2. package/lib/accounts/bulkAccountLoader.js +81 -95
  3. package/lib/accounts/bulkUserSubscription.js +13 -57
  4. package/lib/accounts/fetch.d.ts +4 -0
  5. package/lib/accounts/fetch.js +18 -0
  6. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +34 -38
  7. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +224 -224
  8. package/lib/accounts/pollingOracleSubscriber.d.ts +3 -3
  9. package/lib/accounts/pollingOracleSubscriber.js +37 -49
  10. package/lib/accounts/pollingTokenAccountSubscriber.d.ts +3 -3
  11. package/lib/accounts/pollingTokenAccountSubscriber.js +35 -50
  12. package/lib/accounts/pollingUserAccountSubscriber.d.ts +7 -13
  13. package/lib/accounts/pollingUserAccountSubscriber.js +71 -134
  14. package/lib/accounts/types.d.ts +34 -41
  15. package/lib/accounts/webSocketAccountSubscriber.d.ts +6 -4
  16. package/lib/accounts/webSocketAccountSubscriber.js +39 -35
  17. package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +33 -28
  18. package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +153 -185
  19. package/lib/accounts/webSocketUserAccountSubscriber.d.ts +5 -11
  20. package/lib/accounts/webSocketUserAccountSubscriber.js +22 -67
  21. package/lib/addresses/marketAddresses.d.ts +4 -0
  22. package/lib/addresses/marketAddresses.js +15 -0
  23. package/lib/addresses/pda.d.ts +12 -0
  24. package/lib/addresses/pda.js +83 -0
  25. package/lib/admin.d.ts +12 -18
  26. package/lib/admin.js +398 -558
  27. package/lib/clearingHouse.d.ts +83 -109
  28. package/lib/clearingHouse.js +832 -893
  29. package/lib/clearingHouseConfig.d.ts +34 -0
  30. package/lib/clearingHouseConfig.js +2 -0
  31. package/lib/clearingHouseUser.d.ts +19 -22
  32. package/lib/clearingHouseUser.js +155 -141
  33. package/lib/clearingHouseUserConfig.d.ts +14 -0
  34. package/lib/clearingHouseUserConfig.js +2 -0
  35. package/lib/config.d.ts +12 -0
  36. package/lib/config.js +35 -4
  37. package/lib/constants/banks.d.ts +16 -0
  38. package/lib/constants/banks.js +41 -0
  39. package/lib/constants/markets.d.ts +8 -3
  40. package/lib/constants/markets.js +13 -206
  41. package/lib/constants/numericConstants.d.ts +17 -0
  42. package/lib/constants/numericConstants.js +23 -6
  43. package/lib/events/eventList.d.ts +22 -0
  44. package/lib/events/eventList.js +77 -0
  45. package/lib/events/eventSubscriber.d.ts +34 -0
  46. package/lib/events/eventSubscriber.js +126 -0
  47. package/lib/events/fetchLogs.d.ts +13 -0
  48. package/lib/events/fetchLogs.js +39 -0
  49. package/lib/events/pollingLogProvider.d.ts +15 -0
  50. package/lib/events/pollingLogProvider.js +53 -0
  51. package/lib/events/sort.d.ts +2 -0
  52. package/lib/events/sort.js +44 -0
  53. package/lib/events/txEventCache.d.ts +24 -0
  54. package/lib/events/txEventCache.js +71 -0
  55. package/lib/events/types.d.ts +49 -0
  56. package/lib/events/types.js +20 -0
  57. package/lib/events/webSocketLogProvider.d.ts +12 -0
  58. package/lib/events/webSocketLogProvider.js +30 -0
  59. package/lib/examples/makeTradeExample.js +26 -27
  60. package/lib/factory/bigNum.d.ts +118 -0
  61. package/lib/factory/bigNum.js +364 -0
  62. package/lib/factory/oracleClient.d.ts +1 -2
  63. package/lib/factory/oracleClient.js +6 -2
  64. package/lib/idl/clearing_house.json +2258 -2774
  65. package/lib/index.d.ts +14 -5
  66. package/lib/index.js +18 -5
  67. package/lib/math/amm.d.ts +24 -29
  68. package/lib/math/amm.js +209 -176
  69. package/lib/math/auction.d.ts +5 -0
  70. package/lib/math/auction.js +42 -0
  71. package/lib/math/bankBalance.d.ts +9 -0
  72. package/lib/math/bankBalance.js +75 -0
  73. package/lib/math/conversion.d.ts +0 -1
  74. package/lib/math/conversion.js +1 -5
  75. package/lib/math/funding.d.ts +6 -6
  76. package/lib/math/funding.js +158 -175
  77. package/lib/math/market.d.ts +6 -6
  78. package/lib/math/market.js +10 -9
  79. package/lib/math/orders.d.ts +6 -1
  80. package/lib/math/orders.js +38 -1
  81. package/lib/math/position.d.ts +7 -5
  82. package/lib/math/position.js +29 -27
  83. package/lib/math/repeg.d.ts +22 -0
  84. package/lib/math/repeg.js +128 -0
  85. package/lib/math/trade.d.ts +5 -4
  86. package/lib/math/trade.js +29 -24
  87. package/lib/mockUSDCFaucet.js +87 -116
  88. package/lib/oracles/oracleClientCache.d.ts +8 -0
  89. package/lib/oracles/oracleClientCache.js +19 -0
  90. package/lib/oracles/pythClient.d.ts +3 -5
  91. package/lib/oracles/pythClient.js +12 -31
  92. package/lib/oracles/quoteAssetOracleClient.d.ts +9 -0
  93. package/lib/oracles/quoteAssetOracleClient.js +21 -0
  94. package/lib/oracles/switchboardClient.d.ts +3 -5
  95. package/lib/oracles/switchboardClient.js +29 -50
  96. package/lib/oracles/types.d.ts +6 -1
  97. package/lib/orderParams.d.ts +14 -5
  98. package/lib/orderParams.js +8 -96
  99. package/lib/orders.d.ts +6 -7
  100. package/lib/orders.js +11 -89
  101. package/lib/slot/SlotSubscriber.d.ts +19 -0
  102. package/lib/slot/SlotSubscriber.js +26 -0
  103. package/lib/tx/retryTxSender.d.ts +2 -2
  104. package/lib/tx/retryTxSender.js +108 -123
  105. package/lib/tx/types.d.ts +5 -1
  106. package/lib/tx/utils.d.ts +1 -1
  107. package/lib/tx/utils.js +11 -2
  108. package/lib/types.d.ts +180 -110
  109. package/lib/types.js +54 -1
  110. package/lib/userName.d.ts +4 -0
  111. package/lib/userName.js +20 -0
  112. package/lib/util/computeUnits.js +10 -21
  113. package/lib/util/tps.js +11 -22
  114. package/lib/wallet.js +7 -20
  115. package/package.json +11 -4
  116. package/src/accounts/bulkAccountLoader.js +197 -0
  117. package/src/accounts/bulkAccountLoader.ts +21 -15
  118. package/src/accounts/bulkUserSubscription.js +33 -0
  119. package/src/accounts/bulkUserSubscription.ts +1 -45
  120. package/src/accounts/fetch.js +29 -0
  121. package/src/accounts/fetch.ts +33 -0
  122. package/src/accounts/pollingClearingHouseAccountSubscriber.js +311 -0
  123. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +249 -214
  124. package/src/accounts/pollingOracleSubscriber.js +93 -0
  125. package/src/accounts/pollingOracleSubscriber.ts +16 -8
  126. package/src/accounts/pollingTokenAccountSubscriber.js +90 -0
  127. package/src/accounts/pollingTokenAccountSubscriber.ts +11 -8
  128. package/src/accounts/pollingUserAccountSubscriber.js +132 -0
  129. package/src/accounts/pollingUserAccountSubscriber.ts +21 -86
  130. package/src/accounts/types.js +10 -0
  131. package/src/accounts/types.ts +41 -70
  132. package/src/accounts/utils.js +7 -0
  133. package/src/accounts/webSocketAccountSubscriber.js +93 -0
  134. package/src/accounts/webSocketAccountSubscriber.ts +33 -16
  135. package/src/accounts/webSocketClearingHouseAccountSubscriber.js +233 -0
  136. package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +190 -240
  137. package/src/accounts/webSocketUserAccountSubscriber.js +62 -0
  138. package/src/accounts/webSocketUserAccountSubscriber.ts +11 -71
  139. package/src/addresses/marketAddresses.js +26 -0
  140. package/src/addresses/marketAddresses.ts +18 -0
  141. package/{lib/addresses.js → src/addresses/pda.js} +45 -34
  142. package/src/addresses/pda.ts +118 -0
  143. package/src/admin.ts +247 -336
  144. package/src/assert/assert.js +9 -0
  145. package/src/clearingHouse.ts +1023 -1026
  146. package/src/clearingHouseConfig.ts +37 -0
  147. package/src/clearingHouseUser.ts +275 -185
  148. package/src/clearingHouseUserConfig.ts +18 -0
  149. package/src/config.ts +54 -1
  150. package/src/constants/banks.ts +50 -0
  151. package/src/constants/markets.ts +16 -207
  152. package/src/constants/numericConstants.ts +34 -5
  153. package/src/events/eventList.js +77 -0
  154. package/src/events/eventList.ts +94 -0
  155. package/src/events/eventSubscriber.js +139 -0
  156. package/src/events/eventSubscriber.ts +194 -0
  157. package/src/events/fetchLogs.js +50 -0
  158. package/src/events/fetchLogs.ts +80 -0
  159. package/src/events/pollingLogProvider.js +64 -0
  160. package/src/events/pollingLogProvider.ts +79 -0
  161. package/src/events/sort.js +44 -0
  162. package/src/events/sort.ts +65 -0
  163. package/src/events/txEventCache.js +71 -0
  164. package/src/events/txEventCache.ts +74 -0
  165. package/src/events/types.js +20 -0
  166. package/src/events/types.ts +98 -0
  167. package/src/events/webSocketLogProvider.js +41 -0
  168. package/src/events/webSocketLogProvider.ts +38 -0
  169. package/src/examples/makeTradeExample.js +80 -0
  170. package/src/examples/makeTradeExample.ts +20 -11
  171. package/src/factory/bigNum.js +364 -0
  172. package/src/factory/bigNum.ts +524 -0
  173. package/src/factory/oracleClient.js +20 -0
  174. package/src/factory/oracleClient.ts +7 -4
  175. package/src/idl/clearing_house.json +2258 -2774
  176. package/src/index.js +69 -0
  177. package/src/index.ts +14 -5
  178. package/src/math/amm.js +369 -0
  179. package/src/math/amm.ts +382 -243
  180. package/src/math/auction.js +42 -0
  181. package/src/math/auction.ts +43 -0
  182. package/src/math/bankBalance.js +75 -0
  183. package/src/math/bankBalance.ts +112 -0
  184. package/src/math/conversion.js +11 -0
  185. package/src/math/conversion.ts +1 -11
  186. package/src/math/funding.js +248 -0
  187. package/src/math/funding.ts +12 -9
  188. package/src/math/market.js +57 -0
  189. package/src/math/market.ts +37 -30
  190. package/src/math/oracles.js +26 -0
  191. package/src/math/orders.js +110 -0
  192. package/src/math/orders.ts +43 -1
  193. package/src/math/position.js +140 -0
  194. package/src/math/position.ts +52 -35
  195. package/src/math/repeg.js +128 -0
  196. package/src/math/repeg.ts +176 -0
  197. package/src/math/state.js +15 -0
  198. package/src/math/trade.js +253 -0
  199. package/src/math/trade.ts +55 -47
  200. package/src/math/utils.js +26 -0
  201. package/src/math/utils.js.map +1 -0
  202. package/src/mockUSDCFaucet.js +171 -0
  203. package/src/oracles/oracleClientCache.js +19 -0
  204. package/src/oracles/oracleClientCache.ts +20 -0
  205. package/src/oracles/pythClient.js +46 -0
  206. package/src/oracles/pythClient.ts +4 -11
  207. package/src/oracles/quoteAssetOracleClient.js +32 -0
  208. package/src/oracles/quoteAssetOracleClient.ts +25 -0
  209. package/src/oracles/switchboardClient.js +69 -0
  210. package/src/oracles/switchboardClient.ts +11 -24
  211. package/src/oracles/types.js +2 -0
  212. package/src/oracles/types.ts +7 -1
  213. package/src/orderParams.js +20 -0
  214. package/src/orderParams.ts +20 -141
  215. package/src/orders.js +134 -0
  216. package/src/orders.ts +25 -134
  217. package/src/slot/SlotSubscriber.js +39 -0
  218. package/src/slot/SlotSubscriber.ts +42 -0
  219. package/src/token/index.js +38 -0
  220. package/src/tx/retryTxSender.js +188 -0
  221. package/src/tx/retryTxSender.ts +6 -4
  222. package/src/tx/types.js +2 -0
  223. package/src/tx/types.ts +6 -1
  224. package/src/tx/utils.js +17 -0
  225. package/src/tx/utils.ts +22 -3
  226. package/src/types.js +114 -0
  227. package/src/types.ts +176 -124
  228. package/src/userName.js +20 -0
  229. package/src/userName.ts +20 -0
  230. package/src/util/promiseTimeout.js +14 -0
  231. package/src/util/tps.js +27 -0
  232. package/src/wallet.js +35 -0
  233. package/tests/bn/test.ts +255 -0
  234. package/tsconfig.json +12 -12
  235. package/lib/addresses.d.ts +0 -10
  236. package/lib/constants/accounts.d.ts +0 -15
  237. package/lib/constants/accounts.js +0 -18
  238. package/lib/factory/clearingHouse.d.ts +0 -35
  239. package/lib/factory/clearingHouse.js +0 -81
  240. package/lib/factory/clearingHouseUser.d.ts +0 -19
  241. package/lib/factory/clearingHouseUser.js +0 -34
  242. package/lib/math/insuranceFund.d.ts +0 -15
  243. package/lib/math/insuranceFund.js +0 -33
  244. package/lib/settlement.d.ts +0 -4
  245. package/lib/settlement.js +0 -10
  246. package/lib/tx/defaultTxSender.d.ts +0 -8
  247. package/lib/tx/defaultTxSender.js +0 -12
  248. package/src/addresses.ts +0 -82
  249. package/src/constants/accounts.ts +0 -26
  250. package/src/factory/clearingHouse.ts +0 -173
  251. package/src/factory/clearingHouseUser.ts +0 -73
  252. package/src/math/insuranceFund.ts +0 -29
  253. package/src/settlement.ts +0 -9
  254. package/src/tx/defaultTxSender.ts +0 -24
@@ -1,72 +1,76 @@
1
1
  import {
2
+ DataAndSlot,
2
3
  AccountToPoll,
3
4
  ClearingHouseAccountEvents,
4
5
  ClearingHouseAccountSubscriber,
5
- ClearingHouseAccountTypes,
6
6
  NotSubscribedError,
7
+ OraclesToPoll,
7
8
  } from './types';
8
- import { Program } from '@project-serum/anchor';
9
+ import { BN, Program } from '@project-serum/anchor';
9
10
  import StrictEventEmitter from 'strict-event-emitter-types';
10
11
  import { EventEmitter } from 'events';
11
12
  import {
12
- DepositHistoryAccount,
13
- ExtendedCurveHistoryAccount,
14
- FundingPaymentHistoryAccount,
15
- FundingRateHistoryAccount,
16
- LiquidationHistoryAccount,
17
- MarketsAccount,
18
- OrderHistoryAccount,
19
- OrderStateAccount,
13
+ BankAccount,
14
+ MarketAccount,
20
15
  StateAccount,
21
- TradeHistoryAccount,
16
+ UserAccount,
22
17
  } from '../types';
23
- import { getClearingHouseStateAccountPublicKey } from '../addresses';
18
+ import {
19
+ getClearingHouseStateAccountPublicKey,
20
+ getBankPublicKey,
21
+ getMarketPublicKey,
22
+ } from '../addresses/pda';
24
23
  import { BulkAccountLoader } from './bulkAccountLoader';
25
24
  import { capitalize } from './utils';
26
- import { ClearingHouseConfigType } from '../factory/clearingHouse';
27
25
  import { PublicKey } from '@solana/web3.js';
28
- import { CLEARING_HOUSE_STATE_ACCOUNTS } from '../constants/accounts';
26
+ import { OracleInfo, OraclePriceData } from '../oracles/types';
27
+ import { OracleClientCache } from '../oracles/oracleClientCache';
28
+ import { QUOTE_ORACLE_PRICE_DATA } from '../oracles/quoteAssetOracleClient';
29
29
 
30
30
  export class PollingClearingHouseAccountSubscriber
31
31
  implements ClearingHouseAccountSubscriber
32
32
  {
33
33
  isSubscribed: boolean;
34
34
  program: Program;
35
+ marketIndexes: BN[];
36
+ bankIndexes: BN[];
37
+ oracleInfos: OracleInfo[];
38
+ oracleClientCache = new OracleClientCache();
39
+
35
40
  eventEmitter: StrictEventEmitter<EventEmitter, ClearingHouseAccountEvents>;
36
41
 
37
42
  accountLoader: BulkAccountLoader;
38
43
  accountsToPoll = new Map<string, AccountToPoll>();
44
+ oraclesToPoll = new Map<string, OraclesToPoll>();
39
45
  errorCallbackId?: string;
40
46
 
41
- state?: StateAccount;
42
- markets?: MarketsAccount;
43
- orderState?: OrderStateAccount;
44
- tradeHistory?: TradeHistoryAccount;
45
- depositHistory?: DepositHistoryAccount;
46
- fundingPaymentHistory?: FundingPaymentHistoryAccount;
47
- fundingRateHistory?: FundingRateHistoryAccount;
48
- liquidationHistory?: LiquidationHistoryAccount;
49
- extendedCurveHistory: ExtendedCurveHistoryAccount;
50
- orderHistory?: OrderHistoryAccount;
51
-
52
- optionalExtraSubscriptions: ClearingHouseAccountTypes[] = [];
53
-
54
- type: ClearingHouseConfigType = 'polling';
47
+ state?: DataAndSlot<StateAccount>;
48
+ market = new Map<number, DataAndSlot<MarketAccount>>();
49
+ bank = new Map<number, DataAndSlot<BankAccount>>();
50
+ oracles = new Map<string, DataAndSlot<OraclePriceData>>();
51
+ user?: DataAndSlot<UserAccount>;
55
52
 
56
53
  private isSubscribing = false;
57
54
  private subscriptionPromise: Promise<boolean>;
58
55
  private subscriptionPromiseResolver: (val: boolean) => void;
59
56
 
60
- public constructor(program: Program, accountLoader: BulkAccountLoader) {
57
+ public constructor(
58
+ program: Program,
59
+ accountLoader: BulkAccountLoader,
60
+ marketIndexes: BN[],
61
+ bankIndexes: BN[],
62
+ oracleInfos: OracleInfo[]
63
+ ) {
61
64
  this.isSubscribed = false;
62
65
  this.program = program;
63
66
  this.eventEmitter = new EventEmitter();
64
67
  this.accountLoader = accountLoader;
68
+ this.marketIndexes = marketIndexes;
69
+ this.bankIndexes = bankIndexes;
70
+ this.oracleInfos = oracleInfos;
65
71
  }
66
72
 
67
- public async subscribe(
68
- optionalSubscriptions?: ClearingHouseAccountTypes[]
69
- ): Promise<boolean> {
73
+ public async subscribe(): Promise<boolean> {
70
74
  if (this.isSubscribed) {
71
75
  return true;
72
76
  }
@@ -75,8 +79,6 @@ export class PollingClearingHouseAccountSubscriber
75
79
  return await this.subscriptionPromise;
76
80
  }
77
81
 
78
- this.optionalExtraSubscriptions = optionalSubscriptions;
79
-
80
82
  this.isSubscribing = true;
81
83
 
82
84
  this.subscriptionPromise = new Promise((res) => {
@@ -84,6 +86,7 @@ export class PollingClearingHouseAccountSubscriber
84
86
  });
85
87
 
86
88
  await this.updateAccountsToPoll();
89
+ await this.updateOraclesToPoll();
87
90
  await this.addToAccountLoader();
88
91
 
89
92
  let subscriptionSucceeded = false;
@@ -118,137 +121,94 @@ export class PollingClearingHouseAccountSubscriber
118
121
  eventType: 'stateAccountUpdate',
119
122
  });
120
123
 
121
- this.accountsToPoll.set(accounts.markets.toString(), {
122
- key: 'markets',
123
- publicKey: accounts.markets,
124
- eventType: 'marketsAccountUpdate',
125
- });
124
+ await this.updateMarketAccountsToPoll();
125
+ await this.updateBankAccountsToPoll();
126
+ }
126
127
 
127
- this.accountsToPoll.set(accounts.orderState.toString(), {
128
- key: 'orderState',
129
- publicKey: accounts.orderState,
130
- eventType: 'orderStateAccountUpdate',
128
+ async updateMarketAccountsToPoll(): Promise<boolean> {
129
+ for (const marketIndex of this.marketIndexes) {
130
+ await this.addMarketAccountToPoll(marketIndex);
131
+ }
132
+ return true;
133
+ }
134
+
135
+ async addMarketAccountToPoll(marketIndex: BN): Promise<boolean> {
136
+ const marketPublicKey = await getMarketPublicKey(
137
+ this.program.programId,
138
+ marketIndex
139
+ );
140
+
141
+ this.accountsToPoll.set(marketPublicKey.toString(), {
142
+ key: 'market',
143
+ publicKey: marketPublicKey,
144
+ eventType: 'marketAccountUpdate',
145
+ mapKey: marketIndex.toNumber(),
131
146
  });
132
147
 
133
- if (this.optionalExtraSubscriptions?.includes('tradeHistoryAccount')) {
134
- this.accountsToPoll.set(accounts.tradeHistory.toString(), {
135
- key: 'tradeHistory',
136
- publicKey: accounts.tradeHistory,
137
- eventType: 'tradeHistoryAccountUpdate',
138
- });
139
- }
148
+ return true;
149
+ }
140
150
 
141
- if (this.optionalExtraSubscriptions?.includes('depositHistoryAccount')) {
142
- this.accountsToPoll.set(accounts.depositHistory.toString(), {
143
- key: 'depositHistory',
144
- publicKey: accounts.depositHistory,
145
- eventType: 'depositHistoryAccountUpdate',
146
- });
151
+ async updateBankAccountsToPoll(): Promise<boolean> {
152
+ for (const bankIndex of this.bankIndexes) {
153
+ await this.addBankAccountToPoll(bankIndex);
147
154
  }
148
155
 
149
- if (
150
- this.optionalExtraSubscriptions?.includes('fundingPaymentHistoryAccount')
151
- ) {
152
- this.accountsToPoll.set(accounts.fundingPaymentHistory.toString(), {
153
- key: 'fundingPaymentHistory',
154
- publicKey: accounts.fundingPaymentHistory,
155
- eventType: 'fundingPaymentHistoryAccountUpdate',
156
- });
157
- }
156
+ return true;
157
+ }
158
158
 
159
- if (
160
- this.optionalExtraSubscriptions?.includes('fundingRateHistoryAccount')
161
- ) {
162
- this.accountsToPoll.set(accounts.fundingRateHistory.toString(), {
163
- key: 'fundingRateHistory',
164
- publicKey: accounts.fundingRateHistory,
165
- eventType: 'fundingRateHistoryAccountUpdate',
166
- });
167
- }
159
+ async addBankAccountToPoll(bankIndex: BN): Promise<boolean> {
160
+ const bankPublicKey = await getBankPublicKey(
161
+ this.program.programId,
162
+ bankIndex
163
+ );
168
164
 
169
- if (this.optionalExtraSubscriptions?.includes('curveHistoryAccount')) {
170
- this.accountsToPoll.set(accounts.extendedCurveHistory.toString(), {
171
- key: 'extendedCurveHistory',
172
- publicKey: accounts.extendedCurveHistory,
173
- eventType: 'curveHistoryAccountUpdate',
174
- });
175
- }
165
+ this.accountsToPoll.set(bankPublicKey.toString(), {
166
+ key: 'bank',
167
+ publicKey: bankPublicKey,
168
+ eventType: 'bankAccountUpdate',
169
+ mapKey: bankIndex.toNumber(),
170
+ });
171
+ return true;
172
+ }
176
173
 
177
- if (
178
- this.optionalExtraSubscriptions?.includes('liquidationHistoryAccount')
179
- ) {
180
- this.accountsToPoll.set(accounts.liquidationHistory.toString(), {
181
- key: 'liquidationHistory',
182
- publicKey: accounts.liquidationHistory,
183
- eventType: 'liquidationHistoryAccountUpdate',
184
- });
174
+ updateOraclesToPoll(): boolean {
175
+ for (const oracleInfo of this.oracleInfos) {
176
+ if (!oracleInfo.publicKey.equals(PublicKey.default)) {
177
+ this.addOracleToPoll(oracleInfo);
178
+ }
185
179
  }
186
180
 
187
- if (this.optionalExtraSubscriptions?.includes('orderHistoryAccount')) {
188
- this.accountsToPoll.set(accounts.orderHistory.toString(), {
189
- key: 'orderHistory',
190
- publicKey: accounts.orderHistory,
191
- eventType: 'orderHistoryAccountUpdate',
192
- });
193
- }
181
+ return true;
194
182
  }
195
183
 
196
- async getClearingHouseAccounts(): Promise<ClearingHouseAccounts> {
197
- // Skip extra calls to rpc if we already know all the accounts
198
- if (CLEARING_HOUSE_STATE_ACCOUNTS[this.program.programId.toString()]) {
199
- return CLEARING_HOUSE_STATE_ACCOUNTS[this.program.programId.toString()];
200
- }
184
+ addOracleToPoll(oracleInfo: OracleInfo): boolean {
185
+ this.oraclesToPoll.set(oracleInfo.publicKey.toString(), {
186
+ publicKey: oracleInfo.publicKey,
187
+ source: oracleInfo.source,
188
+ });
201
189
 
190
+ return true;
191
+ }
192
+
193
+ async getClearingHouseAccounts(): Promise<ClearingHouseAccounts> {
202
194
  const statePublicKey = await getClearingHouseStateAccountPublicKey(
203
195
  this.program.programId
204
196
  );
205
197
 
206
- const state = (await this.program.account.state.fetch(
207
- statePublicKey
208
- )) as StateAccount;
209
-
210
198
  const accounts = {
211
199
  state: statePublicKey,
212
- markets: state.markets,
213
- orderState: state.orderState,
214
- tradeHistory: state.tradeHistory,
215
- depositHistory: state.depositHistory,
216
- fundingPaymentHistory: state.fundingPaymentHistory,
217
- fundingRateHistory: state.fundingRateHistory,
218
- extendedCurveHistory: state.extendedCurveHistory,
219
- liquidationHistory: state.liquidationHistory,
220
- orderHistory: undefined,
221
200
  };
222
201
 
223
- if (this.optionalExtraSubscriptions?.includes('orderHistoryAccount')) {
224
- const orderState = (await this.program.account.orderState.fetch(
225
- state.orderState
226
- )) as OrderStateAccount;
227
-
228
- accounts.orderHistory = orderState.orderHistory;
229
- }
230
-
231
202
  return accounts;
232
203
  }
233
204
 
234
205
  async addToAccountLoader(): Promise<void> {
235
206
  for (const [_, accountToPoll] of this.accountsToPoll) {
236
- accountToPoll.callbackId = this.accountLoader.addAccount(
237
- accountToPoll.publicKey,
238
- (buffer) => {
239
- const account = this.program.account[
240
- accountToPoll.key
241
- ].coder.accounts.decode(capitalize(accountToPoll.key), buffer);
242
- this[accountToPoll.key] = account;
243
- // @ts-ignore
244
- this.eventEmitter.emit(accountToPoll.eventType, account);
245
- this.eventEmitter.emit('update');
246
-
247
- if (!this.isSubscribed) {
248
- this.isSubscribed = this.didSubscriptionSucceed();
249
- }
250
- }
251
- );
207
+ this.addAccountToAccountLoader(accountToPoll);
208
+ }
209
+
210
+ for (const [_, oracleToPoll] of this.oraclesToPoll) {
211
+ this.addOracleToAccountLoader(oracleToPoll);
252
212
  }
253
213
 
254
214
  this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
@@ -256,27 +216,114 @@ export class PollingClearingHouseAccountSubscriber
256
216
  });
257
217
  }
258
218
 
219
+ addAccountToAccountLoader(accountToPoll: AccountToPoll): void {
220
+ accountToPoll.callbackId = this.accountLoader.addAccount(
221
+ accountToPoll.publicKey,
222
+ (buffer: Buffer, slot: number) => {
223
+ if (!buffer) return;
224
+
225
+ const account = this.program.account[
226
+ accountToPoll.key
227
+ ].coder.accounts.decode(capitalize(accountToPoll.key), buffer);
228
+ const dataAndSlot = {
229
+ data: account,
230
+ slot,
231
+ };
232
+ if (accountToPoll.mapKey != undefined) {
233
+ this[accountToPoll.key].set(accountToPoll.mapKey, dataAndSlot);
234
+ } else {
235
+ this[accountToPoll.key] = dataAndSlot;
236
+ }
237
+
238
+ // @ts-ignore
239
+ this.eventEmitter.emit(accountToPoll.eventType, account);
240
+ this.eventEmitter.emit('update');
241
+
242
+ if (!this.isSubscribed) {
243
+ this.isSubscribed = this.didSubscriptionSucceed();
244
+ }
245
+ }
246
+ );
247
+ }
248
+
249
+ addOracleToAccountLoader(oracleToPoll: OraclesToPoll): void {
250
+ const oracleClient = this.oracleClientCache.get(
251
+ oracleToPoll.source,
252
+ this.program.provider.connection
253
+ );
254
+
255
+ oracleToPoll.callbackId = this.accountLoader.addAccount(
256
+ oracleToPoll.publicKey,
257
+ (buffer: Buffer, slot: number) => {
258
+ if (!buffer) return;
259
+
260
+ const oraclePriceData =
261
+ oracleClient.getOraclePriceDataFromBuffer(buffer);
262
+ const dataAndSlot = {
263
+ data: oraclePriceData,
264
+ slot,
265
+ };
266
+
267
+ this.oracles.set(oracleToPoll.publicKey.toString(), dataAndSlot);
268
+
269
+ this.eventEmitter.emit(
270
+ 'oraclePriceUpdate',
271
+ oracleToPoll.publicKey,
272
+ oraclePriceData
273
+ );
274
+ this.eventEmitter.emit('update');
275
+ }
276
+ );
277
+ }
278
+
259
279
  public async fetch(): Promise<void> {
260
280
  await this.accountLoader.load();
261
281
  for (const [_, accountToPoll] of this.accountsToPoll) {
262
- const buffer = this.accountLoader.getAccountData(accountToPoll.publicKey);
282
+ const { buffer, slot } = this.accountLoader.getBufferAndSlot(
283
+ accountToPoll.publicKey
284
+ );
263
285
  if (buffer) {
264
- this[accountToPoll.key] = this.program.account[
286
+ const account = this.program.account[
265
287
  accountToPoll.key
266
288
  ].coder.accounts.decode(capitalize(accountToPoll.key), buffer);
289
+
290
+ if (accountToPoll.mapKey != undefined) {
291
+ this[accountToPoll.key].set(accountToPoll.mapKey, {
292
+ data: account,
293
+ slot,
294
+ });
295
+ } else {
296
+ this[accountToPoll.key] = {
297
+ data: account,
298
+ slot,
299
+ };
300
+ }
267
301
  }
268
302
  }
269
- }
270
303
 
271
- didSubscriptionSucceed(): boolean {
272
- let success = true;
273
- for (const [_, accountToPoll] of this.accountsToPoll) {
274
- if (!this[accountToPoll.key]) {
275
- success = false;
276
- break;
304
+ for (const [_, oracleToPoll] of this.oraclesToPoll) {
305
+ const { buffer, slot } = this.accountLoader.getBufferAndSlot(
306
+ oracleToPoll.publicKey
307
+ );
308
+ if (buffer) {
309
+ const oracleClient = this.oracleClientCache.get(
310
+ oracleToPoll.source,
311
+ this.program.provider.connection
312
+ );
313
+ const oraclePriceData =
314
+ oracleClient.getOraclePriceDataFromBuffer(buffer);
315
+ this.oracles.set(oracleToPoll.publicKey.toString(), {
316
+ data: oraclePriceData,
317
+ slot,
318
+ });
277
319
  }
278
320
  }
279
- return success;
321
+ }
322
+
323
+ didSubscriptionSucceed(): boolean {
324
+ if (this.state) return true;
325
+
326
+ return false;
280
327
  }
281
328
 
282
329
  public async unsubscribe(): Promise<void> {
@@ -291,104 +338,92 @@ export class PollingClearingHouseAccountSubscriber
291
338
  );
292
339
  }
293
340
 
341
+ for (const [_, oracleToPoll] of this.oraclesToPoll) {
342
+ this.accountLoader.removeAccount(
343
+ oracleToPoll.publicKey,
344
+ oracleToPoll.callbackId
345
+ );
346
+ }
347
+
294
348
  this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
295
349
  this.errorCallbackId = undefined;
296
350
 
297
351
  this.accountsToPoll.clear();
352
+ this.oraclesToPoll.clear();
298
353
  this.isSubscribed = false;
299
354
  }
300
355
 
301
- assertIsSubscribed(): void {
302
- if (!this.isSubscribed) {
303
- throw new NotSubscribedError(
304
- 'You must call `subscribe` before using this function'
305
- );
356
+ async addBank(bankIndex: BN): Promise<boolean> {
357
+ await this.addBankAccountToPoll(bankIndex);
358
+ const accountToPoll = this.accountsToPoll.get(bankIndex.toString());
359
+ this.addAccountToAccountLoader(accountToPoll);
360
+ return true;
361
+ }
362
+
363
+ async addMarket(marketIndex: BN): Promise<boolean> {
364
+ await this.addMarketAccountToPoll(marketIndex);
365
+ const accountToPoll = this.accountsToPoll.get(marketIndex.toString());
366
+ this.addAccountToAccountLoader(accountToPoll);
367
+ return true;
368
+ }
369
+
370
+ async addOracle(oracleInfo: OracleInfo): Promise<boolean> {
371
+ if (oracleInfo.publicKey.equals(PublicKey.default)) {
372
+ return true;
306
373
  }
374
+
375
+ this.addOracleToPoll(oracleInfo);
376
+ const oracleToPoll = this.oraclesToPoll.get(
377
+ oracleInfo.publicKey.toString()
378
+ );
379
+ this.addOracleToAccountLoader(oracleToPoll);
380
+ return true;
307
381
  }
308
382
 
309
- assertOptionalIsSubscribed(
310
- optionalSubscription: ClearingHouseAccountTypes
311
- ): void {
383
+ assertIsSubscribed(): void {
312
384
  if (!this.isSubscribed) {
313
385
  throw new NotSubscribedError(
314
386
  'You must call `subscribe` before using this function'
315
387
  );
316
388
  }
317
-
318
- if (!this.optionalExtraSubscriptions.includes(optionalSubscription)) {
319
- throw new NotSubscribedError(
320
- `You need to subscribe to the optional Clearing House account "${optionalSubscription}" to use this method`
321
- );
322
- }
323
389
  }
324
390
 
325
- public getStateAccount(): StateAccount {
391
+ public getStateAccountAndSlot(): DataAndSlot<StateAccount> {
326
392
  this.assertIsSubscribed();
327
393
  return this.state;
328
394
  }
329
395
 
330
- public getMarketsAccount(): MarketsAccount {
331
- this.assertIsSubscribed();
332
- return this.markets;
333
- }
334
-
335
- public getOrderStateAccount(): OrderStateAccount {
336
- this.assertIsSubscribed();
337
- return this.orderState;
338
- }
339
-
340
- public getTradeHistoryAccount(): TradeHistoryAccount {
341
- this.assertIsSubscribed();
342
- this.assertOptionalIsSubscribed('tradeHistoryAccount');
343
- return this.tradeHistory;
396
+ public getMarketAccountAndSlot(
397
+ marketIndex: BN
398
+ ): DataAndSlot<MarketAccount> | undefined {
399
+ return this.market.get(marketIndex.toNumber());
344
400
  }
345
401
 
346
- public getDepositHistoryAccount(): DepositHistoryAccount {
347
- this.assertIsSubscribed();
348
- this.assertOptionalIsSubscribed('depositHistoryAccount');
349
- return this.depositHistory;
402
+ public getMarketAccountsAndSlots(): DataAndSlot<MarketAccount>[] {
403
+ return Array.from(this.market.values());
350
404
  }
351
405
 
352
- public getFundingPaymentHistoryAccount(): FundingPaymentHistoryAccount {
353
- this.assertIsSubscribed();
354
- this.assertOptionalIsSubscribed('fundingPaymentHistoryAccount');
355
- return this.fundingPaymentHistory;
356
- }
357
-
358
- public getFundingRateHistoryAccount(): FundingRateHistoryAccount {
359
- this.assertIsSubscribed();
360
- this.assertOptionalIsSubscribed('fundingRateHistoryAccount');
361
- return this.fundingRateHistory;
406
+ public getBankAccountAndSlot(
407
+ bankIndex: BN
408
+ ): DataAndSlot<BankAccount> | undefined {
409
+ return this.bank.get(bankIndex.toNumber());
362
410
  }
363
411
 
364
- public getCurveHistoryAccount(): ExtendedCurveHistoryAccount {
412
+ public getOraclePriceDataAndSlot(
413
+ oraclePublicKey: PublicKey
414
+ ): DataAndSlot<OraclePriceData> | undefined {
365
415
  this.assertIsSubscribed();
366
- this.assertOptionalIsSubscribed('curveHistoryAccount');
367
- return this.extendedCurveHistory;
368
- }
369
-
370
- public getLiquidationHistoryAccount(): LiquidationHistoryAccount {
371
- this.assertIsSubscribed();
372
- this.assertOptionalIsSubscribed('liquidationHistoryAccount');
373
- return this.liquidationHistory;
374
- }
416
+ if (oraclePublicKey.equals(PublicKey.default)) {
417
+ return {
418
+ data: QUOTE_ORACLE_PRICE_DATA,
419
+ slot: 0,
420
+ };
421
+ }
375
422
 
376
- public getOrderHistoryAccount(): OrderHistoryAccount {
377
- this.assertIsSubscribed();
378
- this.assertOptionalIsSubscribed('orderHistoryAccount');
379
- return this.orderHistory;
423
+ return this.oracles.get(oraclePublicKey.toString());
380
424
  }
381
425
  }
382
426
 
383
427
  type ClearingHouseAccounts = {
384
428
  state: PublicKey;
385
- markets: PublicKey;
386
- orderState: PublicKey;
387
- tradeHistory?: PublicKey;
388
- depositHistory?: PublicKey;
389
- fundingPaymentHistory?: PublicKey;
390
- fundingRateHistory?: PublicKey;
391
- extendedCurveHistory?: PublicKey;
392
- liquidationHistory?: PublicKey;
393
- orderHistory?: PublicKey;
394
429
  };