@drift-labs/sdk 0.2.0-master.3 → 0.2.0-master.30

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 (208) hide show
  1. package/README.md +13 -13
  2. package/lib/accounts/bulkUserStatsSubscription.d.ts +7 -0
  3. package/lib/accounts/bulkUserStatsSubscription.js +21 -0
  4. package/lib/accounts/bulkUserSubscription.js +0 -1
  5. package/lib/accounts/fetch.d.ts +2 -1
  6. package/lib/accounts/fetch.js +9 -1
  7. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +16 -16
  8. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +31 -28
  9. package/lib/accounts/pollingUserStatsAccountSubscriber.d.ts +27 -0
  10. package/lib/accounts/pollingUserStatsAccountSubscriber.js +113 -0
  11. package/lib/accounts/types.d.ts +22 -11
  12. package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +17 -17
  13. package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +37 -35
  14. package/lib/accounts/webSocketUserStatsAccountSubsriber.d.ts +20 -0
  15. package/lib/accounts/webSocketUserStatsAccountSubsriber.js +47 -0
  16. package/lib/addresses/marketAddresses.d.ts +1 -3
  17. package/lib/addresses/pda.d.ts +10 -4
  18. package/lib/addresses/pda.js +51 -14
  19. package/lib/admin.d.ts +34 -22
  20. package/lib/admin.js +182 -73
  21. package/lib/clearingHouse.d.ts +120 -42
  22. package/lib/clearingHouse.js +1505 -254
  23. package/lib/clearingHouseConfig.d.ts +4 -4
  24. package/lib/clearingHouseUser.d.ts +50 -38
  25. package/lib/clearingHouseUser.js +410 -190
  26. package/lib/clearingHouseUserStats.d.ts +18 -0
  27. package/lib/clearingHouseUserStats.js +49 -0
  28. package/lib/clearingHouseUserStatsConfig.d.ts +14 -0
  29. package/lib/clearingHouseUserStatsConfig.js +2 -0
  30. package/lib/config.d.ts +7 -9
  31. package/lib/config.js +21 -21
  32. package/lib/constants/numericConstants.d.ts +18 -12
  33. package/lib/constants/numericConstants.js +28 -21
  34. package/lib/constants/perpMarkets.d.ts +18 -0
  35. package/lib/constants/{markets.js → perpMarkets.js} +7 -7
  36. package/lib/constants/spotMarkets.d.ts +19 -0
  37. package/lib/constants/spotMarkets.js +53 -0
  38. package/lib/dlob/DLOB.d.ts +73 -0
  39. package/lib/dlob/DLOB.js +553 -0
  40. package/lib/dlob/DLOBNode.d.ts +52 -0
  41. package/lib/dlob/DLOBNode.js +82 -0
  42. package/lib/dlob/NodeList.d.ts +26 -0
  43. package/lib/dlob/NodeList.js +138 -0
  44. package/lib/events/eventList.js +3 -0
  45. package/lib/events/eventSubscriber.d.ts +4 -2
  46. package/lib/events/eventSubscriber.js +16 -9
  47. package/lib/events/fetchLogs.d.ts +10 -1
  48. package/lib/events/fetchLogs.js +27 -7
  49. package/lib/events/pollingLogProvider.d.ts +2 -1
  50. package/lib/events/pollingLogProvider.js +6 -2
  51. package/lib/events/sort.js +8 -11
  52. package/lib/events/types.d.ts +7 -2
  53. package/lib/events/types.js +5 -0
  54. package/lib/examples/makeTradeExample.js +20 -8
  55. package/lib/factory/bigNum.d.ts +1 -0
  56. package/lib/factory/bigNum.js +34 -10
  57. package/lib/idl/clearing_house.json +4313 -1433
  58. package/lib/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
  59. package/lib/index.d.ts +21 -6
  60. package/lib/index.js +25 -6
  61. package/lib/math/amm.d.ts +8 -5
  62. package/lib/math/amm.js +68 -46
  63. package/lib/math/auction.js +4 -1
  64. package/lib/math/conversion.js +1 -1
  65. package/lib/math/funding.d.ts +6 -6
  66. package/lib/math/funding.js +11 -10
  67. package/lib/math/insurance.d.ts +4 -0
  68. package/lib/math/insurance.js +27 -0
  69. package/lib/math/margin.d.ts +11 -0
  70. package/lib/math/margin.js +77 -0
  71. package/lib/math/market.d.ts +14 -9
  72. package/lib/math/market.js +69 -7
  73. package/lib/math/oracles.d.ts +4 -0
  74. package/lib/math/oracles.js +36 -8
  75. package/lib/math/orders.d.ts +6 -2
  76. package/lib/math/orders.js +78 -3
  77. package/lib/math/position.d.ts +21 -13
  78. package/lib/math/position.js +76 -36
  79. package/lib/math/repeg.js +14 -5
  80. package/lib/math/spotBalance.d.ts +22 -0
  81. package/lib/math/spotBalance.js +193 -0
  82. package/lib/math/spotMarket.d.ts +4 -0
  83. package/lib/math/spotMarket.js +8 -0
  84. package/lib/math/spotPosition.d.ts +6 -0
  85. package/lib/math/spotPosition.js +23 -0
  86. package/lib/math/trade.d.ts +10 -10
  87. package/lib/math/trade.js +22 -29
  88. package/lib/oracles/pythClient.js +1 -1
  89. package/lib/oracles/quoteAssetOracleClient.js +1 -1
  90. package/lib/oracles/switchboardClient.js +1 -1
  91. package/lib/orderParams.d.ts +14 -5
  92. package/lib/orderParams.js +12 -92
  93. package/lib/serum/serumSubscriber.d.ts +23 -0
  94. package/lib/serum/serumSubscriber.js +41 -0
  95. package/lib/serum/types.d.ts +11 -0
  96. package/lib/serum/types.js +2 -0
  97. package/lib/slot/SlotSubscriber.d.ts +7 -0
  98. package/lib/slot/SlotSubscriber.js +3 -0
  99. package/lib/{mockUSDCFaucet.d.ts → tokenFaucet.d.ts} +8 -5
  100. package/lib/{mockUSDCFaucet.js → tokenFaucet.js} +63 -51
  101. package/lib/tx/retryTxSender.d.ts +1 -1
  102. package/lib/tx/retryTxSender.js +13 -4
  103. package/lib/tx/types.d.ts +1 -1
  104. package/lib/tx/utils.js +1 -1
  105. package/lib/types.d.ts +474 -123
  106. package/lib/types.js +99 -5
  107. package/lib/userMap/userMap.d.ts +25 -0
  108. package/lib/userMap/userMap.js +73 -0
  109. package/lib/userMap/userStatsMap.d.ts +19 -0
  110. package/lib/userMap/userStatsMap.js +68 -0
  111. package/lib/util/computeUnits.js +1 -1
  112. package/lib/util/getTokenAddress.d.ts +2 -0
  113. package/lib/util/getTokenAddress.js +9 -0
  114. package/package.json +9 -5
  115. package/src/accounts/bulkUserStatsSubscription.ts +33 -0
  116. package/src/accounts/bulkUserSubscription.ts +0 -1
  117. package/src/accounts/fetch.ts +27 -2
  118. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +46 -42
  119. package/src/accounts/pollingUserStatsAccountSubscriber.ts +172 -0
  120. package/src/accounts/types.ts +31 -11
  121. package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +64 -59
  122. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +80 -0
  123. package/src/addresses/marketAddresses.ts +1 -2
  124. package/src/addresses/pda.ts +88 -14
  125. package/src/admin.ts +333 -128
  126. package/src/assert/assert.js +9 -0
  127. package/src/clearingHouse.ts +2464 -458
  128. package/src/clearingHouseConfig.ts +4 -3
  129. package/src/clearingHouseUser.ts +747 -291
  130. package/src/clearingHouseUserStats.ts +75 -0
  131. package/src/clearingHouseUserStatsConfig.ts +18 -0
  132. package/src/config.ts +30 -31
  133. package/src/constants/numericConstants.ts +41 -25
  134. package/src/constants/{markets.ts → perpMarkets.ts} +10 -10
  135. package/src/constants/spotMarkets.ts +72 -0
  136. package/src/dlob/DLOB.ts +868 -0
  137. package/src/dlob/DLOBNode.ts +162 -0
  138. package/src/dlob/NodeList.ts +185 -0
  139. package/src/events/eventList.js +77 -0
  140. package/src/events/eventList.ts +3 -0
  141. package/src/events/eventSubscriber.ts +20 -12
  142. package/src/events/fetchLogs.ts +35 -8
  143. package/src/events/pollingLogProvider.ts +10 -2
  144. package/src/events/sort.ts +11 -15
  145. package/src/events/types.ts +16 -1
  146. package/src/examples/makeTradeExample.js +157 -0
  147. package/src/examples/makeTradeExample.ts +32 -14
  148. package/src/factory/bigNum.ts +42 -13
  149. package/src/idl/clearing_house.json +4313 -1433
  150. package/src/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
  151. package/src/index.ts +21 -6
  152. package/src/math/amm.ts +136 -66
  153. package/src/math/auction.ts +5 -1
  154. package/src/math/conversion.ts +2 -2
  155. package/src/math/funding.ts +20 -18
  156. package/src/math/insurance.ts +35 -0
  157. package/src/math/margin.ts +127 -0
  158. package/src/math/market.ts +138 -12
  159. package/src/math/oracles.ts +63 -9
  160. package/src/math/orders.ts +138 -4
  161. package/src/math/position.ts +119 -58
  162. package/src/math/repeg.ts +16 -6
  163. package/src/math/spotBalance.ts +316 -0
  164. package/src/math/spotMarket.ts +9 -0
  165. package/src/math/spotPosition.ts +47 -0
  166. package/src/math/trade.ts +43 -49
  167. package/src/oracles/pythClient.ts +2 -2
  168. package/src/oracles/quoteAssetOracleClient.ts +2 -2
  169. package/src/oracles/switchboardClient.ts +2 -2
  170. package/src/orderParams.ts +24 -137
  171. package/src/serum/serumSubscriber.ts +80 -0
  172. package/src/serum/types.ts +13 -0
  173. package/src/slot/SlotSubscriber.ts +11 -1
  174. package/src/token/index.js +38 -0
  175. package/src/{mockUSDCFaucet.ts → tokenFaucet.ts} +82 -70
  176. package/src/tx/retryTxSender.ts +16 -5
  177. package/src/tx/types.js +2 -0
  178. package/src/tx/types.ts +2 -1
  179. package/src/tx/utils.js +17 -0
  180. package/src/tx/utils.ts +1 -1
  181. package/src/types.ts +477 -125
  182. package/src/userMap/userMap.ts +100 -0
  183. package/src/userMap/userStatsMap.ts +110 -0
  184. package/src/util/computeUnits.js +21 -11
  185. package/src/util/computeUnits.ts +1 -1
  186. package/src/util/getTokenAddress.js +9 -0
  187. package/src/util/getTokenAddress.ts +18 -0
  188. package/src/util/promiseTimeout.js +14 -0
  189. package/src/util/tps.js +27 -0
  190. package/tests/bn/test.ts +12 -3
  191. package/tests/dlob/helpers.ts +374 -0
  192. package/tests/dlob/test.ts +2865 -0
  193. package/lib/constants/banks.d.ts +0 -16
  194. package/lib/constants/banks.js +0 -34
  195. package/lib/constants/markets.d.ts +0 -19
  196. package/lib/math/bankBalance.d.ts +0 -9
  197. package/lib/math/bankBalance.js +0 -75
  198. package/lib/math/state.d.ts +0 -8
  199. package/lib/math/state.js +0 -15
  200. package/lib/orders.d.ts +0 -8
  201. package/lib/orders.js +0 -134
  202. package/src/constants/banks.ts +0 -43
  203. package/src/math/bankBalance.ts +0 -112
  204. package/src/math/state.ts +0 -14
  205. package/src/math/utils.js +0 -27
  206. package/src/math/utils.js.map +0 -1
  207. package/src/orders.ts +0 -244
  208. package/src/util/computeUnits.js.map +0 -1
