@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/lib/types.js CHANGED
@@ -1,22 +1,40 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TradeSide = exports.isOneOfVariant = exports.isVariant = exports.OrderTriggerCondition = exports.OrderAction = exports.OrderDiscountTier = exports.OrderStatus = exports.OrderType = exports.OracleSource = exports.PositionDirection = exports.BankBalanceType = exports.SwapDirection = void 0;
3
+ exports.DefaultOrderParams = exports.LiquidationType = exports.LPAction = exports.TradeSide = exports.getVariant = exports.isOneOfVariant = exports.isVariant = exports.SpotFulfillmentStatus = exports.SpotFulfillmentType = exports.OrderTriggerCondition = exports.OrderActionExplanation = exports.OrderAction = exports.OrderDiscountTier = exports.OrderStatus = exports.MarketType = exports.OrderType = exports.OracleSource = exports.DepositDirection = exports.PositionDirection = exports.SpotBalanceType = exports.SwapDirection = exports.ContractType = exports.MarketStatus = void 0;
4
+ const _1 = require(".");
4
5
  // # Utility Types / Enums / Constants
6
+ class MarketStatus {
7
+ }
8
+ exports.MarketStatus = MarketStatus;
9
+ MarketStatus.INITIALIZED = { initialized: {} };
10
+ MarketStatus.REDUCEONLY = { reduceonly: {} };
11
+ MarketStatus.SETTLEMENT = { settlement: {} };
12
+ MarketStatus.DELISTED = { delisted: {} };
13
+ class ContractType {
14
+ }
15
+ exports.ContractType = ContractType;
16
+ ContractType.PERPETUAL = { perpetual: {} };
17
+ ContractType.FUTURE = { future: {} };
5
18
  class SwapDirection {
6
19
  }
7
20
  exports.SwapDirection = SwapDirection;
8
21
  SwapDirection.ADD = { add: {} };
9
22
  SwapDirection.REMOVE = { remove: {} };
10
- class BankBalanceType {
23
+ class SpotBalanceType {
11
24
  }
12
- exports.BankBalanceType = BankBalanceType;
13
- BankBalanceType.DEPOSIT = { deposit: {} };
14
- BankBalanceType.BORROW = { borrow: {} };
25
+ exports.SpotBalanceType = SpotBalanceType;
26
+ SpotBalanceType.DEPOSIT = { deposit: {} };
27
+ SpotBalanceType.BORROW = { borrow: {} };
15
28
  class PositionDirection {
16
29
  }
17
30
  exports.PositionDirection = PositionDirection;
18
31
  PositionDirection.LONG = { long: {} };
19
32
  PositionDirection.SHORT = { short: {} };
33
+ class DepositDirection {
34
+ }
35
+ exports.DepositDirection = DepositDirection;
36
+ DepositDirection.DEPOSIT = { deposit: {} };
37
+ DepositDirection.WITHDRAW = { withdraw: {} };
20
38
  class OracleSource {
21
39
  }
22
40
  exports.OracleSource = OracleSource;
@@ -30,6 +48,11 @@ OrderType.LIMIT = { limit: {} };
30
48
  OrderType.TRIGGER_MARKET = { triggerMarket: {} };
31
49
  OrderType.TRIGGER_LIMIT = { triggerLimit: {} };
32
50
  OrderType.MARKET = { market: {} };
51
+ class MarketType {
52
+ }
53
+ exports.MarketType = MarketType;
54
+ MarketType.SPOT = { spot: {} };
55
+ MarketType.PERP = { perp: {} };
33
56
  class OrderStatus {
34
57
  }
35
58
  exports.OrderStatus = OrderStatus;
@@ -51,11 +74,36 @@ OrderAction.CANCEL = { cancel: {} };
51
74
  OrderAction.EXPIRE = { expire: {} };
52
75
  OrderAction.FILL = { fill: {} };
53
76
  OrderAction.TRIGGER = { trigger: {} };
77
+ class OrderActionExplanation {
78
+ }
79
+ exports.OrderActionExplanation = OrderActionExplanation;
80
+ OrderActionExplanation.NONE = { none: {} };
81
+ OrderActionExplanation.ORACLE_PRICE_BREACHED_LIMIT_PRICE = {
82
+ oraclePriceBreachedLimitPrice: {},
83
+ };
84
+ OrderActionExplanation.MARKET_ORDER_FILLED_TO_LIMIT_PRICE = {
85
+ marketOrderFilledToLimitPrice: {},
86
+ };
87
+ OrderActionExplanation.CANCELED_FOR_LIQUIDATION = {
88
+ canceledForLiquidation: {},
89
+ };
90
+ OrderActionExplanation.MARKET_ORDER_AUCTION_EXPIRED = {
91
+ marketOrderAuctionExpired: {},
92
+ };
54
93
  class OrderTriggerCondition {
55
94
  }
56
95
  exports.OrderTriggerCondition = OrderTriggerCondition;
57
96
  OrderTriggerCondition.ABOVE = { above: {} };
58
97
  OrderTriggerCondition.BELOW = { below: {} };
98
+ class SpotFulfillmentType {
99
+ }
100
+ exports.SpotFulfillmentType = SpotFulfillmentType;
101
+ SpotFulfillmentType.SERUM_v3 = { serumV3: {} };
102
+ class SpotFulfillmentStatus {
103
+ }
104
+ exports.SpotFulfillmentStatus = SpotFulfillmentStatus;
105
+ SpotFulfillmentStatus.ENABLED = { enabled: {} };
106
+ SpotFulfillmentStatus.DISABLED = { disabled: {} };
59
107
  function isVariant(object, type) {
60
108
  return object.hasOwnProperty(type);
61
109
  }
@@ -66,9 +114,55 @@ function isOneOfVariant(object, types) {
66
114
  }, false);
