@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,30 +1,19 @@
1
1
  import {
2
- DepositHistoryAccount,
3
- ExtendedCurveHistoryAccount,
4
- FundingPaymentHistoryAccount,
5
- FundingRateHistoryAccount,
6
- LiquidationHistoryAccount,
7
- MarketsAccount,
8
- OrderHistoryAccount,
9
- OrderStateAccount,
2
+ BankAccount,
3
+ MarketAccount,
4
+ OracleSource,
10
5
  StateAccount,
11
- TradeHistoryAccount,
12
6
  UserAccount,
13
- UserOrdersAccount,
14
- UserPositionsAccount,
15
7
  } from '../types';
16
8
  import StrictEventEmitter from 'strict-event-emitter-types';
17
9
  import { EventEmitter } from 'events';
18
10
  import { PublicKey } from '@solana/web3.js';
19
11
  import { AccountInfo } from '@solana/spl-token';
20
- import {
21
- ClearingHouseConfigType,
22
- ClearingHouseUserConfigType,
23
- OraclePriceData,
24
- } from '..';
12
+ import { OracleInfo, OraclePriceData } from '..';
13
+ import { BN } from '@project-serum/anchor';
25
14
 
26
15
  export interface AccountSubscriber<T> {
27
- data?: T;
16
+ dataAndSlot?: DataAndSlot<T>;
28
17
  subscribe(onChange: (data: T) => void): Promise<void>;
29
18
  fetch(): Promise<void>;
30
19
  unsubscribe(): Promise<void>;
@@ -36,66 +25,39 @@ export class NotSubscribedError extends Error {
36
25
 
37
26
  export interface ClearingHouseAccountEvents {
38
27
  stateAccountUpdate: (payload: StateAccount) => void;
39
- marketsAccountUpdate: (payload: MarketsAccount) => void;
40
- fundingPaymentHistoryAccountUpdate: (
41
- payload: FundingPaymentHistoryAccount
42
- ) => void;
43
- fundingRateHistoryAccountUpdate: (payload: FundingRateHistoryAccount) => void;
44
- tradeHistoryAccountUpdate: (payload: TradeHistoryAccount) => void;
45
- liquidationHistoryAccountUpdate: (payload: LiquidationHistoryAccount) => void;
46
- depositHistoryAccountUpdate: (payload: DepositHistoryAccount) => void;
47
- curveHistoryAccountUpdate: (payload: ExtendedCurveHistoryAccount) => void;
48
- orderHistoryAccountUpdate: (payload: OrderHistoryAccount) => void;
49
- orderStateAccountUpdate: (payload: OrderStateAccount) => void;
28
+ marketAccountUpdate: (payload: MarketAccount) => void;
29
+ bankAccountUpdate: (payload: BankAccount) => void;
30
+ oraclePriceUpdate: (publicKey: PublicKey, data: OraclePriceData) => void;
31
+ userAccountUpdate: (payload: UserAccount) => void;
50
32
  update: void;
51
33
  error: (e: Error) => void;
52
34
  }
53
35
 
54
- export type ClearingHouseAccountTypes =
55
- | 'tradeHistoryAccount'
56
- | 'depositHistoryAccount'
57
- | 'fundingPaymentHistoryAccount'
58
- | 'fundingRateHistoryAccount'
59
- | 'curveHistoryAccount'
60
- | 'liquidationHistoryAccount'
61
- | 'orderHistoryAccount';
62
-
63
36
  export interface ClearingHouseAccountSubscriber {
64
37
  eventEmitter: StrictEventEmitter<EventEmitter, ClearingHouseAccountEvents>;
65
38
  isSubscribed: boolean;
66
39
 
67
- optionalExtraSubscriptions: ClearingHouseAccountTypes[];
68
-
69
- subscribe(
70
- optionalSubscriptions?: ClearingHouseAccountTypes[]
71
- ): Promise<boolean>;
40
+ subscribe(): Promise<boolean>;
72
41
  fetch(): Promise<void>;
73
42
  unsubscribe(): Promise<void>;
74
43
 
75
- getStateAccount(): StateAccount;
76
- getMarketsAccount(): MarketsAccount;
77
- getTradeHistoryAccount(): TradeHistoryAccount;
78
- getDepositHistoryAccount(): DepositHistoryAccount;
79
- getFundingPaymentHistoryAccount(): FundingPaymentHistoryAccount;
80
- getFundingRateHistoryAccount(): FundingRateHistoryAccount;
81
- getCurveHistoryAccount(): ExtendedCurveHistoryAccount;
82
- getLiquidationHistoryAccount(): LiquidationHistoryAccount;
83
- getOrderStateAccount(): OrderStateAccount;
84
- getOrderHistoryAccount(): OrderHistoryAccount;
85
-
86
- type: ClearingHouseConfigType;
44
+ addMarket(marketIndex: BN): Promise<boolean>;
45
+ addBank(bankIndex: BN): Promise<boolean>;
46
+ addOracle(oracleInfo: OracleInfo): Promise<boolean>;
47
+
48
+ getStateAccountAndSlot(): DataAndSlot<StateAccount>;
49
+ getMarketAccountAndSlot(
50
+ marketIndex: BN
51
+ ): DataAndSlot<MarketAccount> | undefined;
52
+ getMarketAccountsAndSlots(): DataAndSlot<MarketAccount>[];
53
+ getBankAccountAndSlot(bankIndex: BN): DataAndSlot<BankAccount> | undefined;
54
+ getOraclePriceDataAndSlot(
55
+ oraclePublicKey: PublicKey
56
+ ): DataAndSlot<OraclePriceData> | undefined;
87
57
  }
88
58
 
89
- export type UserPublicKeys = {
90
- user: PublicKey;
91
- userPositions: PublicKey;
92
- userOrders: PublicKey | undefined;
93
- };
94
-
95
59
  export interface UserAccountEvents {
96
- userAccountData: (payload: UserAccount) => void;
97
- userPositionsData: (payload: UserPositionsAccount) => void;
98
- userOrdersData: (payload: UserOrdersAccount) => void;
60
+ userAccountUpdate: (payload: UserAccount) => void;
99
61
  update: void;
100
62
  error: (e: Error) => void;
101
63
  }
@@ -108,10 +70,7 @@ export interface UserAccountSubscriber {
108
70
  fetch(): Promise<void>;
109
71
  unsubscribe(): Promise<void>;
110
72
 
111
- getUserAccount(): UserAccount;
112
- getUserPositionsAccount(): UserPositionsAccount;
113
- getUserOrdersAccount(): UserOrdersAccount;
114
- type: ClearingHouseUserConfigType;
73
+ getUserAccountAndSlot(): DataAndSlot<UserAccount>;
115
74
  }
116
75
 
117
76
  export interface TokenAccountEvents {
@@ -128,7 +87,7 @@ export interface TokenAccountSubscriber {
128
87
  fetch(): Promise<void>;
129
88
  unsubscribe(): Promise<void>;
130
89
 
131
- getTokenAccount(): AccountInfo;
90
+ getTokenAccountAndSlot(): DataAndSlot<AccountInfo>;
132
91
  }
133
92
 
134
93
  export interface OracleEvents {
@@ -145,7 +104,7 @@ export interface OracleSubscriber {
145
104
  fetch(): Promise<void>;
146
105
  unsubscribe(): Promise<void>;
147
106
 
148
- getOraclePriceData(): OraclePriceData;
107
+ getOraclePriceData(): DataAndSlot<OraclePriceData>;
149
108
  }
150
109
 
151
110
  export type AccountToPoll = {
@@ -153,9 +112,21 @@ export type AccountToPoll = {
153
112
  publicKey: PublicKey;
154
113
  eventType: string;
155
114
  callbackId?: string;
115
+ mapKey?: number;
156
116
  };
157
117
 
158
- export type AccountData = {
118
+ export type OraclesToPoll = {
119
+ publicKey: PublicKey;
120
+ source: OracleSource;
121
+ callbackId?: string;
122
+ };
123
+
124
+ export type BufferAndSlot = {
159
125
  slot: number;
160
126
  buffer: Buffer | undefined;
161
127
  };
128
+
129
+ export type DataAndSlot<T> = {
130
+ data: T;
131
+ slot: number;
132
+ };
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.capitalize = void 0;
4
+ function capitalize(value) {
5
+ return value[0].toUpperCase() + value.slice(1);
6
+ }
7
+ exports.capitalize = capitalize;
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.WebSocketAccountSubscriber = void 0;
13
+ const utils_1 = require("./utils");
14
+ class WebSocketAccountSubscriber {
15
+ constructor(accountName, program, accountPublicKey, decodeBuffer) {
16
+ this.accountName = accountName;
17
+ this.program = program;
18
+ this.accountPublicKey = accountPublicKey;
19
+ this.decodeBufferFn = decodeBuffer;
20
+ }
21
+ subscribe(onChange) {
22
+ return __awaiter(this, void 0, void 0, function* () {
23
+ if (this.listenerId) {
24
+ return;
25
+ }
26
+ this.onChange = onChange;
27
+ yield this.fetch();
28
+ this.listenerId = this.program.provider.connection.onAccountChange(this.accountPublicKey, (accountInfo, context) => {
29
+ this.handleRpcResponse(context, accountInfo);
30
+ }, this.program.provider.opts.commitment);
31
+ });
32
+ }
33
+ fetch() {
34
+ return __awaiter(this, void 0, void 0, function* () {
35
+ const rpcResponse = yield this.program.provider.connection.getAccountInfoAndContext(this.accountPublicKey, this.program.provider.opts.commitment);
36
+ this.handleRpcResponse(rpcResponse.context, rpcResponse === null || rpcResponse === void 0 ? void 0 : rpcResponse.value);
37
+ });
38
+ }
39
+ handleRpcResponse(context, accountInfo) {
40
+ const newSlot = context.slot;
41
+ let newBuffer = undefined;
42
+ if (accountInfo) {
43
+ newBuffer = accountInfo.data;
44
+ }
45
+ if (!this.bufferAndSlot) {
46
+ this.bufferAndSlot = {
47
+ buffer: newBuffer,
48
+ slot: newSlot,
49
+ };
50
+ if (newBuffer) {
51
+ const account = this.decodeBuffer(newBuffer);
52
+ this.dataAndSlot = {
53
+ data: account,
54
+ slot: newSlot,
55
+ };
56
+ this.onChange(account);
57
+ }
58
+ return;
59
+ }
60
+ if (newSlot <= this.bufferAndSlot.slot) {
61
+ return;
62
+ }
63
+ const oldBuffer = this.bufferAndSlot.buffer;
64
+ if (newBuffer && (!oldBuffer || !newBuffer.equals(oldBuffer))) {
65
+ this.bufferAndSlot = {
66
+ buffer: newBuffer,
67
+ slot: newSlot,
68
+ };
69
+ const account = this.decodeBuffer(newBuffer);
70
+ this.dataAndSlot = {
71
+ data: account,
72
+ slot: newSlot,
73
+ };
74
+ this.onChange(account);
75
+ }
76
+ }
77
+ decodeBuffer(buffer) {
78
+ if (this.decodeBufferFn) {
79
+ return this.decodeBufferFn(buffer);
80
+ }
81
+ else {
82
+ return this.program.account[this.accountName].coder.accounts.decode(utils_1.capitalize(this.accountName), buffer);
83
+ }
84
+ }
85
+ unsubscribe() {
86
+ if (this.listenerId) {
87
+ const promise = this.program.provider.connection.removeAccountChangeListener(this.listenerId);
88
+ this.listenerId = undefined;
89
+ return promise;
90
+ }
91
+ }
92
+ }
93
+ exports.WebSocketAccountSubscriber = WebSocketAccountSubscriber;
@@ -1,26 +1,29 @@
1
- import { AccountData, AccountSubscriber } from './types';
1
+ import { DataAndSlot, BufferAndSlot, AccountSubscriber } from './types';
2
2
  import { AnchorProvider, Program } from '@project-serum/anchor';
3
3
  import { AccountInfo, Context, PublicKey } from '@solana/web3.js';
4
4
  import { capitalize } from './utils';
5
5
  import * as Buffer from 'buffer';
6
6
 
7
7
  export class WebSocketAccountSubscriber<T> implements AccountSubscriber<T> {
8
- data?: T;
9
- accountData?: AccountData;
8
+ dataAndSlot?: DataAndSlot<T>;
9
+ bufferAndSlot?: BufferAndSlot;
10
10
  accountName: string;
11
11
  program: Program;
12
12
  accountPublicKey: PublicKey;
13
+ decodeBufferFn: (buffer: Buffer) => T;
13
14
  onChange: (data: T) => void;
14
15
  listenerId?: number;
15
16
 
16
17
  public constructor(
17
18
  accountName: string,
18
19
  program: Program,
19
- accountPublicKey: PublicKey
20
+ accountPublicKey: PublicKey,
21
+ decodeBuffer?: (buffer: Buffer) => T
20
22
  ) {
21
23
  this.accountName = accountName;
22
24
  this.program = program;
23
25
  this.accountPublicKey = accountPublicKey;
26
+ this.decodeBufferFn = decodeBuffer;
24
27
  }
25
28
 
26
29
  async subscribe(onChange: (data: T) => void): Promise<void> {
@@ -56,35 +59,49 @@ export class WebSocketAccountSubscriber<T> implements AccountSubscriber<T> {
56
59
  newBuffer = accountInfo.data;
57
60
  }
58
61
 
59
- if (!this.accountData) {
60
- this.accountData = {
62
+ if (!this.bufferAndSlot) {
63
+ this.bufferAndSlot = {
61
64
  buffer: newBuffer,
62
65
  slot: newSlot,
63
66
  };
64
67
  if (newBuffer) {
65
- this.data = this.program.account[
66
- this.accountName
67
- ].coder.accounts.decode(capitalize(this.accountName), newBuffer);
68
- this.onChange(this.data);
68
+ const account = this.decodeBuffer(newBuffer);
69
+ this.dataAndSlot = {
70
+ data: account,
71
+ slot: newSlot,
72
+ };
73
+ this.onChange(account);
69
74
  }
70
75
  return;
71
76
  }
72
77
 
73
- if (newSlot <= this.accountData.slot) {
78
+ if (newSlot <= this.bufferAndSlot.slot) {
74
79
  return;
75
80
  }
76
81
 
77
- const oldBuffer = this.accountData.buffer;
82
+ const oldBuffer = this.bufferAndSlot.buffer;
78
83
  if (newBuffer && (!oldBuffer || !newBuffer.equals(oldBuffer))) {
79
- this.accountData = {
84
+ this.bufferAndSlot = {
80
85
  buffer: newBuffer,
81
86
  slot: newSlot,
82
87
  };
83
- this.data = this.program.account[this.accountName].coder.accounts.decode(
88
+ const account = this.decodeBuffer(newBuffer);
89
+ this.dataAndSlot = {
90
+ data: account,
91
+ slot: newSlot,
92
+ };
93
+ this.onChange(account);
94
+ }
95
+ }
96
+
97
+ decodeBuffer(buffer: Buffer): T {
98
+ if (this.decodeBufferFn) {
99
+ return this.decodeBufferFn(buffer);
100
+ } else {
101
+ return this.program.account[this.accountName].coder.accounts.decode(
84
102
  capitalize(this.accountName),
85
- newBuffer
103
+ buffer
86
104
  );
87
- this.onChange(this.data);
88
105
  }
89
106
  }
90
107
 
@@ -0,0 +1,233 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.WebSocketClearingHouseAccountSubscriber = void 0;
13
+ const types_1 = require("./types");
14
+ const events_1 = require("events");
15
+ const pda_1 = require("../addresses/pda");
16
+ const webSocketAccountSubscriber_1 = require("./webSocketAccountSubscriber");
17
+ const web3_js_1 = require("@solana/web3.js");
18
+ const oracleClientCache_1 = require("../oracles/oracleClientCache");
19
+ const quoteAssetOracleClient_1 = require("../oracles/quoteAssetOracleClient");
20
+ class WebSocketClearingHouseAccountSubscriber {
21
+ constructor(program, marketIndexes, bankIndexes, oracleInfos) {
22
+ this.oracleClientCache = new oracleClientCache_1.OracleClientCache();
23
+ this.marketAccountSubscribers = new Map();
24
+ this.bankAccountSubscribers = new Map();
25
+ this.oracleSubscribers = new Map();
26
+ this.isSubscribing = false;
27
+ this.isSubscribed = false;
28
+ this.program = program;
29
+ this.eventEmitter = new events_1.EventEmitter();
30
+ this.marketIndexes = marketIndexes;
31
+ this.bankIndexes = bankIndexes;
32
+ this.oracleInfos = oracleInfos;
33
+ }
34
+ subscribe() {
35
+ return __awaiter(this, void 0, void 0, function* () {
36
+ if (this.isSubscribed) {
37
+ return true;
38
+ }
39
+ if (this.isSubscribing) {
40
+ return yield this.subscriptionPromise;
41
+ }
42
+ this.isSubscribing = true;
43
+ this.subscriptionPromise = new Promise((res) => {
44
+ this.subscriptionPromiseResolver = res;
45
+ });
46
+ const statePublicKey = yield pda_1.getClearingHouseStateAccountPublicKey(this.program.programId);
47
+ // create and activate main state account subscription
48
+ this.stateAccountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('state', this.program, statePublicKey);
49
+ yield this.stateAccountSubscriber.subscribe((data) => {
50
+ this.eventEmitter.emit('stateAccountUpdate', data);
51
+ this.eventEmitter.emit('update');
52
+ });
53
+ // subscribe to market accounts
54
+ yield this.subscribeToMarketAccounts();
55
+ // subscribe to bank accounts
56
+ yield this.subscribeToBankAccounts();
57
+ // subscribe to oracles
58
+ yield this.subscribeToOracles();
59
+ this.eventEmitter.emit('update');
60
+ this.isSubscribing = false;
61
+ this.isSubscribed = true;
62
+ this.subscriptionPromiseResolver(true);
63
+ return true;
64
+ });
65
+ }
66
+ subscribeToMarketAccounts() {
67
+ return __awaiter(this, void 0, void 0, function* () {
68
+ for (const marketIndex of this.marketIndexes) {
69
+ yield this.subscribeToMarketAccount(marketIndex);
70
+ }
71
+ return true;
72
+ });
73
+ }
74
+ subscribeToMarketAccount(marketIndex) {
75
+ return __awaiter(this, void 0, void 0, function* () {
76
+ const marketPublicKey = yield pda_1.getMarketPublicKey(this.program.programId, marketIndex);
77
+ const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('market', this.program, marketPublicKey);
78
+ yield accountSubscriber.subscribe((data) => {
79
+ this.eventEmitter.emit('marketAccountUpdate', data);
80
+ this.eventEmitter.emit('update');
81
+ });
82
+ this.marketAccountSubscribers.set(marketIndex.toNumber(), accountSubscriber);
83
+ return true;
84
+ });
85
+ }
86
+ subscribeToBankAccounts() {
87
+ return __awaiter(this, void 0, void 0, function* () {
88
+ for (const bankIndex of this.bankIndexes) {
89
+ yield this.subscribeToBankAccount(bankIndex);
90
+ }
91
+ return true;
92
+ });
93
+ }
94
+ subscribeToBankAccount(bankIndex) {
95
+ return __awaiter(this, void 0, void 0, function* () {
96
+ const bankPublicKey = yield pda_1.getBankPublicKey(this.program.programId, bankIndex);
97
+ const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('bank', this.program, bankPublicKey);
98
+ yield accountSubscriber.subscribe((data) => {
99
+ this.eventEmitter.emit('bankAccountUpdate', data);
100
+ this.eventEmitter.emit('update');
101
+ });
102
+ this.bankAccountSubscribers.set(bankIndex.toNumber(), accountSubscriber);
103
+ return true;
104
+ });
105
+ }
106
+ subscribeToOracles() {
107
+ return __awaiter(this, void 0, void 0, function* () {
108
+ for (const oracleInfo of this.oracleInfos) {
109
+ if (!oracleInfo.publicKey.equals(web3_js_1.PublicKey.default)) {
110
+ yield this.subscribeToOracle(oracleInfo);
111
+ }
112
+ }
113
+ return true;
114
+ });
115
+ }
116
+ subscribeToOracle(oracleInfo) {
117
+ return __awaiter(this, void 0, void 0, function* () {
118
+ const client = this.oracleClientCache.get(oracleInfo.source, this.program.provider.connection);
119
+ const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('oracle', this.program, oracleInfo.publicKey, (buffer) => {
120
+ return client.getOraclePriceDataFromBuffer(buffer);
121
+ });
122
+ yield accountSubscriber.subscribe((data) => {
123
+ this.eventEmitter.emit('oraclePriceUpdate', oracleInfo.publicKey, data);
124
+ this.eventEmitter.emit('update');
125
+ });
126
+ this.oracleSubscribers.set(oracleInfo.publicKey.toString(), accountSubscriber);
127
+ return true;
128
+ });
129
+ }
130
+ unsubscribeFromMarketAccounts() {
131
+ return __awaiter(this, void 0, void 0, function* () {
132
+ for (const accountSubscriber of this.marketAccountSubscribers.values()) {
133
+ yield accountSubscriber.unsubscribe();
134
+ }
135
+ });
136
+ }
137
+ unsubscribeFromBankAccounts() {
138
+ return __awaiter(this, void 0, void 0, function* () {
139
+ for (const accountSubscriber of this.bankAccountSubscribers.values()) {
140
+ yield accountSubscriber.unsubscribe();
141
+ }
142
+ });
143
+ }
144
+ unsubscribeFromOracles() {
145
+ return __awaiter(this, void 0, void 0, function* () {
146
+ for (const accountSubscriber of this.oracleSubscribers.values()) {
147
+ yield accountSubscriber.unsubscribe();
148
+ }
149
+ });
150
+ }
151
+ fetch() {
152
+ return __awaiter(this, void 0, void 0, function* () {
153
+ if (!this.isSubscribed) {
154
+ return;
155
+ }
156
+ const promises = [this.stateAccountSubscriber.fetch()]
157
+ .concat(Array.from(this.marketAccountSubscribers.values()).map((subscriber) => subscriber.fetch()))
158
+ .concat(Array.from(this.bankAccountSubscribers.values()).map((subscriber) => subscriber.fetch()));
159
+ yield Promise.all(promises);
160
+ });
161
+ }
162
+ unsubscribe() {
163
+ return __awaiter(this, void 0, void 0, function* () {
164
+ if (!this.isSubscribed) {
165
+ return;
166
+ }
167
+ yield this.stateAccountSubscriber.unsubscribe();
168
+ yield this.unsubscribeFromMarketAccounts();
169
+ yield this.unsubscribeFromBankAccounts();
170
+ yield this.unsubscribeFromOracles();
171
+ this.isSubscribed = false;
172
+ });
173
+ }
174
+ addBank(bankIndex) {
175
+ return __awaiter(this, void 0, void 0, function* () {
176
+ if (this.bankAccountSubscribers.has(bankIndex.toNumber())) {
177
+ return true;
178
+ }
179
+ return this.subscribeToBankAccount(bankIndex);
180
+ });
181
+ }
182
+ addMarket(marketIndex) {
183
+ return __awaiter(this, void 0, void 0, function* () {
184
+ if (this.marketAccountSubscribers.has(marketIndex.toNumber())) {
185
+ return true;
186
+ }
187
+ return this.subscribeToMarketAccount(marketIndex);
188
+ });
189
+ }
190
+ addOracle(oracleInfo) {
191
+ return __awaiter(this, void 0, void 0, function* () {
192
+ if (this.oracleSubscribers.has(oracleInfo.publicKey.toString())) {
193
+ return true;
194
+ }
195
+ if (oracleInfo.publicKey.equals(web3_js_1.PublicKey.default)) {
196
+ return true;
197
+ }
198
+ return this.subscribeToOracle(oracleInfo);
199
+ });
200
+ }
201
+ assertIsSubscribed() {
202
+ if (!this.isSubscribed) {
203
+ throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
204
+ }
205
+ }
206
+ getStateAccountAndSlot() {
207
+ this.assertIsSubscribed();
208
+ return this.stateAccountSubscriber.dataAndSlot;
209
+ }
210
+ getMarketAccountAndSlot(marketIndex) {
211
+ this.assertIsSubscribed();
212
+ return this.marketAccountSubscribers.get(marketIndex.toNumber())
213
+ .dataAndSlot;
214
+ }
215
+ getMarketAccountsAndSlots() {
216
+ return Array.from(this.marketAccountSubscribers.values()).map((subscriber) => subscriber.dataAndSlot);
217
+ }
218
+ getBankAccountAndSlot(bankIndex) {
219
+ this.assertIsSubscribed();
220
+ return this.bankAccountSubscribers.get(bankIndex.toNumber()).dataAndSlot;
221
+ }
222
+ getOraclePriceDataAndSlot(oraclePublicKey) {
223
+ this.assertIsSubscribed();
224
+ if (oraclePublicKey.equals(web3_js_1.PublicKey.default)) {
225
+ return {
226
+ data: quoteAssetOracleClient_1.QUOTE_ORACLE_PRICE_DATA,
227
+ slot: 0,
228
+ };
229
+ }
230
+ return this.oracleSubscribers.get(oraclePublicKey.toString()).dataAndSlot;
231
+ }
232
+ }
233
+ exports.WebSocketClearingHouseAccountSubscriber = WebSocketClearingHouseAccountSubscriber;