@drift-labs/sdk 0.2.0-temp.1 → 2.0.0

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 (274) hide show
  1. package/README.md +27 -29
  2. package/lib/accounts/bulkAccountLoader.d.ts +2 -0
  3. package/lib/accounts/bulkAccountLoader.js +36 -29
  4. package/lib/accounts/bulkUserStatsSubscription.d.ts +7 -0
  5. package/lib/accounts/bulkUserStatsSubscription.js +21 -0
  6. package/lib/accounts/bulkUserSubscription.d.ts +2 -2
  7. package/lib/accounts/bulkUserSubscription.js +0 -1
  8. package/lib/accounts/fetch.d.ts +2 -1
  9. package/lib/accounts/fetch.js +9 -1
  10. package/lib/accounts/{pollingClearingHouseAccountSubscriber.d.ts → pollingDriftClientAccountSubscriber.d.ts} +20 -25
  11. package/lib/accounts/{pollingClearingHouseAccountSubscriber.js → pollingDriftClientAccountSubscriber.js} +45 -49
  12. package/lib/accounts/{pollingOracleSubscriber.d.ts → pollingOracleAccountSubscriber.d.ts} +2 -2
  13. package/lib/accounts/{pollingOracleSubscriber.js → pollingOracleAccountSubscriber.js} +3 -3
  14. package/lib/accounts/pollingUserAccountSubscriber.d.ts +1 -1
  15. package/lib/accounts/pollingUserAccountSubscriber.js +5 -11
  16. package/lib/accounts/pollingUserStatsAccountSubscriber.d.ts +27 -0
  17. package/lib/accounts/pollingUserStatsAccountSubscriber.js +107 -0
  18. package/lib/accounts/types.d.ts +26 -15
  19. package/lib/accounts/webSocketDriftClientAccountSubscriber.d.ts +49 -0
  20. package/lib/accounts/{webSocketClearingHouseAccountSubscriber.js → webSocketDriftClientAccountSubscriber.js} +47 -45
  21. package/lib/accounts/webSocketUserStatsAccountSubsriber.d.ts +20 -0
  22. package/lib/accounts/webSocketUserStatsAccountSubsriber.js +47 -0
  23. package/lib/addresses/marketAddresses.d.ts +1 -3
  24. package/lib/addresses/marketAddresses.js +1 -1
  25. package/lib/addresses/pda.d.ts +15 -9
  26. package/lib/addresses/pda.js +73 -35
  27. package/lib/adminClient.d.ts +65 -0
  28. package/lib/adminClient.js +637 -0
  29. package/lib/config.d.ts +10 -10
  30. package/lib/config.js +26 -22
  31. package/lib/constants/numericConstants.d.ts +29 -12
  32. package/lib/constants/numericConstants.js +40 -21
  33. package/lib/constants/perpMarkets.d.ts +18 -0
  34. package/lib/constants/{markets.js → perpMarkets.js} +20 -9
  35. package/lib/constants/spotMarkets.d.ts +19 -0
  36. package/lib/constants/spotMarkets.js +63 -0
  37. package/lib/dlob/DLOB.d.ts +82 -0
  38. package/lib/dlob/DLOB.js +694 -0
  39. package/lib/dlob/DLOBNode.d.ts +54 -0
  40. package/lib/dlob/DLOBNode.js +77 -0
  41. package/lib/dlob/NodeList.d.ts +27 -0
  42. package/lib/dlob/NodeList.js +144 -0
  43. package/lib/driftClient.d.ts +234 -0
  44. package/lib/driftClient.js +2108 -0
  45. package/lib/{clearingHouseConfig.d.ts → driftClientConfig.d.ts} +9 -9
  46. package/lib/{clearingHouseConfig.js → driftClientConfig.js} +0 -0
  47. package/lib/events/eventList.js +3 -0
  48. package/lib/events/eventSubscriber.d.ts +5 -2
  49. package/lib/events/eventSubscriber.js +25 -11
  50. package/lib/events/fetchLogs.d.ts +13 -2
  51. package/lib/events/fetchLogs.js +45 -14
  52. package/lib/events/pollingLogProvider.d.ts +2 -1
  53. package/lib/events/pollingLogProvider.js +7 -3
  54. package/lib/events/sort.js +8 -11
  55. package/lib/events/types.d.ts +11 -3
  56. package/lib/events/types.js +8 -0
  57. package/lib/events/webSocketLogProvider.js +1 -1
  58. package/lib/examples/makeTradeExample.js +30 -18
  59. package/lib/factory/bigNum.d.ts +8 -4
  60. package/lib/factory/bigNum.js +109 -19
  61. package/lib/idl/drift.json +8392 -0
  62. package/lib/index.d.ts +29 -12
  63. package/lib/index.js +29 -12
  64. package/lib/math/amm.d.ts +9 -6
  65. package/lib/math/amm.js +91 -38
  66. package/lib/math/conversion.js +1 -1
  67. package/lib/math/exchangeStatus.d.ts +4 -0
  68. package/lib/math/exchangeStatus.js +18 -0
  69. package/lib/math/funding.d.ts +6 -6
  70. package/lib/math/funding.js +23 -21
  71. package/lib/math/insurance.d.ts +4 -0
  72. package/lib/math/insurance.js +27 -0
  73. package/lib/math/margin.d.ts +11 -0
  74. package/lib/math/margin.js +82 -0
  75. package/lib/math/market.d.ts +14 -9
  76. package/lib/math/market.js +70 -10
  77. package/lib/math/oracles.d.ts +4 -0
  78. package/lib/math/oracles.js +36 -8
  79. package/lib/math/orders.d.ts +16 -6
  80. package/lib/math/orders.js +97 -17
  81. package/lib/math/position.d.ts +27 -13
  82. package/lib/math/position.js +91 -37
  83. package/lib/math/repeg.js +17 -8
  84. package/lib/math/spotBalance.d.ts +22 -0
  85. package/lib/math/spotBalance.js +192 -0
  86. package/lib/math/spotMarket.d.ts +4 -0
  87. package/lib/math/spotMarket.js +8 -0
  88. package/lib/math/spotPosition.d.ts +6 -0
  89. package/lib/math/spotPosition.js +23 -0
  90. package/lib/math/trade.d.ts +10 -10
  91. package/lib/math/trade.js +27 -31
  92. package/lib/oracles/pythClient.js +1 -1
  93. package/lib/oracles/quoteAssetOracleClient.js +1 -1
  94. package/lib/oracles/switchboardClient.js +1 -1
  95. package/lib/orderParams.d.ts +4 -4
  96. package/lib/orderParams.js +12 -4
  97. package/lib/serum/serumFulfillmentConfigMap.d.ts +10 -0
  98. package/lib/serum/serumFulfillmentConfigMap.js +17 -0
  99. package/lib/serum/serumSubscriber.d.ts +27 -0
  100. package/lib/serum/serumSubscriber.js +56 -0
  101. package/lib/serum/types.d.ts +11 -0
  102. package/{src/oracles → lib/serum}/types.js +0 -0
  103. package/lib/tokenFaucet.d.ts +1 -0
  104. package/lib/tokenFaucet.js +23 -12
  105. package/lib/tx/retryTxSender.d.ts +1 -1
  106. package/lib/tx/retryTxSender.js +13 -4
  107. package/lib/tx/types.d.ts +1 -1
  108. package/lib/types.d.ts +631 -222
  109. package/lib/types.js +137 -24
  110. package/lib/user.d.ts +228 -0
  111. package/lib/user.js +959 -0
  112. package/lib/userConfig.d.ts +14 -0
  113. package/lib/{clearingHouseUserConfig.js → userConfig.js} +0 -0
  114. package/lib/userMap/userMap.d.ts +41 -0
  115. package/lib/userMap/userMap.js +85 -0
  116. package/lib/userMap/userStatsMap.d.ts +19 -0
  117. package/lib/userMap/userStatsMap.js +68 -0
  118. package/lib/userName.d.ts +1 -0
  119. package/lib/userName.js +3 -2
  120. package/lib/userStats.d.ts +18 -0
  121. package/lib/userStats.js +49 -0
  122. package/lib/userStatsConfig.d.ts +14 -0
  123. package/{src/clearingHouseConfig.js → lib/userStatsConfig.js} +0 -0
  124. package/lib/util/getTokenAddress.d.ts +2 -0
  125. package/lib/util/getTokenAddress.js +9 -0
  126. package/package.json +12 -5
  127. package/src/accounts/bulkAccountLoader.ts +44 -34
  128. package/src/accounts/bulkUserStatsSubscription.ts +33 -0
  129. package/src/accounts/bulkUserSubscription.ts +2 -3
  130. package/src/accounts/fetch.ts +27 -2
  131. package/src/accounts/{pollingClearingHouseAccountSubscriber.ts → pollingDriftClientAccountSubscriber.ts} +65 -75
  132. package/src/accounts/{pollingOracleSubscriber.ts → pollingOracleAccountSubscriber.ts} +2 -2
  133. package/src/accounts/pollingUserAccountSubscriber.ts +5 -12
  134. package/src/accounts/pollingUserStatsAccountSubscriber.ts +166 -0
  135. package/src/accounts/types.ts +35 -15
  136. package/src/accounts/{webSocketClearingHouseAccountSubscriber.ts → webSocketDriftClientAccountSubscriber.ts} +78 -73
  137. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +80 -0
  138. package/src/addresses/marketAddresses.ts +3 -4
  139. package/src/addresses/pda.ts +105 -33
  140. package/src/adminClient.ts +1207 -0
  141. package/src/config.ts +41 -34
  142. package/src/constants/numericConstants.ts +59 -26
  143. package/src/constants/{markets.ts → perpMarkets.ts} +22 -11
  144. package/src/constants/spotMarkets.ts +83 -0
  145. package/src/dlob/DLOB.ts +1120 -0
  146. package/src/dlob/DLOBNode.ts +155 -0
  147. package/src/dlob/NodeList.ts +195 -0
  148. package/src/driftClient.ts +3594 -0
  149. package/src/{clearingHouseConfig.ts → driftClientConfig.ts} +9 -8
  150. package/src/events/eventList.ts +3 -0
  151. package/src/events/eventSubscriber.ts +36 -14
  152. package/src/events/fetchLogs.ts +60 -15
  153. package/src/events/pollingLogProvider.ts +11 -3
  154. package/src/events/sort.ts +11 -15
  155. package/src/events/types.ts +27 -2
  156. package/src/events/webSocketLogProvider.ts +1 -1
  157. package/src/examples/makeTradeExample.js +152 -75
  158. package/src/examples/makeTradeExample.ts +44 -28
  159. package/src/factory/bigNum.ts +150 -22
  160. package/src/idl/drift.json +8392 -0
  161. package/src/idl/pyth.json +98 -2
  162. package/src/index.ts +29 -12
  163. package/src/math/amm.ts +161 -48
  164. package/src/math/conversion.ts +2 -2
  165. package/src/math/exchangeStatus.ts +31 -0
  166. package/src/math/funding.ts +41 -31
  167. package/src/math/insurance.ts +35 -0
  168. package/src/math/margin.ts +133 -0
  169. package/src/math/market.ts +143 -14
  170. package/src/math/oracles.ts +63 -9
  171. package/src/math/orders.ts +168 -26
  172. package/src/math/position.ts +133 -59
  173. package/src/math/repeg.ts +19 -9
  174. package/src/math/spotBalance.ts +319 -0
  175. package/src/math/spotMarket.ts +9 -0
  176. package/src/math/spotPosition.ts +47 -0
  177. package/src/math/trade.ts +33 -37
  178. package/src/oracles/pythClient.ts +2 -2
  179. package/src/oracles/quoteAssetOracleClient.ts +2 -2
  180. package/src/oracles/switchboardClient.ts +2 -2
  181. package/src/orderParams.ts +16 -8
  182. package/src/serum/serumFulfillmentConfigMap.ts +26 -0
  183. package/src/serum/serumSubscriber.ts +99 -0
  184. package/src/serum/types.ts +13 -0
  185. package/src/tokenFaucet.ts +38 -15
  186. package/src/tx/retryTxSender.ts +16 -5
  187. package/src/tx/types.ts +2 -1
  188. package/src/types.ts +594 -195
  189. package/src/user.ts +1599 -0
  190. package/src/{clearingHouseUserConfig.ts → userConfig.ts} +5 -5
  191. package/src/userMap/userMap.ts +124 -0
  192. package/src/userMap/userStatsMap.ts +108 -0
  193. package/src/userName.ts +2 -1
  194. package/src/userStats.ts +75 -0
  195. package/src/userStatsConfig.ts +18 -0
  196. package/src/util/getTokenAddress.ts +18 -0
  197. package/tests/bn/test.ts +46 -11
  198. package/tests/dlob/helpers.ts +619 -0
  199. package/tests/dlob/test.ts +4586 -0
  200. package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +0 -49
  201. package/lib/admin.d.ts +0 -44
  202. package/lib/admin.js +0 -438
  203. package/lib/clearingHouse.d.ts +0 -146
  204. package/lib/clearingHouse.js +0 -1154
  205. package/lib/clearingHouseUser.d.ts +0 -187
  206. package/lib/clearingHouseUser.js +0 -634
  207. package/lib/clearingHouseUserConfig.d.ts +0 -14
  208. package/lib/constants/banks.d.ts +0 -16
  209. package/lib/constants/banks.js +0 -41
  210. package/lib/constants/markets.d.ts +0 -19
  211. package/lib/idl/clearing_house.json +0 -4464
  212. package/lib/math/bankBalance.d.ts +0 -9
  213. package/lib/math/bankBalance.js +0 -75
  214. package/lib/math/state.d.ts +0 -8
  215. package/lib/math/state.js +0 -15
  216. package/lib/orders.d.ts +0 -8
  217. package/lib/orders.js +0 -134
  218. package/src/accounts/bulkAccountLoader.js +0 -197
  219. package/src/accounts/bulkUserSubscription.js +0 -33
  220. package/src/accounts/pollingClearingHouseAccountSubscriber.js +0 -311
  221. package/src/accounts/pollingOracleSubscriber.js +0 -93
  222. package/src/accounts/pollingTokenAccountSubscriber.js +0 -90
  223. package/src/accounts/pollingUserAccountSubscriber.js +0 -132
  224. package/src/accounts/types.js +0 -10
  225. package/src/accounts/utils.js +0 -7
  226. package/src/accounts/webSocketAccountSubscriber.js +0 -93
  227. package/src/accounts/webSocketClearingHouseAccountSubscriber.js +0 -233
  228. package/src/accounts/webSocketUserAccountSubscriber.js +0 -62
  229. package/src/addresses/marketAddresses.js +0 -26
  230. package/src/admin.js +0 -517
  231. package/src/admin.ts +0 -730
  232. package/src/clearingHouse.ts +0 -1828
  233. package/src/clearingHouseUser.ts +0 -978
  234. package/src/clearingHouseUserConfig.js +0 -2
  235. package/src/config.js +0 -67
  236. package/src/constants/banks.js +0 -42
  237. package/src/constants/banks.ts +0 -50
  238. package/src/constants/markets.js +0 -42
  239. package/src/constants/numericConstants.js +0 -41
  240. package/src/events/eventSubscriber.js +0 -139
  241. package/src/events/fetchLogs.js +0 -50
  242. package/src/events/pollingLogProvider.js +0 -64
  243. package/src/events/sort.js +0 -44
  244. package/src/events/txEventCache.js +0 -71
  245. package/src/events/types.js +0 -20
  246. package/src/events/webSocketLogProvider.js +0 -41
  247. package/src/factory/bigNum.js +0 -390
  248. package/src/factory/oracleClient.js +0 -20
  249. package/src/idl/clearing_house.json +0 -4464
  250. package/src/index.js +0 -69
  251. package/src/math/amm.js +0 -369
  252. package/src/math/auction.js +0 -42
  253. package/src/math/bankBalance.ts +0 -112
  254. package/src/math/conversion.js +0 -11
  255. package/src/math/funding.js +0 -248
  256. package/src/math/oracles.js +0 -26
  257. package/src/math/repeg.js +0 -128
  258. package/src/math/state.js +0 -15
  259. package/src/math/state.ts +0 -14
  260. package/src/math/trade.js +0 -253
  261. package/src/math/utils.js +0 -26
  262. package/src/math/utils.js.map +0 -1
  263. package/src/mockUSDCFaucet.js +0 -280
  264. package/src/oracles/oracleClientCache.js +0 -19
  265. package/src/oracles/pythClient.js +0 -46
  266. package/src/oracles/quoteAssetOracleClient.js +0 -32
  267. package/src/oracles/switchboardClient.js +0 -69
  268. package/src/orderParams.js +0 -20
  269. package/src/orders.ts +0 -245
  270. package/src/slot/SlotSubscriber.js +0 -39
  271. package/src/tokenFaucet.js +0 -189
  272. package/src/types.js +0 -125
  273. package/src/userName.js +0 -20
  274. package/src/wallet.js +0 -35
