@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
@@ -1,1154 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
- Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.ClearingHouse = void 0;
30
- const anchor_1 = require("@project-serum/anchor");
31
- const spl_token_1 = require("@solana/spl-token");
32
- const types_1 = require("./types");
33
- const anchor = __importStar(require("@project-serum/anchor"));
34
- const clearing_house_json_1 = __importDefault(require("./idl/clearing_house.json"));
35
- const web3_js_1 = require("@solana/web3.js");
36
- const pda_1 = require("./addresses/pda");
37
- const utils_1 = require("./tx/utils");
38
- const numericConstants_1 = require("./constants/numericConstants");
39
- const position_1 = require("./math/position");
40
- const bankBalance_1 = require("./math/bankBalance");
41
- const userName_1 = require("./userName");
42
- const pollingClearingHouseAccountSubscriber_1 = require("./accounts/pollingClearingHouseAccountSubscriber");
43
- const webSocketClearingHouseAccountSubscriber_1 = require("./accounts/webSocketClearingHouseAccountSubscriber");
44
- const retryTxSender_1 = require("./tx/retryTxSender");
45
- const clearingHouseUser_1 = require("./clearingHouseUser");
46
- const config_1 = require("./config");
47
- /**
48
- * # ClearingHouse
49
- * This class is the main way to interact with Drift Protocol. It allows you to subscribe to the various accounts where the Market's state is stored, as well as: opening positions, liquidating, settling funding, depositing & withdrawing, and more.
50
- */
51
- class ClearingHouse {
52
- constructor(config) {
53
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
54
- this.users = new Map();
55
- this._isSubscribed = false;
56
- this.marketLastSlotCache = new Map();
57
- this.connection = config.connection;
58
- this.wallet = config.wallet;
59
- this.opts = config.opts || anchor_1.AnchorProvider.defaultOptions();
60
- this.provider = new anchor_1.AnchorProvider(config.connection, config.wallet, this.opts);
61
- this.program = new anchor_1.Program(clearing_house_json_1.default, config.programID, this.provider);
62
- const userIds = (_a = config.userIds) !== null && _a !== void 0 ? _a : [0];
63
- this.activeUserId = (_b = config.activeUserId) !== null && _b !== void 0 ? _b : userIds[0];
64
- this.userAccountSubscriptionConfig =
65
- ((_c = config.accountSubscription) === null || _c === void 0 ? void 0 : _c.type) === 'polling'
66
- ? {
67
- type: 'polling',
68
- accountLoader: config.accountSubscription.accountLoader,
69
- }
70
- : {
71
- type: 'websocket',
72
- };
73
- this.createUsers(userIds, this.userAccountSubscriptionConfig);
74
- let marketIndexes = config.marketIndexes;
75
- let bankIndexes = config.bankIndexes;
76
- let oracleInfos = config.oracleInfos;
77
- if (config.env) {
78
- const { marketIndexes: envMarketIndexes, bankIndexes: envBankIndexes, oracleInfos: envOralceInfos, } = (0, config_1.getMarketsBanksAndOraclesForSubscription)(config.env);
79
- marketIndexes = marketIndexes ? marketIndexes : envMarketIndexes;
80
- bankIndexes = bankIndexes ? bankIndexes : envBankIndexes;
81
- oracleInfos = oracleInfos ? oracleInfos : envOralceInfos;
82
- }
83
- if (((_d = config.accountSubscription) === null || _d === void 0 ? void 0 : _d.type) === 'polling') {
84
- this.accountSubscriber = new pollingClearingHouseAccountSubscriber_1.PollingClearingHouseAccountSubscriber(this.program, config.accountSubscription.accountLoader, marketIndexes !== null && marketIndexes !== void 0 ? marketIndexes : [], bankIndexes !== null && bankIndexes !== void 0 ? bankIndexes : [], oracleInfos !== null && oracleInfos !== void 0 ? oracleInfos : []);
85
- }
86
- else {
87
- this.accountSubscriber = new webSocketClearingHouseAccountSubscriber_1.WebSocketClearingHouseAccountSubscriber(this.program, (_e = config.marketIndexes) !== null && _e !== void 0 ? _e : [], (_f = config.bankIndexes) !== null && _f !== void 0 ? _f : [], (_g = config.oracleInfos) !== null && _g !== void 0 ? _g : []);
88
- }
89
- this.eventEmitter = this.accountSubscriber.eventEmitter;
90
- this.txSender = new retryTxSender_1.RetryTxSender(this.provider, (_h = config.txSenderConfig) === null || _h === void 0 ? void 0 : _h.timeout, (_j = config.txSenderConfig) === null || _j === void 0 ? void 0 : _j.retrySleep, (_k = config.txSenderConfig) === null || _k === void 0 ? void 0 : _k.additionalConnections);
91
- }
92
- get isSubscribed() {
93
- return this._isSubscribed && this.accountSubscriber.isSubscribed;
94
- }
95
- set isSubscribed(val) {
96
- this._isSubscribed = val;
97
- }
98
- createUsers(userIds, accountSubscriptionConfig) {
99
- for (const userId of userIds) {
100
- const user = this.createUser(userId, accountSubscriptionConfig);
101
- this.users.set(userId, user);
102
- }
103
- }
104
- createUser(userId, accountSubscriptionConfig) {
105
- const userAccountPublicKey = (0, pda_1.getUserAccountPublicKeySync)(this.program.programId, this.wallet.publicKey, userId);
106
- return new clearingHouseUser_1.ClearingHouseUser({
107
- clearingHouse: this,
108
- userAccountPublicKey,
109
- accountSubscription: accountSubscriptionConfig,
110
- });
111
- }
112
- async subscribe() {
113
- const subscribePromises = this.subscribeUsers().concat(this.accountSubscriber.subscribe());
114
- this.isSubscribed = (await Promise.all(subscribePromises)).reduce((success, prevSuccess) => success && prevSuccess);
115
- return this.isSubscribed;
116
- }
117
- subscribeUsers() {
118
- return [...this.users.values()].map((user) => user.subscribe());
119
- }
120
- /**
121
- * Forces the accountSubscriber to fetch account updates from rpc
122
- */
123
- async fetchAccounts() {
124
- await Promise.all([...this.users.values()]
125
- .map((user) => user.fetchAccounts())
126
- .concat(this.accountSubscriber.fetch()));
127
- }
128
- async unsubscribe() {
129
- const unsubscribePromises = this.unsubscribeUsers().concat(this.accountSubscriber.unsubscribe());
130
- await Promise.all(unsubscribePromises);
131
- this.isSubscribed = false;
132
- }
133
- unsubscribeUsers() {
134
- return [...this.users.values()].map((user) => user.unsubscribe());
135
- }
136
- async getStatePublicKey() {
137
- if (this.statePublicKey) {
138
- return this.statePublicKey;
139
- }
140
- this.statePublicKey = await (0, pda_1.getClearingHouseStateAccountPublicKey)(this.program.programId);
141
- return this.statePublicKey;
142
- }
143
- getStateAccount() {
144
- return this.accountSubscriber.getStateAccountAndSlot().data;
145
- }
146
- getMarketAccount(marketIndex) {
147
- var _a;
148
- marketIndex = marketIndex instanceof anchor_1.BN ? marketIndex : new anchor_1.BN(marketIndex);
149
- return (_a = this.accountSubscriber.getMarketAccountAndSlot(marketIndex)) === null || _a === void 0 ? void 0 : _a.data;
150
- }
151
- getMarketAccounts() {
152
- return this.accountSubscriber
153
- .getMarketAccountsAndSlots()
154
- .map((value) => value.data);
155
- }
156
- getBankAccount(bankIndex) {
157
- bankIndex = bankIndex instanceof anchor_1.BN ? bankIndex : new anchor_1.BN(bankIndex);
158
- return this.accountSubscriber.getBankAccountAndSlot(bankIndex).data;
159
- }
160
- getQuoteAssetBankAccount() {
161
- return this.accountSubscriber.getBankAccountAndSlot(numericConstants_1.QUOTE_ASSET_BANK_INDEX)
162
- .data;
163
- }
164
- getOraclePriceDataAndSlot(oraclePublicKey) {
165
- return this.accountSubscriber.getOraclePriceDataAndSlot(oraclePublicKey);
166
- }
167
- /**
168
- * Update the wallet to use for clearing house transactions and linked user account
169
- * @param newWallet
170
- * @param userIds
171
- * @param activeUserId
172
- */
173
- async updateWallet(newWallet, userIds = [0], activeUserId = 0) {
174
- const newProvider = new anchor_1.AnchorProvider(this.connection, newWallet, this.opts);
175
- const newProgram = new anchor_1.Program(clearing_house_json_1.default, this.program.programId, newProvider);
176
- // Update provider for txSender with new wallet details
177
- this.txSender.provider = newProvider;
178
- this.wallet = newWallet;
179
- this.provider = newProvider;
180
- this.program = newProgram;
181
- if (this.isSubscribed) {
182
- await Promise.all(this.unsubscribeUsers());
183
- }
184
- this.users.clear();
185
- this.createUsers(userIds, this.userAccountSubscriptionConfig);
186
- if (this.isSubscribed) {
187
- await Promise.all(this.subscribeUsers());
188
- }
189
- this.activeUserId = activeUserId;
190
- }
191
- async switchActiveUser(userId) {
192
- this.activeUserId = userId;
193
- }
194
- async addUser(userId) {
195
- if (this.users.has(userId)) {
196
- return;
197
- }
198
- const user = this.createUser(userId, this.userAccountSubscriptionConfig);
199
- await user.subscribe();
200
- this.users.set(userId, user);
201
- }
202
- async initializeUserAccount(userId = 0, name = userName_1.DEFAULT_USER_NAME) {
203
- const [userAccountPublicKey, initializeUserAccountIx] = await this.getInitializeUserInstructions(userId, name);
204
- const tx = new web3_js_1.Transaction().add(initializeUserAccountIx);
205
- const { txSig } = await this.txSender.send(tx, [], this.opts);
206
- return [txSig, userAccountPublicKey];
207
- }
208
- async getInitializeUserInstructions(userId = 0, name = userName_1.DEFAULT_USER_NAME) {
209
- const userAccountPublicKey = await (0, pda_1.getUserAccountPublicKey)(this.program.programId, this.wallet.publicKey, userId);
210
- const nameBuffer = (0, userName_1.encodeName)(name);
211
- const initializeUserAccountIx = await this.program.instruction.initializeUser(userId, nameBuffer, {
212
- accounts: {
213
- user: userAccountPublicKey,
214
- authority: this.wallet.publicKey,
215
- payer: this.wallet.publicKey,
216
- rent: anchor.web3.SYSVAR_RENT_PUBKEY,
217
- systemProgram: anchor.web3.SystemProgram.programId,
218
- state: await this.getStatePublicKey(),
219
- },
220
- });
221
- return [userAccountPublicKey, initializeUserAccountIx];
222
- }
223
- getUser(userId) {
224
- userId = userId !== null && userId !== void 0 ? userId : this.activeUserId;
225
- if (!this.users.has(userId)) {
226
- throw new Error(`Clearing House has no user for user id ${userId}`);
227
- }
228
- return this.users.get(userId);
229
- }
230
- getUsers() {
231
- return [...this.users.values()];
232
- }
233
- async getUserAccountPublicKey() {
234
- return this.getUser().userAccountPublicKey;
235
- }
236
- getUserAccount(userId) {
237
- return this.getUser(userId).getUserAccount();
238
- }
239
- getUserAccountAndSlot(userId) {
240
- return this.getUser(userId).getUserAccountAndSlot();
241
- }
242
- getUserBankBalance(bankIndex) {
243
- const bankIndexBN = bankIndex instanceof anchor_1.BN ? bankIndex : new anchor_1.BN(bankIndex);
244
- return this.getUserAccount().bankBalances.find((bankBalance) => bankBalance.bankIndex.eq(bankIndexBN));
245
- }
246
- getQuoteAssetTokenAmount() {
247
- const bank = this.getBankAccount(numericConstants_1.QUOTE_ASSET_BANK_INDEX);
248
- const userBankBalance = this.getUserBankBalance(numericConstants_1.QUOTE_ASSET_BANK_INDEX);
249
- return (0, bankBalance_1.getTokenAmount)(userBankBalance.balance, bank, userBankBalance.balanceType);
250
- }
251
- getRemainingAccounts(params) {
252
- const userAccountAndSlot = this.getUserAccountAndSlot();
253
- if (!userAccountAndSlot) {
254
- throw Error('No user account found. Most likely user account does not exist or failed to fetch account');
255
- }
256
- const { data: userAccount, slot: lastUserPositionsSlot } = userAccountAndSlot;
257
- const oracleAccountMap = new Map();
258
- const bankAccountMap = new Map();
259
- const marketAccountMap = new Map();
260
- for (const [marketIndexNum, slot] of this.marketLastSlotCache.entries()) {
261
- // if cache has more recent slot than user positions account slot, add market to remaining accounts
262
- // otherwise remove from slot
263
- if (slot > lastUserPositionsSlot) {
264
- const marketAccount = this.getMarketAccount(marketIndexNum);
265
- marketAccountMap.set(marketIndexNum, {
266
- pubkey: marketAccount.pubkey,
267
- isSigner: false,
268
- isWritable: false,
269
- });
270
- oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
271
- pubkey: marketAccount.amm.oracle,
272
- isSigner: false,
273
- isWritable: false,
274
- });
275
- }
276
- else {
277
- this.marketLastSlotCache.delete(marketIndexNum);
278
- }
279
- }
280
- for (const position of userAccount.positions) {
281
- if (!(0, position_1.positionIsAvailable)(position)) {
282
- const marketIndexNum = position.marketIndex.toNumber();
283
- const marketAccount = this.getMarketAccount(marketIndexNum);
284
- marketAccountMap.set(marketIndexNum, {
285
- pubkey: marketAccount.pubkey,
286
- isSigner: false,
287
- // isWritable: false, // TODO
288
- isWritable: true,
289
- });
290
- oracleAccountMap.set(marketAccount.pubkey.toString(), {
291
- pubkey: marketAccount.amm.oracle,
292
- isSigner: false,
293
- isWritable: false,
294
- });
295
- }
296
- }
297
- if (params.writableMarketIndex) {
298
- const marketAccount = this.getMarketAccount(params.writableMarketIndex.toNumber());
299
- marketAccountMap.set(params.writableMarketIndex.toNumber(), {
300
- pubkey: marketAccount.pubkey,
301
- isSigner: false,
302
- isWritable: true,
303
- });
304
- oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
305
- pubkey: marketAccount.amm.oracle,
306
- isSigner: false,
307
- isWritable: false,
308
- });
309
- }
310
- for (const userBankBalance of userAccount.bankBalances) {
311
- if (!userBankBalance.balance.eq(numericConstants_1.ZERO)) {
312
- const bankAccount = this.getBankAccount(userBankBalance.bankIndex);
313
- bankAccountMap.set(userBankBalance.bankIndex.toNumber(), {
314
- pubkey: bankAccount.pubkey,
315
- isSigner: false,
316
- isWritable: false,
317
- });
318
- if (!bankAccount.bankIndex.eq(numericConstants_1.ZERO)) {
319
- oracleAccountMap.set(bankAccount.oracle.toString(), {
320
- pubkey: bankAccount.oracle,
321
- isSigner: false,
322
- isWritable: false,
323
- });
324
- }
325
- }
326
- }
327
- if (params.writableBankIndex) {
328
- const bankAccount = this.getBankAccount(params.writableBankIndex);
329
- bankAccountMap.set(params.writableBankIndex.toNumber(), {
330
- pubkey: bankAccount.pubkey,
331
- isSigner: false,
332
- isWritable: true,
333
- });
334
- if (!bankAccount.bankIndex.eq(numericConstants_1.ZERO)) {
335
- oracleAccountMap.set(bankAccount.oracle.toString(), {
336
- pubkey: bankAccount.oracle,
337
- isSigner: false,
338
- isWritable: false,
339
- });
340
- }
341
- }
342
- return [
343
- ...oracleAccountMap.values(),
344
- ...bankAccountMap.values(),
345
- ...marketAccountMap.values(),
346
- ];
347
- }
348
- getOrder(orderId) {
349
- var _a;
350
- const orderIdBN = orderId instanceof anchor_1.BN ? orderId : new anchor_1.BN(orderId);
351
- return (_a = this.getUserAccount()) === null || _a === void 0 ? void 0 : _a.orders.find((order) => order.orderId.eq(orderIdBN));
352
- }
353
- getOrderByUserId(userOrderId) {
354
- var _a;
355
- return (_a = this.getUserAccount()) === null || _a === void 0 ? void 0 : _a.orders.find((order) => order.userOrderId === userOrderId);
356
- }
357
- async deposit(amount, bankIndex, collateralAccountPublicKey, userId, reduceOnly = false) {
358
- const depositCollateralIx = await this.getDepositInstruction(amount, bankIndex, collateralAccountPublicKey, userId, reduceOnly, true);
359
- const tx = new web3_js_1.Transaction().add(depositCollateralIx);
360
- const { txSig } = await this.txSender.send(tx);
361
- return txSig;
362
- }
363
- async getDepositInstruction(amount, bankIndex, userTokenAccount, userId, reduceOnly = false, userInitialized = true) {
364
- const userAccountPublicKey = userId
365
- ? await (0, pda_1.getUserAccountPublicKey)(this.program.programId, this.wallet.publicKey, userId)
366
- : await this.getUserAccountPublicKey();
367
- let remainingAccounts = [];
368
- if (userInitialized) {
369
- remainingAccounts = this.getRemainingAccounts({
370
- writableBankIndex: bankIndex,
371
- });
372
- }
373
- else {
374
- const bankAccount = this.getBankAccount(bankIndex);
375
- if (!bankAccount.oracle.equals(web3_js_1.PublicKey.default)) {
376
- remainingAccounts.push({
377
- pubkey: bankAccount.oracle,
378
- isSigner: false,
379
- isWritable: false,
380
- });
381
- }
382
- remainingAccounts.push({
383
- pubkey: bankAccount.pubkey,
384
- isSigner: false,
385
- isWritable: true,
386
- });
387
- }
388
- const bank = this.getBankAccount(bankIndex);
389
- return await this.program.instruction.deposit(bankIndex, amount, reduceOnly, {
390
- accounts: {
391
- state: await this.getStatePublicKey(),
392
- bank: bank.pubkey,
393
- bankVault: bank.vault,
394
- user: userAccountPublicKey,
395
- userTokenAccount: userTokenAccount,
396
- authority: this.wallet.publicKey,
397
- tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
398
- },
399
- remainingAccounts,
400
- });
401
- }
402
- /**
403
- * Creates the Clearing House User account for a user, and deposits some initial collateral
404
- * @param userId
405
- * @param name
406
- * @param amount
407
- * @param userTokenAccount
408
- * @param fromUserId
409
- * @returns
410
- */
411
- async initializeUserAccountAndDepositCollateral(amount, userTokenAccount, bankIndex = new anchor_1.BN(0), userId = 0, name = userName_1.DEFAULT_USER_NAME, fromUserId) {
412
- const [userAccountPublicKey, initializeUserAccountIx] = await this.getInitializeUserInstructions(userId, name);
413
- const depositCollateralIx = fromUserId != null
414
- ? await this.getTransferDepositIx(amount, bankIndex, fromUserId, userId)
415
- : await this.getDepositInstruction(amount, bankIndex, userTokenAccount, userId, false, false);
416
- const tx = new web3_js_1.Transaction()
417
- .add(initializeUserAccountIx)
418
- .add(depositCollateralIx);
419
- const { txSig } = await this.txSender.send(tx, []);
420
- return [txSig, userAccountPublicKey];
421
- }
422
- async initializeUserAccountForDevnet(userId = 0, name = userName_1.DEFAULT_USER_NAME, bankIndex, tokenFaucet, amount) {
423
- const [associateTokenPublicKey, createAssociatedAccountIx, mintToIx] = await tokenFaucet.createAssociatedTokenAccountAndMintToInstructions(this.wallet.publicKey, amount);
424
- const [userAccountPublicKey, initializeUserAccountIx] = await this.getInitializeUserInstructions(userId, name);
425
- const depositCollateralIx = await this.getDepositInstruction(amount, bankIndex, associateTokenPublicKey, userId, false, false);
426
- const tx = new web3_js_1.Transaction()
427
- .add(createAssociatedAccountIx)
428
- .add(mintToIx)
429
- .add(initializeUserAccountIx)
430
- .add(depositCollateralIx);
431
- const txSig = await this.program.provider.sendAndConfirm(tx, []);
432
- return [txSig, userAccountPublicKey];
433
- }
434
- async withdraw(amount, bankIndex, userTokenAccount, reduceOnly = false) {
435
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getWithdrawIx(amount, bankIndex, userTokenAccount, reduceOnly)), [], this.opts);
436
- return txSig;
437
- }
438
- async getWithdrawIx(amount, bankIndex, userTokenAccount, reduceOnly = false) {
439
- const userAccountPublicKey = await this.getUserAccountPublicKey();
440
- const remainingAccounts = this.getRemainingAccounts({
441
- writableBankIndex: bankIndex,
442
- });
443
- const bank = this.getBankAccount(bankIndex);
444
- return await this.program.instruction.withdraw(bankIndex, amount, reduceOnly, {
445
- accounts: {
446
- state: await this.getStatePublicKey(),
447
- bank: bank.pubkey,
448
- bankVault: bank.vault,
449
- bankVaultAuthority: bank.vaultAuthority,
450
- user: userAccountPublicKey,
451
- userTokenAccount: userTokenAccount,
452
- authority: this.wallet.publicKey,
453
- tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
454
- },
455
- remainingAccounts,
456
- });
457
- }
458
- async transferDeposit(amount, bankIndex, fromUserId, toUserId) {
459
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getTransferDepositIx(amount, bankIndex, fromUserId, toUserId)), [], this.opts);
460
- return txSig;
461
- }
462
- async getTransferDepositIx(amount, bankIndex, fromUserId, toUserId) {
463
- const fromUser = await (0, pda_1.getUserAccountPublicKey)(this.program.programId, this.wallet.publicKey, fromUserId);
464
- const toUser = await (0, pda_1.getUserAccountPublicKey)(this.program.programId, this.wallet.publicKey, toUserId);
465
- const remainingAccounts = this.getRemainingAccounts({
466
- writableBankIndex: bankIndex,
467
- });
468
- return await this.program.instruction.transferDeposit(bankIndex, amount, {
469
- accounts: {
470
- authority: this.wallet.publicKey,
471
- fromUser,
472
- toUser,
473
- state: await this.getStatePublicKey(),
474
- },
475
- remainingAccounts,
476
- });
477
- }
478
- async updateBankCumulativeInterest(bankIndex) {
479
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.updateBankCumulativeInterestIx(bankIndex)), [], this.opts);
480
- return txSig;
481
- }
482
- async updateBankCumulativeInterestIx(bankIndex) {
483
- const bank = this.getBankAccount(bankIndex);
484
- return await this.program.instruction.updateBankCumulativeInterest({
485
- accounts: {
486
- bank: bank.pubkey,
487
- },
488
- });
489
- }
490
- async openPosition(direction, amount, marketIndex, limitPrice) {
491
- return await this.placeAndTake({
492
- orderType: types_1.OrderType.MARKET,
493
- marketIndex,
494
- direction,
495
- baseAssetAmount: amount,
496
- price: limitPrice,
497
- });
498
- }
499
- async placeOrder(orderParams) {
500
- const { txSig, slot } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getPlaceOrderIx(orderParams)), [], this.opts);
501
- this.marketLastSlotCache.set(orderParams.marketIndex.toNumber(), slot);
502
- return txSig;
503
- }
504
- getOrderParams(optionalOrderParams) {
505
- return Object.assign({}, types_1.DefaultOrderParams, optionalOrderParams);
506
- }
507
- async getPlaceOrderIx(orderParams) {
508
- orderParams = this.getOrderParams(orderParams);
509
- const userAccountPublicKey = await this.getUserAccountPublicKey();
510
- const remainingAccounts = this.getRemainingAccounts({
511
- writableMarketIndex: orderParams.marketIndex,
512
- });
513
- return await this.program.instruction.placeOrder(orderParams, {
514
- accounts: {
515
- state: await this.getStatePublicKey(),
516
- user: userAccountPublicKey,
517
- authority: this.wallet.publicKey,
518
- },
519
- remainingAccounts,
520
- });
521
- }
522
- async updateAMMs(marketIndexes) {
523
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getUpdateAMMsIx(marketIndexes)), [], this.opts);
524
- return txSig;
525
- }
526
- async getUpdateAMMsIx(marketIndexes) {
527
- for (let i = marketIndexes.length; i < 5; i++) {
528
- marketIndexes.push(new anchor_1.BN(100));
529
- }
530
- const marketAccountInfos = [];
531
- const oracleAccountInfos = [];
532
- for (const marketIndex of marketIndexes) {
533
- if (!marketIndex.eq(new anchor_1.BN(100))) {
534
- const market = this.getMarketAccount(marketIndex);
535
- marketAccountInfos.push({
536
- pubkey: market.pubkey,
537
- isWritable: true,
538
- isSigner: false,
539
- });
540
- oracleAccountInfos.push({
541
- pubkey: market.amm.oracle,
542
- isWritable: false,
543
- isSigner: false,
544
- });
545
- }
546
- }
547
- const remainingAccounts = oracleAccountInfos.concat(marketAccountInfos);
548
- return await this.program.instruction.updateAmms(marketIndexes, {
549
- accounts: {
550
- state: await this.getStatePublicKey(),
551
- authority: this.wallet.publicKey,
552
- },
553
- remainingAccounts,
554
- });
555
- }
556
- async cancelOrder(orderId) {
557
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getCancelOrderIx(orderId)), [], this.opts);
558
- return txSig;
559
- }
560
- async getCancelOrderIx(orderId) {
561
- const userAccountPublicKey = await this.getUserAccountPublicKey();
562
- const remainingAccounts = this.getRemainingAccounts({});
563
- return await this.program.instruction.cancelOrder(orderId !== null && orderId !== void 0 ? orderId : null, {
564
- accounts: {
565
- state: await this.getStatePublicKey(),
566
- user: userAccountPublicKey,
567
- authority: this.wallet.publicKey,
568
- },
569
- remainingAccounts,
570
- });
571
- }
572
- async cancelOrderByUserId(userOrderId) {
573
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getCancelOrderByUserIdIx(userOrderId)), [], this.opts);
574
- return txSig;
575
- }
576
- async getCancelOrderByUserIdIx(userOrderId) {
577
- const userAccountPublicKey = await this.getUserAccountPublicKey();
578
- const order = this.getOrderByUserId(userOrderId);
579
- const oracle = this.getMarketAccount(order.marketIndex).amm.oracle;
580
- const remainingAccounts = this.getRemainingAccounts({});
581
- return await this.program.instruction.cancelOrderByUserId(userOrderId, {
582
- accounts: {
583
- state: await this.getStatePublicKey(),
584
- user: userAccountPublicKey,
585
- authority: this.wallet.publicKey,
586
- oracle,
587
- },
588
- remainingAccounts,
589
- });
590
- }
591
- async fillOrder(userAccountPublicKey, user, order, makerInfo) {
592
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getFillOrderIx(userAccountPublicKey, user, order, makerInfo)), [], this.opts);
593
- return txSig;
594
- }
595
- async getFillOrderIx(userAccountPublicKey, userAccount, order, makerInfo) {
596
- const fillerPublicKey = await this.getUserAccountPublicKey();
597
- const marketIndex = order.marketIndex;
598
- const marketAccount = this.getMarketAccount(marketIndex);
599
- const oracleAccountMap = new Map();
600
- const bankAccountMap = new Map();
601
- const marketAccountMap = new Map();
602
- marketAccountMap.set(marketIndex.toNumber(), {
603
- pubkey: marketAccount.pubkey,
604
- isWritable: true,
605
- isSigner: false,
606
- });
607
- oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
608
- pubkey: marketAccount.amm.oracle,
609
- isWritable: false,
610
- isSigner: false,
611
- });
612
- for (const bankBalance of userAccount.bankBalances) {
613
- if (!bankBalance.balance.eq(numericConstants_1.ZERO)) {
614
- const bankAccount = this.getBankAccount(bankBalance.bankIndex);
615
- bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
616
- pubkey: bankAccount.pubkey,
617
- isSigner: false,
618
- isWritable: true,
619
- });
620
- if (!bankAccount.oracle.equals(web3_js_1.PublicKey.default)) {
621
- oracleAccountMap.set(bankAccount.oracle.toString(), {
622
- pubkey: bankAccount.oracle,
623
- isSigner: false,
624
- isWritable: false,
625
- });
626
- }
627
- }
628
- }
629
- for (const position of userAccount.positions) {
630
- if (!(0, position_1.positionIsAvailable)(position) &&
631
- !position.marketIndex.eq(order.marketIndex)) {
632
- const market = this.getMarketAccount(position.marketIndex);
633
- marketAccountMap.set(position.marketIndex.toNumber(), {
634
- pubkey: market.pubkey,
635
- isWritable: true,
636
- isSigner: false,
637
- });
638
- oracleAccountMap.set(market.amm.oracle.toString(), {
639
- pubkey: market.amm.oracle,
640
- isWritable: false,
641
- isSigner: false,
642
- });
643
- }
644
- }
645
- const remainingAccounts = [
646
- ...oracleAccountMap.values(),
647
- ...bankAccountMap.values(),
648
- ...marketAccountMap.values(),
649
- ];
650
- if (makerInfo) {
651
- remainingAccounts.push({
652
- pubkey: makerInfo.maker,
653
- isWritable: true,
654
- isSigner: false,
655
- });
656
- }
657
- const orderId = order.orderId;
658
- const makerOrderId = makerInfo ? makerInfo.order.orderId : null;
659
- return await this.program.instruction.fillOrder(orderId, makerOrderId, {
660
- accounts: {
661
- state: await this.getStatePublicKey(),
662
- filler: fillerPublicKey,
663
- user: userAccountPublicKey,
664
- authority: this.wallet.publicKey,
665
- },
666
- remainingAccounts,
667
- });
668
- }
669
- async triggerOrder(userAccountPublicKey, user, order) {
670
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getTriggerOrderIx(userAccountPublicKey, user, order)), [], this.opts);
671
- return txSig;
672
- }
673
- async getTriggerOrderIx(userAccountPublicKey, userAccount, order) {
674
- const fillerPublicKey = await this.getUserAccountPublicKey();
675
- const marketIndex = order.marketIndex;
676
- const marketAccount = this.getMarketAccount(marketIndex);
677
- const oracleAccountMap = new Map();
678
- const bankAccountMap = new Map();
679
- const marketAccountMap = new Map();
680
- marketAccountMap.set(marketIndex.toNumber(), {
681
- pubkey: marketAccount.pubkey,
682
- isWritable: true,
683
- isSigner: false,
684
- });
685
- oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
686
- pubkey: marketAccount.amm.oracle,
687
- isWritable: false,
688
- isSigner: false,
689
- });
690
- for (const bankBalance of userAccount.bankBalances) {
691
- if (!bankBalance.balance.eq(numericConstants_1.ZERO)) {
692
- const bankAccount = this.getBankAccount(bankBalance.bankIndex);
693
- bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
694
- pubkey: bankAccount.pubkey,
695
- isSigner: false,
696
- isWritable: true,
697
- });
698
- if (!bankAccount.oracle.equals(web3_js_1.PublicKey.default)) {
699
- oracleAccountMap.set(bankAccount.oracle.toString(), {
700
- pubkey: bankAccount.oracle,
701
- isSigner: false,
702
- isWritable: false,
703
- });
704
- }
705
- }
706
- }
707
- for (const position of userAccount.positions) {
708
- if (!(0, position_1.positionIsAvailable)(position) &&
709
- !position.marketIndex.eq(order.marketIndex)) {
710
- const market = this.getMarketAccount(position.marketIndex);
711
- marketAccountMap.set(position.marketIndex.toNumber(), {
712
- pubkey: market.pubkey,
713
- isWritable: true,
714
- isSigner: false,
715
- });
716
- oracleAccountMap.set(market.amm.oracle.toString(), {
717
- pubkey: market.amm.oracle,
718
- isWritable: false,
719
- isSigner: false,
720
- });
721
- }
722
- }
723
- const remainingAccounts = [
724
- ...oracleAccountMap.values(),
725
- ...bankAccountMap.values(),
726
- ...marketAccountMap.values(),
727
- ];
728
- const orderId = order.orderId;
729
- return await this.program.instruction.triggerOrder(orderId, {
730
- accounts: {
731
- state: await this.getStatePublicKey(),
732
- filler: fillerPublicKey,
733
- user: userAccountPublicKey,
734
- authority: this.wallet.publicKey,
735
- },
736
- remainingAccounts,
737
- });
738
- }
739
- async placeAndTake(orderParams, makerInfo) {
740
- const { txSig, slot } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getPlaceAndTakeIx(orderParams, makerInfo)), [], this.opts);
741
- this.marketLastSlotCache.set(orderParams.marketIndex.toNumber(), slot);
742
- return txSig;
743
- }
744
- async getPlaceAndTakeIx(orderParams, makerInfo) {
745
- orderParams = this.getOrderParams(orderParams);
746
- const userAccountPublicKey = await this.getUserAccountPublicKey();
747
- const remainingAccounts = this.getRemainingAccounts({
748
- writableMarketIndex: orderParams.marketIndex,
749
- writableBankIndex: numericConstants_1.QUOTE_ASSET_BANK_INDEX,
750
- });
751
- let makerOrderId = null;
752
- if (makerInfo) {
753
- makerOrderId = makerInfo.order.orderId;
754
- remainingAccounts.push({
755
- pubkey: makerInfo.maker,
756
- isSigner: false,
757
- isWritable: true,
758
- });
759
- }
760
- return await this.program.instruction.placeAndTake(orderParams, makerOrderId, {
761
- accounts: {
762
- state: await this.getStatePublicKey(),
763
- user: userAccountPublicKey,
764
- authority: this.wallet.publicKey,
765
- },
766
- remainingAccounts,
767
- });
768
- }
769
- async placeAndMake(orderParams, takerInfo) {
770
- const { txSig, slot } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getPlaceAndMakeIx(orderParams, takerInfo)), [], this.opts);
771
- this.marketLastSlotCache.set(orderParams.marketIndex.toNumber(), slot);
772
- return txSig;
773
- }
774
- async getPlaceAndMakeIx(orderParams, takerInfo) {
775
- orderParams = this.getOrderParams(orderParams);
776
- const userAccountPublicKey = await this.getUserAccountPublicKey();
777
- const remainingAccounts = this.getRemainingAccounts({
778
- writableMarketIndex: orderParams.marketIndex,
779
- writableBankIndex: numericConstants_1.QUOTE_ASSET_BANK_INDEX,
780
- });
781
- const takerOrderId = takerInfo.order.orderId;
782
- remainingAccounts.push({
783
- pubkey: takerInfo.taker,
784
- isSigner: false,
785
- isWritable: true,
786
- });
787
- return await this.program.instruction.placeAndMake(orderParams, takerOrderId, {
788
- accounts: {
789
- state: await this.getStatePublicKey(),
790
- user: userAccountPublicKey,
791
- taker: takerInfo.taker,
792
- authority: this.wallet.publicKey,
793
- },
794
- remainingAccounts,
795
- });
796
- }
797
- /**
798
- * Close an entire position. If you want to reduce a position, use the {@link openPosition} method in the opposite direction of the current position.
799
- * @param marketIndex
800
- * @returns
801
- */
802
- async closePosition(marketIndex) {
803
- const userPosition = this.getUser().getUserPosition(marketIndex);
804
- if (!userPosition) {
805
- throw Error(`No position in market ${marketIndex.toString()}`);
806
- }
807
- return await this.placeAndTake({
808
- orderType: types_1.OrderType.MARKET,
809
- marketIndex,
810
- direction: (0, position_1.findDirectionToClose)(userPosition),
811
- baseAssetAmount: userPosition.baseAssetAmount,
812
- reduceOnly: true,
813
- });
814
- }
815
- async settlePNLs(users, marketIndex) {
816
- const ixs = [];
817
- for (const { settleeUserAccountPublicKey, settleeUserAccount } of users) {
818
- ixs.push(await this.settlePNLIx(settleeUserAccountPublicKey, settleeUserAccount, marketIndex));
819
- }
820
- const tx = new web3_js_1.Transaction().add(...ixs);
821
- const { txSig } = await this.txSender.send(tx, [], this.opts);
822
- return txSig;
823
- }
824
- async settlePNL(settleeUserAccountPublicKey, settleeUserAccount, marketIndex) {
825
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.settlePNLIx(settleeUserAccountPublicKey, settleeUserAccount, marketIndex)), [], this.opts);
826
- return txSig;
827
- }
828
- async settlePNLIx(settleeUserAccountPublicKey, settleeUserAccount, marketIndex) {
829
- const marketAccountMap = new Map();
830
- const oracleAccountMap = new Map();
831
- const bankAccountMap = new Map();
832
- for (const position of settleeUserAccount.positions) {
833
- if (!(0, position_1.positionIsAvailable)(position)) {
834
- const market = this.getMarketAccount(position.marketIndex);
835
- marketAccountMap.set(position.marketIndex.toNumber(), {
836
- pubkey: market.pubkey,
837
- isWritable: true,
838
- isSigner: false,
839
- });
840
- oracleAccountMap.set(market.amm.oracle.toString(), {
841
- pubkey: market.amm.oracle,
842
- isWritable: false,
843
- isSigner: false,
844
- });
845
- }
846
- }
847
- for (const userBankBalance of settleeUserAccount.bankBalances) {
848
- if (!userBankBalance.balance.eq(numericConstants_1.QUOTE_ASSET_BANK_INDEX)) {
849
- const bankAccount = this.getBankAccount(userBankBalance.bankIndex);
850
- bankAccountMap.set(userBankBalance.bankIndex.toNumber(), {
851
- pubkey: bankAccount.pubkey,
852
- isSigner: false,
853
- isWritable: false,
854
- });
855
- if (!bankAccount.bankIndex.eq(numericConstants_1.ZERO)) {
856
- oracleAccountMap.set(bankAccount.oracle.toString(), {
857
- pubkey: bankAccount.oracle,
858
- isSigner: false,
859
- isWritable: false,
860
- });
861
- }
862
- }
863
- }
864
- const marketAccount = this.getMarketAccount(marketIndex.toNumber());
865
- marketAccountMap.set(marketIndex.toNumber(), {
866
- pubkey: marketAccount.pubkey,
867
- isSigner: false,
868
- isWritable: true,
869
- });
870
- oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
871
- pubkey: marketAccount.amm.oracle,
872
- isSigner: false,
873
- isWritable: false,
874
- });
875
- bankAccountMap.set(numericConstants_1.QUOTE_ASSET_BANK_INDEX.toNumber(), {
876
- pubkey: this.getBankAccount(numericConstants_1.QUOTE_ASSET_BANK_INDEX).pubkey,
877
- isSigner: false,
878
- isWritable: true,
879
- });
880
- const remainingAccounts = [
881
- ...oracleAccountMap.values(),
882
- ...bankAccountMap.values(),
883
- ...marketAccountMap.values(),
884
- ];
885
- return await this.program.instruction.settlePnl(marketIndex, {
886
- accounts: {
887
- state: await this.getStatePublicKey(),
888
- authority: this.wallet.publicKey,
889
- user: settleeUserAccountPublicKey,
890
- },
891
- remainingAccounts: remainingAccounts,
892
- });
893
- }
894
- async liquidatePerp(userAccountPublicKey, userAccount, marketIndex, maxBaseAssetAmount) {
895
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getLiquidatePerpIx(userAccountPublicKey, userAccount, marketIndex, maxBaseAssetAmount)), [], this.opts);
896
- return txSig;
897
- }
898
- async getLiquidatePerpIx(userAccountPublicKey, userAccount, marketIndex, maxBaseAssetAmount) {
899
- const liquidatorPublicKey = await this.getUserAccountPublicKey();
900
- const remainingAccounts = this.getRemainingAccountsForLiquidation({
901
- writableMarketIndex: marketIndex,
902
- userAccount,
903
- });
904
- return await this.program.instruction.liquidatePerp(marketIndex, maxBaseAssetAmount, {
905
- accounts: {
906
- state: await this.getStatePublicKey(),
907
- authority: this.wallet.publicKey,
908
- user: userAccountPublicKey,
909
- liquidator: liquidatorPublicKey,
910
- },
911
- remainingAccounts: remainingAccounts,
912
- });
913
- }
914
- async liquidateBorrow(userAccountPublicKey, userAccount, assetBankIndex, liabilityBankIndex, maxLiabilityTransfer) {
915
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getLiquidateBorrowIx(userAccountPublicKey, userAccount, assetBankIndex, liabilityBankIndex, maxLiabilityTransfer)), [], this.opts);
916
- return txSig;
917
- }
918
- async getLiquidateBorrowIx(userAccountPublicKey, userAccount, assetBankIndex, liabilityBankIndex, maxLiabilityTransfer) {
919
- const liquidatorPublicKey = await this.getUserAccountPublicKey();
920
- const remainingAccounts = this.getRemainingAccountsForLiquidation({
921
- userAccount,
922
- writableBankIndexes: [liabilityBankIndex, assetBankIndex],
923
- });
924
- return await this.program.instruction.liquidateBorrow(assetBankIndex, liabilityBankIndex, maxLiabilityTransfer, {
925
- accounts: {
926
- state: await this.getStatePublicKey(),
927
- authority: this.wallet.publicKey,
928
- user: userAccountPublicKey,
929
- liquidator: liquidatorPublicKey,
930
- },
931
- remainingAccounts: remainingAccounts,
932
- });
933
- }
934
- async liquidateBorrowForPerpPnl(userAccountPublicKey, userAccount, perpMarketIndex, liabilityBankIndex, maxLiabilityTransfer) {
935
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getLiquidateBorrowForPerpPnlIx(userAccountPublicKey, userAccount, perpMarketIndex, liabilityBankIndex, maxLiabilityTransfer)), [], this.opts);
936
- return txSig;
937
- }
938
- async getLiquidateBorrowForPerpPnlIx(userAccountPublicKey, userAccount, perpMarketIndex, liabilityBankIndex, maxLiabilityTransfer) {
939
- const liquidatorPublicKey = await this.getUserAccountPublicKey();
940
- const remainingAccounts = this.getRemainingAccountsForLiquidation({
941
- userAccount,
942
- writableMarketIndex: perpMarketIndex,
943
- writableBankIndexes: [liabilityBankIndex],
944
- });
945
- return await this.program.instruction.liquidateBorrowForPerpPnl(perpMarketIndex, liabilityBankIndex, maxLiabilityTransfer, {
946
- accounts: {
947
- state: await this.getStatePublicKey(),
948
- authority: this.wallet.publicKey,
949
- user: userAccountPublicKey,
950
- liquidator: liquidatorPublicKey,
951
- },
952
- remainingAccounts: remainingAccounts,
953
- });
954
- }
955
- async liquidatePerpPnlForDeposit(userAccountPublicKey, userAccount, perpMarketIndex, assetBankIndex, maxPnlTransfer) {
956
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getLiquidatePerpPnlForDepositIx(userAccountPublicKey, userAccount, perpMarketIndex, assetBankIndex, maxPnlTransfer)), [], this.opts);
957
- return txSig;
958
- }
959
- async getLiquidatePerpPnlForDepositIx(userAccountPublicKey, userAccount, perpMarketIndex, assetBankIndex, maxPnlTransfer) {
960
- const liquidatorPublicKey = await this.getUserAccountPublicKey();
961
- const remainingAccounts = this.getRemainingAccountsForLiquidation({
962
- userAccount,
963
- writableMarketIndex: perpMarketIndex,
964
- writableBankIndexes: [assetBankIndex],
965
- });
966
- return await this.program.instruction.liquidatePerpPnlForDeposit(perpMarketIndex, assetBankIndex, maxPnlTransfer, {
967
- accounts: {
968
- state: await this.getStatePublicKey(),
969
- authority: this.wallet.publicKey,
970
- user: userAccountPublicKey,
971
- liquidator: liquidatorPublicKey,
972
- },
973
- remainingAccounts: remainingAccounts,
974
- });
975
- }
976
- getRemainingAccountsForLiquidation(params) {
977
- const liquidateeUserAccount = params.userAccount;
978
- const oracleAccountMap = new Map();
979
- const bankAccountMap = new Map();
980
- const marketAccountMap = new Map();
981
- for (const bankBalance of liquidateeUserAccount.bankBalances) {
982
- if (!bankBalance.balance.eq(numericConstants_1.ZERO)) {
983
- const bankAccount = this.getBankAccount(bankBalance.bankIndex);
984
- bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
985
- pubkey: bankAccount.pubkey,
986
- isSigner: false,
987
- isWritable: false,
988
- });
989
- if (!bankAccount.oracle.equals(web3_js_1.PublicKey.default)) {
990
- oracleAccountMap.set(bankAccount.oracle.toString(), {
991
- pubkey: bankAccount.oracle,
992
- isSigner: false,
993
- isWritable: false,
994
- });
995
- }
996
- }
997
- }
998
- for (const position of liquidateeUserAccount.positions) {
999
- if (!(0, position_1.positionIsAvailable)(position)) {
1000
- const market = this.getMarketAccount(position.marketIndex);
1001
- marketAccountMap.set(position.marketIndex.toNumber(), {
1002
- pubkey: market.pubkey,
1003
- isWritable: false,
1004
- isSigner: false,
1005
- });
1006
- oracleAccountMap.set(market.amm.oracle.toString(), {
1007
- pubkey: market.amm.oracle,
1008
- isWritable: false,
1009
- isSigner: false,
1010
- });
1011
- }
1012
- }
1013
- const userAccountAndSlot = this.getUserAccountAndSlot();
1014
- if (!userAccountAndSlot) {
1015
- throw Error('No user account found. Most likely user account does not exist or failed to fetch account');
1016
- }
1017
- const { data: userAccount, slot: lastUserPositionsSlot } = userAccountAndSlot;
1018
- for (const [marketIndexNum, slot] of this.marketLastSlotCache.entries()) {
1019
- // if cache has more recent slot than user positions account slot, add market to remaining accounts
1020
- // otherwise remove from slot
1021
- if (slot > lastUserPositionsSlot) {
1022
- const marketAccount = this.getMarketAccount(marketIndexNum);
1023
- marketAccountMap.set(marketIndexNum, {
1024
- pubkey: marketAccount.pubkey,
1025
- isSigner: false,
1026
- isWritable: false,
1027
- });
1028
- oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
1029
- pubkey: marketAccount.amm.oracle,
1030
- isSigner: false,
1031
- isWritable: false,
1032
- });
1033
- }
1034
- else {
1035
- this.marketLastSlotCache.delete(marketIndexNum);
1036
- }
1037
- }
1038
- for (const bankBalance of userAccount.bankBalances) {
1039
- if (!bankBalance.balance.eq(numericConstants_1.ZERO)) {
1040
- const bankAccount = this.getBankAccount(bankBalance.bankIndex);
1041
- bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
1042
- pubkey: bankAccount.pubkey,
1043
- isSigner: false,
1044
- isWritable: false,
1045
- });
1046
- if (!bankAccount.oracle.equals(web3_js_1.PublicKey.default)) {
1047
- oracleAccountMap.set(bankAccount.oracle.toString(), {
1048
- pubkey: bankAccount.oracle,
1049
- isSigner: false,
1050
- isWritable: false,
1051
- });
1052
- }
1053
- }
1054
- }
1055
- for (const position of userAccount.positions) {
1056
- if (!(0, position_1.positionIsAvailable)(position)) {
1057
- const market = this.getMarketAccount(position.marketIndex);
1058
- marketAccountMap.set(position.marketIndex.toNumber(), {
1059
- pubkey: market.pubkey,
1060
- isWritable: false,
1061
- isSigner: false,
1062
- });
1063
- oracleAccountMap.set(market.amm.oracle.toString(), {
1064
- pubkey: market.amm.oracle,
1065
- isWritable: false,
1066
- isSigner: false,
1067
- });
1068
- }
1069
- }
1070
- if (params.writableMarketIndex) {
1071
- const market = this.getMarketAccount(params.writableMarketIndex);
1072
- marketAccountMap.set(market.marketIndex.toNumber(), {
1073
- pubkey: market.pubkey,
1074
- isSigner: false,
1075
- isWritable: true,
1076
- });
1077
- oracleAccountMap.set(market.amm.oracle.toString(), {
1078
- pubkey: market.amm.oracle,
1079
- isSigner: false,
1080
- isWritable: false,
1081
- });
1082
- }
1083
- if (params.writableBankIndexes) {
1084
- for (const writableBankIndex of params.writableBankIndexes) {
1085
- const bank = this.getBankAccount(writableBankIndex);
1086
- bankAccountMap.set(bank.bankIndex.toNumber(), {
1087
- pubkey: bank.pubkey,
1088
- isSigner: false,
1089
- isWritable: true,
1090
- });
1091
- if (!bank.oracle.equals(web3_js_1.PublicKey.default)) {
1092
- oracleAccountMap.set(bank.oracle.toString(), {
1093
- pubkey: bank.oracle,
1094
- isSigner: false,
1095
- isWritable: false,
1096
- });
1097
- }
1098
- }
1099
- }
1100
- return [
1101
- ...oracleAccountMap.values(),
1102
- ...bankAccountMap.values(),
1103
- ...marketAccountMap.values(),
1104
- ];
1105
- }
1106
- async updateFundingRate(oracle, marketIndex) {
1107
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getUpdateFundingRateIx(oracle, marketIndex)), [], this.opts);
1108
- return txSig;
1109
- }
1110
- async getUpdateFundingRateIx(oracle, marketIndex) {
1111
- return await this.program.instruction.updateFundingRate(marketIndex, {
1112
- accounts: {
1113
- state: await this.getStatePublicKey(),
1114
- market: await (0, pda_1.getMarketPublicKey)(this.program.programId, marketIndex),
1115
- oracle: oracle,
1116
- },
1117
- });
1118
- }
1119
- async settleFundingPayment(userAccount) {
1120
- const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getSettleFundingPaymentIx(userAccount)), [], this.opts);
1121
- return txSig;
1122
- }
1123
- async getSettleFundingPaymentIx(userAccount) {
1124
- const user = (await this.program.account.user.fetch(userAccount));
1125
- const userPositions = user.positions;
1126
- const remainingAccounts = [];
1127
- for (const position of userPositions) {
1128
- if (!(0, position_1.positionIsAvailable)(position)) {
1129
- const marketPublicKey = await (0, pda_1.getMarketPublicKey)(this.program.programId, position.marketIndex);
1130
- remainingAccounts.push({
1131
- pubkey: marketPublicKey,
1132
- isWritable: false,
1133
- isSigner: false,
1134
- });
1135
- }
1136
- }
1137
- return await this.program.instruction.settleFundingPayment({
1138
- accounts: {
1139
- state: await this.getStatePublicKey(),
1140
- user: userAccount,
1141
- },
1142
- remainingAccounts,
1143
- });
1144
- }
1145
- triggerEvent(eventName, data) {
1146
- this.eventEmitter.emit(eventName, data);
1147
- }
1148
- getOracleDataForMarket(marketIndex) {
1149
- const oracleKey = this.getMarketAccount(marketIndex).amm.oracle;
1150
- const oracleData = this.getOraclePriceDataAndSlot(oracleKey).data;
1151
- return oracleData;
1152
- }
1153
- }
1154
- exports.ClearingHouse = ClearingHouse;