package/README.md CHANGED
@@ -54,13 +54,13 @@ a BigNum: 10,500,000, with precision 10^6, is equal to 10.5 because 10,500,000 /
54
54
 
55
55
  The Drift SDK uses some common precisions, which are available as constants to import from the SDK.
56
56
 
57
- | Precision Name | Value |
58
- | ------------------------- | ----- |
59
- | QUOTE_PRECISION | 10^6 |
60
- | MARK_PRICE_PRECISION | 10^10 |
61
- | AMM_RESERVE_PRECISION | 10^13 |
62
- | FUNDING_PAYMENT_PRECISION | 10^4 |
63
- | PEG_PRECISION | 10^3 |
57
+ | Precision Name | Value |
58
+ | --------------------- | ----- |
59
+ | FUNDING_RATE_BUFFER | 10^3 |
60
+ | QUOTE_PRECISION | 10^6 |
61
+ | PEG_PRECISION | 10^6 |
62
+ | PRICE_PRECISION | 10^6 |
63
+ | AMM_RESERVE_PRECISION | 10^9 |
64
64
 
65
65
  **Important Note for BigNum division**
66
66
 
@@ -88,7 +88,7 @@ import { BN, Provider } from '@project-serum/anchor';
88
88
  import { Token, TOKEN_PROGRAM_ID } from '@solana/spl-token';