67
115
  }
68
116
  exports.isOneOfVariant = isOneOfVariant;
117
+ function getVariant(object) {
118
+ return Object.keys(object)[0];
119
+ }
120
+ exports.getVariant = getVariant;
69
121
  var TradeSide;
70
122
  (function (TradeSide) {
71
123
  TradeSide[TradeSide["None"] = 0] = "None";
72
124
  TradeSide[TradeSide["Buy"] = 1] = "Buy";
73
125
  TradeSide[TradeSide["Sell"] = 2] = "Sell";
74
126
  })(TradeSide = exports.TradeSide || (exports.TradeSide = {}));
127
+ class LPAction {
128
+ }
129
+ exports.LPAction = LPAction;
130
+ LPAction.ADD_LIQUIDITY = { addLiquidity: {} };
131
+ LPAction.REMOVE_LIQUIDITY = { removeLiquidity: {} };
132
+ LPAction.SETTLE_LIQUIDITY = { settleLiquidity: {} };
133
+ class LiquidationType {
134
+ }
135
+ exports.LiquidationType = LiquidationType;
136
+ LiquidationType.LIQUIDATE_PERP = { liquidatePerp: {} };
137
+ LiquidationType.LIQUIDATE_BORROW = { liquidateBorrow: {} };
138
+ LiquidationType.LIQUIDATE_BORROW_FOR_PERP_PNL = {
139
+ liquidateBorrowForPerpPnl: {},
140
+ };
141
+ LiquidationType.LIQUIDATE_PERP_PNL_FOR_DEPOSIT = {
142
+ liquidatePerpPnlForDeposit: {},
143
+ };
144
+ LiquidationType.PERP_BANKRUPTCY = {
145
+ perpBankruptcy: {},
146
+ };
147
+ LiquidationType.BORROW_BANKRUPTCY = {
148
+ borrowBankruptcy: {},
149
+ };
150
+ exports.DefaultOrderParams = {
151
+ orderType: OrderType.MARKET,
152
+ marketType: MarketType.PERP,
153
+ userOrderId: 0,
154
+ direction: PositionDirection.LONG,
155
+ baseAssetAmount: _1.ZERO,
156
+ price: _1.ZERO,
157
+ marketIndex: 0,
158
+ reduceOnly: false,
159
+ postOnly: false,
160
+ immediateOrCancel: false,
161
+ triggerPrice: _1.ZERO,
162
+ triggerCondition: OrderTriggerCondition.ABOVE,
163
+ positionLimit: _1.ZERO,
164
+ oraclePriceOffset: _1.ZERO,
165
+ auctionDuration: null,
166
+ timeInForce: null,
167
+ auctionStartPrice: null,
168
+ };
@@ -0,0 +1,25 @@
1
+ import { ClearingHouseUser, ClearingHouse, OrderRecord, ClearingHouseUserAccountSubscriptionConfig } from '..';
2
+ import { PublicKey } from '@solana/web3.js';
3
+ export declare class UserMap {
4
+ private userMap;
5
+ private clearingHouse;
6
+ private accountSubscription;
7
+ constructor(clearingHouse: ClearingHouse, accountSubscription: ClearingHouseUserAccountSubscriptionConfig);
8
+ fetchAllUsers(): Promise<void>;
9
+ addPubkey(userAccountPublicKey: PublicKey): Promise<void>;
10
+ has(key: string): boolean;
11
+ /**
12
+ * gets the ClearingHouseUser for a particular userAccountPublicKey, if no ClearingHouseUser exists, undefined is returned
13
+ * @param key userAccountPublicKey to get ClearngHouseUserFor
14
+ * @returns user ClearingHouseUser | undefined
15
+ */
16
+ get(key: string): ClearingHouseUser | undefined;
17
+ /**
18
+ * gets the ClearingHouseUser for a particular userAccountPublicKey, if no ClearingHouseUser exists, new one is created
19
+ * @param key userAccountPublicKey to get ClearngHouseUserFor
20
+ * @returns ClearingHouseUser
21
+ */
22
+ mustGet(key: string): Promise<ClearingHouseUser>;
23
+ updateWithOrderRecord(record: OrderRecord): Promise<void>;
24
+ values(): IterableIterator<ClearingHouseUser>;
25
+ }
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UserMap = void 0;
4
+ const __1 = require("..");
5
+ const web3_js_1 = require("@solana/web3.js");
6
+ class UserMap {
7
+ constructor(clearingHouse, accountSubscription) {
8
+ this.userMap = new Map();
9
+ this.clearingHouse = clearingHouse;
10
+ this.accountSubscription = accountSubscription;
11
+ }
12
+ async fetchAllUsers() {
13
+ const userArray = [];
14
+ const programUserAccounts = (await this.clearingHouse.program.account.user.all());
15
+ for (const programUserAccount of programUserAccounts) {
16
+ if (this.userMap.has(programUserAccount.publicKey.toString())) {
17
+ continue;
18
+ }
19
+ const user = new __1.ClearingHouseUser({
20
+ clearingHouse: this.clearingHouse,
21
+ userAccountPublicKey: programUserAccount.publicKey,
22
+ accountSubscription: this.accountSubscription,
23
+ });
24
+ userArray.push(user);
25
+ }
26
+ if (this.accountSubscription.type === 'polling') {
27
+ await (0, __1.bulkPollingUserSubscribe)(userArray, this.accountSubscription.accountLoader);
28
+ }
29
+ for (const user of userArray) {
30
+ this.userMap.set(user.getUserAccountPublicKey().toString(), user);
31
+ }
32
+ }
33
+ async addPubkey(userAccountPublicKey) {
34
+ const user = new __1.ClearingHouseUser({
35
+ clearingHouse: this.clearingHouse,
36
+ userAccountPublicKey,
37
+ accountSubscription: this.accountSubscription,
38
+ });
39
+ await user.subscribe();
40
+ this.userMap.set(userAccountPublicKey.toString(), user);
41
+ }
42
+ has(key) {
43
+ return this.userMap.has(key);
44
+ }
45
+ /**
46
+ * gets the ClearingHouseUser for a particular userAccountPublicKey, if no ClearingHouseUser exists, undefined is returned
47
+ * @param key userAccountPublicKey to get ClearngHouseUserFor
48
+ * @returns user ClearingHouseUser | undefined
49
+ */
50
+ get(key) {
51
+ return this.userMap.get(key);
52
+ }
53
+ /**
54
+ * gets the ClearingHouseUser for a particular userAccountPublicKey, if no ClearingHouseUser exists, new one is created
55
+ * @param key userAccountPublicKey to get ClearngHouseUserFor
56
+ * @returns ClearingHouseUser
57
+ */
58
+ async mustGet(key) {
59
+ if (!this.has(key)) {
60
+ await this.addPubkey(new web3_js_1.PublicKey(key));
61
+ }
62
+ const user = this.userMap.get(key);
63
+ await user.fetchAccounts();
64
+ return user;
65
+ }
66
+ async updateWithOrderRecord(record) {
67
+ await this.addPubkey(record.user);
68
+ }
69
+ values() {
70
+ return this.userMap.values();
71
+ }
72
+ }
73
+ exports.UserMap = UserMap;
@@ -0,0 +1,19 @@
1
+ import { ClearingHouse, OrderRecord, ClearingHouseUserStats, ClearingHouseUserStatsAccountSubscriptionConfig } from '..';
2
+ import { PublicKey } from '@solana/web3.js';
3
+ import { UserMap } from './userMap';
4
+ export declare class UserStatsMap {
5
+ /**
6
+ * map from authority pubkey to ClearingHouseUserStats
7
+ */
8
+ private userStatsMap;
9
+ private clearingHouse;
10
+ private accountSubscription;
11
+ constructor(clearingHouse: ClearingHouse, accountSubscription: ClearingHouseUserStatsAccountSubscriptionConfig);
12
+ fetchAllUserStats(): Promise<void>;
13
+ addUserStat(authority: PublicKey): Promise<void>;
14
+ updateWithOrderRecord(record: OrderRecord, userMap: UserMap): Promise<void>;
15
+ has(authorityPublicKey: string): boolean;
16
+ get(authorityPublicKey: string): ClearingHouseUserStats;
17
+ mustGet(authorityPublicKey: string): Promise<ClearingHouseUserStats>;
18
+ values(): IterableIterator<ClearingHouseUserStats>;
19
+ }
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UserStatsMap = void 0;
4
+ const __1 = require("..");
5
+ const web3_js_1 = require("@solana/web3.js");
6
+ class UserStatsMap {
7
+ constructor(clearingHouse, accountSubscription) {
8
+ /**
9
+ * map from authority pubkey to ClearingHouseUserStats
10
+ */
11
+ this.userStatsMap = new Map();
12
+ this.clearingHouse = clearingHouse;
13
+ this.accountSubscription = accountSubscription;
14
+ }
15
+ async fetchAllUserStats() {
16
+ const userStatArray = [];
17
+ const programUserAccounts = (await this.clearingHouse.program.account.userStats.all());
18
+ for (const programUserAccount of programUserAccounts) {
19
+ const userStat = programUserAccount.account;
20
+ if (this.userStatsMap.has(userStat.authority.toString())) {
21
+ continue;
22
+ }
23
+ const chUserStat = new __1.ClearingHouseUserStats({
24
+ clearingHouse: this.clearingHouse,
25
+ userStatsAccountPublicKey: (0, __1.getUserStatsAccountPublicKey)(this.clearingHouse.program.programId, userStat.authority),
26
+ accountSubscription: this.accountSubscription,
27
+ });
28
+ userStatArray.push(chUserStat);
29
+ }
30
+ if (this.accountSubscription.type === 'polling') {
31
+ await (0, __1.bulkPollingUserStatsSubscribe)(userStatArray, this.accountSubscription.accountLoader);
32
+ }
33
+ for (const userStat of userStatArray) {
34
+ this.userStatsMap.set(userStat.getAccount().authority.toString(), userStat);
35
+ }
36
+ }
37
+ async addUserStat(authority) {
38
+ const userStat = new __1.ClearingHouseUserStats({
39
+ clearingHouse: this.clearingHouse,
40
+ userStatsAccountPublicKey: (0, __1.getUserStatsAccountPublicKey)(this.clearingHouse.program.programId, authority),
41
+ accountSubscription: this.accountSubscription,
42
+ });
43
+ await userStat.subscribe();
44
+ this.userStatsMap.set(authority.toString(), userStat);
45
+ }
46
+ async updateWithOrderRecord(record, userMap) {
47
+ if (!this.has(record.user.toString())) {
48
+ const takerUserAccount = await userMap.mustGet(record.user.toString());
49
+ this.addUserStat(takerUserAccount.getUserAccount().authority);
50
+ }
51
+ }
52
+ has(authorityPublicKey) {
53
+ return this.userStatsMap.has(authorityPublicKey);
54
+ }
55
+ get(authorityPublicKey) {
56
+ return this.userStatsMap.get(authorityPublicKey);
57
+ }
58
+ async mustGet(authorityPublicKey) {
59
+ if (!this.has(authorityPublicKey)) {
60
+ await this.addUserStat(new web3_js_1.PublicKey(authorityPublicKey));
61
+ }
62
+ return this.get(authorityPublicKey);
63
+ }
64
+ values() {
65
+ return this.userStatsMap.values();
66
+ }
67
+ }
68
+ exports.UserStatsMap = UserStatsMap;
@@ -4,7 +4,7 @@ exports.findComputeUnitConsumption = void 0;
4
4
  async function findComputeUnitConsumption(programId, connection, txSignature, commitment = 'confirmed') {
5
5
  const tx = await connection.getTransaction(txSignature, { commitment });
6
6
  const computeUnits = [];
7
- const regex = new RegExp(`Program ${programId.toString()} consumed ([0-9]{0,6}) of 200000 compute units`);
7
+ const regex = new RegExp(`Program ${programId.toString()} consumed ([0-9]{0,6}) of ([0-9]{0,7}) compute units`);
8
8
  tx.meta.logMessages.forEach((logMessage) => {
9
9
  const match = logMessage.match(regex);
10
10
  if (match && match[1]) {
@@ -0,0 +1,2 @@
1
+ import { PublicKey } from '@solana/web3.js';
2
+ export declare const getTokenAddress: (mintAddress: string, userPubKey: string) => Promise<PublicKey>;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getTokenAddress = void 0;
4
+ const spl_token_1 = require("@solana/spl-token");
5
+ const web3_js_1 = require("@solana/web3.js");
6
+ const getTokenAddress = (mintAddress, userPubKey) => {
7
+ return spl_token_1.Token.getAssociatedTokenAddress(spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID, spl_token_1.TOKEN_PROGRAM_ID, new web3_js_1.PublicKey(mintAddress), new web3_js_1.PublicKey(userPubKey));
8
+ };
9
+ exports.getTokenAddress = getTokenAddress;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "0.2.0-master.3",
3
+ "version": "0.2.0-master.30",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -14,7 +14,9 @@
14
14
  "build": "yarn clean && tsc",
15
15
  "clean": "rm -rf lib",
16
16
  "test": "mocha -r ts-node/register tests/**/*.ts",
17
- "patch-and-pub": "npm version patch --force && npm publish"
17
+ "patch-and-pub": "npm version patch --force && npm publish",
18
+ "prettify": "prettier --check './src/***/*.ts'",
19
+ "prettify:fix": "prettier --write './{src,tests}/***/*.ts'"
18
20
  },
19
21
  "keywords": [
20
22
  "drift-labs",
@@ -29,8 +31,9 @@
29
31
  "access": "public"
30
32
  },
31
33
  "dependencies": {
34
+ "@project-serum/serum": "^0.13.38",
32
35
  "@project-serum/anchor": "0.24.2",
33
- "@pythnetwork/client": "2.5.1",
36
+ "@pythnetwork/client": "2.5.3",
34
37
  "@solana/spl-token": "^0.1.6",
35
38
  "@solana/web3.js": "1.41.0",
36
39
  "@switchboard-xyz/switchboard-v2": "^0.0.67",
@@ -39,16 +42,17 @@
39
42
  },
40
43
  "devDependencies": {
41
44
  "@types/chai": "^4.3.1",
45
+ "@types/jest": "^28.1.3",
42
46
  "@types/mocha": "^9.1.1",
43
47
  "@typescript-eslint/eslint-plugin": "^4.28.0",
44
48
  "@typescript-eslint/parser": "^4.28.0",
45
- "@types/jest": "^28.1.3",
46
49
  "chai": "^4.3.6",
47
50
  "eslint": "^7.29.0",
48
51
  "eslint-config-prettier": "^8.3.0",
49
52
  "eslint-plugin-prettier": "^3.4.0",
50
53
  "mocha": "^10.0.0",
51
- "ts-node": "^10.8.0"
54
+ "ts-node": "^10.8.0",
55
+ "prettier": "^2.4.1"
52
56
  },
53
57
  "description": "SDK for Drift Protocol v1",
54
58
  "engines": {
@@ -0,0 +1,33 @@
1
+ import { ClearingHouseUserStats } from '../clearingHouseUserStats';
2
+ import { BulkAccountLoader } from './bulkAccountLoader';
3
+ import { PollingUserStatsAccountSubscriber } from './pollingUserStatsAccountSubscriber';
4
+
5
+ /**
6
+ * @param userStats
7
+ * @param accountLoader
8
+ */
9
+ export async function bulkPollingUserStatsSubscribe(
10
+ userStats: ClearingHouseUserStats[],
11
+ accountLoader: BulkAccountLoader
12
+ ): Promise<void> {
13
+ if (userStats.length === 0) {
14
+ await accountLoader.load();
15
+ return;
16
+ }
17
+
18
+ await Promise.all(
19
+ userStats.map((userStat) => {
20
+ return (
21
+ userStat.accountSubscriber as PollingUserStatsAccountSubscriber
22
+ ).addToAccountLoader();
23
+ })
24
+ );
25
+
26
+ await accountLoader.load();
27
+
28
+ await Promise.all(
29
+ userStats.map(async (userStat) => {
30
+ return userStat.subscribe();
31
+ })
32
+ );
33
+ }
@@ -17,7 +17,6 @@ export async function bulkPollingUserSubscribe(
17
17
 
18
18
  await Promise.all(
19
19
  users.map((user) => {
20
- // Pull the keys from the authority map so we can skip fetching them in addToAccountLoader
21
20
  return (
22
21
  user.accountSubscriber as PollingUserAccountSubscriber
23
22
  ).addToAccountLoader();
@@ -1,6 +1,9 @@
1
1
  import { Connection, PublicKey } from '@solana/web3.js';
2
- import { UserAccount } from '../types';
3
- import { getUserAccountPublicKey } from '../addresses/pda';
2
+ import { UserAccount, UserStatsAccount } from '../types';
3
+ import {
4
+ getUserAccountPublicKey,
5
+ getUserStatsAccountPublicKey,
6
+ } from '../addresses/pda';
4
7
  import { Program } from '@project-serum/anchor';
5
8
 
6
9
  export async function fetchUserAccounts(
@@ -31,3 +34,25 @@ export async function fetchUserAccounts(
31
34
  ) as UserAccount;
32
35
  });
33
36
  }
37
+
38
+ export async function fetchUserStatsAccount(
39
+ connection: Connection,
40
+ program: Program,
41
+ authority: PublicKey
42
+ ): Promise<UserStatsAccount | undefined> {
43
+ const userStatsPublicKey = getUserStatsAccountPublicKey(
44
+ program.programId,
45
+ authority
46
+ );
47
+ const accountInfo = await connection.getAccountInfo(
48
+ userStatsPublicKey,
49
+ 'confirmed'
50
+ );
51
+
52
+ return accountInfo
53
+ ? (program.account.user.coder.accounts.decode(
54
+ 'UserStats',
55
+ accountInfo.data
56
+ ) as UserStatsAccount)
57
+ : undefined;
58
+ }
@@ -6,18 +6,18 @@ import {
6
6
  NotSubscribedError,
7
7
  OraclesToPoll,
8
8
  } from './types';
9
- import { BN, Program } from '@project-serum/anchor';
9
+ import { Program } from '@project-serum/anchor';
10
10
  import StrictEventEmitter from 'strict-event-emitter-types';
11
11
  import { EventEmitter } from 'events';
12
12
  import {
13
- BankAccount,
14
- MarketAccount,
13
+ SpotMarketAccount,
14
+ PerpMarketAccount,
15
15
  StateAccount,
16
16
  UserAccount,
17
17
  } from '../types';
18
18
  import {
19
19
  getClearingHouseStateAccountPublicKey,
20
- getBankPublicKey,
20
+ getSpotMarketPublicKey,
21
21
  getMarketPublicKey,
22
22
  } from '../addresses/pda';
23
23
  import { BulkAccountLoader } from './bulkAccountLoader';
@@ -32,8 +32,8 @@ export class PollingClearingHouseAccountSubscriber
32
32
  {
33
33
  isSubscribed: boolean;
34
34
  program: Program;
35
- marketIndexes: BN[];
36
- bankIndexes: BN[];
35
+ perpMarketIndexes: number[];
36
+ spotMarketIndexes: number[];
37
37
  oracleInfos: OracleInfo[];
38
38
  oracleClientCache = new OracleClientCache();
39
39
 
@@ -45,8 +45,8 @@ export class PollingClearingHouseAccountSubscriber
45
45
  errorCallbackId?: string;
46
46
 
47
47
  state?: DataAndSlot<StateAccount>;
48
- market = new Map<number, DataAndSlot<MarketAccount>>();
49
- bank = new Map<number, DataAndSlot<BankAccount>>();
48
+ perpMarket = new Map<number, DataAndSlot<PerpMarketAccount>>();
49
+ spotMarket = new Map<number, DataAndSlot<SpotMarketAccount>>();
50
50
  oracles = new Map<string, DataAndSlot<OraclePriceData>>();
51
51
  user?: DataAndSlot<UserAccount>;
52
52
 
@@ -57,16 +57,16 @@ export class PollingClearingHouseAccountSubscriber
57
57
  public constructor(
58
58
  program: Program,
59
59
  accountLoader: BulkAccountLoader,
60
- marketIndexes: BN[],
61
- bankIndexes: BN[],
60
+ perpMarketIndexes: number[],
61
+ spotMarketIndexes: number[],
62
62
  oracleInfos: OracleInfo[]
63
63
  ) {
64
64
  this.isSubscribed = false;
65
65
  this.program = program;
66
66
  this.eventEmitter = new EventEmitter();
67
67
  this.accountLoader = accountLoader;
68
- this.marketIndexes = marketIndexes;
69
- this.bankIndexes = bankIndexes;
68
+ this.perpMarketIndexes = perpMarketIndexes;
69
+ this.spotMarketIndexes = spotMarketIndexes;
70
70
  this.oracleInfos = oracleInfos;
71
71
  }
72
72
 
@@ -122,51 +122,51 @@ export class PollingClearingHouseAccountSubscriber
122
122
  });
123
123
 
124
124
  await this.updateMarketAccountsToPoll();
125
- await this.updateBankAccountsToPoll();
125
+ await this.updateSpotMarketAccountsToPoll();
126
126
  }
127
127
 
128
128
  async updateMarketAccountsToPoll(): Promise<boolean> {
129
- for (const marketIndex of this.marketIndexes) {
129
+ for (const marketIndex of this.perpMarketIndexes) {
130
130
  await this.addMarketAccountToPoll(marketIndex);
131
131
  }
132
132
  return true;
133
133
  }
134
134
 
135
- async addMarketAccountToPoll(marketIndex: BN): Promise<boolean> {
135
+ async addMarketAccountToPoll(marketIndex: number): Promise<boolean> {
136
136
  const marketPublicKey = await getMarketPublicKey(
137
137
  this.program.programId,
138
138
  marketIndex
139
139
  );
140
140
 
141
141
  this.accountsToPoll.set(marketPublicKey.toString(), {
142
- key: 'market',
142
+ key: 'perpMarket',
143
143
  publicKey: marketPublicKey,
144
- eventType: 'marketAccountUpdate',
145
- mapKey: marketIndex.toNumber(),
144
+ eventType: 'perpMarketAccountUpdate',
145
+ mapKey: marketIndex,
146
146
  });
147
147
 
148
148
  return true;
149
149
  }
150
150
 
151
- async updateBankAccountsToPoll(): Promise<boolean> {
152
- for (const bankIndex of this.bankIndexes) {
153
- await this.addBankAccountToPoll(bankIndex);
151
+ async updateSpotMarketAccountsToPoll(): Promise<boolean> {
152
+ for (const marketIndex of this.spotMarketIndexes) {
153
+ await this.addSpotMarketAccountToPoll(marketIndex);
154
154
  }
155
155
 
156
156
  return true;
157
157
  }
158
158
 
159
- async addBankAccountToPoll(bankIndex: BN): Promise<boolean> {
160
- const bankPublicKey = await getBankPublicKey(
159
+ async addSpotMarketAccountToPoll(marketIndex: number): Promise<boolean> {
160
+ const marketPublicKey = await getSpotMarketPublicKey(
161
161
  this.program.programId,
162
- bankIndex
162
+ marketIndex
163
163
  );
164
164
 
165
- this.accountsToPoll.set(bankPublicKey.toString(), {
166
- key: 'bank',
167
- publicKey: bankPublicKey,
168
- eventType: 'bankAccountUpdate',
169
- mapKey: bankIndex.toNumber(),
165
+ this.accountsToPoll.set(marketPublicKey.toString(), {
166
+ key: 'spotMarket',
167
+ publicKey: marketPublicKey,
168
+ eventType: 'spotMarketAccountUpdate',
169
+ mapKey: marketIndex,
170
170
  });
171
171
  return true;
172
172
  }
@@ -353,14 +353,14 @@ export class PollingClearingHouseAccountSubscriber
353
353
  this.isSubscribed = false;
354
354
  }
355
355
 
356
- async addBank(bankIndex: BN): Promise<boolean> {
357
- await this.addBankAccountToPoll(bankIndex);
358
- const accountToPoll = this.accountsToPoll.get(bankIndex.toString());
356
+ async addSpotMarket(marketIndex: number): Promise<boolean> {
357
+ await this.addSpotMarketAccountToPoll(marketIndex);
358
+ const accountToPoll = this.accountsToPoll.get(marketIndex.toString());
359
359
  this.addAccountToAccountLoader(accountToPoll);
360
360
  return true;
361
361
  }
362
362
 
363
- async addMarket(marketIndex: BN): Promise<boolean> {
363
+ async addPerpMarket(marketIndex: number): Promise<boolean> {
364
364
  await this.addMarketAccountToPoll(marketIndex);
365
365
  const accountToPoll = this.accountsToPoll.get(marketIndex.toString());
366
366
  this.addAccountToAccountLoader(accountToPoll);
@@ -394,19 +394,23 @@ export class PollingClearingHouseAccountSubscriber
394
394
  }
395
395
 
396
396
  public getMarketAccountAndSlot(
397
- marketIndex: BN
398
- ): DataAndSlot<MarketAccount> | undefined {
399
- return this.market.get(marketIndex.toNumber());
397
+ marketIndex: number
398
+ ): DataAndSlot<PerpMarketAccount> | undefined {
399
+ return this.perpMarket.get(marketIndex);
400
+ }
401
+
402
+ public getMarketAccountsAndSlots(): DataAndSlot<PerpMarketAccount>[] {
403
+ return Array.from(this.perpMarket.values());
400
404
  }
401
405
 
402
- public getMarketAccountsAndSlots(): DataAndSlot<MarketAccount>[] {
403
- return Array.from(this.market.values());
406
+ public getSpotMarketAccountAndSlot(
407
+ marketIndex: number
408
+ ): DataAndSlot<SpotMarketAccount> | undefined {
409
+ return this.spotMarket.get(marketIndex);
404
410
  }
405
411
 
406
- public getBankAccountAndSlot(
407
- bankIndex: BN
408
- ): DataAndSlot<BankAccount> | undefined {
409
- return this.bank.get(bankIndex.toNumber());
412
+ public getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[] {
413
+ return Array.from(this.spotMarket.values());
410
414
  }
411
415
 
412
416
  public getOraclePriceDataAndSlot(