@@ -0,0 +1,14 @@
1
+ import { DriftClient } from './driftClient';
2
+ import { PublicKey } from '@solana/web3.js';
3
+ import { BulkAccountLoader } from './accounts/bulkAccountLoader';
4
+ export declare type UserConfig = {
5
+ accountSubscription?: UserSubscriptionConfig;
6
+ driftClient: DriftClient;
7
+ userAccountPublicKey: PublicKey;
8
+ };
9
+ export declare type UserSubscriptionConfig = {
10
+ type: 'websocket';
11
+ } | {
12
+ type: 'polling';
13
+ accountLoader: BulkAccountLoader;
14
+ };
@@ -0,0 +1,41 @@
1
+ import { User, DriftClient, OrderRecord, UserSubscriptionConfig } from '..';
2
+ import { PublicKey } from '@solana/web3.js';
3
+ export interface UserMapInterface {
4
+ fetchAllUsers(): Promise<void>;
5
+ addPubkey(userAccountPublicKey: PublicKey): Promise<void>;
6
+ has(key: string): boolean;
7
+ get(key: string): User | undefined;
8
+ mustGet(key: string): Promise<User>;
9
+ getUserAuthority(key: string): PublicKey | undefined;
10
+ updateWithOrderRecord(record: OrderRecord): Promise<void>;
11
+ values(): IterableIterator<User>;
12
+ }
13
+ export declare class UserMap implements UserMapInterface {
14
+ private userMap;
15
+ private driftClient;
16
+ private accountSubscription;
17
+ constructor(driftClient: DriftClient, accountSubscription: UserSubscriptionConfig);
18
+ fetchAllUsers(): Promise<void>;
19
+ addPubkey(userAccountPublicKey: PublicKey): Promise<void>;
20
+ has(key: string): boolean;
21
+ /**
22
+ * gets the User for a particular userAccountPublicKey, if no User exists, undefined is returned
23
+ * @param key userAccountPublicKey to get User for
24
+ * @returns user User | undefined
25
+ */
26
+ get(key: string): User | undefined;
27
+ /**
28
+ * gets the User for a particular userAccountPublicKey, if no User exists, new one is created
29
+ * @param key userAccountPublicKey to get User for
30
+ * @returns User
31
+ */
32
+ mustGet(key: string): Promise<User>;
33
+ /**
34
+ * gets the Authority for a particular userAccountPublicKey, if no User exists, undefined is returned
35
+ * @param key userAccountPublicKey to get User for
36
+ * @returns authority PublicKey | undefined
37
+ */
38
+ getUserAuthority(key: string): PublicKey | undefined;
39
+ updateWithOrderRecord(record: OrderRecord): Promise<void>;
40
+ values(): IterableIterator<User>;
41
+ }
@@ -0,0 +1,85 @@
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(driftClient, accountSubscription) {
8
+ this.userMap = new Map();
9
+ this.driftClient = driftClient;
10
+ this.accountSubscription = accountSubscription;
11
+ }
12
+ async fetchAllUsers() {
13
+ const userArray = [];
14
+ const programUserAccounts = (await this.driftClient.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.User({
20
+ driftClient: this.driftClient,
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.User({
35
+ driftClient: this.driftClient,
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 User for a particular userAccountPublicKey, if no User exists, undefined is returned
47
+ * @param key userAccountPublicKey to get User for
48
+ * @returns user User | undefined
49
+ */
50
+ get(key) {
51
+ return this.userMap.get(key);
52
+ }
53
+ /**
54
+ * gets the User for a particular userAccountPublicKey, if no User exists, new one is created
55
+ * @param key userAccountPublicKey to get User for
56
+ * @returns User
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
+ /**
67
+ * gets the Authority for a particular userAccountPublicKey, if no User exists, undefined is returned
68
+ * @param key userAccountPublicKey to get User for
69
+ * @returns authority PublicKey | undefined
70
+ */
71
+ getUserAuthority(key) {
72
+ const chUser = this.userMap.get(key);
73
+ if (!chUser) {
74
+ return undefined;
75
+ }
76
+ return chUser.getUserAccount().authority;
77
+ }
78
+ async updateWithOrderRecord(record) {
79
+ await this.addPubkey(record.user);
80
+ }
81
+ values() {
82
+ return this.userMap.values();
83
+ }
84
+ }
85
+ exports.UserMap = UserMap;
@@ -0,0 +1,19 @@
1
+ import { DriftClient, OrderRecord, UserStats, UserStatsSubscriptionConfig } 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 UserStats
7
+ */
8
+ private userStatsMap;
9
+ private driftClient;
10
+ private accountSubscription;
11
+ constructor(driftClient: DriftClient, accountSubscription: UserStatsSubscriptionConfig);
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): UserStats;
17
+ mustGet(authorityPublicKey: string): Promise<UserStats>;
18
+ values(): IterableIterator<UserStats>;
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(driftClient, accountSubscription) {
8
+ /**
9
+ * map from authority pubkey to UserStats
10
+ */
11
+ this.userStatsMap = new Map();
12
+ this.driftClient = driftClient;
13
+ this.accountSubscription = accountSubscription;
14
+ }
15
+ async fetchAllUserStats() {
16
+ const userStatArray = [];
17
+ const programUserAccounts = (await this.driftClient.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.UserStats({
24
+ driftClient: this.driftClient,
25
+ userStatsAccountPublicKey: (0, __1.getUserStatsAccountPublicKey)(this.driftClient.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.UserStats({
39
+ driftClient: this.driftClient,
40
+ userStatsAccountPublicKey: (0, __1.getUserStatsAccountPublicKey)(this.driftClient.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;
package/lib/userName.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export declare const MAX_NAME_LENGTH = 32;
2
2
  export declare const DEFAULT_USER_NAME = "Main Account";
3
+ export declare const DEFAULT_MARKET_NAME = "Default Market Name";
3
4
  export declare function encodeName(name: string): number[];
4
5
  export declare function decodeName(bytes: number[]): string;
package/lib/userName.js CHANGED
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.decodeName = exports.encodeName = exports.DEFAULT_USER_NAME = exports.MAX_NAME_LENGTH = void 0;
3
+ exports.decodeName = exports.encodeName = exports.DEFAULT_MARKET_NAME = exports.DEFAULT_USER_NAME = exports.MAX_NAME_LENGTH = void 0;
4
4
  exports.MAX_NAME_LENGTH = 32;
5
5
  exports.DEFAULT_USER_NAME = 'Main Account';
6
+ exports.DEFAULT_MARKET_NAME = 'Default Market Name';
6
7
  function encodeName(name) {
7
8
  if (name.length > exports.MAX_NAME_LENGTH) {
8
- throw Error(`User name (${name}) longer than 32 characters`);
9
+ throw Error(`Name (${name}) longer than 32 characters`);
9
10
  }
10
11
  const buffer = Buffer.alloc(32);
11
12
  buffer.fill(name);
@@ -0,0 +1,18 @@
1
+ import { DriftClient } from './driftClient';
2
+ import { PublicKey } from '@solana/web3.js';
3
+ import { DataAndSlot, UserStatsAccountSubscriber } from './accounts/types';
4
+ import { UserStatsConfig } from './userStatsConfig';
5
+ import { ReferrerInfo, UserStatsAccount } from './types';
6
+ export declare class UserStats {
7
+ driftClient: DriftClient;
8
+ userStatsAccountPublicKey: PublicKey;
9
+ accountSubscriber: UserStatsAccountSubscriber;
10
+ isSubscribed: boolean;
11
+ constructor(config: UserStatsConfig);
12
+ subscribe(): Promise<boolean>;
13
+ fetchAccounts(): Promise<void>;
14
+ unsubscribe(): Promise<void>;
15
+ getAccountAndSlot(): DataAndSlot<UserStatsAccount>;
16
+ getAccount(): UserStatsAccount;
17
+ getReferrerInfo(): ReferrerInfo | undefined;
18
+ }
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UserStats = void 0;
4
+ const web3_js_1 = require("@solana/web3.js");
5
+ const pollingUserStatsAccountSubscriber_1 = require("./accounts/pollingUserStatsAccountSubscriber");
6
+ const webSocketUserStatsAccountSubsriber_1 = require("./accounts/webSocketUserStatsAccountSubsriber");
7
+ const pda_1 = require("./addresses/pda");
8
+ class UserStats {
9
+ constructor(config) {
10
+ var _a;
11
+ this.driftClient = config.driftClient;
12
+ this.userStatsAccountPublicKey = config.userStatsAccountPublicKey;
13
+ if (((_a = config.accountSubscription) === null || _a === void 0 ? void 0 : _a.type) === 'polling') {
14
+ this.accountSubscriber = new pollingUserStatsAccountSubscriber_1.PollingUserStatsAccountSubscriber(config.driftClient.program, config.userStatsAccountPublicKey, config.accountSubscription.accountLoader);
15
+ }
16
+ else {
17
+ this.accountSubscriber = new webSocketUserStatsAccountSubsriber_1.WebSocketUserStatsAccountSubscriber(config.driftClient.program, config.userStatsAccountPublicKey);
18
+ }
19
+ }
20
+ async subscribe() {
21
+ this.isSubscribed = await this.accountSubscriber.subscribe();
22
+ return this.isSubscribed;
23
+ }
24
+ async fetchAccounts() {
25
+ await this.accountSubscriber.fetch();
26
+ }
27
+ async unsubscribe() {
28
+ await this.accountSubscriber.unsubscribe();
29
+ this.isSubscribed = false;
30
+ }
31
+ getAccountAndSlot() {
32
+ return this.accountSubscriber.getUserStatsAccountAndSlot();
33
+ }
34
+ getAccount() {
35
+ return this.accountSubscriber.getUserStatsAccountAndSlot().data;
36
+ }
37
+ getReferrerInfo() {
38
+ if (this.getAccount().referrer.equals(web3_js_1.PublicKey.default)) {
39
+ return undefined;
40
+ }
41
+ else {
42
+ return {
43
+ referrer: (0, pda_1.getUserAccountPublicKeySync)(this.driftClient.program.programId, this.getAccount().referrer, 0),
44
+ referrerStats: (0, pda_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, this.getAccount().referrer),
45
+ };
46
+ }
47
+ }
48
+ }
49
+ exports.UserStats = UserStats;
@@ -0,0 +1,14 @@
1
+ import { DriftClient } from './driftClient';
2
+ import { PublicKey } from '@solana/web3.js';
3
+ import { BulkAccountLoader } from './accounts/bulkAccountLoader';
4
+ export declare type UserStatsConfig = {
5
+ accountSubscription?: UserStatsSubscriptionConfig;
6
+ driftClient: DriftClient;
7
+ userStatsAccountPublicKey: PublicKey;
8
+ };
9
+ export declare type UserStatsSubscriptionConfig = {
10
+ type: 'websocket';
11
+ } | {
12
+ type: 'polling';
13
+ accountLoader: BulkAccountLoader;
14
+ };
@@ -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,20 +1,24 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "0.2.0-temp.1",
3
+ "version": "2.0.0",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
7
7
  "homepage": "https://www.drift.trade/",
8
8
  "repository": {
9
9
  "type": "git",
10
- "url": "git@github.com:drift-labs/protocol-v1.git"
10
+ "url": "git@github.com:drift-labs/protocol-v2.git"
11
11
  },
12
12
  "scripts": {
13
13
  "lint": "eslint './**/*.{ts,tsx}' --quiet",
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
+ "test:inspect": "mocha --inspect-brk -r ts-node/register tests/**/*.ts",
18
+ "test:bignum": "mocha -r ts-node/register tests/bn/**/*.ts",
19
+ "patch-and-pub": "npm version patch --force && npm publish",
20
+ "prettify": "prettier --check './src/***/*.ts'",
21
+ "prettify:fix": "prettier --write './{src,tests}/***/*.ts'"
18
22
  },
19
23
  "keywords": [
20
24
  "drift-labs",
@@ -29,11 +33,13 @@
29
33
  "access": "public"
30
34
  },
31
35
  "dependencies": {
32
- "@project-serum/anchor": "0.24.2",
36
+ "@project-serum/anchor": "0.25.0-beta.1",
37
+ "@project-serum/serum": "^0.13.38",
33
38
  "@pythnetwork/client": "2.5.3",
34
39
  "@solana/spl-token": "^0.1.6",
35
- "@solana/web3.js": "1.41.0",
40
+ "@solana/web3.js": "1.66.2",
36
41
  "@switchboard-xyz/switchboard-v2": "^0.0.67",
42
+ "async-mutex": "^0.4.0",
37
43
  "strict-event-emitter-types": "^2.0.0",
38
44
  "uuid": "^8.3.2"
39
45
  },
@@ -48,6 +54,7 @@
48
54
  "eslint-config-prettier": "^8.3.0",
49
55
  "eslint-plugin-prettier": "^3.4.0",
50
56
  "mocha": "^10.0.0",
57
+ "prettier": "^2.4.1",
51
58
  "ts-node": "^10.8.0"
52
59
  },
53
60
  "description": "SDK for Drift Protocol v1",
@@ -2,6 +2,7 @@ import { Commitment, Connection, PublicKey } from '@solana/web3.js';
2
2
  import { v4 as uuidv4 } from 'uuid';
3
3
  import { BufferAndSlot } from './types';
4
4
  import { promiseTimeout } from '../util/promiseTimeout';
5
+ import { Mutex } from 'async-mutex';
5
6
 
6
7
  type AccountToLoad = {
7
8
  publicKey: PublicKey;
@@ -22,6 +23,7 @@ export class BulkAccountLoader {
22
23
  intervalId?: NodeJS.Timer;
23
24
  // to handle clients spamming load
24
25
  loadPromise?: Promise<void>;
26
+ loadPromiseLock: Mutex = new Mutex();
25
27
  loadPromiseResolver: () => void;
26
28
  lastTimeLoadingPromiseCleared = Date.now();
27
29
  mostRecentSlot = 0;
@@ -64,7 +66,9 @@ export class BulkAccountLoader {
64
66
  }
65
67
 
66
68
  // if a new account needs to be polled, remove the cached loadPromise in case client calls load immediately after
67
- this.loadPromise = undefined;
69
+ this.loadPromiseLock.runExclusive(() => {
70
+ this.loadPromise = undefined;
71
+ });
68
72
 
69
73
  return callbackId;
70
74
  }
@@ -101,41 +105,43 @@ export class BulkAccountLoader {
101
105
  }
102
106
 
103
107
  public async load(): Promise<void> {
104
- if (this.loadPromise) {
105
- const now = Date.now();
106
- if (now - this.lastTimeLoadingPromiseCleared > oneMinute) {
107
- this.loadPromise = undefined;
108
- } else {
109
- return this.loadPromise;
108
+ await this.loadPromiseLock.runExclusive(async () => {
109
+ if (this.loadPromise) {
110
+ const now = Date.now();
111
+ if (now - this.lastTimeLoadingPromiseCleared > oneMinute) {
112
+ this.loadPromise = undefined;
113
+ } else {
114
+ return this.loadPromise;
115
+ }
110
116
  }
111
- }
112
-
113
- this.loadPromise = new Promise((resolver) => {
114
- this.loadPromiseResolver = resolver;
115
- });
116
- this.lastTimeLoadingPromiseCleared = Date.now();
117
-
118
- try {
119
- const chunks = this.chunks(
120
- Array.from(this.accountsToLoad.values()),
121
- GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE
122
- );
123
117
 
124
- await Promise.all(
125
- chunks.map((chunk) => {
126
- return this.loadChunk(chunk);
127
- })
128
- );
129
- } catch (e) {
130
- console.error(`Error in bulkAccountLoader.load()`);
131
- console.error(e);
132
- for (const [_, callback] of this.errorCallbacks) {
133
- callback(e);
118
+ this.loadPromise = new Promise((resolver) => {
119
+ this.loadPromiseResolver = resolver;
120
+ });
121
+ this.lastTimeLoadingPromiseCleared = Date.now();
122
+
123
+ try {
124
+ const chunks = this.chunks(
125
+ Array.from(this.accountsToLoad.values()),
126
+ GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE
127
+ );
128
+
129
+ await Promise.all(
130
+ chunks.map((chunk) => {
131
+ return this.loadChunk(chunk);
132
+ })
133
+ );
134
+ } catch (e) {
135
+ console.error(`Error in bulkAccountLoader.load()`);
136
+ console.error(e);
137
+ for (const [_, callback] of this.errorCallbacks) {
138
+ callback(e);
139
+ }
140
+ } finally {
141
+ this.loadPromiseResolver();
142
+ this.loadPromise = undefined;
134
143
  }
135
- } finally {
136
- this.loadPromiseResolver();
137
- this.loadPromise = undefined;
138
- }
144
+ });
139
145
  }
140
146
 
141
147
  async loadChunk(accountsToLoad: AccountToLoad[]): Promise<void> {
@@ -222,7 +228,11 @@ export class BulkAccountLoader {
222
228
  return;
223
229
  }
224
230
 
225
- this.intervalId = setInterval(this.load.bind(this), this.pollingFrequency);
231
+ if (this.pollingFrequency !== 0)
232
+ this.intervalId = setInterval(
233
+ this.load.bind(this),
234
+ this.pollingFrequency
235
+ );
226
236
  }
227
237
 
228
238
  public stopPolling(): void {
@@ -0,0 +1,33 @@
1
+ import { UserStats } from '../userStats';
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: UserStats[],
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
+ }
@@ -1,4 +1,4 @@
1
- import { ClearingHouseUser } from '../clearingHouseUser';
1
+ import { User } from '../user';
2
2
  import { BulkAccountLoader } from './bulkAccountLoader';
3
3
  import { PollingUserAccountSubscriber } from './pollingUserAccountSubscriber';
4
4
 
@@ -7,7 +7,7 @@ import { PollingUserAccountSubscriber } from './pollingUserAccountSubscriber';
7
7
  * @param accountLoader
8
8
  */
9
9
  export async function bulkPollingUserSubscribe(
10
- users: ClearingHouseUser[],
10
+ users: User[],
11
11
  accountLoader: BulkAccountLoader
12
12
  ): Promise<void> {
13
13
  if (users.length === 0) {
@@ -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
+ }