89
89
  import { Connection, Keypair, PublicKey } from '@solana/web3.js';
90
90
  import {
91
- calculateMarkPrice,
91
+ calculateReservePrice,
92
92
  ClearingHouse,
93
93
  ClearingHouseUser,
94
94
  initialize,
@@ -96,9 +96,9 @@ import {
96
96
  PositionDirection,
97
97
  convertToNumber,
98
98
  calculateTradeSlippage,
99
- MARK_PRICE_PRECISION,
99
+ PRICE_PRECISION,
100
100
  QUOTE_PRECISION,
101
- Wallet
101
+ Wallet,
102
102
  } from '@drift-labs/sdk';
103
103
 
104
104
  export const getTokenAddress = (
@@ -177,11 +177,11 @@ const main = async () => {
177
177
  (market) => market.baseAssetSymbol === 'SOL'
178
178
  );
179
179
 
180
- const currentMarketPrice = calculateMarkPrice(
180
+ const currentMarketPrice = calculateReservePrice(
181
181
  clearingHouse.getMarket(solMarketInfo.marketIndex)
182
182
  );
183
183
 
184
- const formattedPrice = convertToNumber(currentMarketPrice, MARK_PRICE_PRECISION);
184
+ const formattedPrice = convertToNumber(currentMarketPrice, PRICE_PRECISION);
185
185
 
186
186
  console.log(`Current Market Price is $${formattedPrice}`);
187
187
 
@@ -194,7 +194,7 @@ const main = async () => {
194
194
  new BN(5000).mul(QUOTE_PRECISION),
195
195
  solMarketAccount
196
196
  )[0],
197
- MARK_PRICE_PRECISION
197
+ PRICE_PRECISION
198
198
  );
199
199
 
200
200
  console.log(
@@ -0,0 +1,7 @@
1
+ import { ClearingHouseUserStats } from '../clearingHouseUserStats';
2
+ import { BulkAccountLoader } from './bulkAccountLoader';
3
+ /**
4
+ * @param userStats
5
+ * @param accountLoader
6
+ */
7
+ export declare function bulkPollingUserStatsSubscribe(userStats: ClearingHouseUserStats[], accountLoader: BulkAccountLoader): Promise<void>;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.bulkPollingUserStatsSubscribe = void 0;
4
+ /**
5
+ * @param userStats
6
+ * @param accountLoader
7
+ */
8
+ async function bulkPollingUserStatsSubscribe(userStats, accountLoader) {
9
+ if (userStats.length === 0) {
10
+ await accountLoader.load();
11
+ return;
12
+ }
13
+ await Promise.all(userStats.map((userStat) => {
14
+ return userStat.accountSubscriber.addToAccountLoader();
15
+ }));
16
+ await accountLoader.load();
17
+ await Promise.all(userStats.map(async (userStat) => {
18
+ return userStat.subscribe();
19
+ }));
20
+ }
21
+ exports.bulkPollingUserStatsSubscribe = bulkPollingUserStatsSubscribe;
@@ -11,7 +11,6 @@ async function bulkPollingUserSubscribe(users, accountLoader) {
11
11
  return;
12
12
  }
13
13
  await Promise.all(users.map((user) => {
14
- // Pull the keys from the authority map so we can skip fetching them in addToAccountLoader
15
14
  return user.accountSubscriber.addToAccountLoader();
16
15
  }));
17
16
  await accountLoader.load();
@@ -1,4 +1,5 @@
1
1
  import { Connection, PublicKey } from '@solana/web3.js';
2
- import { UserAccount } from '../types';
2
+ import { UserAccount, UserStatsAccount } from '../types';
3
3
  import { Program } from '@project-serum/anchor';
4
4
  export declare function fetchUserAccounts(connection: Connection, program: Program, authority: PublicKey, limit?: number): Promise<(UserAccount | undefined)[]>;
5
+ export declare function fetchUserStatsAccount(connection: Connection, program: Program, authority: PublicKey): Promise<UserStatsAccount | undefined>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.fetchUserAccounts = void 0;
3
+ exports.fetchUserStatsAccount = exports.fetchUserAccounts = void 0;
4
4
  const pda_1 = require("../addresses/pda");
5
5
  async function fetchUserAccounts(connection, program, authority, limit = 8) {
6
6
  const userAccountPublicKeys = new Array();
@@ -16,3 +16,11 @@ async function fetchUserAccounts(connection, program, authority, limit = 8) {
16
16
  });
17
17
  }
18
18
  exports.fetchUserAccounts = fetchUserAccounts;
19
+ async function fetchUserStatsAccount(connection, program, authority) {
20
+ const userStatsPublicKey = (0, pda_1.getUserStatsAccountPublicKey)(program.programId, authority);
21
+ const accountInfo = await connection.getAccountInfo(userStatsPublicKey, 'confirmed');
22
+ return accountInfo
23
+ ? program.account.user.coder.accounts.decode('UserStats', accountInfo.data)
24
+ : undefined;
25
+ }
26
+ exports.fetchUserStatsAccount = fetchUserStatsAccount;
@@ -1,10 +1,9 @@
1
- /// <reference types="bn.js" />
2
1
  /// <reference types="node" />
3
2
  import { DataAndSlot, AccountToPoll, ClearingHouseAccountEvents, ClearingHouseAccountSubscriber, OraclesToPoll } from './types';
4
- import { BN, Program } from '@project-serum/anchor';
3
+ import { Program } from '@project-serum/anchor';
5
4
  import StrictEventEmitter from 'strict-event-emitter-types';
6
5
  import { EventEmitter } from 'events';
7
- import { BankAccount, MarketAccount, StateAccount, UserAccount } from '../types';
6
+ import { SpotMarketAccount, PerpMarketAccount, StateAccount, UserAccount } from '../types';
8
7
  import { BulkAccountLoader } from './bulkAccountLoader';
9
8
  import { PublicKey } from '@solana/web3.js';
10
9
  import { OracleInfo, OraclePriceData } from '../oracles/types';
@@ -12,8 +11,8 @@ import { OracleClientCache } from '../oracles/oracleClientCache';
12
11
  export declare class PollingClearingHouseAccountSubscriber implements ClearingHouseAccountSubscriber {
13
12
  isSubscribed: boolean;
14
13
  program: Program;
15
- marketIndexes: BN[];
16
- bankIndexes: BN[];
14
+ perpMarketIndexes: number[];
15
+ spotMarketIndexes: number[];
17
16
  oracleInfos: OracleInfo[];
18
17
  oracleClientCache: OracleClientCache;
19
18
  eventEmitter: StrictEventEmitter<EventEmitter, ClearingHouseAccountEvents>;
@@ -22,20 +21,20 @@ export declare class PollingClearingHouseAccountSubscriber implements ClearingHo
22
21
  oraclesToPoll: Map<string, OraclesToPoll>;
23
22
  errorCallbackId?: string;
24
23
  state?: DataAndSlot<StateAccount>;
25
- market: Map<number, DataAndSlot<MarketAccount>>;
26
- bank: Map<number, DataAndSlot<BankAccount>>;
24
+ perpMarket: Map<number, DataAndSlot<PerpMarketAccount>>;
25
+ spotMarket: Map<number, DataAndSlot<SpotMarketAccount>>;
27
26
  oracles: Map<string, DataAndSlot<OraclePriceData>>;
28
27
  user?: DataAndSlot<UserAccount>;
29
28
  private isSubscribing;
30
29
  private subscriptionPromise;
31
30
  private subscriptionPromiseResolver;
32
- constructor(program: Program, accountLoader: BulkAccountLoader, marketIndexes: BN[], bankIndexes: BN[], oracleInfos: OracleInfo[]);
31
+ constructor(program: Program, accountLoader: BulkAccountLoader, perpMarketIndexes: number[], spotMarketIndexes: number[], oracleInfos: OracleInfo[]);
33
32
  subscribe(): Promise<boolean>;
34
33
  updateAccountsToPoll(): Promise<void>;
35
34
  updateMarketAccountsToPoll(): Promise<boolean>;
36
- addMarketAccountToPoll(marketIndex: BN): Promise<boolean>;
37
- updateBankAccountsToPoll(): Promise<boolean>;
38
- addBankAccountToPoll(bankIndex: BN): Promise<boolean>;
35
+ addMarketAccountToPoll(marketIndex: number): Promise<boolean>;
36
+ updateSpotMarketAccountsToPoll(): Promise<boolean>;
37
+ addSpotMarketAccountToPoll(marketIndex: number): Promise<boolean>;
39
38
  updateOraclesToPoll(): boolean;
40
39
  addOracleToPoll(oracleInfo: OracleInfo): boolean;
41
40
  getClearingHouseAccounts(): Promise<ClearingHouseAccounts>;
@@ -45,14 +44,15 @@ export declare class PollingClearingHouseAccountSubscriber implements ClearingHo
45
44
  fetch(): Promise<void>;
46
45
  didSubscriptionSucceed(): boolean;
47
46
  unsubscribe(): Promise<void>;
48
- addBank(bankIndex: BN): Promise<boolean>;
49
- addMarket(marketIndex: BN): Promise<boolean>;
47
+ addSpotMarket(marketIndex: number): Promise<boolean>;
48
+ addPerpMarket(marketIndex: number): Promise<boolean>;
50
49
  addOracle(oracleInfo: OracleInfo): Promise<boolean>;
51
50
  assertIsSubscribed(): void;
52
51
  getStateAccountAndSlot(): DataAndSlot<StateAccount>;
53
- getMarketAccountAndSlot(marketIndex: BN): DataAndSlot<MarketAccount> | undefined;
54
- getMarketAccountsAndSlots(): DataAndSlot<MarketAccount>[];
55
- getBankAccountAndSlot(bankIndex: BN): DataAndSlot<BankAccount> | undefined;
52
+ getMarketAccountAndSlot(marketIndex: number): DataAndSlot<PerpMarketAccount> | undefined;
53
+ getMarketAccountsAndSlots(): DataAndSlot<PerpMarketAccount>[];
54
+ getSpotMarketAccountAndSlot(marketIndex: number): DataAndSlot<SpotMarketAccount> | undefined;
55
+ getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[];
56
56
  getOraclePriceDataAndSlot(oraclePublicKey: PublicKey): DataAndSlot<OraclePriceData> | undefined;
57
57
  }
58
58
  declare type ClearingHouseAccounts = {
@@ -9,20 +9,20 @@ const web3_js_1 = require("@solana/web3.js");
9
9
  const oracleClientCache_1 = require("../oracles/oracleClientCache");
10
10
  const quoteAssetOracleClient_1 = require("../oracles/quoteAssetOracleClient");
11
11
  class PollingClearingHouseAccountSubscriber {
12
- constructor(program, accountLoader, marketIndexes, bankIndexes, oracleInfos) {
12
+ constructor(program, accountLoader, perpMarketIndexes, spotMarketIndexes, oracleInfos) {
13
13
  this.oracleClientCache = new oracleClientCache_1.OracleClientCache();
14
14
  this.accountsToPoll = new Map();
15
15
  this.oraclesToPoll = new Map();
16
- this.market = new Map();
17
- this.bank = new Map();
16
+ this.perpMarket = new Map();
17
+ this.spotMarket = new Map();
18
18
  this.oracles = new Map();
19
19
  this.isSubscribing = false;
20
20
  this.isSubscribed = false;
21
21
  this.program = program;
22
22
  this.eventEmitter = new events_1.EventEmitter();
23
23
  this.accountLoader = accountLoader;
24
- this.marketIndexes = marketIndexes;
25
- this.bankIndexes = bankIndexes;
24
+ this.perpMarketIndexes = perpMarketIndexes;
25
+ this.spotMarketIndexes = spotMarketIndexes;
26
26
  this.oracleInfos = oracleInfos;
27
27
  }
28
28
  async subscribe() {
@@ -65,10 +65,10 @@ class PollingClearingHouseAccountSubscriber {
65
65
  eventType: 'stateAccountUpdate',
66
66
  });
67
67
  await this.updateMarketAccountsToPoll();
68
- await this.updateBankAccountsToPoll();
68
+ await this.updateSpotMarketAccountsToPoll();
69
69
  }
70
70
  async updateMarketAccountsToPoll() {
71
- for (const marketIndex of this.marketIndexes) {
71
+ for (const marketIndex of this.perpMarketIndexes) {
72
72
  await this.addMarketAccountToPoll(marketIndex);
73
73
  }
74
74
  return true;
@@ -76,26 +76,26 @@ class PollingClearingHouseAccountSubscriber {
76
76
  async addMarketAccountToPoll(marketIndex) {
77
77
  const marketPublicKey = await (0, pda_1.getMarketPublicKey)(this.program.programId, marketIndex);
78
78
  this.accountsToPoll.set(marketPublicKey.toString(), {
79
- key: 'market',
79
+ key: 'perpMarket',
80
80
  publicKey: marketPublicKey,
81
- eventType: 'marketAccountUpdate',
82
- mapKey: marketIndex.toNumber(),
81
+ eventType: 'perpMarketAccountUpdate',
82
+ mapKey: marketIndex,
83
83
  });
84
84
  return true;
85
85
  }
86
- async updateBankAccountsToPoll() {
87
- for (const bankIndex of this.bankIndexes) {
88
- await this.addBankAccountToPoll(bankIndex);
86
+ async updateSpotMarketAccountsToPoll() {
87
+ for (const marketIndex of this.spotMarketIndexes) {
88
+ await this.addSpotMarketAccountToPoll(marketIndex);
89
89
  }
90
90
  return true;
91
91
  }
92
- async addBankAccountToPoll(bankIndex) {
93
- const bankPublicKey = await (0, pda_1.getBankPublicKey)(this.program.programId, bankIndex);
94
- this.accountsToPoll.set(bankPublicKey.toString(), {
95
- key: 'bank',
96
- publicKey: bankPublicKey,
97
- eventType: 'bankAccountUpdate',
98
- mapKey: bankIndex.toNumber(),
92
+ async addSpotMarketAccountToPoll(marketIndex) {
93
+ const marketPublicKey = await (0, pda_1.getSpotMarketPublicKey)(this.program.programId, marketIndex);
94
+ this.accountsToPoll.set(marketPublicKey.toString(), {
95
+ key: 'spotMarket',
96
+ publicKey: marketPublicKey,
97
+ eventType: 'spotMarketAccountUpdate',
98
+ mapKey: marketIndex,
99
99
  });
100
100
  return true;
101
101
  }
@@ -223,13 +223,13 @@ class PollingClearingHouseAccountSubscriber {
223
223
  this.oraclesToPoll.clear();
224
224
  this.isSubscribed = false;
225
225
  }
226
- async addBank(bankIndex) {
227
- await this.addBankAccountToPoll(bankIndex);
228
- const accountToPoll = this.accountsToPoll.get(bankIndex.toString());
226
+ async addSpotMarket(marketIndex) {
227
+ await this.addSpotMarketAccountToPoll(marketIndex);
228
+ const accountToPoll = this.accountsToPoll.get(marketIndex.toString());
229
229
  this.addAccountToAccountLoader(accountToPoll);
230
230
  return true;
231
231
  }
232
- async addMarket(marketIndex) {
232
+ async addPerpMarket(marketIndex) {
233
233
  await this.addMarketAccountToPoll(marketIndex);
234
234
  const accountToPoll = this.accountsToPoll.get(marketIndex.toString());
235
235
  this.addAccountToAccountLoader(accountToPoll);
@@ -254,13 +254,16 @@ class PollingClearingHouseAccountSubscriber {
254
254
  return this.state;
255
255
  }
256
256
  getMarketAccountAndSlot(marketIndex) {
257
- return this.market.get(marketIndex.toNumber());
257
+ return this.perpMarket.get(marketIndex);
258
258
  }
259
259
  getMarketAccountsAndSlots() {
260
- return Array.from(this.market.values());
260
+ return Array.from(this.perpMarket.values());
261
+ }
262
+ getSpotMarketAccountAndSlot(marketIndex) {
263
+ return this.spotMarket.get(marketIndex);
261
264
  }
262
- getBankAccountAndSlot(bankIndex) {
263
- return this.bank.get(bankIndex.toNumber());
265
+ getSpotMarketAccountsAndSlots() {
266
+ return Array.from(this.spotMarket.values());
264
267
  }
265
268
  getOraclePriceDataAndSlot(oraclePublicKey) {
266
269
  this.assertIsSubscribed();
@@ -0,0 +1,27 @@
1
+ /// <reference types="node" />
2
+ import { DataAndSlot, AccountToPoll, UserStatsAccountSubscriber, UserStatsAccountEvents } from './types';
3
+ import { Program } from '@project-serum/anchor';
4
+ import StrictEventEmitter from 'strict-event-emitter-types';
5
+ import { EventEmitter } from 'events';
6
+ import { PublicKey } from '@solana/web3.js';
7
+ import { UserStatsAccount } from '../types';
8
+ import { BulkAccountLoader } from './bulkAccountLoader';
9
+ export declare class PollingUserStatsAccountSubscriber implements UserStatsAccountSubscriber {
10
+ isSubscribed: boolean;
11
+ program: Program;
12
+ eventEmitter: StrictEventEmitter<EventEmitter, UserStatsAccountEvents>;
13
+ userStatsAccountPublicKey: PublicKey;
14
+ accountLoader: BulkAccountLoader;
15
+ accountsToPoll: Map<string, AccountToPoll>;
16
+ errorCallbackId?: string;
17
+ userStats?: DataAndSlot<UserStatsAccount>;
18
+ constructor(program: Program, userStatsAccountPublicKey: PublicKey, accountLoader: BulkAccountLoader);
19
+ subscribe(): Promise<boolean>;
20
+ addToAccountLoader(): Promise<void>;
21
+ fetchIfUnloaded(): Promise<void>;
22
+ fetch(): Promise<void>;
23
+ didSubscriptionSucceed(): boolean;
24
+ unsubscribe(): Promise<void>;
25
+ assertIsSubscribed(): void;
26
+ getUserStatsAccountAndSlot(): DataAndSlot<UserStatsAccount>;
27
+ }
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PollingUserStatsAccountSubscriber = void 0;
4
+ const types_1 = require("./types");
5
+ const events_1 = require("events");
6
+ const utils_1 = require("./utils");
7
+ class PollingUserStatsAccountSubscriber {
8
+ constructor(program, userStatsAccountPublicKey, accountLoader) {
9
+ this.accountsToPoll = new Map();
10
+ this.isSubscribed = false;
11
+ this.program = program;
12
+ this.accountLoader = accountLoader;
13
+ this.eventEmitter = new events_1.EventEmitter();
14
+ this.userStatsAccountPublicKey = userStatsAccountPublicKey;
15
+ }
16
+ async subscribe() {
17
+ if (this.isSubscribed) {
18
+ return true;
19
+ }
20
+ await this.addToAccountLoader();
21
+ let subscriptionSucceeded = false;
22
+ let retries = 0;
23
+ while (!subscriptionSucceeded && retries < 5) {
24
+ await this.fetchIfUnloaded();
25
+ subscriptionSucceeded = this.didSubscriptionSucceed();
26
+ retries++;
27
+ }
28
+ if (subscriptionSucceeded) {
29
+ this.eventEmitter.emit('update');
30
+ }
31
+ this.isSubscribed = subscriptionSucceeded;
32
+ return subscriptionSucceeded;
33
+ }
34
+ async addToAccountLoader() {
35
+ if (this.accountsToPoll.size > 0) {
36
+ return;
37
+ }
38
+ this.accountsToPoll.set(this.userStatsAccountPublicKey.toString(), {
39
+ key: 'userStats',
40
+ publicKey: this.userStatsAccountPublicKey,
41
+ eventType: 'userStatsAccountUpdate',
42
+ });
43
+ for (const [_, accountToPoll] of this.accountsToPoll) {
44
+ accountToPoll.callbackId = this.accountLoader.addAccount(accountToPoll.publicKey, (buffer, slot) => {
45
+ if (!buffer) {
46
+ return;
47
+ }
48
+ const account = this.program.account[accountToPoll.key].coder.accounts.decode((0, utils_1.capitalize)(accountToPoll.key), buffer);
49
+ this[accountToPoll.key] = { data: account, slot };
50
+ // @ts-ignore
51
+ this.eventEmitter.emit(accountToPoll.eventType, account);
52
+ this.eventEmitter.emit('update');
53
+ });
54
+ }
55
+ this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
56
+ this.eventEmitter.emit('error', error);
57
+ });
58
+ }
59
+ async fetchIfUnloaded() {
60
+ let shouldFetch = false;
61
+ for (const [_, accountToPoll] of this.accountsToPoll) {
62
+ if (this[accountToPoll.key] === undefined) {
63
+ shouldFetch = true;
64
+ break;
65
+ }
66
+ }
67
+ if (shouldFetch) {
68
+ await this.fetch();
69
+ }
70
+ }
71
+ async fetch() {
72
+ await this.accountLoader.load();
73
+ for (const [_, accountToPoll] of this.accountsToPoll) {
74
+ const { buffer, slot } = this.accountLoader.getBufferAndSlot(accountToPoll.publicKey);
75
+ if (buffer) {
76
+ const account = this.program.account[accountToPoll.key].coder.accounts.decode((0, utils_1.capitalize)(accountToPoll.key), buffer);
77
+ this[accountToPoll.key] = { data: account, slot };
78
+ }
79
+ }
80
+ }
81
+ didSubscriptionSucceed() {
82
+ let success = true;
83
+ for (const [_, accountToPoll] of this.accountsToPoll) {
84
+ if (!this[accountToPoll.key]) {
85
+ success = false;
86
+ break;
87
+ }
88
+ }
89
+ return success;
90
+ }
91
+ async unsubscribe() {
92
+ if (!this.isSubscribed) {
93
+ return;
94
+ }
95
+ for (const [_, accountToPoll] of this.accountsToPoll) {
96
+ this.accountLoader.removeAccount(accountToPoll.publicKey, accountToPoll.callbackId);
97
+ }
98
+ this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
99
+ this.errorCallbackId = undefined;
100
+ this.accountsToPoll.clear();
101
+ this.isSubscribed = false;
102
+ }
103
+ assertIsSubscribed() {
104
+ if (!this.isSubscribed) {
105
+ throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
106
+ }
107
+ }
108
+ getUserStatsAccountAndSlot() {
109
+ this.assertIsSubscribed();
110
+ return this.userStats;
111
+ }
112
+ }
113
+ exports.PollingUserStatsAccountSubscriber = PollingUserStatsAccountSubscriber;
@@ -1,13 +1,10 @@
1
1
  /// <reference types="node" />
2
- /// <reference types="bn.js" />
3
- /// <reference types="node" />
4
- import { BankAccount, MarketAccount, OracleSource, StateAccount, UserAccount } from '../types';
2
+ import { SpotMarketAccount, PerpMarketAccount, OracleSource, StateAccount, UserAccount, UserStatsAccount } from '../types';
5
3
  import StrictEventEmitter from 'strict-event-emitter-types';
6
4
  import { EventEmitter } from 'events';
7
5
  import { PublicKey } from '@solana/web3.js';
8
6
  import { AccountInfo } from '@solana/spl-token';
9
7
  import { OracleInfo, OraclePriceData } from '..';
10
- import { BN } from '@project-serum/anchor';
11
8
  export interface AccountSubscriber<T> {
12
9
  dataAndSlot?: DataAndSlot<T>;
13
10
  subscribe(onChange: (data: T) => void): Promise<void>;
@@ -19,8 +16,8 @@ export declare class NotSubscribedError extends Error {
19
16
  }
20
17
  export interface ClearingHouseAccountEvents {
21
18
  stateAccountUpdate: (payload: StateAccount) => void;
22
- marketAccountUpdate: (payload: MarketAccount) => void;
23
- bankAccountUpdate: (payload: BankAccount) => void;
19
+ perpMarketAccountUpdate: (payload: PerpMarketAccount) => void;
20
+ spotMarketAccountUpdate: (payload: SpotMarketAccount) => void;
24
21
  oraclePriceUpdate: (publicKey: PublicKey, data: OraclePriceData) => void;
25
22
  userAccountUpdate: (payload: UserAccount) => void;
26
23
  update: void;
@@ -32,13 +29,14 @@ export interface ClearingHouseAccountSubscriber {
32
29
  subscribe(): Promise<boolean>;
33
30
  fetch(): Promise<void>;
34
31
  unsubscribe(): Promise<void>;
35
- addMarket(marketIndex: BN): Promise<boolean>;
36
- addBank(bankIndex: BN): Promise<boolean>;
32
+ addPerpMarket(marketIndex: number): Promise<boolean>;
33
+ addSpotMarket(marketIndex: number): Promise<boolean>;
37
34
  addOracle(oracleInfo: OracleInfo): Promise<boolean>;
38
35
  getStateAccountAndSlot(): DataAndSlot<StateAccount>;
39
- getMarketAccountAndSlot(marketIndex: BN): DataAndSlot<MarketAccount> | undefined;
40
- getMarketAccountsAndSlots(): DataAndSlot<MarketAccount>[];
41
- getBankAccountAndSlot(bankIndex: BN): DataAndSlot<BankAccount> | undefined;
36
+ getMarketAccountAndSlot(marketIndex: number): DataAndSlot<PerpMarketAccount> | undefined;
37
+ getMarketAccountsAndSlots(): DataAndSlot<PerpMarketAccount>[];
38
+ getSpotMarketAccountAndSlot(marketIndex: number): DataAndSlot<SpotMarketAccount> | undefined;
39
+ getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[];
42
40
  getOraclePriceDataAndSlot(oraclePublicKey: PublicKey): DataAndSlot<OraclePriceData> | undefined;
43
41
  }
44
42
  export interface UserAccountEvents {
@@ -100,3 +98,16 @@ export declare type DataAndSlot<T> = {
100
98
  data: T;
101
99
  slot: number;
102
100
  };
101
+ export interface UserStatsAccountEvents {
102
+ userStatsAccountUpdate: (payload: UserStatsAccount) => void;
103
+ update: void;
104
+ error: (e: Error) => void;
105
+ }
106
+ export interface UserStatsAccountSubscriber {
107
+ eventEmitter: StrictEventEmitter<EventEmitter, UserStatsAccountEvents>;
108
+ isSubscribed: boolean;
109
+ subscribe(): Promise<boolean>;
110
+ fetch(): Promise<void>;
111
+ unsubscribe(): Promise<void>;
112
+ getUserStatsAccountAndSlot(): DataAndSlot<UserStatsAccount>;
113
+ }
@@ -1,9 +1,8 @@
1
- /// <reference types="bn.js" />
2
1
  /// <reference types="node" />
3
2
  import { ClearingHouseAccountSubscriber, ClearingHouseAccountEvents, DataAndSlot } from './types';
4
3
  import { AccountSubscriber } from './types';
5
- import { BankAccount, MarketAccount, StateAccount } from '../types';
6
- import { BN, Program } from '@project-serum/anchor';
4
+ import { SpotMarketAccount, PerpMarketAccount, StateAccount } from '../types';
5
+ import { Program } from '@project-serum/anchor';
7
6
  import StrictEventEmitter from 'strict-event-emitter-types';
8
7
  import { EventEmitter } from 'events';
9
8
  import { PublicKey } from '@solana/web3.js';
@@ -12,38 +11,39 @@ import { OracleClientCache } from '../oracles/oracleClientCache';
12
11
  export declare class WebSocketClearingHouseAccountSubscriber implements ClearingHouseAccountSubscriber {
13
12
  isSubscribed: boolean;
14
13
  program: Program;
15
- marketIndexes: BN[];
16
- bankIndexes: BN[];
14
+ perpMarketIndexes: number[];
15
+ spotMarketIndexes: number[];
17
16
  oracleInfos: OracleInfo[];
18
17
  oracleClientCache: OracleClientCache;
19
18
  eventEmitter: StrictEventEmitter<EventEmitter, ClearingHouseAccountEvents>;
20
19
  stateAccountSubscriber?: AccountSubscriber<StateAccount>;
21
- marketAccountSubscribers: Map<number, AccountSubscriber<MarketAccount>>;
22
- bankAccountSubscribers: Map<number, AccountSubscriber<BankAccount>>;
20
+ perpMarketAccountSubscribers: Map<number, AccountSubscriber<PerpMarketAccount>>;
21
+ spotMarketAccountSubscribers: Map<number, AccountSubscriber<SpotMarketAccount>>;
23
22
  oracleSubscribers: Map<string, AccountSubscriber<OraclePriceData>>;
24
23
  private isSubscribing;
25
24
  private subscriptionPromise;
26
25
  private subscriptionPromiseResolver;
27
- constructor(program: Program, marketIndexes: BN[], bankIndexes: BN[], oracleInfos: OracleInfo[]);
26
+ constructor(program: Program, perpMarketIndexes: number[], spotMarketIndexes: number[], oracleInfos: OracleInfo[]);
28
27
  subscribe(): Promise<boolean>;
29
28
  subscribeToMarketAccounts(): Promise<boolean>;
30
- subscribeToMarketAccount(marketIndex: BN): Promise<boolean>;
31
- subscribeToBankAccounts(): Promise<boolean>;
32
- subscribeToBankAccount(bankIndex: BN): Promise<boolean>;
29
+ subscribeToMarketAccount(marketIndex: number): Promise<boolean>;
30
+ subscribeToSpotMarketAccounts(): Promise<boolean>;
31
+ subscribeToSpotMarketAccount(marketIndex: number): Promise<boolean>;
33
32
  subscribeToOracles(): Promise<boolean>;
34
33
  subscribeToOracle(oracleInfo: OracleInfo): Promise<boolean>;
35
34
  unsubscribeFromMarketAccounts(): Promise<void>;
36
- unsubscribeFromBankAccounts(): Promise<void>;
35
+ unsubscribeFromSpotMarketAccounts(): Promise<void>;
37
36
  unsubscribeFromOracles(): Promise<void>;
38
37
  fetch(): Promise<void>;
39
38
  unsubscribe(): Promise<void>;
40
- addBank(bankIndex: BN): Promise<boolean>;
41
- addMarket(marketIndex: BN): Promise<boolean>;
39
+ addSpotMarket(marketIndex: number): Promise<boolean>;
40
+ addPerpMarket(marketIndex: number): Promise<boolean>;
42
41
  addOracle(oracleInfo: OracleInfo): Promise<boolean>;
43
42
  assertIsSubscribed(): void;
44
43
  getStateAccountAndSlot(): DataAndSlot<StateAccount>;
45
- getMarketAccountAndSlot(marketIndex: BN): DataAndSlot<MarketAccount> | undefined;
46
- getMarketAccountsAndSlots(): DataAndSlot<MarketAccount>[];
47
- getBankAccountAndSlot(bankIndex: BN): DataAndSlot<BankAccount> | undefined;
44
+ getMarketAccountAndSlot(marketIndex: number): DataAndSlot<PerpMarketAccount> | undefined;
45
+ getMarketAccountsAndSlots(): DataAndSlot<PerpMarketAccount>[];
46
+ getSpotMarketAccountAndSlot(marketIndex: number): DataAndSlot<SpotMarketAccount> | undefined;
47
+ getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[];
48
48
  getOraclePriceDataAndSlot(oraclePublicKey: PublicKey): DataAndSlot<OraclePriceData> | undefined;
49
49
  }