@drift-labs/sdk-browser 2.104.0-beta.21

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 (935) hide show
  1. package/README.md +276 -0
  2. package/VERSION +1 -0
  3. package/bun.lockb +0 -0
  4. package/get_events.ts +47 -0
  5. package/lib/browser/accounts/basicUserAccountSubscriber.d.ts +27 -0
  6. package/lib/browser/accounts/basicUserAccountSubscriber.js +38 -0
  7. package/lib/browser/accounts/bulkAccountLoader.d.ts +37 -0
  8. package/lib/browser/accounts/bulkAccountLoader.js +222 -0
  9. package/lib/browser/accounts/bulkUserStatsSubscription.d.ts +7 -0
  10. package/lib/browser/accounts/bulkUserStatsSubscription.js +21 -0
  11. package/lib/browser/accounts/bulkUserSubscription.d.ts +7 -0
  12. package/lib/browser/accounts/bulkUserSubscription.js +21 -0
  13. package/lib/browser/accounts/fetch.d.ts +6 -0
  14. package/lib/browser/accounts/fetch.js +30 -0
  15. package/lib/browser/accounts/grpcAccountSubscriber.d.ts +16 -0
  16. package/lib/browser/accounts/grpcAccountSubscriber.js +154 -0
  17. package/lib/browser/accounts/grpcDriftClientAccountSubscriber.d.ts +12 -0
  18. package/lib/browser/accounts/grpcDriftClientAccountSubscriber.js +98 -0
  19. package/lib/browser/accounts/grpcInsuranceFundStakeAccountSubscriber.d.ts +10 -0
  20. package/lib/browser/accounts/grpcInsuranceFundStakeAccountSubscriber.js +30 -0
  21. package/lib/browser/accounts/grpcProgramAccountSubscriber.d.ts +18 -0
  22. package/lib/browser/accounts/grpcProgramAccountSubscriber.js +171 -0
  23. package/lib/browser/accounts/grpcUserAccountSubscriber.d.ts +10 -0
  24. package/lib/browser/accounts/grpcUserAccountSubscriber.js +28 -0
  25. package/lib/browser/accounts/grpcUserStatsAccountSubscriber.d.ts +10 -0
  26. package/lib/browser/accounts/grpcUserStatsAccountSubscriber.js +28 -0
  27. package/lib/browser/accounts/oneShotUserAccountSubscriber.d.ts +18 -0
  28. package/lib/browser/accounts/oneShotUserAccountSubscriber.js +48 -0
  29. package/lib/browser/accounts/pollingDriftClientAccountSubscriber.d.ts +69 -0
  30. package/lib/browser/accounts/pollingDriftClientAccountSubscriber.js +418 -0
  31. package/lib/browser/accounts/pollingHighLeverageModeConfigAccountSubscriber.d.ts +29 -0
  32. package/lib/browser/accounts/pollingHighLeverageModeConfigAccountSubscriber.js +111 -0
  33. package/lib/browser/accounts/pollingInsuranceFundStakeAccountSubscriber.d.ts +29 -0
  34. package/lib/browser/accounts/pollingInsuranceFundStakeAccountSubscriber.js +110 -0
  35. package/lib/browser/accounts/pollingOracleAccountSubscriber.d.ts +27 -0
  36. package/lib/browser/accounts/pollingOracleAccountSubscriber.js +78 -0
  37. package/lib/browser/accounts/pollingTokenAccountSubscriber.d.ts +26 -0
  38. package/lib/browser/accounts/pollingTokenAccountSubscriber.js +78 -0
  39. package/lib/browser/accounts/pollingUserAccountSubscriber.d.ts +29 -0
  40. package/lib/browser/accounts/pollingUserAccountSubscriber.js +102 -0
  41. package/lib/browser/accounts/pollingUserStatsAccountSubscriber.d.ts +27 -0
  42. package/lib/browser/accounts/pollingUserStatsAccountSubscriber.js +94 -0
  43. package/lib/browser/accounts/testBulkAccountLoader.d.ts +4 -0
  44. package/lib/browser/accounts/testBulkAccountLoader.js +45 -0
  45. package/lib/browser/accounts/types.d.ts +168 -0
  46. package/lib/browser/accounts/types.js +16 -0
  47. package/lib/browser/accounts/utils.d.ts +8 -0
  48. package/lib/browser/accounts/utils.js +49 -0
  49. package/lib/browser/accounts/webSocketAccountSubscriber.d.ts +29 -0
  50. package/lib/browser/accounts/webSocketAccountSubscriber.js +149 -0
  51. package/lib/browser/accounts/webSocketDriftClientAccountSubscriber.d.ts +66 -0
  52. package/lib/browser/accounts/webSocketDriftClientAccountSubscriber.js +358 -0
  53. package/lib/browser/accounts/webSocketHighLeverageModeConfigAccountSubscriber.d.ts +23 -0
  54. package/lib/browser/accounts/webSocketHighLeverageModeConfigAccountSubscriber.js +69 -0
  55. package/lib/browser/accounts/webSocketInsuranceFundStakeAccountSubscriber.d.ts +23 -0
  56. package/lib/browser/accounts/webSocketInsuranceFundStakeAccountSubscriber.js +67 -0
  57. package/lib/browser/accounts/webSocketProgramAccountSubscriber.d.ts +32 -0
  58. package/lib/browser/accounts/webSocketProgramAccountSubscriber.js +120 -0
  59. package/lib/browser/accounts/webSocketUserAccountSubscriber.d.ts +23 -0
  60. package/lib/browser/accounts/webSocketUserAccountSubscriber.js +61 -0
  61. package/lib/browser/accounts/webSocketUserStatsAccountSubsriber.d.ts +22 -0
  62. package/lib/browser/accounts/webSocketUserStatsAccountSubsriber.js +52 -0
  63. package/lib/browser/addresses/marketAddresses.d.ts +2 -0
  64. package/lib/browser/addresses/marketAddresses.js +15 -0
  65. package/lib/browser/addresses/pda.d.ts +32 -0
  66. package/lib/browser/addresses/pda.js +211 -0
  67. package/lib/browser/adminClient.d.ts +206 -0
  68. package/lib/browser/adminClient.js +1858 -0
  69. package/lib/browser/assert/assert.d.ts +1 -0
  70. package/lib/browser/assert/assert.js +9 -0
  71. package/lib/browser/auctionSubscriber/auctionSubscriber.d.ts +14 -0
  72. package/lib/browser/auctionSubscriber/auctionSubscriber.js +32 -0
  73. package/lib/browser/auctionSubscriber/auctionSubscriberGrpc.d.ts +15 -0
  74. package/lib/browser/auctionSubscriber/auctionSubscriberGrpc.js +32 -0
  75. package/lib/browser/auctionSubscriber/index.d.ts +3 -0
  76. package/lib/browser/auctionSubscriber/index.js +19 -0
  77. package/lib/browser/auctionSubscriber/types.d.ts +14 -0
  78. package/lib/browser/auctionSubscriber/types.js +2 -0
  79. package/lib/browser/bankrun/bankrunConnection.d.ts +75 -0
  80. package/lib/browser/bankrun/bankrunConnection.js +332 -0
  81. package/lib/browser/blockhashSubscriber/BlockhashSubscriber.d.ts +27 -0
  82. package/lib/browser/blockhashSubscriber/BlockhashSubscriber.js +89 -0
  83. package/lib/browser/blockhashSubscriber/index.d.ts +1 -0
  84. package/lib/browser/blockhashSubscriber/index.js +17 -0
  85. package/lib/browser/blockhashSubscriber/types.d.ts +7 -0
  86. package/lib/browser/blockhashSubscriber/types.js +2 -0
  87. package/lib/browser/clock/clockSubscriber.d.ts +31 -0
  88. package/lib/browser/clock/clockSubscriber.js +80 -0
  89. package/lib/browser/config.d.ts +60 -0
  90. package/lib/browser/config.js +130 -0
  91. package/lib/browser/constants/numericConstants.d.ts +71 -0
  92. package/lib/browser/constants/numericConstants.js +75 -0
  93. package/lib/browser/constants/perpMarkets.d.ts +19 -0
  94. package/lib/browser/constants/perpMarkets.js +997 -0
  95. package/lib/browser/constants/spotMarkets.d.ts +24 -0
  96. package/lib/browser/constants/spotMarkets.js +470 -0
  97. package/lib/browser/constants/txConstants.d.ts +1 -0
  98. package/lib/browser/constants/txConstants.js +4 -0
  99. package/lib/browser/decode/phoenix.d.ts +7 -0
  100. package/lib/browser/decode/phoenix.js +159 -0
  101. package/lib/browser/decode/user.d.ts +4 -0
  102. package/lib/browser/decode/user.js +339 -0
  103. package/lib/browser/dlob/DLOB.d.ts +186 -0
  104. package/lib/browser/dlob/DLOB.js +1039 -0
  105. package/lib/browser/dlob/DLOBNode.d.ts +68 -0
  106. package/lib/browser/dlob/DLOBNode.js +100 -0
  107. package/lib/browser/dlob/DLOBSubscriber.d.ts +54 -0
  108. package/lib/browser/dlob/DLOBSubscriber.js +139 -0
  109. package/lib/browser/dlob/NodeList.d.ts +25 -0
  110. package/lib/browser/dlob/NodeList.js +126 -0
  111. package/lib/browser/dlob/orderBookLevels.d.ts +72 -0
  112. package/lib/browser/dlob/orderBookLevels.js +438 -0
  113. package/lib/browser/dlob/types.d.ts +18 -0
  114. package/lib/browser/dlob/types.js +2 -0
  115. package/lib/browser/driftClient.d.ts +861 -0
  116. package/lib/browser/driftClient.js +4768 -0
  117. package/lib/browser/driftClientConfig.d.ts +49 -0
  118. package/lib/browser/driftClientConfig.js +2 -0
  119. package/lib/browser/events/eventList.d.ts +22 -0
  120. package/lib/browser/events/eventList.js +80 -0
  121. package/lib/browser/events/eventSubscriber.d.ts +46 -0
  122. package/lib/browser/events/eventSubscriber.js +223 -0
  123. package/lib/browser/events/eventsServerLogProvider.d.ts +21 -0
  124. package/lib/browser/events/eventsServerLogProvider.js +121 -0
  125. package/lib/browser/events/fetchLogs.d.ts +25 -0
  126. package/lib/browser/events/fetchLogs.js +99 -0
  127. package/lib/browser/events/parse.d.ts +6 -0
  128. package/lib/browser/events/parse.js +106 -0
  129. package/lib/browser/events/pollingLogProvider.d.ts +17 -0
  130. package/lib/browser/events/pollingLogProvider.js +58 -0
  131. package/lib/browser/events/sort.d.ts +2 -0
  132. package/lib/browser/events/sort.js +24 -0
  133. package/lib/browser/events/txEventCache.d.ts +24 -0
  134. package/lib/browser/events/txEventCache.js +71 -0
  135. package/lib/browser/events/types.d.ts +79 -0
  136. package/lib/browser/events/types.js +32 -0
  137. package/lib/browser/events/webSocketLogProvider.d.ts +24 -0
  138. package/lib/browser/events/webSocketLogProvider.js +96 -0
  139. package/lib/browser/factory/bigNum.d.ts +122 -0
  140. package/lib/browser/factory/bigNum.js +457 -0
  141. package/lib/browser/factory/oracleClient.d.ts +5 -0
  142. package/lib/browser/factory/oracleClient.js +56 -0
  143. package/lib/browser/idl/drift.json +14440 -0
  144. package/lib/browser/idl/openbook.json +3854 -0
  145. package/lib/browser/idl/pyth_solana_receiver.json +628 -0
  146. package/lib/browser/idl/switchboard.json +8354 -0
  147. package/lib/browser/idl/switchboard_on_demand_30.json +4546 -0
  148. package/lib/browser/idl/token_faucet.json +142 -0
  149. package/lib/browser/index.d.ts +125 -0
  150. package/lib/browser/index.js +147 -0
  151. package/lib/browser/isomorphic/grpc.browser.d.ts +1 -0
  152. package/lib/browser/isomorphic/grpc.browser.js +8 -0
  153. package/lib/browser/isomorphic/grpc.d.ts +1 -0
  154. package/lib/browser/isomorphic/grpc.js +8 -0
  155. package/lib/browser/jupiter/jupiterClient.d.ts +302 -0
  156. package/lib/browser/jupiter/jupiterClient.js +178 -0
  157. package/lib/browser/keypair.d.ts +2 -0
  158. package/lib/browser/keypair.js +28 -0
  159. package/lib/browser/marinade/index.d.ts +12 -0
  160. package/lib/browser/marinade/index.js +36 -0
  161. package/lib/browser/marinade/types.d.ts +1963 -0
  162. package/lib/browser/marinade/types.js +1965 -0
  163. package/lib/browser/math/amm.d.ts +98 -0
  164. package/lib/browser/math/amm.js +626 -0
  165. package/lib/browser/math/auction.d.ts +23 -0
  166. package/lib/browser/math/auction.js +130 -0
  167. package/lib/browser/math/bankruptcy.d.ts +2 -0
  168. package/lib/browser/math/bankruptcy.js +31 -0
  169. package/lib/browser/math/conversion.d.ts +2 -0
  170. package/lib/browser/math/conversion.js +11 -0
  171. package/lib/browser/math/exchangeStatus.d.ts +6 -0
  172. package/lib/browser/math/exchangeStatus.js +77 -0
  173. package/lib/browser/math/fuel.d.ts +6 -0
  174. package/lib/browser/math/fuel.js +55 -0
  175. package/lib/browser/math/funding.d.ts +34 -0
  176. package/lib/browser/math/funding.js +209 -0
  177. package/lib/browser/math/insurance.d.ts +7 -0
  178. package/lib/browser/math/insurance.js +73 -0
  179. package/lib/browser/math/margin.d.ts +39 -0
  180. package/lib/browser/math/margin.js +184 -0
  181. package/lib/browser/math/market.d.ts +39 -0
  182. package/lib/browser/math/market.js +163 -0
  183. package/lib/browser/math/oracles.d.ts +14 -0
  184. package/lib/browser/math/oracles.js +134 -0
  185. package/lib/browser/math/orders.d.ts +23 -0
  186. package/lib/browser/math/orders.js +216 -0
  187. package/lib/browser/math/position.d.ts +70 -0
  188. package/lib/browser/math/position.js +225 -0
  189. package/lib/browser/math/repeg.d.ts +22 -0
  190. package/lib/browser/math/repeg.js +164 -0
  191. package/lib/browser/math/spotBalance.d.ts +83 -0
  192. package/lib/browser/math/spotBalance.js +373 -0
  193. package/lib/browser/math/spotMarket.d.ts +11 -0
  194. package/lib/browser/math/spotMarket.js +49 -0
  195. package/lib/browser/math/spotPosition.d.ts +19 -0
  196. package/lib/browser/math/spotPosition.js +78 -0
  197. package/lib/browser/math/state.d.ts +5 -0
  198. package/lib/browser/math/state.js +30 -0
  199. package/lib/browser/math/superStake.d.ts +167 -0
  200. package/lib/browser/math/superStake.js +306 -0
  201. package/lib/browser/math/tiers.d.ts +4 -0
  202. package/lib/browser/math/tiers.js +52 -0
  203. package/lib/browser/math/trade.d.ts +117 -0
  204. package/lib/browser/math/trade.js +637 -0
  205. package/lib/browser/math/userStatus.d.ts +2 -0
  206. package/lib/browser/math/userStatus.js +8 -0
  207. package/lib/browser/math/utils.d.ts +23 -0
  208. package/lib/browser/math/utils.js +112 -0
  209. package/lib/browser/memcmp.d.ts +11 -0
  210. package/lib/browser/memcmp.js +99 -0
  211. package/lib/browser/openbook/openbookV2FulfillmentConfigMap.d.ts +10 -0
  212. package/lib/browser/openbook/openbookV2FulfillmentConfigMap.js +17 -0
  213. package/lib/browser/openbook/openbookV2Subscriber.d.ts +36 -0
  214. package/lib/browser/openbook/openbookV2Subscriber.js +104 -0
  215. package/lib/browser/oracles/oracleClientCache.d.ts +9 -0
  216. package/lib/browser/oracles/oracleClientCache.js +19 -0
  217. package/lib/browser/oracles/oracleId.d.ts +4 -0
  218. package/lib/browser/oracles/oracleId.js +38 -0
  219. package/lib/browser/oracles/prelaunchOracleClient.d.ts +12 -0
  220. package/lib/browser/oracles/prelaunchOracleClient.js +24 -0
  221. package/lib/browser/oracles/pythClient.d.ts +14 -0
  222. package/lib/browser/oracles/pythClient.js +51 -0
  223. package/lib/browser/oracles/pythLazerClient.d.ts +16 -0
  224. package/lib/browser/oracles/pythLazerClient.js +61 -0
  225. package/lib/browser/oracles/pythPullClient.d.ts +19 -0
  226. package/lib/browser/oracles/pythPullClient.js +60 -0
  227. package/lib/browser/oracles/quoteAssetOracleClient.d.ts +10 -0
  228. package/lib/browser/oracles/quoteAssetOracleClient.js +21 -0
  229. package/lib/browser/oracles/strictOraclePrice.d.ts +9 -0
  230. package/lib/browser/oracles/strictOraclePrice.js +17 -0
  231. package/lib/browser/oracles/switchboardClient.d.ts +12 -0
  232. package/lib/browser/oracles/switchboardClient.js +40 -0
  233. package/lib/browser/oracles/switchboardOnDemandClient.d.ts +12 -0
  234. package/lib/browser/oracles/switchboardOnDemandClient.js +32 -0
  235. package/lib/browser/oracles/types.d.ts +23 -0
  236. package/lib/browser/oracles/types.js +2 -0
  237. package/lib/browser/orderParams.d.ts +29 -0
  238. package/lib/browser/orderParams.js +44 -0
  239. package/lib/browser/orderSubscriber/OrderSubscriber.d.ts +42 -0
  240. package/lib/browser/orderSubscriber/OrderSubscriber.js +172 -0
  241. package/lib/browser/orderSubscriber/PollingSubscription.d.ts +12 -0
  242. package/lib/browser/orderSubscriber/PollingSubscription.js +23 -0
  243. package/lib/browser/orderSubscriber/WebsocketSubscription.d.ts +23 -0
  244. package/lib/browser/orderSubscriber/WebsocketSubscription.js +67 -0
  245. package/lib/browser/orderSubscriber/grpcSubscription.d.ts +22 -0
  246. package/lib/browser/orderSubscriber/grpcSubscription.js +66 -0
  247. package/lib/browser/orderSubscriber/index.d.ts +2 -0
  248. package/lib/browser/orderSubscriber/index.js +18 -0
  249. package/lib/browser/orderSubscriber/types.d.ts +34 -0
  250. package/lib/browser/orderSubscriber/types.js +2 -0
  251. package/lib/browser/phoenix/phoenixFulfillmentConfigMap.d.ts +10 -0
  252. package/lib/browser/phoenix/phoenixFulfillmentConfigMap.js +17 -0
  253. package/lib/browser/phoenix/phoenixSubscriber.d.ts +41 -0
  254. package/lib/browser/phoenix/phoenixSubscriber.js +152 -0
  255. package/lib/browser/priorityFee/averageOverSlotsStrategy.d.ts +5 -0
  256. package/lib/browser/priorityFee/averageOverSlotsStrategy.js +16 -0
  257. package/lib/browser/priorityFee/averageStrategy.d.ts +5 -0
  258. package/lib/browser/priorityFee/averageStrategy.js +11 -0
  259. package/lib/browser/priorityFee/driftPriorityFeeMethod.d.ts +13 -0
  260. package/lib/browser/priorityFee/driftPriorityFeeMethod.js +26 -0
  261. package/lib/browser/priorityFee/ewmaStrategy.d.ts +11 -0
  262. package/lib/browser/priorityFee/ewmaStrategy.js +33 -0
  263. package/lib/browser/priorityFee/heliusPriorityFeeMethod.d.ts +20 -0
  264. package/lib/browser/priorityFee/heliusPriorityFeeMethod.js +46 -0
  265. package/lib/browser/priorityFee/index.d.ts +11 -0
  266. package/lib/browser/priorityFee/index.js +27 -0
  267. package/lib/browser/priorityFee/maxOverSlotsStrategy.d.ts +5 -0
  268. package/lib/browser/priorityFee/maxOverSlotsStrategy.js +17 -0
  269. package/lib/browser/priorityFee/maxStrategy.d.ts +7 -0
  270. package/lib/browser/priorityFee/maxStrategy.js +9 -0
  271. package/lib/browser/priorityFee/priorityFeeSubscriber.d.ts +46 -0
  272. package/lib/browser/priorityFee/priorityFeeSubscriber.js +188 -0
  273. package/lib/browser/priorityFee/priorityFeeSubscriberMap.d.ts +48 -0
  274. package/lib/browser/priorityFee/priorityFeeSubscriberMap.js +88 -0
  275. package/lib/browser/priorityFee/solanaPriorityFeeMethod.d.ts +6 -0
  276. package/lib/browser/priorityFee/solanaPriorityFeeMethod.js +21 -0
  277. package/lib/browser/priorityFee/types.d.ts +31 -0
  278. package/lib/browser/priorityFee/types.js +10 -0
  279. package/lib/browser/serum/serumFulfillmentConfigMap.d.ts +10 -0
  280. package/lib/browser/serum/serumFulfillmentConfigMap.js +17 -0
  281. package/lib/browser/serum/serumSubscriber.d.ts +32 -0
  282. package/lib/browser/serum/serumSubscriber.js +107 -0
  283. package/lib/browser/serum/types.d.ts +13 -0
  284. package/lib/browser/serum/types.js +2 -0
  285. package/lib/browser/slot/SlotSubscriber.d.ts +27 -0
  286. package/lib/browser/slot/SlotSubscriber.js +71 -0
  287. package/lib/browser/slot/SlothashSubscriber.d.ts +26 -0
  288. package/lib/browser/slot/SlothashSubscriber.js +85 -0
  289. package/lib/browser/testClient.d.ts +8 -0
  290. package/lib/browser/testClient.js +23 -0
  291. package/lib/browser/token/index.d.ts +5 -0
  292. package/lib/browser/token/index.js +15 -0
  293. package/lib/browser/tokenFaucet.d.ts +41 -0
  294. package/lib/browser/tokenFaucet.js +188 -0
  295. package/lib/browser/tx/baseTxSender.d.ts +59 -0
  296. package/lib/browser/tx/baseTxSender.js +294 -0
  297. package/lib/browser/tx/blockhashFetcher/baseBlockhashFetcher.d.ts +8 -0
  298. package/lib/browser/tx/blockhashFetcher/baseBlockhashFetcher.js +13 -0
  299. package/lib/browser/tx/blockhashFetcher/cachedBlockhashFetcher.d.ts +28 -0
  300. package/lib/browser/tx/blockhashFetcher/cachedBlockhashFetcher.js +73 -0
  301. package/lib/browser/tx/blockhashFetcher/types.d.ts +4 -0
  302. package/lib/browser/tx/blockhashFetcher/types.js +2 -0
  303. package/lib/browser/tx/fastSingleTxSender.d.ts +41 -0
  304. package/lib/browser/tx/fastSingleTxSender.js +86 -0
  305. package/lib/browser/tx/forwardOnlyTxSender.d.ts +37 -0
  306. package/lib/browser/tx/forwardOnlyTxSender.js +92 -0
  307. package/lib/browser/tx/priorityFeeCalculator.d.ts +44 -0
  308. package/lib/browser/tx/priorityFeeCalculator.js +85 -0
  309. package/lib/browser/tx/reportTransactionError.d.ts +20 -0
  310. package/lib/browser/tx/reportTransactionError.js +103 -0
  311. package/lib/browser/tx/retryTxSender.d.ts +37 -0
  312. package/lib/browser/tx/retryTxSender.js +86 -0
  313. package/lib/browser/tx/txHandler.d.ts +154 -0
  314. package/lib/browser/tx/txHandler.js +453 -0
  315. package/lib/browser/tx/txParamProcessor.d.ts +25 -0
  316. package/lib/browser/tx/txParamProcessor.js +88 -0
  317. package/lib/browser/tx/types.d.ts +29 -0
  318. package/lib/browser/tx/types.js +20 -0
  319. package/lib/browser/tx/utils.d.ts +2 -0
  320. package/lib/browser/tx/utils.js +10 -0
  321. package/lib/browser/tx/whileValidTxSender.d.ts +45 -0
  322. package/lib/browser/tx/whileValidTxSender.js +167 -0
  323. package/lib/browser/types.d.ts +1385 -0
  324. package/lib/browser/types.js +366 -0
  325. package/lib/browser/user.d.ts +411 -0
  326. package/lib/browser/user.js +2151 -0
  327. package/lib/browser/userConfig.d.ts +26 -0
  328. package/lib/browser/userConfig.js +2 -0
  329. package/lib/browser/userMap/PollingSubscription.d.ts +16 -0
  330. package/lib/browser/userMap/PollingSubscription.js +30 -0
  331. package/lib/browser/userMap/WebsocketSubscription.d.ts +27 -0
  332. package/lib/browser/userMap/WebsocketSubscription.js +45 -0
  333. package/lib/browser/userMap/grpcSubscription.d.ts +27 -0
  334. package/lib/browser/userMap/grpcSubscription.js +44 -0
  335. package/lib/browser/userMap/referrerMap.d.ts +45 -0
  336. package/lib/browser/userMap/referrerMap.js +181 -0
  337. package/lib/browser/userMap/userMap.d.ts +90 -0
  338. package/lib/browser/userMap/userMap.js +467 -0
  339. package/lib/browser/userMap/userMapConfig.d.ts +39 -0
  340. package/lib/browser/userMap/userMapConfig.js +2 -0
  341. package/lib/browser/userMap/userStatsMap.d.ts +46 -0
  342. package/lib/browser/userMap/userStatsMap.js +165 -0
  343. package/lib/browser/userName.d.ts +5 -0
  344. package/lib/browser/userName.js +21 -0
  345. package/lib/browser/userStats.d.ts +22 -0
  346. package/lib/browser/userStats.js +91 -0
  347. package/lib/browser/userStatsConfig.d.ts +25 -0
  348. package/lib/browser/userStatsConfig.js +2 -0
  349. package/lib/browser/util/TransactionConfirmationManager.d.ts +16 -0
  350. package/lib/browser/util/TransactionConfirmationManager.js +174 -0
  351. package/lib/browser/util/chainClock.d.ts +17 -0
  352. package/lib/browser/util/chainClock.js +29 -0
  353. package/lib/browser/util/computeUnits.d.ts +8 -0
  354. package/lib/browser/util/computeUnits.js +48 -0
  355. package/lib/browser/util/digest.d.ts +4 -0
  356. package/lib/browser/util/digest.js +14 -0
  357. package/lib/browser/util/promiseTimeout.d.ts +1 -0
  358. package/lib/browser/util/promiseTimeout.js +14 -0
  359. package/lib/browser/util/pythOracleUtils.d.ts +17 -0
  360. package/lib/browser/util/pythOracleUtils.js +107 -0
  361. package/lib/browser/util/tps.d.ts +2 -0
  362. package/lib/browser/util/tps.js +16 -0
  363. package/lib/browser/wallet.d.ts +11 -0
  364. package/lib/browser/wallet.js +32 -0
  365. package/lib/node/accounts/basicUserAccountSubscriber.d.ts +27 -0
  366. package/lib/node/accounts/basicUserAccountSubscriber.js +38 -0
  367. package/lib/node/accounts/bulkAccountLoader.d.ts +37 -0
  368. package/lib/node/accounts/bulkAccountLoader.js +222 -0
  369. package/lib/node/accounts/bulkUserStatsSubscription.d.ts +7 -0
  370. package/lib/node/accounts/bulkUserStatsSubscription.js +21 -0
  371. package/lib/node/accounts/bulkUserSubscription.d.ts +7 -0
  372. package/lib/node/accounts/bulkUserSubscription.js +21 -0
  373. package/lib/node/accounts/fetch.d.ts +6 -0
  374. package/lib/node/accounts/fetch.js +30 -0
  375. package/lib/node/accounts/grpcAccountSubscriber.d.ts +16 -0
  376. package/lib/node/accounts/grpcAccountSubscriber.js +154 -0
  377. package/lib/node/accounts/grpcDriftClientAccountSubscriber.d.ts +12 -0
  378. package/lib/node/accounts/grpcDriftClientAccountSubscriber.js +98 -0
  379. package/lib/node/accounts/grpcInsuranceFundStakeAccountSubscriber.d.ts +10 -0
  380. package/lib/node/accounts/grpcInsuranceFundStakeAccountSubscriber.js +30 -0
  381. package/lib/node/accounts/grpcProgramAccountSubscriber.d.ts +18 -0
  382. package/lib/node/accounts/grpcProgramAccountSubscriber.js +171 -0
  383. package/lib/node/accounts/grpcUserAccountSubscriber.d.ts +10 -0
  384. package/lib/node/accounts/grpcUserAccountSubscriber.js +28 -0
  385. package/lib/node/accounts/grpcUserStatsAccountSubscriber.d.ts +10 -0
  386. package/lib/node/accounts/grpcUserStatsAccountSubscriber.js +28 -0
  387. package/lib/node/accounts/oneShotUserAccountSubscriber.d.ts +18 -0
  388. package/lib/node/accounts/oneShotUserAccountSubscriber.js +48 -0
  389. package/lib/node/accounts/pollingDriftClientAccountSubscriber.d.ts +69 -0
  390. package/lib/node/accounts/pollingDriftClientAccountSubscriber.js +418 -0
  391. package/lib/node/accounts/pollingHighLeverageModeConfigAccountSubscriber.d.ts +29 -0
  392. package/lib/node/accounts/pollingHighLeverageModeConfigAccountSubscriber.js +111 -0
  393. package/lib/node/accounts/pollingInsuranceFundStakeAccountSubscriber.d.ts +29 -0
  394. package/lib/node/accounts/pollingInsuranceFundStakeAccountSubscriber.js +110 -0
  395. package/lib/node/accounts/pollingOracleAccountSubscriber.d.ts +27 -0
  396. package/lib/node/accounts/pollingOracleAccountSubscriber.js +78 -0
  397. package/lib/node/accounts/pollingTokenAccountSubscriber.d.ts +26 -0
  398. package/lib/node/accounts/pollingTokenAccountSubscriber.js +78 -0
  399. package/lib/node/accounts/pollingUserAccountSubscriber.d.ts +29 -0
  400. package/lib/node/accounts/pollingUserAccountSubscriber.js +102 -0
  401. package/lib/node/accounts/pollingUserStatsAccountSubscriber.d.ts +27 -0
  402. package/lib/node/accounts/pollingUserStatsAccountSubscriber.js +94 -0
  403. package/lib/node/accounts/testBulkAccountLoader.d.ts +4 -0
  404. package/lib/node/accounts/testBulkAccountLoader.js +45 -0
  405. package/lib/node/accounts/types.d.ts +168 -0
  406. package/lib/node/accounts/types.js +16 -0
  407. package/lib/node/accounts/utils.d.ts +8 -0
  408. package/lib/node/accounts/utils.js +49 -0
  409. package/lib/node/accounts/webSocketAccountSubscriber.d.ts +29 -0
  410. package/lib/node/accounts/webSocketAccountSubscriber.js +149 -0
  411. package/lib/node/accounts/webSocketDriftClientAccountSubscriber.d.ts +66 -0
  412. package/lib/node/accounts/webSocketDriftClientAccountSubscriber.js +358 -0
  413. package/lib/node/accounts/webSocketHighLeverageModeConfigAccountSubscriber.d.ts +23 -0
  414. package/lib/node/accounts/webSocketHighLeverageModeConfigAccountSubscriber.js +69 -0
  415. package/lib/node/accounts/webSocketInsuranceFundStakeAccountSubscriber.d.ts +23 -0
  416. package/lib/node/accounts/webSocketInsuranceFundStakeAccountSubscriber.js +67 -0
  417. package/lib/node/accounts/webSocketProgramAccountSubscriber.d.ts +32 -0
  418. package/lib/node/accounts/webSocketProgramAccountSubscriber.js +120 -0
  419. package/lib/node/accounts/webSocketUserAccountSubscriber.d.ts +23 -0
  420. package/lib/node/accounts/webSocketUserAccountSubscriber.js +61 -0
  421. package/lib/node/accounts/webSocketUserStatsAccountSubsriber.d.ts +22 -0
  422. package/lib/node/accounts/webSocketUserStatsAccountSubsriber.js +52 -0
  423. package/lib/node/addresses/marketAddresses.d.ts +2 -0
  424. package/lib/node/addresses/marketAddresses.js +15 -0
  425. package/lib/node/addresses/pda.d.ts +32 -0
  426. package/lib/node/addresses/pda.js +211 -0
  427. package/lib/node/adminClient.d.ts +206 -0
  428. package/lib/node/adminClient.js +1858 -0
  429. package/lib/node/assert/assert.d.ts +1 -0
  430. package/lib/node/assert/assert.js +9 -0
  431. package/lib/node/auctionSubscriber/auctionSubscriber.d.ts +14 -0
  432. package/lib/node/auctionSubscriber/auctionSubscriber.js +32 -0
  433. package/lib/node/auctionSubscriber/auctionSubscriberGrpc.d.ts +15 -0
  434. package/lib/node/auctionSubscriber/auctionSubscriberGrpc.js +32 -0
  435. package/lib/node/auctionSubscriber/index.d.ts +3 -0
  436. package/lib/node/auctionSubscriber/index.js +19 -0
  437. package/lib/node/auctionSubscriber/types.d.ts +14 -0
  438. package/lib/node/auctionSubscriber/types.js +2 -0
  439. package/lib/node/bankrun/bankrunConnection.d.ts +75 -0
  440. package/lib/node/bankrun/bankrunConnection.js +332 -0
  441. package/lib/node/blockhashSubscriber/BlockhashSubscriber.d.ts +27 -0
  442. package/lib/node/blockhashSubscriber/BlockhashSubscriber.js +89 -0
  443. package/lib/node/blockhashSubscriber/index.d.ts +1 -0
  444. package/lib/node/blockhashSubscriber/index.js +17 -0
  445. package/lib/node/blockhashSubscriber/types.d.ts +7 -0
  446. package/lib/node/blockhashSubscriber/types.js +2 -0
  447. package/lib/node/clock/clockSubscriber.d.ts +31 -0
  448. package/lib/node/clock/clockSubscriber.js +80 -0
  449. package/lib/node/config.d.ts +60 -0
  450. package/lib/node/config.js +130 -0
  451. package/lib/node/constants/numericConstants.d.ts +71 -0
  452. package/lib/node/constants/numericConstants.js +75 -0
  453. package/lib/node/constants/perpMarkets.d.ts +19 -0
  454. package/lib/node/constants/perpMarkets.js +997 -0
  455. package/lib/node/constants/spotMarkets.d.ts +24 -0
  456. package/lib/node/constants/spotMarkets.js +470 -0
  457. package/lib/node/constants/txConstants.d.ts +1 -0
  458. package/lib/node/constants/txConstants.js +4 -0
  459. package/lib/node/decode/phoenix.d.ts +7 -0
  460. package/lib/node/decode/phoenix.js +159 -0
  461. package/lib/node/decode/user.d.ts +4 -0
  462. package/lib/node/decode/user.js +339 -0
  463. package/lib/node/dlob/DLOB.d.ts +186 -0
  464. package/lib/node/dlob/DLOB.js +1039 -0
  465. package/lib/node/dlob/DLOBNode.d.ts +68 -0
  466. package/lib/node/dlob/DLOBNode.js +100 -0
  467. package/lib/node/dlob/DLOBSubscriber.d.ts +54 -0
  468. package/lib/node/dlob/DLOBSubscriber.js +139 -0
  469. package/lib/node/dlob/NodeList.d.ts +25 -0
  470. package/lib/node/dlob/NodeList.js +126 -0
  471. package/lib/node/dlob/orderBookLevels.d.ts +72 -0
  472. package/lib/node/dlob/orderBookLevels.js +438 -0
  473. package/lib/node/dlob/types.d.ts +18 -0
  474. package/lib/node/dlob/types.js +2 -0
  475. package/lib/node/driftClient.d.ts +861 -0
  476. package/lib/node/driftClient.js +4768 -0
  477. package/lib/node/driftClientConfig.d.ts +49 -0
  478. package/lib/node/driftClientConfig.js +2 -0
  479. package/lib/node/events/eventList.d.ts +22 -0
  480. package/lib/node/events/eventList.js +80 -0
  481. package/lib/node/events/eventSubscriber.d.ts +46 -0
  482. package/lib/node/events/eventSubscriber.js +223 -0
  483. package/lib/node/events/eventsServerLogProvider.d.ts +21 -0
  484. package/lib/node/events/eventsServerLogProvider.js +121 -0
  485. package/lib/node/events/fetchLogs.d.ts +25 -0
  486. package/lib/node/events/fetchLogs.js +99 -0
  487. package/lib/node/events/parse.d.ts +6 -0
  488. package/lib/node/events/parse.js +106 -0
  489. package/lib/node/events/pollingLogProvider.d.ts +17 -0
  490. package/lib/node/events/pollingLogProvider.js +58 -0
  491. package/lib/node/events/sort.d.ts +2 -0
  492. package/lib/node/events/sort.js +24 -0
  493. package/lib/node/events/txEventCache.d.ts +24 -0
  494. package/lib/node/events/txEventCache.js +71 -0
  495. package/lib/node/events/types.d.ts +79 -0
  496. package/lib/node/events/types.js +32 -0
  497. package/lib/node/events/webSocketLogProvider.d.ts +24 -0
  498. package/lib/node/events/webSocketLogProvider.js +96 -0
  499. package/lib/node/factory/bigNum.d.ts +122 -0
  500. package/lib/node/factory/bigNum.js +457 -0
  501. package/lib/node/factory/oracleClient.d.ts +5 -0
  502. package/lib/node/factory/oracleClient.js +56 -0
  503. package/lib/node/idl/drift.json +14440 -0
  504. package/lib/node/idl/openbook.json +3854 -0
  505. package/lib/node/idl/pyth_solana_receiver.json +628 -0
  506. package/lib/node/idl/switchboard.json +8354 -0
  507. package/lib/node/idl/switchboard_on_demand_30.json +4546 -0
  508. package/lib/node/idl/token_faucet.json +142 -0
  509. package/lib/node/index.d.ts +125 -0
  510. package/lib/node/index.js +147 -0
  511. package/lib/node/isomorphic/grpc.browser.d.ts +1 -0
  512. package/lib/node/isomorphic/grpc.browser.js +8 -0
  513. package/lib/node/isomorphic/grpc.d.ts +1 -0
  514. package/lib/node/isomorphic/grpc.js +8 -0
  515. package/lib/node/jupiter/jupiterClient.d.ts +302 -0
  516. package/lib/node/jupiter/jupiterClient.js +178 -0
  517. package/lib/node/keypair.d.ts +2 -0
  518. package/lib/node/keypair.js +28 -0
  519. package/lib/node/marinade/index.d.ts +12 -0
  520. package/lib/node/marinade/index.js +36 -0
  521. package/lib/node/marinade/types.d.ts +1963 -0
  522. package/lib/node/marinade/types.js +1965 -0
  523. package/lib/node/math/amm.d.ts +98 -0
  524. package/lib/node/math/amm.js +626 -0
  525. package/lib/node/math/auction.d.ts +23 -0
  526. package/lib/node/math/auction.js +130 -0
  527. package/lib/node/math/bankruptcy.d.ts +2 -0
  528. package/lib/node/math/bankruptcy.js +31 -0
  529. package/lib/node/math/conversion.d.ts +2 -0
  530. package/lib/node/math/conversion.js +11 -0
  531. package/lib/node/math/exchangeStatus.d.ts +6 -0
  532. package/lib/node/math/exchangeStatus.js +77 -0
  533. package/lib/node/math/fuel.d.ts +6 -0
  534. package/lib/node/math/fuel.js +55 -0
  535. package/lib/node/math/funding.d.ts +34 -0
  536. package/lib/node/math/funding.js +209 -0
  537. package/lib/node/math/insurance.d.ts +7 -0
  538. package/lib/node/math/insurance.js +73 -0
  539. package/lib/node/math/margin.d.ts +39 -0
  540. package/lib/node/math/margin.js +184 -0
  541. package/lib/node/math/market.d.ts +39 -0
  542. package/lib/node/math/market.js +163 -0
  543. package/lib/node/math/oracles.d.ts +14 -0
  544. package/lib/node/math/oracles.js +134 -0
  545. package/lib/node/math/orders.d.ts +23 -0
  546. package/lib/node/math/orders.js +216 -0
  547. package/lib/node/math/position.d.ts +70 -0
  548. package/lib/node/math/position.js +225 -0
  549. package/lib/node/math/repeg.d.ts +22 -0
  550. package/lib/node/math/repeg.js +164 -0
  551. package/lib/node/math/spotBalance.d.ts +83 -0
  552. package/lib/node/math/spotBalance.js +373 -0
  553. package/lib/node/math/spotMarket.d.ts +11 -0
  554. package/lib/node/math/spotMarket.js +49 -0
  555. package/lib/node/math/spotPosition.d.ts +19 -0
  556. package/lib/node/math/spotPosition.js +78 -0
  557. package/lib/node/math/state.d.ts +5 -0
  558. package/lib/node/math/state.js +30 -0
  559. package/lib/node/math/superStake.d.ts +167 -0
  560. package/lib/node/math/superStake.js +306 -0
  561. package/lib/node/math/tiers.d.ts +4 -0
  562. package/lib/node/math/tiers.js +52 -0
  563. package/lib/node/math/trade.d.ts +117 -0
  564. package/lib/node/math/trade.js +637 -0
  565. package/lib/node/math/userStatus.d.ts +2 -0
  566. package/lib/node/math/userStatus.js +8 -0
  567. package/lib/node/math/utils.d.ts +23 -0
  568. package/lib/node/math/utils.js +112 -0
  569. package/lib/node/memcmp.d.ts +11 -0
  570. package/lib/node/memcmp.js +99 -0
  571. package/lib/node/openbook/openbookV2FulfillmentConfigMap.d.ts +10 -0
  572. package/lib/node/openbook/openbookV2FulfillmentConfigMap.js +17 -0
  573. package/lib/node/openbook/openbookV2Subscriber.d.ts +36 -0
  574. package/lib/node/openbook/openbookV2Subscriber.js +104 -0
  575. package/lib/node/oracles/oracleClientCache.d.ts +9 -0
  576. package/lib/node/oracles/oracleClientCache.js +19 -0
  577. package/lib/node/oracles/oracleId.d.ts +4 -0
  578. package/lib/node/oracles/oracleId.js +38 -0
  579. package/lib/node/oracles/prelaunchOracleClient.d.ts +12 -0
  580. package/lib/node/oracles/prelaunchOracleClient.js +24 -0
  581. package/lib/node/oracles/pythClient.d.ts +14 -0
  582. package/lib/node/oracles/pythClient.js +51 -0
  583. package/lib/node/oracles/pythLazerClient.d.ts +16 -0
  584. package/lib/node/oracles/pythLazerClient.js +61 -0
  585. package/lib/node/oracles/pythPullClient.d.ts +19 -0
  586. package/lib/node/oracles/pythPullClient.js +60 -0
  587. package/lib/node/oracles/quoteAssetOracleClient.d.ts +10 -0
  588. package/lib/node/oracles/quoteAssetOracleClient.js +21 -0
  589. package/lib/node/oracles/strictOraclePrice.d.ts +9 -0
  590. package/lib/node/oracles/strictOraclePrice.js +17 -0
  591. package/lib/node/oracles/switchboardClient.d.ts +12 -0
  592. package/lib/node/oracles/switchboardClient.js +40 -0
  593. package/lib/node/oracles/switchboardOnDemandClient.d.ts +12 -0
  594. package/lib/node/oracles/switchboardOnDemandClient.js +32 -0
  595. package/lib/node/oracles/types.d.ts +23 -0
  596. package/lib/node/oracles/types.js +2 -0
  597. package/lib/node/orderParams.d.ts +29 -0
  598. package/lib/node/orderParams.js +44 -0
  599. package/lib/node/orderSubscriber/OrderSubscriber.d.ts +42 -0
  600. package/lib/node/orderSubscriber/OrderSubscriber.js +172 -0
  601. package/lib/node/orderSubscriber/PollingSubscription.d.ts +12 -0
  602. package/lib/node/orderSubscriber/PollingSubscription.js +23 -0
  603. package/lib/node/orderSubscriber/WebsocketSubscription.d.ts +23 -0
  604. package/lib/node/orderSubscriber/WebsocketSubscription.js +67 -0
  605. package/lib/node/orderSubscriber/grpcSubscription.d.ts +22 -0
  606. package/lib/node/orderSubscriber/grpcSubscription.js +66 -0
  607. package/lib/node/orderSubscriber/index.d.ts +2 -0
  608. package/lib/node/orderSubscriber/index.js +18 -0
  609. package/lib/node/orderSubscriber/types.d.ts +34 -0
  610. package/lib/node/orderSubscriber/types.js +2 -0
  611. package/lib/node/phoenix/phoenixFulfillmentConfigMap.d.ts +10 -0
  612. package/lib/node/phoenix/phoenixFulfillmentConfigMap.js +17 -0
  613. package/lib/node/phoenix/phoenixSubscriber.d.ts +41 -0
  614. package/lib/node/phoenix/phoenixSubscriber.js +152 -0
  615. package/lib/node/priorityFee/averageOverSlotsStrategy.d.ts +5 -0
  616. package/lib/node/priorityFee/averageOverSlotsStrategy.js +16 -0
  617. package/lib/node/priorityFee/averageStrategy.d.ts +5 -0
  618. package/lib/node/priorityFee/averageStrategy.js +11 -0
  619. package/lib/node/priorityFee/driftPriorityFeeMethod.d.ts +13 -0
  620. package/lib/node/priorityFee/driftPriorityFeeMethod.js +26 -0
  621. package/lib/node/priorityFee/ewmaStrategy.d.ts +11 -0
  622. package/lib/node/priorityFee/ewmaStrategy.js +33 -0
  623. package/lib/node/priorityFee/heliusPriorityFeeMethod.d.ts +20 -0
  624. package/lib/node/priorityFee/heliusPriorityFeeMethod.js +46 -0
  625. package/lib/node/priorityFee/index.d.ts +11 -0
  626. package/lib/node/priorityFee/index.js +27 -0
  627. package/lib/node/priorityFee/maxOverSlotsStrategy.d.ts +5 -0
  628. package/lib/node/priorityFee/maxOverSlotsStrategy.js +17 -0
  629. package/lib/node/priorityFee/maxStrategy.d.ts +7 -0
  630. package/lib/node/priorityFee/maxStrategy.js +9 -0
  631. package/lib/node/priorityFee/priorityFeeSubscriber.d.ts +46 -0
  632. package/lib/node/priorityFee/priorityFeeSubscriber.js +188 -0
  633. package/lib/node/priorityFee/priorityFeeSubscriberMap.d.ts +48 -0
  634. package/lib/node/priorityFee/priorityFeeSubscriberMap.js +88 -0
  635. package/lib/node/priorityFee/solanaPriorityFeeMethod.d.ts +6 -0
  636. package/lib/node/priorityFee/solanaPriorityFeeMethod.js +21 -0
  637. package/lib/node/priorityFee/types.d.ts +31 -0
  638. package/lib/node/priorityFee/types.js +10 -0
  639. package/lib/node/serum/serumFulfillmentConfigMap.d.ts +10 -0
  640. package/lib/node/serum/serumFulfillmentConfigMap.js +17 -0
  641. package/lib/node/serum/serumSubscriber.d.ts +32 -0
  642. package/lib/node/serum/serumSubscriber.js +107 -0
  643. package/lib/node/serum/types.d.ts +13 -0
  644. package/lib/node/serum/types.js +2 -0
  645. package/lib/node/slot/SlotSubscriber.d.ts +27 -0
  646. package/lib/node/slot/SlotSubscriber.js +71 -0
  647. package/lib/node/slot/SlothashSubscriber.d.ts +26 -0
  648. package/lib/node/slot/SlothashSubscriber.js +85 -0
  649. package/lib/node/testClient.d.ts +8 -0
  650. package/lib/node/testClient.js +23 -0
  651. package/lib/node/token/index.d.ts +5 -0
  652. package/lib/node/token/index.js +15 -0
  653. package/lib/node/tokenFaucet.d.ts +41 -0
  654. package/lib/node/tokenFaucet.js +188 -0
  655. package/lib/node/tx/baseTxSender.d.ts +59 -0
  656. package/lib/node/tx/baseTxSender.js +294 -0
  657. package/lib/node/tx/blockhashFetcher/baseBlockhashFetcher.d.ts +8 -0
  658. package/lib/node/tx/blockhashFetcher/baseBlockhashFetcher.js +13 -0
  659. package/lib/node/tx/blockhashFetcher/cachedBlockhashFetcher.d.ts +28 -0
  660. package/lib/node/tx/blockhashFetcher/cachedBlockhashFetcher.js +73 -0
  661. package/lib/node/tx/blockhashFetcher/types.d.ts +4 -0
  662. package/lib/node/tx/blockhashFetcher/types.js +2 -0
  663. package/lib/node/tx/fastSingleTxSender.d.ts +41 -0
  664. package/lib/node/tx/fastSingleTxSender.js +86 -0
  665. package/lib/node/tx/forwardOnlyTxSender.d.ts +37 -0
  666. package/lib/node/tx/forwardOnlyTxSender.js +92 -0
  667. package/lib/node/tx/priorityFeeCalculator.d.ts +44 -0
  668. package/lib/node/tx/priorityFeeCalculator.js +85 -0
  669. package/lib/node/tx/reportTransactionError.d.ts +20 -0
  670. package/lib/node/tx/reportTransactionError.js +103 -0
  671. package/lib/node/tx/retryTxSender.d.ts +37 -0
  672. package/lib/node/tx/retryTxSender.js +86 -0
  673. package/lib/node/tx/txHandler.d.ts +154 -0
  674. package/lib/node/tx/txHandler.js +453 -0
  675. package/lib/node/tx/txParamProcessor.d.ts +25 -0
  676. package/lib/node/tx/txParamProcessor.js +88 -0
  677. package/lib/node/tx/types.d.ts +29 -0
  678. package/lib/node/tx/types.js +20 -0
  679. package/lib/node/tx/utils.d.ts +2 -0
  680. package/lib/node/tx/utils.js +10 -0
  681. package/lib/node/tx/whileValidTxSender.d.ts +45 -0
  682. package/lib/node/tx/whileValidTxSender.js +167 -0
  683. package/lib/node/types.d.ts +1385 -0
  684. package/lib/node/types.js +366 -0
  685. package/lib/node/user.d.ts +411 -0
  686. package/lib/node/user.js +2151 -0
  687. package/lib/node/userConfig.d.ts +26 -0
  688. package/lib/node/userConfig.js +2 -0
  689. package/lib/node/userMap/PollingSubscription.d.ts +16 -0
  690. package/lib/node/userMap/PollingSubscription.js +30 -0
  691. package/lib/node/userMap/WebsocketSubscription.d.ts +27 -0
  692. package/lib/node/userMap/WebsocketSubscription.js +45 -0
  693. package/lib/node/userMap/grpcSubscription.d.ts +27 -0
  694. package/lib/node/userMap/grpcSubscription.js +44 -0
  695. package/lib/node/userMap/referrerMap.d.ts +45 -0
  696. package/lib/node/userMap/referrerMap.js +181 -0
  697. package/lib/node/userMap/userMap.d.ts +90 -0
  698. package/lib/node/userMap/userMap.js +467 -0
  699. package/lib/node/userMap/userMapConfig.d.ts +39 -0
  700. package/lib/node/userMap/userMapConfig.js +2 -0
  701. package/lib/node/userMap/userStatsMap.d.ts +46 -0
  702. package/lib/node/userMap/userStatsMap.js +165 -0
  703. package/lib/node/userName.d.ts +5 -0
  704. package/lib/node/userName.js +21 -0
  705. package/lib/node/userStats.d.ts +22 -0
  706. package/lib/node/userStats.js +91 -0
  707. package/lib/node/userStatsConfig.d.ts +25 -0
  708. package/lib/node/userStatsConfig.js +2 -0
  709. package/lib/node/util/TransactionConfirmationManager.d.ts +16 -0
  710. package/lib/node/util/TransactionConfirmationManager.js +174 -0
  711. package/lib/node/util/chainClock.d.ts +17 -0
  712. package/lib/node/util/chainClock.js +29 -0
  713. package/lib/node/util/computeUnits.d.ts +8 -0
  714. package/lib/node/util/computeUnits.js +48 -0
  715. package/lib/node/util/digest.d.ts +4 -0
  716. package/lib/node/util/digest.js +14 -0
  717. package/lib/node/util/promiseTimeout.d.ts +1 -0
  718. package/lib/node/util/promiseTimeout.js +14 -0
  719. package/lib/node/util/pythOracleUtils.d.ts +17 -0
  720. package/lib/node/util/pythOracleUtils.js +107 -0
  721. package/lib/node/util/tps.d.ts +2 -0
  722. package/lib/node/util/tps.js +16 -0
  723. package/lib/node/wallet.d.ts +11 -0
  724. package/lib/node/wallet.js +32 -0
  725. package/package.json +92 -0
  726. package/scripts/postbuild.js +95 -0
  727. package/scripts/updateVersion.js +28 -0
  728. package/src/accounts/basicUserAccountSubscriber.ts +59 -0
  729. package/src/accounts/bulkAccountLoader.ts +294 -0
  730. package/src/accounts/bulkUserStatsSubscription.ts +33 -0
  731. package/src/accounts/bulkUserSubscription.ts +33 -0
  732. package/src/accounts/fetch.ts +66 -0
  733. package/src/accounts/grpcAccountSubscriber.ts +160 -0
  734. package/src/accounts/grpcDriftClientAccountSubscriber.ts +203 -0
  735. package/src/accounts/grpcInsuranceFundStakeAccountSubscriber.ts +56 -0
  736. package/src/accounts/grpcProgramAccountSubscriber.ts +190 -0
  737. package/src/accounts/grpcUserAccountSubscriber.ts +48 -0
  738. package/src/accounts/grpcUserStatsAccountSubscriber.ts +50 -0
  739. package/src/accounts/oneShotUserAccountSubscriber.ts +68 -0
  740. package/src/accounts/pollingDriftClientAccountSubscriber.ts +644 -0
  741. package/src/accounts/pollingHighLeverageModeConfigAccountSubscriber.ts +189 -0
  742. package/src/accounts/pollingInsuranceFundStakeAccountSubscriber.ts +185 -0
  743. package/src/accounts/pollingOracleAccountSubscriber.ts +125 -0
  744. package/src/accounts/pollingTokenAccountSubscriber.ts +118 -0
  745. package/src/accounts/pollingUserAccountSubscriber.ts +160 -0
  746. package/src/accounts/pollingUserStatsAccountSubscriber.ts +156 -0
  747. package/src/accounts/testBulkAccountLoader.ts +53 -0
  748. package/src/accounts/types.ts +245 -0
  749. package/src/accounts/utils.ts +62 -0
  750. package/src/accounts/webSocketAccountSubscriber.ts +205 -0
  751. package/src/accounts/webSocketDriftClientAccountSubscriber.ts +621 -0
  752. package/src/accounts/webSocketHighLeverageModeConfigAccountSubscriber.ts +131 -0
  753. package/src/accounts/webSocketInsuranceFundStakeAccountSubscriber.ts +129 -0
  754. package/src/accounts/webSocketProgramAccountSubscriber.ts +182 -0
  755. package/src/accounts/webSocketUserAccountSubscriber.ts +104 -0
  756. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +98 -0
  757. package/src/addresses/marketAddresses.ts +17 -0
  758. package/src/addresses/pda.ts +355 -0
  759. package/src/adminClient.ts +4030 -0
  760. package/src/assert/assert.ts +5 -0
  761. package/src/auctionSubscriber/auctionSubscriber.ts +66 -0
  762. package/src/auctionSubscriber/auctionSubscriberGrpc.ts +70 -0
  763. package/src/auctionSubscriber/index.ts +3 -0
  764. package/src/auctionSubscriber/types.ts +20 -0
  765. package/src/bankrun/bankrunConnection.ts +534 -0
  766. package/src/blockhashSubscriber/BlockhashSubscriber.ts +126 -0
  767. package/src/blockhashSubscriber/index.ts +1 -0
  768. package/src/blockhashSubscriber/types.ts +12 -0
  769. package/src/clock/clockSubscriber.ts +121 -0
  770. package/src/config.ts +212 -0
  771. package/src/constants/numericConstants.ts +113 -0
  772. package/src/constants/perpMarkets.ts +1084 -0
  773. package/src/constants/spotMarkets.ts +565 -0
  774. package/src/constants/txConstants.ts +1 -0
  775. package/src/decode/phoenix.ts +207 -0
  776. package/src/decode/user.ts +368 -0
  777. package/src/dlob/DLOB.ts +1897 -0
  778. package/src/dlob/DLOBNode.ts +197 -0
  779. package/src/dlob/DLOBSubscriber.ts +201 -0
  780. package/src/dlob/NodeList.ts +173 -0
  781. package/src/dlob/orderBookLevels.ts +643 -0
  782. package/src/dlob/types.ts +22 -0
  783. package/src/driftClient.ts +9032 -0
  784. package/src/driftClientConfig.ts +60 -0
  785. package/src/events/eventList.ts +97 -0
  786. package/src/events/eventSubscriber.ts +364 -0
  787. package/src/events/eventsServerLogProvider.ts +152 -0
  788. package/src/events/fetchLogs.ts +169 -0
  789. package/src/events/parse.ts +133 -0
  790. package/src/events/pollingLogProvider.ts +89 -0
  791. package/src/events/sort.ts +39 -0
  792. package/src/events/txEventCache.ts +74 -0
  793. package/src/events/types.ts +185 -0
  794. package/src/events/webSocketLogProvider.ts +121 -0
  795. package/src/factory/bigNum.ts +660 -0
  796. package/src/factory/oracleClient.ts +72 -0
  797. package/src/idl/drift.json +14440 -0
  798. package/src/idl/openbook.json +3854 -0
  799. package/src/idl/pyth.json +142 -0
  800. package/src/idl/pyth_solana_receiver.json +628 -0
  801. package/src/idl/switchboard.json +8354 -0
  802. package/src/idl/switchboard_on_demand_30.json +4546 -0
  803. package/src/idl/token_faucet.json +142 -0
  804. package/src/index.ts +127 -0
  805. package/src/isomorphic/README.md +19 -0
  806. package/src/isomorphic/grpc.browser.ts +4 -0
  807. package/src/isomorphic/grpc.node.ts +23 -0
  808. package/src/isomorphic/grpc.ts +1 -0
  809. package/src/jupiter/jupiterClient.ts +510 -0
  810. package/src/keypair.ts +24 -0
  811. package/src/marinade/idl/idl.json +1962 -0
  812. package/src/marinade/index.ts +64 -0
  813. package/src/marinade/types.ts +3925 -0
  814. package/src/math/amm.ts +1162 -0
  815. package/src/math/auction.ts +173 -0
  816. package/src/math/bankruptcy.ts +34 -0
  817. package/src/math/conversion.ts +13 -0
  818. package/src/math/exchangeStatus.ts +121 -0
  819. package/src/math/fuel.ts +70 -0
  820. package/src/math/funding.ts +342 -0
  821. package/src/math/insurance.ts +110 -0
  822. package/src/math/margin.ts +340 -0
  823. package/src/math/market.ts +336 -0
  824. package/src/math/oracles.ts +228 -0
  825. package/src/math/orders.ts +343 -0
  826. package/src/math/position.ts +324 -0
  827. package/src/math/repeg.ts +214 -0
  828. package/src/math/spotBalance.ts +630 -0
  829. package/src/math/spotMarket.ts +82 -0
  830. package/src/math/spotPosition.ts +184 -0
  831. package/src/math/state.ts +29 -0
  832. package/src/math/superStake.ts +525 -0
  833. package/src/math/tiers.ts +44 -0
  834. package/src/math/trade.ts +993 -0
  835. package/src/math/userStatus.ts +5 -0
  836. package/src/math/utils.ts +120 -0
  837. package/src/memcmp.ts +94 -0
  838. package/src/openbook/openbookV2FulfillmentConfigMap.ts +29 -0
  839. package/src/openbook/openbookV2Subscriber.ts +165 -0
  840. package/src/oracles/oracleClientCache.ts +25 -0
  841. package/src/oracles/oracleId.ts +28 -0
  842. package/src/oracles/prelaunchOracleClient.ts +37 -0
  843. package/src/oracles/pythClient.ts +85 -0
  844. package/src/oracles/pythLazerClient.ts +102 -0
  845. package/src/oracles/pythPullClient.ts +111 -0
  846. package/src/oracles/quoteAssetOracleClient.ts +25 -0
  847. package/src/oracles/strictOraclePrice.ts +19 -0
  848. package/src/oracles/switchboardClient.ts +77 -0
  849. package/src/oracles/switchboardOnDemandClient.ts +56 -0
  850. package/src/oracles/types.ts +23 -0
  851. package/src/orderParams.ts +79 -0
  852. package/src/orderSubscriber/OrderSubscriber.ts +249 -0
  853. package/src/orderSubscriber/PollingSubscription.ts +39 -0
  854. package/src/orderSubscriber/WebsocketSubscription.ts +119 -0
  855. package/src/orderSubscriber/grpcSubscription.ts +121 -0
  856. package/src/orderSubscriber/index.ts +2 -0
  857. package/src/orderSubscriber/types.ts +54 -0
  858. package/src/phoenix/phoenixFulfillmentConfigMap.ts +26 -0
  859. package/src/phoenix/phoenixSubscriber.ts +235 -0
  860. package/src/priorityFee/averageOverSlotsStrategy.ts +16 -0
  861. package/src/priorityFee/averageStrategy.ts +12 -0
  862. package/src/priorityFee/driftPriorityFeeMethod.ts +42 -0
  863. package/src/priorityFee/ewmaStrategy.ts +41 -0
  864. package/src/priorityFee/heliusPriorityFeeMethod.ts +57 -0
  865. package/src/priorityFee/index.ts +11 -0
  866. package/src/priorityFee/maxOverSlotsStrategy.ts +17 -0
  867. package/src/priorityFee/maxStrategy.ts +7 -0
  868. package/src/priorityFee/priorityFeeSubscriber.ts +251 -0
  869. package/src/priorityFee/priorityFeeSubscriberMap.ts +112 -0
  870. package/src/priorityFee/solanaPriorityFeeMethod.ts +34 -0
  871. package/src/priorityFee/types.ts +60 -0
  872. package/src/serum/serumFulfillmentConfigMap.ts +26 -0
  873. package/src/serum/serumSubscriber.ts +169 -0
  874. package/src/serum/types.ts +17 -0
  875. package/src/slot/SlotSubscriber.ts +101 -0
  876. package/src/slot/SlothashSubscriber.ts +126 -0
  877. package/src/testClient.ts +41 -0
  878. package/src/token/index.ts +13 -0
  879. package/src/tokenFaucet.ts +269 -0
  880. package/src/tx/baseTxSender.ts +477 -0
  881. package/src/tx/blockhashFetcher/baseBlockhashFetcher.ts +19 -0
  882. package/src/tx/blockhashFetcher/cachedBlockhashFetcher.ts +90 -0
  883. package/src/tx/blockhashFetcher/types.ts +5 -0
  884. package/src/tx/fastSingleTxSender.ts +142 -0
  885. package/src/tx/forwardOnlyTxSender.ts +145 -0
  886. package/src/tx/priorityFeeCalculator.ts +117 -0
  887. package/src/tx/reportTransactionError.ts +159 -0
  888. package/src/tx/retryTxSender.ts +135 -0
  889. package/src/tx/txHandler.ts +737 -0
  890. package/src/tx/txParamProcessor.ts +155 -0
  891. package/src/tx/types.ts +71 -0
  892. package/src/tx/utils.ts +11 -0
  893. package/src/tx/whileValidTxSender.ts +265 -0
  894. package/src/types.ts +1386 -0
  895. package/src/user.ts +4054 -0
  896. package/src/userConfig.ts +32 -0
  897. package/src/userMap/PollingSubscription.ts +47 -0
  898. package/src/userMap/WebsocketSubscription.ts +84 -0
  899. package/src/userMap/grpcSubscription.ts +85 -0
  900. package/src/userMap/referrerMap.ts +267 -0
  901. package/src/userMap/userMap.ts +654 -0
  902. package/src/userMap/userMapConfig.ts +63 -0
  903. package/src/userMap/userStatsMap.ts +218 -0
  904. package/src/userName.ts +21 -0
  905. package/src/userStats.ts +174 -0
  906. package/src/userStatsConfig.ts +31 -0
  907. package/src/util/TransactionConfirmationManager.ts +292 -0
  908. package/src/util/chainClock.ts +41 -0
  909. package/src/util/computeUnits.ts +65 -0
  910. package/src/util/digest.ts +11 -0
  911. package/src/util/promiseTimeout.ts +14 -0
  912. package/src/util/pythOracleUtils.ts +136 -0
  913. package/src/util/tps.ts +27 -0
  914. package/src/wallet.ts +43 -0
  915. package/tests/amm/test.ts +2092 -0
  916. package/tests/auctions/test.ts +81 -0
  917. package/tests/bn/test.ts +341 -0
  918. package/tests/ci/idl.ts +101 -0
  919. package/tests/ci/verifyConstants.ts +278 -0
  920. package/tests/decode/phoenix.ts +71 -0
  921. package/tests/decode/test.ts +266 -0
  922. package/tests/decode/userAccountBufferStrings.ts +102 -0
  923. package/tests/dlob/helpers.ts +749 -0
  924. package/tests/dlob/test.ts +6623 -0
  925. package/tests/insurance/test.ts +40 -0
  926. package/tests/spot/test.ts +226 -0
  927. package/tests/subscriber/openbook.ts +62 -0
  928. package/tests/tx/TransactionConfirmationManager.test.ts +305 -0
  929. package/tests/tx/cachedBlockhashFetcher.test.ts +96 -0
  930. package/tests/tx/priorityFeeCalculator.ts +77 -0
  931. package/tests/tx/priorityFeeStrategy.ts +95 -0
  932. package/tests/user/helpers.ts +92 -0
  933. package/tests/user/test.ts +517 -0
  934. package/tsconfig.browser.json +13 -0
  935. package/tsconfig.json +13 -0
@@ -0,0 +1,2151 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.User = void 0;
4
+ const types_1 = require("./types");
5
+ const position_1 = require("./math/position");
6
+ const numericConstants_1 = require("./constants/numericConstants");
7
+ const _1 = require(".");
8
+ const spotBalance_1 = require("./math/spotBalance");
9
+ const amm_1 = require("./math/amm");
10
+ const margin_1 = require("./math/margin");
11
+ const pollingUserAccountSubscriber_1 = require("./accounts/pollingUserAccountSubscriber");
12
+ const webSocketUserAccountSubscriber_1 = require("./accounts/webSocketUserAccountSubscriber");
13
+ const spotPosition_1 = require("./math/spotPosition");
14
+ const oracles_1 = require("./math/oracles");
15
+ const tiers_1 = require("./math/tiers");
16
+ const strictOraclePrice_1 = require("./oracles/strictOraclePrice");
17
+ const fuel_1 = require("./math/fuel");
18
+ const grpcUserAccountSubscriber_1 = require("./accounts/grpcUserAccountSubscriber");
19
+ class User {
20
+ get isSubscribed() {
21
+ return this._isSubscribed && this.accountSubscriber.isSubscribed;
22
+ }
23
+ set isSubscribed(val) {
24
+ this._isSubscribed = val;
25
+ }
26
+ constructor(config) {
27
+ var _a, _b, _c, _d, _e, _f, _g, _h;
28
+ this._isSubscribed = false;
29
+ this.driftClient = config.driftClient;
30
+ this.userAccountPublicKey = config.userAccountPublicKey;
31
+ if (((_a = config.accountSubscription) === null || _a === void 0 ? void 0 : _a.type) === 'polling') {
32
+ this.accountSubscriber = new pollingUserAccountSubscriber_1.PollingUserAccountSubscriber(config.driftClient.connection, config.userAccountPublicKey, config.accountSubscription.accountLoader, this.driftClient.program.account.user.coder.accounts.decodeUnchecked.bind(this.driftClient.program.account.user.coder.accounts));
33
+ }
34
+ else if (((_b = config.accountSubscription) === null || _b === void 0 ? void 0 : _b.type) === 'custom') {
35
+ this.accountSubscriber = config.accountSubscription.userAccountSubscriber;
36
+ }
37
+ else if (((_c = config.accountSubscription) === null || _c === void 0 ? void 0 : _c.type) === 'grpc') {
38
+ this.accountSubscriber = new grpcUserAccountSubscriber_1.grpcUserAccountSubscriber(config.accountSubscription.grpcConfigs, config.driftClient.program, config.userAccountPublicKey, {
39
+ resubTimeoutMs: (_d = config.accountSubscription) === null || _d === void 0 ? void 0 : _d.resubTimeoutMs,
40
+ logResubMessages: (_e = config.accountSubscription) === null || _e === void 0 ? void 0 : _e.logResubMessages,
41
+ });
42
+ }
43
+ else {
44
+ this.accountSubscriber = new webSocketUserAccountSubscriber_1.WebSocketUserAccountSubscriber(config.driftClient.program, config.userAccountPublicKey, {
45
+ resubTimeoutMs: (_f = config.accountSubscription) === null || _f === void 0 ? void 0 : _f.resubTimeoutMs,
46
+ logResubMessages: (_g = config.accountSubscription) === null || _g === void 0 ? void 0 : _g.logResubMessages,
47
+ }, (_h = config.accountSubscription) === null || _h === void 0 ? void 0 : _h.commitment);
48
+ }
49
+ this.eventEmitter = this.accountSubscriber.eventEmitter;
50
+ }
51
+ /**
52
+ * Subscribe to User state accounts
53
+ * @returns SusbcriptionSuccess result
54
+ */
55
+ async subscribe(userAccount) {
56
+ this.isSubscribed = await this.accountSubscriber.subscribe(userAccount);
57
+ return this.isSubscribed;
58
+ }
59
+ /**
60
+ * Forces the accountSubscriber to fetch account updates from rpc
61
+ */
62
+ async fetchAccounts() {
63
+ await this.accountSubscriber.fetch();
64
+ }
65
+ async unsubscribe() {
66
+ await this.accountSubscriber.unsubscribe();
67
+ this.isSubscribed = false;
68
+ }
69
+ getUserAccount() {
70
+ return this.accountSubscriber.getUserAccountAndSlot().data;
71
+ }
72
+ async forceGetUserAccount() {
73
+ await this.fetchAccounts();
74
+ return this.accountSubscriber.getUserAccountAndSlot().data;
75
+ }
76
+ getUserAccountAndSlot() {
77
+ return this.accountSubscriber.getUserAccountAndSlot();
78
+ }
79
+ getPerpPositionForUserAccount(userAccount, marketIndex) {
80
+ return this.getActivePerpPositionsForUserAccount(userAccount).find((position) => position.marketIndex === marketIndex);
81
+ }
82
+ /**
83
+ * Gets the user's current position for a given perp market. If the user has no position returns undefined
84
+ * @param marketIndex
85
+ * @returns userPerpPosition
86
+ */
87
+ getPerpPosition(marketIndex) {
88
+ const userAccount = this.getUserAccount();
89
+ return this.getPerpPositionForUserAccount(userAccount, marketIndex);
90
+ }
91
+ getPerpPositionAndSlot(marketIndex) {
92
+ const userAccount = this.getUserAccountAndSlot();
93
+ const perpPosition = this.getPerpPositionForUserAccount(userAccount.data, marketIndex);
94
+ return {
95
+ data: perpPosition,
96
+ slot: userAccount.slot,
97
+ };
98
+ }
99
+ getSpotPositionForUserAccount(userAccount, marketIndex) {
100
+ return userAccount.spotPositions.find((position) => position.marketIndex === marketIndex);
101
+ }
102
+ /**
103
+ * Gets the user's current position for a given spot market. If the user has no position returns undefined
104
+ * @param marketIndex
105
+ * @returns userSpotPosition
106
+ */
107
+ getSpotPosition(marketIndex) {
108
+ const userAccount = this.getUserAccount();
109
+ return this.getSpotPositionForUserAccount(userAccount, marketIndex);
110
+ }
111
+ getSpotPositionAndSlot(marketIndex) {
112
+ const userAccount = this.getUserAccountAndSlot();
113
+ const spotPosition = this.getSpotPositionForUserAccount(userAccount.data, marketIndex);
114
+ return {
115
+ data: spotPosition,
116
+ slot: userAccount.slot,
117
+ };
118
+ }
119
+ getEmptySpotPosition(marketIndex) {
120
+ return {
121
+ marketIndex,
122
+ scaledBalance: numericConstants_1.ZERO,
123
+ balanceType: _1.SpotBalanceType.DEPOSIT,
124
+ cumulativeDeposits: numericConstants_1.ZERO,
125
+ openAsks: numericConstants_1.ZERO,
126
+ openBids: numericConstants_1.ZERO,
127
+ openOrders: 0,
128
+ };
129
+ }
130
+ /**
131
+ * Returns the token amount for a given market. The spot market precision is based on the token mint decimals.
132
+ * Positive if it is a deposit, negative if it is a borrow.
133
+ *
134
+ * @param marketIndex
135
+ */
136
+ getTokenAmount(marketIndex) {
137
+ const spotPosition = this.getSpotPosition(marketIndex);
138
+ if (spotPosition === undefined) {
139
+ return numericConstants_1.ZERO;
140
+ }
141
+ const spotMarket = this.driftClient.getSpotMarketAccount(marketIndex);
142
+ return (0, _1.getSignedTokenAmount)((0, spotBalance_1.getTokenAmount)(spotPosition.scaledBalance, spotMarket, spotPosition.balanceType), spotPosition.balanceType);
143
+ }
144
+ getEmptyPosition(marketIndex) {
145
+ return {
146
+ baseAssetAmount: numericConstants_1.ZERO,
147
+ remainderBaseAssetAmount: 0,
148
+ lastCumulativeFundingRate: numericConstants_1.ZERO,
149
+ marketIndex,
150
+ quoteAssetAmount: numericConstants_1.ZERO,
151
+ quoteEntryAmount: numericConstants_1.ZERO,
152
+ quoteBreakEvenAmount: numericConstants_1.ZERO,
153
+ openOrders: 0,
154
+ openBids: numericConstants_1.ZERO,
155
+ openAsks: numericConstants_1.ZERO,
156
+ settledPnl: numericConstants_1.ZERO,
157
+ lpShares: numericConstants_1.ZERO,
158
+ lastBaseAssetAmountPerLp: numericConstants_1.ZERO,
159
+ lastQuoteAssetAmountPerLp: numericConstants_1.ZERO,
160
+ perLpBase: 0,
161
+ };
162
+ }
163
+ getClonedPosition(position) {
164
+ const clonedPosition = Object.assign({}, position);
165
+ return clonedPosition;
166
+ }
167
+ getOrderForUserAccount(userAccount, orderId) {
168
+ return userAccount.orders.find((order) => order.orderId === orderId);
169
+ }
170
+ /**
171
+ * @param orderId
172
+ * @returns Order
173
+ */
174
+ getOrder(orderId) {
175
+ const userAccount = this.getUserAccount();
176
+ return this.getOrderForUserAccount(userAccount, orderId);
177
+ }
178
+ getOrderAndSlot(orderId) {
179
+ const userAccount = this.getUserAccountAndSlot();
180
+ const order = this.getOrderForUserAccount(userAccount.data, orderId);
181
+ return {
182
+ data: order,
183
+ slot: userAccount.slot,
184
+ };
185
+ }
186
+ getOrderByUserIdForUserAccount(userAccount, userOrderId) {
187
+ return userAccount.orders.find((order) => order.userOrderId === userOrderId);
188
+ }
189
+ /**
190
+ * @param userOrderId
191
+ * @returns Order
192
+ */
193
+ getOrderByUserOrderId(userOrderId) {
194
+ const userAccount = this.getUserAccount();
195
+ return this.getOrderByUserIdForUserAccount(userAccount, userOrderId);
196
+ }
197
+ getOrderByUserOrderIdAndSlot(userOrderId) {
198
+ const userAccount = this.getUserAccountAndSlot();
199
+ const order = this.getOrderByUserIdForUserAccount(userAccount.data, userOrderId);
200
+ return {
201
+ data: order,
202
+ slot: userAccount.slot,
203
+ };
204
+ }
205
+ getOpenOrdersForUserAccount(userAccount) {
206
+ return userAccount === null || userAccount === void 0 ? void 0 : userAccount.orders.filter((order) => (0, types_1.isVariant)(order.status, 'open'));
207
+ }
208
+ getOpenOrders() {
209
+ const userAccount = this.getUserAccount();
210
+ return this.getOpenOrdersForUserAccount(userAccount);
211
+ }
212
+ getOpenOrdersAndSlot() {
213
+ const userAccount = this.getUserAccountAndSlot();
214
+ const openOrders = this.getOpenOrdersForUserAccount(userAccount.data);
215
+ return {
216
+ data: openOrders,
217
+ slot: userAccount.slot,
218
+ };
219
+ }
220
+ getUserAccountPublicKey() {
221
+ return this.userAccountPublicKey;
222
+ }
223
+ async exists() {
224
+ const userAccountRPCResponse = await this.driftClient.connection.getParsedAccountInfo(this.userAccountPublicKey);
225
+ return userAccountRPCResponse.value !== null;
226
+ }
227
+ /**
228
+ * calculates the total open bids/asks in a perp market (including lps)
229
+ * @returns : open bids
230
+ * @returns : open asks
231
+ */
232
+ getPerpBidAsks(marketIndex) {
233
+ const position = this.getPerpPosition(marketIndex);
234
+ const [lpOpenBids, lpOpenAsks] = this.getLPBidAsks(marketIndex);
235
+ const totalOpenBids = lpOpenBids.add(position.openBids);
236
+ const totalOpenAsks = lpOpenAsks.add(position.openAsks);
237
+ return [totalOpenBids, totalOpenAsks];
238
+ }
239
+ /**
240
+ * calculates the open bids and asks for an lp
241
+ * optionally pass in lpShares to see what bid/asks a user *would* take on
242
+ * @returns : lp open bids
243
+ * @returns : lp open asks
244
+ */
245
+ getLPBidAsks(marketIndex, lpShares) {
246
+ const position = this.getPerpPosition(marketIndex);
247
+ const lpSharesToCalc = lpShares !== null && lpShares !== void 0 ? lpShares : position === null || position === void 0 ? void 0 : position.lpShares;
248
+ if (!lpSharesToCalc || lpSharesToCalc.eq(numericConstants_1.ZERO)) {
249
+ return [numericConstants_1.ZERO, numericConstants_1.ZERO];
250
+ }
251
+ const market = this.driftClient.getPerpMarketAccount(marketIndex);
252
+ const [marketOpenBids, marketOpenAsks] = (0, amm_1.calculateMarketOpenBidAsk)(market.amm.baseAssetReserve, market.amm.minBaseAssetReserve, market.amm.maxBaseAssetReserve, market.amm.orderStepSize);
253
+ const lpOpenBids = marketOpenBids.mul(lpSharesToCalc).div(market.amm.sqrtK);
254
+ const lpOpenAsks = marketOpenAsks.mul(lpSharesToCalc).div(market.amm.sqrtK);
255
+ return [lpOpenBids, lpOpenAsks];
256
+ }
257
+ /**
258
+ * calculates the market position if the lp position was settled
259
+ * @returns : the settled userPosition
260
+ * @returns : the dust base asset amount (ie, < stepsize)
261
+ * @returns : pnl from settle
262
+ */
263
+ getPerpPositionWithLPSettle(marketIndex, originalPosition, burnLpShares = false, includeRemainderInBaseAmount = false) {
264
+ var _a;
265
+ originalPosition =
266
+ (_a = originalPosition !== null && originalPosition !== void 0 ? originalPosition : this.getPerpPosition(marketIndex)) !== null && _a !== void 0 ? _a : this.getEmptyPosition(marketIndex);
267
+ if (originalPosition.lpShares.eq(numericConstants_1.ZERO)) {
268
+ return [originalPosition, numericConstants_1.ZERO, numericConstants_1.ZERO];
269
+ }
270
+ const position = this.getClonedPosition(originalPosition);
271
+ const market = this.driftClient.getPerpMarketAccount(position.marketIndex);
272
+ if (market.amm.perLpBase != position.perLpBase) {
273
+ // perLpBase = 1 => per 10 LP shares, perLpBase = -1 => per 0.1 LP shares
274
+ const expoDiff = market.amm.perLpBase - position.perLpBase;
275
+ const marketPerLpRebaseScalar = new _1.BN(10 ** Math.abs(expoDiff));
276
+ if (expoDiff > 0) {
277
+ position.lastBaseAssetAmountPerLp =
278
+ position.lastBaseAssetAmountPerLp.mul(marketPerLpRebaseScalar);
279
+ position.lastQuoteAssetAmountPerLp =
280
+ position.lastQuoteAssetAmountPerLp.mul(marketPerLpRebaseScalar);
281
+ }
282
+ else {
283
+ position.lastBaseAssetAmountPerLp =
284
+ position.lastBaseAssetAmountPerLp.div(marketPerLpRebaseScalar);
285
+ position.lastQuoteAssetAmountPerLp =
286
+ position.lastQuoteAssetAmountPerLp.div(marketPerLpRebaseScalar);
287
+ }
288
+ position.perLpBase = position.perLpBase + expoDiff;
289
+ }
290
+ const nShares = position.lpShares;
291
+ // incorp unsettled funding on pre settled position
292
+ const quoteFundingPnl = (0, position_1.calculateUnsettledFundingPnl)(market, position);
293
+ let baseUnit = numericConstants_1.AMM_RESERVE_PRECISION;
294
+ if (market.amm.perLpBase == position.perLpBase) {
295
+ if (position.perLpBase >= 0 &&
296
+ position.perLpBase <= numericConstants_1.AMM_RESERVE_PRECISION_EXP.toNumber()) {
297
+ const marketPerLpRebase = new _1.BN(10 ** market.amm.perLpBase);
298
+ baseUnit = baseUnit.mul(marketPerLpRebase);
299
+ }
300
+ else if (position.perLpBase < 0 &&
301
+ position.perLpBase >= -numericConstants_1.AMM_RESERVE_PRECISION_EXP.toNumber()) {
302
+ const marketPerLpRebase = new _1.BN(10 ** Math.abs(market.amm.perLpBase));
303
+ baseUnit = baseUnit.div(marketPerLpRebase);
304
+ }
305
+ else {
306
+ throw 'cannot calc';
307
+ }
308
+ }
309
+ else {
310
+ throw 'market.amm.perLpBase != position.perLpBase';
311
+ }
312
+ const deltaBaa = market.amm.baseAssetAmountPerLp
313
+ .sub(position.lastBaseAssetAmountPerLp)
314
+ .mul(nShares)
315
+ .div(baseUnit);
316
+ const deltaQaa = market.amm.quoteAssetAmountPerLp
317
+ .sub(position.lastQuoteAssetAmountPerLp)
318
+ .mul(nShares)
319
+ .div(baseUnit);
320
+ function sign(v) {
321
+ return v.isNeg() ? new _1.BN(-1) : new _1.BN(1);
322
+ }
323
+ function standardize(amount, stepSize) {
324
+ const remainder = amount.abs().mod(stepSize).mul(sign(amount));
325
+ const standardizedAmount = amount.sub(remainder);
326
+ return [standardizedAmount, remainder];
327
+ }
328
+ const [standardizedBaa, remainderBaa] = standardize(deltaBaa, market.amm.orderStepSize);
329
+ position.remainderBaseAssetAmount += remainderBaa.toNumber();
330
+ if (Math.abs(position.remainderBaseAssetAmount) >
331
+ market.amm.orderStepSize.toNumber()) {
332
+ const [newStandardizedBaa, newRemainderBaa] = standardize(new _1.BN(position.remainderBaseAssetAmount), market.amm.orderStepSize);
333
+ position.baseAssetAmount =
334
+ position.baseAssetAmount.add(newStandardizedBaa);
335
+ position.remainderBaseAssetAmount = newRemainderBaa.toNumber();
336
+ }
337
+ let dustBaseAssetValue = numericConstants_1.ZERO;
338
+ if (burnLpShares && position.remainderBaseAssetAmount != 0) {
339
+ const oraclePriceData = this.driftClient.getOracleDataForPerpMarket(position.marketIndex);
340
+ dustBaseAssetValue = new _1.BN(Math.abs(position.remainderBaseAssetAmount))
341
+ .mul(oraclePriceData.price)
342
+ .div(numericConstants_1.AMM_RESERVE_PRECISION)
343
+ .add(numericConstants_1.ONE);
344
+ }
345
+ let updateType;
346
+ if (position.baseAssetAmount.eq(numericConstants_1.ZERO)) {
347
+ updateType = 'open';
348
+ }
349
+ else if (sign(position.baseAssetAmount).eq(sign(deltaBaa))) {
350
+ updateType = 'increase';
351
+ }
352
+ else if (position.baseAssetAmount.abs().gt(deltaBaa.abs())) {
353
+ updateType = 'reduce';
354
+ }
355
+ else if (position.baseAssetAmount.abs().eq(deltaBaa.abs())) {
356
+ updateType = 'close';
357
+ }
358
+ else {
359
+ updateType = 'flip';
360
+ }
361
+ let newQuoteEntry;
362
+ let pnl;
363
+ if (updateType == 'open' || updateType == 'increase') {
364
+ newQuoteEntry = position.quoteEntryAmount.add(deltaQaa);
365
+ pnl = numericConstants_1.ZERO;
366
+ }
367
+ else if (updateType == 'reduce' || updateType == 'close') {
368
+ newQuoteEntry = position.quoteEntryAmount.sub(position.quoteEntryAmount
369
+ .mul(deltaBaa.abs())
370
+ .div(position.baseAssetAmount.abs()));
371
+ pnl = position.quoteEntryAmount.sub(newQuoteEntry).add(deltaQaa);
372
+ }
373
+ else {
374
+ newQuoteEntry = deltaQaa.sub(deltaQaa.mul(position.baseAssetAmount.abs()).div(deltaBaa.abs()));
375
+ pnl = position.quoteEntryAmount.add(deltaQaa.sub(newQuoteEntry));
376
+ }
377
+ position.quoteEntryAmount = newQuoteEntry;
378
+ position.baseAssetAmount = position.baseAssetAmount.add(standardizedBaa);
379
+ position.quoteAssetAmount = position.quoteAssetAmount
380
+ .add(deltaQaa)
381
+ .add(quoteFundingPnl)
382
+ .sub(dustBaseAssetValue);
383
+ position.quoteBreakEvenAmount = position.quoteBreakEvenAmount
384
+ .add(deltaQaa)
385
+ .add(quoteFundingPnl)
386
+ .sub(dustBaseAssetValue);
387
+ // update open bids/asks
388
+ const [marketOpenBids, marketOpenAsks] = (0, amm_1.calculateMarketOpenBidAsk)(market.amm.baseAssetReserve, market.amm.minBaseAssetReserve, market.amm.maxBaseAssetReserve, market.amm.orderStepSize);
389
+ const lpOpenBids = marketOpenBids
390
+ .mul(position.lpShares)
391
+ .div(market.amm.sqrtK);
392
+ const lpOpenAsks = marketOpenAsks
393
+ .mul(position.lpShares)
394
+ .div(market.amm.sqrtK);
395
+ position.openBids = lpOpenBids.add(position.openBids);
396
+ position.openAsks = lpOpenAsks.add(position.openAsks);
397
+ // eliminate counting funding on settled position
398
+ if (position.baseAssetAmount.gt(numericConstants_1.ZERO)) {
399
+ position.lastCumulativeFundingRate = market.amm.cumulativeFundingRateLong;
400
+ }
401
+ else if (position.baseAssetAmount.lt(numericConstants_1.ZERO)) {
402
+ position.lastCumulativeFundingRate =
403
+ market.amm.cumulativeFundingRateShort;
404
+ }
405
+ else {
406
+ position.lastCumulativeFundingRate = numericConstants_1.ZERO;
407
+ }
408
+ const remainderBeforeRemoval = new _1.BN(position.remainderBaseAssetAmount);
409
+ if (includeRemainderInBaseAmount) {
410
+ position.baseAssetAmount = position.baseAssetAmount.add(remainderBeforeRemoval);
411
+ position.remainderBaseAssetAmount = 0;
412
+ }
413
+ return [position, remainderBeforeRemoval, pnl];
414
+ }
415
+ /**
416
+ * calculates Buying Power = free collateral / initial margin ratio
417
+ * @returns : Precision QUOTE_PRECISION
418
+ */
419
+ getPerpBuyingPower(marketIndex, collateralBuffer = numericConstants_1.ZERO) {
420
+ const perpPosition = this.getPerpPositionWithLPSettle(marketIndex, undefined, true)[0];
421
+ const perpMarket = this.driftClient.getPerpMarketAccount(marketIndex);
422
+ const oraclePriceData = this.getOracleDataForPerpMarket(marketIndex);
423
+ const worstCaseBaseAssetAmount = perpPosition
424
+ ? (0, margin_1.calculateWorstCaseBaseAssetAmount)(perpPosition, perpMarket, oraclePriceData.price)
425
+ : numericConstants_1.ZERO;
426
+ const freeCollateral = this.getFreeCollateral().sub(collateralBuffer);
427
+ return this.getPerpBuyingPowerFromFreeCollateralAndBaseAssetAmount(marketIndex, freeCollateral, worstCaseBaseAssetAmount);
428
+ }
429
+ getPerpBuyingPowerFromFreeCollateralAndBaseAssetAmount(marketIndex, freeCollateral, baseAssetAmount) {
430
+ const marginRatio = (0, _1.calculateMarketMarginRatio)(this.driftClient.getPerpMarketAccount(marketIndex), baseAssetAmount, 'Initial', this.getUserAccount().maxMarginRatio, this.isHighLeverageMode());
431
+ return freeCollateral.mul(numericConstants_1.MARGIN_PRECISION).div(new _1.BN(marginRatio));
432
+ }
433
+ /**
434
+ * calculates Free Collateral = Total collateral - margin requirement
435
+ * @returns : Precision QUOTE_PRECISION
436
+ */
437
+ getFreeCollateral(marginCategory = 'Initial') {
438
+ const totalCollateral = this.getTotalCollateral(marginCategory, true);
439
+ const marginRequirement = marginCategory === 'Initial'
440
+ ? this.getInitialMarginRequirement()
441
+ : this.getMaintenanceMarginRequirement();
442
+ const freeCollateral = totalCollateral.sub(marginRequirement);
443
+ return freeCollateral.gte(numericConstants_1.ZERO) ? freeCollateral : numericConstants_1.ZERO;
444
+ }
445
+ /**
446
+ * @returns The margin requirement of a certain type (Initial or Maintenance) in USDC. : QUOTE_PRECISION
447
+ */
448
+ getMarginRequirement(marginCategory, liquidationBuffer, strict = false, includeOpenOrders = true) {
449
+ return this.getTotalPerpPositionLiability(marginCategory, liquidationBuffer, includeOpenOrders, strict).add(this.getSpotMarketLiabilityValue(undefined, marginCategory, liquidationBuffer, includeOpenOrders, strict));
450
+ }
451
+ /**
452
+ * @returns The initial margin requirement in USDC. : QUOTE_PRECISION
453
+ */
454
+ getInitialMarginRequirement() {
455
+ return this.getMarginRequirement('Initial', undefined, true);
456
+ }
457
+ /**
458
+ * @returns The maintenance margin requirement in USDC. : QUOTE_PRECISION
459
+ */
460
+ getMaintenanceMarginRequirement() {
461
+ // if user being liq'd, can continue to be liq'd until total collateral above the margin requirement plus buffer
462
+ let liquidationBuffer = undefined;
463
+ if (this.isBeingLiquidated()) {
464
+ liquidationBuffer = new _1.BN(this.driftClient.getStateAccount().liquidationMarginBufferRatio);
465
+ }
466
+ return this.getMarginRequirement('Maintenance', liquidationBuffer);
467
+ }
468
+ getActivePerpPositionsForUserAccount(userAccount) {
469
+ return userAccount.perpPositions.filter((pos) => !pos.baseAssetAmount.eq(numericConstants_1.ZERO) ||
470
+ !pos.quoteAssetAmount.eq(numericConstants_1.ZERO) ||
471
+ !(pos.openOrders == 0) ||
472
+ !pos.lpShares.eq(numericConstants_1.ZERO));
473
+ }
474
+ getActivePerpPositions() {
475
+ const userAccount = this.getUserAccount();
476
+ return this.getActivePerpPositionsForUserAccount(userAccount);
477
+ }
478
+ getActivePerpPositionsAndSlot() {
479
+ const userAccount = this.getUserAccountAndSlot();
480
+ const positions = this.getActivePerpPositionsForUserAccount(userAccount.data);
481
+ return {
482
+ data: positions,
483
+ slot: userAccount.slot,
484
+ };
485
+ }
486
+ getActiveSpotPositionsForUserAccount(userAccount) {
487
+ return userAccount.spotPositions.filter((pos) => !(0, spotPosition_1.isSpotPositionAvailable)(pos));
488
+ }
489
+ getActiveSpotPositions() {
490
+ const userAccount = this.getUserAccount();
491
+ return this.getActiveSpotPositionsForUserAccount(userAccount);
492
+ }
493
+ getActiveSpotPositionsAndSlot() {
494
+ const userAccount = this.getUserAccountAndSlot();
495
+ const positions = this.getActiveSpotPositionsForUserAccount(userAccount.data);
496
+ return {
497
+ data: positions,
498
+ slot: userAccount.slot,
499
+ };
500
+ }
501
+ /**
502
+ * calculates unrealized position price pnl
503
+ * @returns : Precision QUOTE_PRECISION
504
+ */
505
+ getUnrealizedPNL(withFunding, marketIndex, withWeightMarginCategory, strict = false) {
506
+ return this.getActivePerpPositions()
507
+ .filter((pos) => marketIndex !== undefined ? pos.marketIndex === marketIndex : true)
508
+ .reduce((unrealizedPnl, perpPosition) => {
509
+ const market = this.driftClient.getPerpMarketAccount(perpPosition.marketIndex);
510
+ const oraclePriceData = this.getOracleDataForPerpMarket(market.marketIndex);
511
+ const quoteSpotMarket = this.driftClient.getSpotMarketAccount(market.quoteSpotMarketIndex);
512
+ const quoteOraclePriceData = this.getOracleDataForSpotMarket(market.quoteSpotMarketIndex);
513
+ if (perpPosition.lpShares.gt(numericConstants_1.ZERO)) {
514
+ perpPosition = this.getPerpPositionWithLPSettle(perpPosition.marketIndex, undefined, !!withWeightMarginCategory)[0];
515
+ }
516
+ let positionUnrealizedPnl = (0, _1.calculatePositionPNL)(market, perpPosition, withFunding, oraclePriceData);
517
+ let quotePrice;
518
+ if (strict && positionUnrealizedPnl.gt(numericConstants_1.ZERO)) {
519
+ quotePrice = _1.BN.min(quoteOraclePriceData.price, quoteSpotMarket.historicalOracleData.lastOraclePriceTwap5Min);
520
+ }
521
+ else if (strict && positionUnrealizedPnl.lt(numericConstants_1.ZERO)) {
522
+ quotePrice = _1.BN.max(quoteOraclePriceData.price, quoteSpotMarket.historicalOracleData.lastOraclePriceTwap5Min);
523
+ }
524
+ else {
525
+ quotePrice = quoteOraclePriceData.price;
526
+ }
527
+ positionUnrealizedPnl = positionUnrealizedPnl
528
+ .mul(quotePrice)
529
+ .div(numericConstants_1.PRICE_PRECISION);
530
+ if (withWeightMarginCategory !== undefined) {
531
+ if (positionUnrealizedPnl.gt(numericConstants_1.ZERO)) {
532
+ positionUnrealizedPnl = positionUnrealizedPnl
533
+ .mul((0, _1.calculateUnrealizedAssetWeight)(market, quoteSpotMarket, positionUnrealizedPnl, withWeightMarginCategory, oraclePriceData))
534
+ .div(new _1.BN(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION));
535
+ }
536
+ }
537
+ return unrealizedPnl.add(positionUnrealizedPnl);
538
+ }, numericConstants_1.ZERO);
539
+ }
540
+ /**
541
+ * calculates unrealized funding payment pnl
542
+ * @returns : Precision QUOTE_PRECISION
543
+ */
544
+ getUnrealizedFundingPNL(marketIndex) {
545
+ return this.getUserAccount()
546
+ .perpPositions.filter((pos) => marketIndex !== undefined ? pos.marketIndex === marketIndex : true)
547
+ .reduce((pnl, perpPosition) => {
548
+ const market = this.driftClient.getPerpMarketAccount(perpPosition.marketIndex);
549
+ return pnl.add((0, position_1.calculateUnsettledFundingPnl)(market, perpPosition));
550
+ }, numericConstants_1.ZERO);
551
+ }
552
+ getFuelBonus(now, includeSettled = true, includeUnsettled = true) {
553
+ const userAccount = this.getUserAccount();
554
+ const result = {
555
+ insuranceFuel: numericConstants_1.ZERO,
556
+ takerFuel: numericConstants_1.ZERO,
557
+ makerFuel: numericConstants_1.ZERO,
558
+ depositFuel: numericConstants_1.ZERO,
559
+ borrowFuel: numericConstants_1.ZERO,
560
+ positionFuel: numericConstants_1.ZERO,
561
+ };
562
+ const userStats = this.driftClient.getUserStats();
563
+ const userStatsAccount = userStats.getAccount();
564
+ if (includeSettled) {
565
+ result.takerFuel = result.takerFuel.add(new _1.BN(userStatsAccount.fuelTaker));
566
+ result.makerFuel = result.makerFuel.add(new _1.BN(userStatsAccount.fuelMaker));
567
+ result.depositFuel = result.depositFuel.add(new _1.BN(userStatsAccount.fuelDeposits));
568
+ result.borrowFuel = result.borrowFuel.add(new _1.BN(userStatsAccount.fuelBorrows));
569
+ result.positionFuel = result.positionFuel.add(new _1.BN(userStatsAccount.fuelPositions));
570
+ }
571
+ if (includeUnsettled) {
572
+ const fuelBonusNumerator = _1.BN.max(now.sub(_1.BN.max(new _1.BN(userAccount.lastFuelBonusUpdateTs), numericConstants_1.FUEL_START_TS)), numericConstants_1.ZERO);
573
+ if (fuelBonusNumerator.gt(numericConstants_1.ZERO)) {
574
+ for (const spotPosition of this.getActiveSpotPositions()) {
575
+ const spotMarketAccount = this.driftClient.getSpotMarketAccount(spotPosition.marketIndex);
576
+ const tokenAmount = this.getTokenAmount(spotPosition.marketIndex);
577
+ const oraclePriceData = this.getOracleDataForSpotMarket(spotPosition.marketIndex);
578
+ const twap5min = (0, oracles_1.calculateLiveOracleTwap)(spotMarketAccount.historicalOracleData, oraclePriceData, now, numericConstants_1.FIVE_MINUTE // 5MIN
579
+ );
580
+ const strictOraclePrice = new strictOraclePrice_1.StrictOraclePrice(oraclePriceData.price, twap5min);
581
+ const signedTokenValue = (0, _1.getStrictTokenValue)(tokenAmount, spotMarketAccount.decimals, strictOraclePrice);
582
+ if (signedTokenValue.gt(numericConstants_1.ZERO)) {
583
+ result.depositFuel = result.depositFuel.add((0, fuel_1.calculateSpotFuelBonus)(spotMarketAccount, signedTokenValue, fuelBonusNumerator));
584
+ }
585
+ else {
586
+ result.borrowFuel = result.borrowFuel.add((0, fuel_1.calculateSpotFuelBonus)(spotMarketAccount, signedTokenValue, fuelBonusNumerator));
587
+ }
588
+ }
589
+ for (const perpPosition of this.getActivePerpPositions()) {
590
+ const oraclePriceData = this.getOracleDataForPerpMarket(perpPosition.marketIndex);
591
+ const perpMarketAccount = this.driftClient.getPerpMarketAccount(perpPosition.marketIndex);
592
+ const baseAssetValue = this.getPerpPositionValue(perpPosition.marketIndex, oraclePriceData, false);
593
+ result.positionFuel = result.positionFuel.add((0, fuel_1.calculatePerpFuelBonus)(perpMarketAccount, baseAssetValue, fuelBonusNumerator));
594
+ }
595
+ }
596
+ }
597
+ result.insuranceFuel = userStats.getInsuranceFuelBonus(now, includeSettled, includeUnsettled);
598
+ return result;
599
+ }
600
+ getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, liquidationBuffer, includeOpenOrders, strict = false, now) {
601
+ now = now || new _1.BN(new Date().getTime() / 1000);
602
+ let netQuoteValue = numericConstants_1.ZERO;
603
+ let totalAssetValue = numericConstants_1.ZERO;
604
+ let totalLiabilityValue = numericConstants_1.ZERO;
605
+ for (const spotPosition of this.getUserAccount().spotPositions) {
606
+ const countForBase = marketIndex === undefined || spotPosition.marketIndex === marketIndex;
607
+ const countForQuote = marketIndex === undefined ||
608
+ marketIndex === numericConstants_1.QUOTE_SPOT_MARKET_INDEX ||
609
+ (includeOpenOrders && spotPosition.openOrders !== 0);
610
+ if ((0, spotPosition_1.isSpotPositionAvailable)(spotPosition) ||
611
+ (!countForBase && !countForQuote)) {
612
+ continue;
613
+ }
614
+ const spotMarketAccount = this.driftClient.getSpotMarketAccount(spotPosition.marketIndex);
615
+ const oraclePriceData = this.getOracleDataForSpotMarket(spotPosition.marketIndex);
616
+ let twap5min;
617
+ if (strict) {
618
+ twap5min = (0, oracles_1.calculateLiveOracleTwap)(spotMarketAccount.historicalOracleData, oraclePriceData, now, numericConstants_1.FIVE_MINUTE // 5MIN
619
+ );
620
+ }
621
+ const strictOraclePrice = new strictOraclePrice_1.StrictOraclePrice(oraclePriceData.price, twap5min);
622
+ if (spotPosition.marketIndex === numericConstants_1.QUOTE_SPOT_MARKET_INDEX &&
623
+ countForQuote) {
624
+ const tokenAmount = (0, _1.getSignedTokenAmount)((0, spotBalance_1.getTokenAmount)(spotPosition.scaledBalance, spotMarketAccount, spotPosition.balanceType), spotPosition.balanceType);
625
+ if ((0, types_1.isVariant)(spotPosition.balanceType, 'borrow')) {
626
+ const weightedTokenValue = this.getSpotLiabilityValue(tokenAmount, strictOraclePrice, spotMarketAccount, marginCategory, liquidationBuffer).abs();
627
+ netQuoteValue = netQuoteValue.sub(weightedTokenValue);
628
+ }
629
+ else {
630
+ const weightedTokenValue = this.getSpotAssetValue(tokenAmount, strictOraclePrice, spotMarketAccount, marginCategory);
631
+ netQuoteValue = netQuoteValue.add(weightedTokenValue);
632
+ }
633
+ continue;
634
+ }
635
+ if (!includeOpenOrders && countForBase) {
636
+ if ((0, types_1.isVariant)(spotPosition.balanceType, 'borrow')) {
637
+ const tokenAmount = (0, _1.getSignedTokenAmount)((0, spotBalance_1.getTokenAmount)(spotPosition.scaledBalance, spotMarketAccount, spotPosition.balanceType), _1.SpotBalanceType.BORROW);
638
+ const liabilityValue = this.getSpotLiabilityValue(tokenAmount, strictOraclePrice, spotMarketAccount, marginCategory, liquidationBuffer).abs();
639
+ totalLiabilityValue = totalLiabilityValue.add(liabilityValue);
640
+ continue;
641
+ }
642
+ else {
643
+ const tokenAmount = (0, spotBalance_1.getTokenAmount)(spotPosition.scaledBalance, spotMarketAccount, spotPosition.balanceType);
644
+ const assetValue = this.getSpotAssetValue(tokenAmount, strictOraclePrice, spotMarketAccount, marginCategory);
645
+ totalAssetValue = totalAssetValue.add(assetValue);
646
+ continue;
647
+ }
648
+ }
649
+ const { tokenAmount: worstCaseTokenAmount, ordersValue: worstCaseQuoteTokenAmount, } = (0, spotPosition_1.getWorstCaseTokenAmounts)(spotPosition, spotMarketAccount, strictOraclePrice, marginCategory, this.getUserAccount().maxMarginRatio);
650
+ if (worstCaseTokenAmount.gt(numericConstants_1.ZERO) && countForBase) {
651
+ const baseAssetValue = this.getSpotAssetValue(worstCaseTokenAmount, strictOraclePrice, spotMarketAccount, marginCategory);
652
+ totalAssetValue = totalAssetValue.add(baseAssetValue);
653
+ }
654
+ if (worstCaseTokenAmount.lt(numericConstants_1.ZERO) && countForBase) {
655
+ const baseLiabilityValue = this.getSpotLiabilityValue(worstCaseTokenAmount, strictOraclePrice, spotMarketAccount, marginCategory, liquidationBuffer).abs();
656
+ totalLiabilityValue = totalLiabilityValue.add(baseLiabilityValue);
657
+ }
658
+ if (worstCaseQuoteTokenAmount.gt(numericConstants_1.ZERO) && countForQuote) {
659
+ netQuoteValue = netQuoteValue.add(worstCaseQuoteTokenAmount);
660
+ }
661
+ if (worstCaseQuoteTokenAmount.lt(numericConstants_1.ZERO) && countForQuote) {
662
+ let weight = numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION;
663
+ if (marginCategory === 'Initial') {
664
+ weight = _1.BN.max(weight, new _1.BN(this.getUserAccount().maxMarginRatio));
665
+ }
666
+ const weightedTokenValue = worstCaseQuoteTokenAmount
667
+ .abs()
668
+ .mul(weight)
669
+ .div(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION);
670
+ netQuoteValue = netQuoteValue.sub(weightedTokenValue);
671
+ }
672
+ totalLiabilityValue = totalLiabilityValue.add(new _1.BN(spotPosition.openOrders).mul(numericConstants_1.OPEN_ORDER_MARGIN_REQUIREMENT));
673
+ }
674
+ if (marketIndex === undefined || marketIndex === numericConstants_1.QUOTE_SPOT_MARKET_INDEX) {
675
+ if (netQuoteValue.gt(numericConstants_1.ZERO)) {
676
+ totalAssetValue = totalAssetValue.add(netQuoteValue);
677
+ }
678
+ else {
679
+ totalLiabilityValue = totalLiabilityValue.add(netQuoteValue.abs());
680
+ }
681
+ }
682
+ return { totalAssetValue, totalLiabilityValue };
683
+ }
684
+ getSpotMarketLiabilityValue(marketIndex, marginCategory, liquidationBuffer, includeOpenOrders, strict = false, now) {
685
+ const { totalLiabilityValue } = this.getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, liquidationBuffer, includeOpenOrders, strict, now);
686
+ return totalLiabilityValue;
687
+ }
688
+ getSpotLiabilityValue(tokenAmount, strictOraclePrice, spotMarketAccount, marginCategory, liquidationBuffer) {
689
+ let liabilityValue = (0, _1.getStrictTokenValue)(tokenAmount, spotMarketAccount.decimals, strictOraclePrice);
690
+ if (marginCategory !== undefined) {
691
+ let weight = (0, spotBalance_1.calculateLiabilityWeight)(tokenAmount, spotMarketAccount, marginCategory);
692
+ if (marginCategory === 'Initial' &&
693
+ spotMarketAccount.marketIndex !== numericConstants_1.QUOTE_SPOT_MARKET_INDEX) {
694
+ weight = _1.BN.max(weight, numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION.addn(this.getUserAccount().maxMarginRatio));
695
+ }
696
+ if (liquidationBuffer !== undefined) {
697
+ weight = weight.add(liquidationBuffer);
698
+ }
699
+ liabilityValue = liabilityValue
700
+ .mul(weight)
701
+ .div(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION);
702
+ }
703
+ return liabilityValue;
704
+ }
705
+ getSpotMarketAssetValue(marketIndex, marginCategory, includeOpenOrders, strict = false, now) {
706
+ const { totalAssetValue } = this.getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, undefined, includeOpenOrders, strict, now);
707
+ return totalAssetValue;
708
+ }
709
+ getSpotAssetValue(tokenAmount, strictOraclePrice, spotMarketAccount, marginCategory) {
710
+ let assetValue = (0, _1.getStrictTokenValue)(tokenAmount, spotMarketAccount.decimals, strictOraclePrice);
711
+ if (marginCategory !== undefined) {
712
+ let weight = (0, spotBalance_1.calculateAssetWeight)(tokenAmount, strictOraclePrice.current, spotMarketAccount, marginCategory);
713
+ if (marginCategory === 'Initial' &&
714
+ spotMarketAccount.marketIndex !== numericConstants_1.QUOTE_SPOT_MARKET_INDEX) {
715
+ const userCustomAssetWeight = _1.BN.max(numericConstants_1.ZERO, numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION.subn(this.getUserAccount().maxMarginRatio));
716
+ weight = _1.BN.min(weight, userCustomAssetWeight);
717
+ }
718
+ assetValue = assetValue.mul(weight).div(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION);
719
+ }
720
+ return assetValue;
721
+ }
722
+ getSpotPositionValue(marketIndex, marginCategory, includeOpenOrders, strict = false, now) {
723
+ const { totalAssetValue, totalLiabilityValue } = this.getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, undefined, includeOpenOrders, strict, now);
724
+ return totalAssetValue.sub(totalLiabilityValue);
725
+ }
726
+ getNetSpotMarketValue(withWeightMarginCategory) {
727
+ const { totalAssetValue, totalLiabilityValue } = this.getSpotMarketAssetAndLiabilityValue(undefined, withWeightMarginCategory);
728
+ return totalAssetValue.sub(totalLiabilityValue);
729
+ }
730
+ /**
731
+ * calculates TotalCollateral: collateral + unrealized pnl
732
+ * @returns : Precision QUOTE_PRECISION
733
+ */
734
+ getTotalCollateral(marginCategory = 'Initial', strict = false, includeOpenOrders = true) {
735
+ return this.getSpotMarketAssetValue(undefined, marginCategory, includeOpenOrders, strict).add(this.getUnrealizedPNL(true, undefined, marginCategory, strict));
736
+ }
737
+ /**
738
+ * calculates User Health by comparing total collateral and maint. margin requirement
739
+ * @returns : number (value from [0, 100])
740
+ */
741
+ getHealth() {
742
+ if (this.isBeingLiquidated()) {
743
+ return 0;
744
+ }
745
+ const totalCollateral = this.getTotalCollateral('Maintenance');
746
+ const maintenanceMarginReq = this.getMaintenanceMarginRequirement();
747
+ let health;
748
+ if (maintenanceMarginReq.eq(numericConstants_1.ZERO) && totalCollateral.gte(numericConstants_1.ZERO)) {
749
+ health = 100;
750
+ }
751
+ else if (totalCollateral.lte(numericConstants_1.ZERO)) {
752
+ health = 0;
753
+ }
754
+ else {
755
+ health = Math.round(Math.min(100, Math.max(0, (1 - maintenanceMarginReq.toNumber() / totalCollateral.toNumber()) *
756
+ 100)));
757
+ }
758
+ return health;
759
+ }
760
+ calculateWeightedPerpPositionLiability(perpPosition, marginCategory, liquidationBuffer, includeOpenOrders, strict = false) {
761
+ const market = this.driftClient.getPerpMarketAccount(perpPosition.marketIndex);
762
+ if (perpPosition.lpShares.gt(numericConstants_1.ZERO)) {
763
+ // is an lp, clone so we dont mutate the position
764
+ perpPosition = this.getPerpPositionWithLPSettle(market.marketIndex, this.getClonedPosition(perpPosition), !!marginCategory)[0];
765
+ }
766
+ let valuationPrice = this.getOracleDataForPerpMarket(market.marketIndex).price;
767
+ if ((0, types_1.isVariant)(market.status, 'settlement')) {
768
+ valuationPrice = market.expiryPrice;
769
+ }
770
+ let baseAssetAmount;
771
+ let liabilityValue;
772
+ if (includeOpenOrders) {
773
+ const { worstCaseBaseAssetAmount, worstCaseLiabilityValue } = (0, _1.calculateWorstCasePerpLiabilityValue)(perpPosition, market, valuationPrice);
774
+ baseAssetAmount = worstCaseBaseAssetAmount;
775
+ liabilityValue = worstCaseLiabilityValue;
776
+ }
777
+ else {
778
+ baseAssetAmount = perpPosition.baseAssetAmount;
779
+ liabilityValue = (0, _1.calculatePerpLiabilityValue)(baseAssetAmount, valuationPrice, (0, types_1.isVariant)(market.contractType, 'prediction'));
780
+ }
781
+ if (marginCategory) {
782
+ let marginRatio = new _1.BN((0, _1.calculateMarketMarginRatio)(market, baseAssetAmount.abs(), marginCategory, this.getUserAccount().maxMarginRatio, this.isHighLeverageMode()));
783
+ if (liquidationBuffer !== undefined) {
784
+ marginRatio = marginRatio.add(liquidationBuffer);
785
+ }
786
+ if ((0, types_1.isVariant)(market.status, 'settlement')) {
787
+ marginRatio = numericConstants_1.ZERO;
788
+ }
789
+ const quoteSpotMarket = this.driftClient.getSpotMarketAccount(market.quoteSpotMarketIndex);
790
+ const quoteOraclePriceData = this.driftClient.getOracleDataForSpotMarket(numericConstants_1.QUOTE_SPOT_MARKET_INDEX);
791
+ let quotePrice;
792
+ if (strict) {
793
+ quotePrice = _1.BN.max(quoteOraclePriceData.price, quoteSpotMarket.historicalOracleData.lastOraclePriceTwap5Min);
794
+ }
795
+ else {
796
+ quotePrice = quoteOraclePriceData.price;
797
+ }
798
+ liabilityValue = liabilityValue
799
+ .mul(quotePrice)
800
+ .div(numericConstants_1.PRICE_PRECISION)
801
+ .mul(marginRatio)
802
+ .div(numericConstants_1.MARGIN_PRECISION);
803
+ if (includeOpenOrders) {
804
+ liabilityValue = liabilityValue.add(new _1.BN(perpPosition.openOrders).mul(numericConstants_1.OPEN_ORDER_MARGIN_REQUIREMENT));
805
+ if (perpPosition.lpShares.gt(numericConstants_1.ZERO)) {
806
+ liabilityValue = liabilityValue.add(_1.BN.max(numericConstants_1.QUOTE_PRECISION, valuationPrice
807
+ .mul(market.amm.orderStepSize)
808
+ .mul(numericConstants_1.QUOTE_PRECISION)
809
+ .div(numericConstants_1.AMM_RESERVE_PRECISION)
810
+ .div(numericConstants_1.PRICE_PRECISION)));
811
+ }
812
+ }
813
+ }
814
+ return liabilityValue;
815
+ }
816
+ /**
817
+ * calculates position value of a single perp market in margin system
818
+ * @returns : Precision QUOTE_PRECISION
819
+ */
820
+ getPerpMarketLiabilityValue(marketIndex, marginCategory, liquidationBuffer, includeOpenOrders, strict = false) {
821
+ const perpPosition = this.getPerpPosition(marketIndex);
822
+ return this.calculateWeightedPerpPositionLiability(perpPosition, marginCategory, liquidationBuffer, includeOpenOrders, strict);
823
+ }
824
+ /**
825
+ * calculates sum of position value across all positions in margin system
826
+ * @returns : Precision QUOTE_PRECISION
827
+ */
828
+ getTotalPerpPositionLiability(marginCategory, liquidationBuffer, includeOpenOrders, strict = false) {
829
+ return this.getActivePerpPositions().reduce((totalPerpValue, perpPosition) => {
830
+ const baseAssetValue = this.calculateWeightedPerpPositionLiability(perpPosition, marginCategory, liquidationBuffer, includeOpenOrders, strict);
831
+ return totalPerpValue.add(baseAssetValue);
832
+ }, numericConstants_1.ZERO);
833
+ }
834
+ /**
835
+ * calculates position value based on oracle
836
+ * @returns : Precision QUOTE_PRECISION
837
+ */
838
+ getPerpPositionValue(marketIndex, oraclePriceData, includeOpenOrders = false) {
839
+ const userPosition = this.getPerpPositionWithLPSettle(marketIndex, undefined, false, true)[0] || this.getEmptyPosition(marketIndex);
840
+ const market = this.driftClient.getPerpMarketAccount(userPosition.marketIndex);
841
+ return (0, margin_1.calculateBaseAssetValueWithOracle)(market, userPosition, oraclePriceData, includeOpenOrders);
842
+ }
843
+ /**
844
+ * calculates position liabiltiy value in margin system
845
+ * @returns : Precision QUOTE_PRECISION
846
+ */
847
+ getPerpLiabilityValue(marketIndex, oraclePriceData, includeOpenOrders = false) {
848
+ const userPosition = this.getPerpPositionWithLPSettle(marketIndex, undefined, false, true)[0] || this.getEmptyPosition(marketIndex);
849
+ const market = this.driftClient.getPerpMarketAccount(userPosition.marketIndex);
850
+ if (includeOpenOrders) {
851
+ return (0, _1.calculateWorstCasePerpLiabilityValue)(userPosition, market, oraclePriceData.price).worstCaseLiabilityValue;
852
+ }
853
+ else {
854
+ return (0, _1.calculatePerpLiabilityValue)(userPosition.baseAssetAmount, oraclePriceData.price, (0, types_1.isVariant)(market.contractType, 'prediction'));
855
+ }
856
+ }
857
+ getPositionSide(currentPosition) {
858
+ if (currentPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
859
+ return _1.PositionDirection.LONG;
860
+ }
861
+ else if (currentPosition.baseAssetAmount.lt(numericConstants_1.ZERO)) {
862
+ return _1.PositionDirection.SHORT;
863
+ }
864
+ else {
865
+ return undefined;
866
+ }
867
+ }
868
+ /**
869
+ * calculates average exit price (optionally for closing up to 100% of position)
870
+ * @returns : Precision PRICE_PRECISION
871
+ */
872
+ getPositionEstimatedExitPriceAndPnl(position, amountToClose, useAMMClose = false) {
873
+ const market = this.driftClient.getPerpMarketAccount(position.marketIndex);
874
+ const entryPrice = (0, position_1.calculateEntryPrice)(position);
875
+ const oraclePriceData = this.getOracleDataForPerpMarket(position.marketIndex);
876
+ if (amountToClose) {
877
+ if (amountToClose.eq(numericConstants_1.ZERO)) {
878
+ return [(0, _1.calculateReservePrice)(market, oraclePriceData), numericConstants_1.ZERO];
879
+ }
880
+ position = {
881
+ baseAssetAmount: amountToClose,
882
+ lastCumulativeFundingRate: position.lastCumulativeFundingRate,
883
+ marketIndex: position.marketIndex,
884
+ quoteAssetAmount: position.quoteAssetAmount,
885
+ };
886
+ }
887
+ let baseAssetValue;
888
+ if (useAMMClose) {
889
+ baseAssetValue = (0, _1.calculateBaseAssetValue)(market, position, oraclePriceData);
890
+ }
891
+ else {
892
+ baseAssetValue = (0, margin_1.calculateBaseAssetValueWithOracle)(market, position, oraclePriceData);
893
+ }
894
+ if (position.baseAssetAmount.eq(numericConstants_1.ZERO)) {
895
+ return [numericConstants_1.ZERO, numericConstants_1.ZERO];
896
+ }
897
+ const exitPrice = baseAssetValue
898
+ .mul(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
899
+ .mul(numericConstants_1.PRICE_PRECISION)
900
+ .div(position.baseAssetAmount.abs());
901
+ const pnlPerBase = exitPrice.sub(entryPrice);
902
+ const pnl = pnlPerBase
903
+ .mul(position.baseAssetAmount)
904
+ .div(numericConstants_1.PRICE_PRECISION)
905
+ .div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
906
+ return [exitPrice, pnl];
907
+ }
908
+ /**
909
+ * calculates current user leverage which is (total liability size) / (net asset value)
910
+ * @returns : Precision TEN_THOUSAND
911
+ */
912
+ getLeverage(includeOpenOrders = true) {
913
+ return this.calculateLeverageFromComponents(this.getLeverageComponents(includeOpenOrders));
914
+ }
915
+ calculateLeverageFromComponents({ perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue, }) {
916
+ const totalLiabilityValue = perpLiabilityValue.add(spotLiabilityValue);
917
+ const totalAssetValue = spotAssetValue.add(perpPnl);
918
+ const netAssetValue = totalAssetValue.sub(spotLiabilityValue);
919
+ if (netAssetValue.eq(numericConstants_1.ZERO)) {
920
+ return numericConstants_1.ZERO;
921
+ }
922
+ return totalLiabilityValue.mul(numericConstants_1.TEN_THOUSAND).div(netAssetValue);
923
+ }
924
+ getLeverageComponents(includeOpenOrders = true, marginCategory = undefined) {
925
+ const perpLiability = this.getTotalPerpPositionLiability(marginCategory, undefined, includeOpenOrders);
926
+ const perpPnl = this.getUnrealizedPNL(true, undefined, marginCategory);
927
+ const { totalAssetValue: spotAssetValue, totalLiabilityValue: spotLiabilityValue, } = this.getSpotMarketAssetAndLiabilityValue(undefined, marginCategory, undefined, includeOpenOrders);
928
+ return {
929
+ perpLiabilityValue: perpLiability,
930
+ perpPnl,
931
+ spotAssetValue,
932
+ spotLiabilityValue,
933
+ };
934
+ }
935
+ isDustDepositPosition(spotMarketAccount) {
936
+ const marketIndex = spotMarketAccount.marketIndex;
937
+ const spotPosition = this.getSpotPosition(spotMarketAccount.marketIndex);
938
+ if ((0, spotPosition_1.isSpotPositionAvailable)(spotPosition)) {
939
+ return false;
940
+ }
941
+ const depositAmount = this.getTokenAmount(spotMarketAccount.marketIndex);
942
+ if (depositAmount.lte(numericConstants_1.ZERO)) {
943
+ return false;
944
+ }
945
+ const oraclePriceData = this.getOracleDataForSpotMarket(marketIndex);
946
+ const strictOraclePrice = new strictOraclePrice_1.StrictOraclePrice(oraclePriceData.price, oraclePriceData.twap);
947
+ const balanceValue = this.getSpotAssetValue(depositAmount, strictOraclePrice, spotMarketAccount);
948
+ if (balanceValue.lt(numericConstants_1.DUST_POSITION_SIZE)) {
949
+ return true;
950
+ }
951
+ return false;
952
+ }
953
+ getSpotMarketAccountsWithDustPosition() {
954
+ const spotMarketAccounts = this.driftClient.getSpotMarketAccounts();
955
+ const dustPositionAccounts = [];
956
+ for (const spotMarketAccount of spotMarketAccounts) {
957
+ const isDust = this.isDustDepositPosition(spotMarketAccount);
958
+ if (isDust) {
959
+ dustPositionAccounts.push(spotMarketAccount);
960
+ }
961
+ }
962
+ return dustPositionAccounts;
963
+ }
964
+ getTotalLiabilityValue(marginCategory) {
965
+ return this.getTotalPerpPositionLiability(marginCategory, undefined, true).add(this.getSpotMarketLiabilityValue(undefined, marginCategory, undefined, true));
966
+ }
967
+ getTotalAssetValue(marginCategory) {
968
+ return this.getSpotMarketAssetValue(undefined, marginCategory, true).add(this.getUnrealizedPNL(true, undefined, marginCategory));
969
+ }
970
+ getNetUsdValue() {
971
+ const netSpotValue = this.getNetSpotMarketValue();
972
+ const unrealizedPnl = this.getUnrealizedPNL(true, undefined, undefined);
973
+ return netSpotValue.add(unrealizedPnl);
974
+ }
975
+ /**
976
+ * Calculates the all time P&L of the user.
977
+ *
978
+ * Net withdraws + Net spot market value + Net unrealized P&L -
979
+ */
980
+ getTotalAllTimePnl() {
981
+ const netUsdValue = this.getNetUsdValue();
982
+ const totalDeposits = this.getUserAccount().totalDeposits;
983
+ const totalWithdraws = this.getUserAccount().totalWithdraws;
984
+ const totalPnl = netUsdValue.add(totalWithdraws).sub(totalDeposits);
985
+ return totalPnl;
986
+ }
987
+ /**
988
+ * calculates max allowable leverage exceeding hitting requirement category
989
+ * for large sizes where imf factor activates, result is a lower bound
990
+ * @param marginCategory {Initial, Maintenance}
991
+ * @param isLp if calculating max leveraging for adding lp, need to add buffer
992
+ * @returns : Precision TEN_THOUSAND
993
+ */
994
+ getMaxLeverageForPerp(perpMarketIndex, marginCategory = 'Initial', isLp = false) {
995
+ const market = this.driftClient.getPerpMarketAccount(perpMarketIndex);
996
+ const marketPrice = this.driftClient.getOracleDataForPerpMarket(perpMarketIndex).price;
997
+ const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } = this.getLeverageComponents();
998
+ const totalAssetValue = spotAssetValue.add(perpPnl);
999
+ const netAssetValue = totalAssetValue.sub(spotLiabilityValue);
1000
+ if (netAssetValue.eq(numericConstants_1.ZERO)) {
1001
+ return numericConstants_1.ZERO;
1002
+ }
1003
+ const totalLiabilityValue = perpLiabilityValue.add(spotLiabilityValue);
1004
+ const lpBuffer = isLp
1005
+ ? marketPrice.mul(market.amm.orderStepSize).div(numericConstants_1.AMM_RESERVE_PRECISION)
1006
+ : numericConstants_1.ZERO;
1007
+ const freeCollateral = this.getFreeCollateral().sub(lpBuffer);
1008
+ let rawMarginRatio;
1009
+ switch (marginCategory) {
1010
+ case 'Initial':
1011
+ rawMarginRatio = Math.max(market.marginRatioInitial, this.getUserAccount().maxMarginRatio);
1012
+ break;
1013
+ case 'Maintenance':
1014
+ rawMarginRatio = market.marginRatioMaintenance;
1015
+ break;
1016
+ default:
1017
+ rawMarginRatio = market.marginRatioInitial;
1018
+ break;
1019
+ }
1020
+ // absolute max fesible size (upper bound)
1021
+ const maxSize = _1.BN.max(numericConstants_1.ZERO, freeCollateral
1022
+ .mul(numericConstants_1.MARGIN_PRECISION)
1023
+ .div(new _1.BN(rawMarginRatio))
1024
+ .mul(numericConstants_1.PRICE_PRECISION)
1025
+ .div(marketPrice));
1026
+ // margin ratio incorporting upper bound on size
1027
+ let marginRatio = (0, _1.calculateMarketMarginRatio)(market, maxSize, marginCategory, this.getUserAccount().maxMarginRatio, this.isHighLeverageMode());
1028
+ // use more fesible size since imf factor activated
1029
+ let attempts = 0;
1030
+ while (marginRatio > rawMarginRatio + 1e-4 && attempts < 10) {
1031
+ // more fesible size (upper bound)
1032
+ const targetSize = _1.BN.max(numericConstants_1.ZERO, freeCollateral
1033
+ .mul(numericConstants_1.MARGIN_PRECISION)
1034
+ .div(new _1.BN(marginRatio))
1035
+ .mul(numericConstants_1.PRICE_PRECISION)
1036
+ .div(marketPrice));
1037
+ // margin ratio incorporting more fesible target size
1038
+ marginRatio = (0, _1.calculateMarketMarginRatio)(market, targetSize, marginCategory, this.getUserAccount().maxMarginRatio, this.isHighLeverageMode());
1039
+ attempts += 1;
1040
+ }
1041
+ // how much more liabilities can be opened w remaining free collateral
1042
+ const additionalLiabilities = freeCollateral
1043
+ .mul(numericConstants_1.MARGIN_PRECISION)
1044
+ .div(new _1.BN(marginRatio));
1045
+ return totalLiabilityValue
1046
+ .add(additionalLiabilities)
1047
+ .mul(numericConstants_1.TEN_THOUSAND)
1048
+ .div(netAssetValue);
1049
+ }
1050
+ /**
1051
+ * calculates max allowable leverage exceeding hitting requirement category
1052
+ * @param spotMarketIndex
1053
+ * @param direction
1054
+ * @returns : Precision TEN_THOUSAND
1055
+ */
1056
+ getMaxLeverageForSpot(spotMarketIndex, direction) {
1057
+ const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } = this.getLeverageComponents();
1058
+ const totalLiabilityValue = perpLiabilityValue.add(spotLiabilityValue);
1059
+ const totalAssetValue = spotAssetValue.add(perpPnl);
1060
+ const netAssetValue = totalAssetValue.sub(spotLiabilityValue);
1061
+ if (netAssetValue.eq(numericConstants_1.ZERO)) {
1062
+ return numericConstants_1.ZERO;
1063
+ }
1064
+ const currentQuoteAssetValue = this.getSpotMarketAssetValue(numericConstants_1.QUOTE_SPOT_MARKET_INDEX);
1065
+ const currentQuoteLiabilityValue = this.getSpotMarketLiabilityValue(numericConstants_1.QUOTE_SPOT_MARKET_INDEX);
1066
+ const currentQuoteValue = currentQuoteAssetValue.sub(currentQuoteLiabilityValue);
1067
+ const currentSpotMarketAssetValue = this.getSpotMarketAssetValue(spotMarketIndex);
1068
+ const currentSpotMarketLiabilityValue = this.getSpotMarketLiabilityValue(spotMarketIndex);
1069
+ const currentSpotMarketNetValue = currentSpotMarketAssetValue.sub(currentSpotMarketLiabilityValue);
1070
+ const tradeQuoteAmount = this.getMaxTradeSizeUSDCForSpot(spotMarketIndex, direction, currentQuoteAssetValue, currentSpotMarketNetValue);
1071
+ let assetValueToAdd = numericConstants_1.ZERO;
1072
+ let liabilityValueToAdd = numericConstants_1.ZERO;
1073
+ const newQuoteNetValue = (0, types_1.isVariant)(direction, 'short')
1074
+ ? currentQuoteValue.add(tradeQuoteAmount)
1075
+ : currentQuoteValue.sub(tradeQuoteAmount);
1076
+ const newQuoteAssetValue = _1.BN.max(newQuoteNetValue, numericConstants_1.ZERO);
1077
+ const newQuoteLiabilityValue = _1.BN.min(newQuoteNetValue, numericConstants_1.ZERO).abs();
1078
+ assetValueToAdd = assetValueToAdd.add(newQuoteAssetValue.sub(currentQuoteAssetValue));
1079
+ liabilityValueToAdd = liabilityValueToAdd.add(newQuoteLiabilityValue.sub(currentQuoteLiabilityValue));
1080
+ const newSpotMarketNetValue = (0, types_1.isVariant)(direction, 'long')
1081
+ ? currentSpotMarketNetValue.add(tradeQuoteAmount)
1082
+ : currentSpotMarketNetValue.sub(tradeQuoteAmount);
1083
+ const newSpotMarketAssetValue = _1.BN.max(newSpotMarketNetValue, numericConstants_1.ZERO);
1084
+ const newSpotMarketLiabilityValue = _1.BN.min(newSpotMarketNetValue, numericConstants_1.ZERO).abs();
1085
+ assetValueToAdd = assetValueToAdd.add(newSpotMarketAssetValue.sub(currentSpotMarketAssetValue));
1086
+ liabilityValueToAdd = liabilityValueToAdd.add(newSpotMarketLiabilityValue.sub(currentSpotMarketLiabilityValue));
1087
+ const finalTotalAssetValue = totalAssetValue.add(assetValueToAdd);
1088
+ const finalTotalSpotLiability = spotLiabilityValue.add(liabilityValueToAdd);
1089
+ const finalTotalLiabilityValue = totalLiabilityValue.add(liabilityValueToAdd);
1090
+ const finalNetAssetValue = finalTotalAssetValue.sub(finalTotalSpotLiability);
1091
+ return finalTotalLiabilityValue.mul(numericConstants_1.TEN_THOUSAND).div(finalNetAssetValue);
1092
+ }
1093
+ /**
1094
+ * calculates margin ratio: 1 / leverage
1095
+ * @returns : Precision TEN_THOUSAND
1096
+ */
1097
+ getMarginRatio() {
1098
+ const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } = this.getLeverageComponents();
1099
+ const totalLiabilityValue = perpLiabilityValue.add(spotLiabilityValue);
1100
+ const totalAssetValue = spotAssetValue.add(perpPnl);
1101
+ if (totalLiabilityValue.eq(numericConstants_1.ZERO)) {
1102
+ return numericConstants_1.BN_MAX;
1103
+ }
1104
+ const netAssetValue = totalAssetValue.sub(spotLiabilityValue);
1105
+ return netAssetValue.mul(numericConstants_1.TEN_THOUSAND).div(totalLiabilityValue);
1106
+ }
1107
+ canBeLiquidated() {
1108
+ const totalCollateral = this.getTotalCollateral('Maintenance');
1109
+ const marginRequirement = this.getMaintenanceMarginRequirement();
1110
+ const canBeLiquidated = totalCollateral.lt(marginRequirement);
1111
+ return {
1112
+ canBeLiquidated,
1113
+ marginRequirement,
1114
+ totalCollateral,
1115
+ };
1116
+ }
1117
+ isBeingLiquidated() {
1118
+ return ((this.getUserAccount().status &
1119
+ (types_1.UserStatus.BEING_LIQUIDATED | types_1.UserStatus.BANKRUPT)) >
1120
+ 0);
1121
+ }
1122
+ hasStatus(status) {
1123
+ return (this.getUserAccount().status & status) > 0;
1124
+ }
1125
+ isBankrupt() {
1126
+ return (this.getUserAccount().status & types_1.UserStatus.BANKRUPT) > 0;
1127
+ }
1128
+ isHighLeverageMode() {
1129
+ return (0, types_1.isVariant)(this.getUserAccount().marginMode, 'highLeverage');
1130
+ }
1131
+ /**
1132
+ * Checks if any user position cumulative funding differs from respective market cumulative funding
1133
+ * @returns
1134
+ */
1135
+ needsToSettleFundingPayment() {
1136
+ for (const userPosition of this.getUserAccount().perpPositions) {
1137
+ if (userPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
1138
+ continue;
1139
+ }
1140
+ const market = this.driftClient.getPerpMarketAccount(userPosition.marketIndex);
1141
+ if (market.amm.cumulativeFundingRateLong.eq(userPosition.lastCumulativeFundingRate) ||
1142
+ market.amm.cumulativeFundingRateShort.eq(userPosition.lastCumulativeFundingRate)) {
1143
+ continue;
1144
+ }
1145
+ return true;
1146
+ }
1147
+ return false;
1148
+ }
1149
+ /**
1150
+ * Calculate the liquidation price of a spot position
1151
+ * @param marketIndex
1152
+ * @returns Precision : PRICE_PRECISION
1153
+ */
1154
+ spotLiquidationPrice(marketIndex, positionBaseSizeChange = numericConstants_1.ZERO) {
1155
+ const currentSpotPosition = this.getSpotPosition(marketIndex);
1156
+ if (!currentSpotPosition) {
1157
+ return new _1.BN(-1);
1158
+ }
1159
+ const totalCollateral = this.getTotalCollateral('Maintenance');
1160
+ const maintenanceMarginRequirement = this.getMaintenanceMarginRequirement();
1161
+ const freeCollateral = _1.BN.max(numericConstants_1.ZERO, totalCollateral.sub(maintenanceMarginRequirement));
1162
+ const market = this.driftClient.getSpotMarketAccount(marketIndex);
1163
+ let signedTokenAmount = (0, _1.getSignedTokenAmount)((0, spotBalance_1.getTokenAmount)(currentSpotPosition.scaledBalance, market, currentSpotPosition.balanceType), currentSpotPosition.balanceType);
1164
+ signedTokenAmount = signedTokenAmount.add(positionBaseSizeChange);
1165
+ if (signedTokenAmount.eq(numericConstants_1.ZERO)) {
1166
+ return new _1.BN(-1);
1167
+ }
1168
+ let freeCollateralDelta = this.calculateFreeCollateralDeltaForSpot(market, signedTokenAmount);
1169
+ const oracle = market.oracle;
1170
+ const perpMarketWithSameOracle = this.driftClient
1171
+ .getPerpMarketAccounts()
1172
+ .find((market) => market.amm.oracle.equals(oracle));
1173
+ const oraclePrice = this.driftClient.getOracleDataForSpotMarket(marketIndex).price;
1174
+ if (perpMarketWithSameOracle) {
1175
+ const perpPosition = this.getPerpPositionWithLPSettle(perpMarketWithSameOracle.marketIndex, undefined, true)[0];
1176
+ if (perpPosition) {
1177
+ const freeCollateralDeltaForPerp = this.calculateFreeCollateralDeltaForPerp(perpMarketWithSameOracle, perpPosition, numericConstants_1.ZERO, oraclePrice);
1178
+ freeCollateralDelta = freeCollateralDelta.add(freeCollateralDeltaForPerp || numericConstants_1.ZERO);
1179
+ }
1180
+ }
1181
+ if (freeCollateralDelta.eq(numericConstants_1.ZERO)) {
1182
+ return new _1.BN(-1);
1183
+ }
1184
+ const liqPriceDelta = freeCollateral
1185
+ .mul(numericConstants_1.QUOTE_PRECISION)
1186
+ .div(freeCollateralDelta);
1187
+ const liqPrice = oraclePrice.sub(liqPriceDelta);
1188
+ if (liqPrice.lt(numericConstants_1.ZERO)) {
1189
+ return new _1.BN(-1);
1190
+ }
1191
+ return liqPrice;
1192
+ }
1193
+ /**
1194
+ * Calculate the liquidation price of a perp position, with optional parameter to calculate the liquidation price after a trade
1195
+ * @param marketIndex
1196
+ * @param positionBaseSizeChange // change in position size to calculate liquidation price for : Precision 10^9
1197
+ * @param estimatedEntryPrice
1198
+ * @param marginCategory // allow Initial to be passed in if we are trying to calculate price for DLP de-risking
1199
+ * @param includeOpenOrders
1200
+ * @param offsetCollateral // allows calculating the liquidation price after this offset collateral is added to the user's account (e.g. : what will the liquidation price be for this position AFTER I deposit $x worth of collateral)
1201
+ * @returns Precision : PRICE_PRECISION
1202
+ */
1203
+ liquidationPrice(marketIndex, positionBaseSizeChange = numericConstants_1.ZERO, estimatedEntryPrice = numericConstants_1.ZERO, marginCategory = 'Maintenance', includeOpenOrders = false, offsetCollateral = numericConstants_1.ZERO) {
1204
+ const totalCollateral = this.getTotalCollateral(marginCategory, false, includeOpenOrders);
1205
+ const marginRequirement = this.getMarginRequirement(marginCategory, undefined, false, includeOpenOrders);
1206
+ let freeCollateral = _1.BN.max(numericConstants_1.ZERO, totalCollateral.sub(marginRequirement)).add(offsetCollateral);
1207
+ const oracle = this.driftClient.getPerpMarketAccount(marketIndex).amm.oracle;
1208
+ const oraclePrice = this.driftClient.getOracleDataForPerpMarket(marketIndex).price;
1209
+ const market = this.driftClient.getPerpMarketAccount(marketIndex);
1210
+ const currentPerpPosition = this.getPerpPositionWithLPSettle(marketIndex, undefined, true)[0] ||
1211
+ this.getEmptyPosition(marketIndex);
1212
+ positionBaseSizeChange = (0, _1.standardizeBaseAssetAmount)(positionBaseSizeChange, market.amm.orderStepSize);
1213
+ const freeCollateralChangeFromNewPosition = this.calculateEntriesEffectOnFreeCollateral(market, oraclePrice, currentPerpPosition, positionBaseSizeChange, estimatedEntryPrice, includeOpenOrders);
1214
+ freeCollateral = freeCollateral.add(freeCollateralChangeFromNewPosition);
1215
+ let freeCollateralDelta = this.calculateFreeCollateralDeltaForPerp(market, currentPerpPosition, positionBaseSizeChange, oraclePrice, marginCategory, includeOpenOrders);
1216
+ if (!freeCollateralDelta) {
1217
+ return new _1.BN(-1);
1218
+ }
1219
+ const spotMarketWithSameOracle = this.driftClient
1220
+ .getSpotMarketAccounts()
1221
+ .find((market) => market.oracle.equals(oracle));
1222
+ if (spotMarketWithSameOracle) {
1223
+ const spotPosition = this.getSpotPosition(spotMarketWithSameOracle.marketIndex);
1224
+ if (spotPosition) {
1225
+ const signedTokenAmount = (0, _1.getSignedTokenAmount)((0, spotBalance_1.getTokenAmount)(spotPosition.scaledBalance, spotMarketWithSameOracle, spotPosition.balanceType), spotPosition.balanceType);
1226
+ const spotFreeCollateralDelta = this.calculateFreeCollateralDeltaForSpot(spotMarketWithSameOracle, signedTokenAmount, marginCategory);
1227
+ freeCollateralDelta = freeCollateralDelta.add(spotFreeCollateralDelta || numericConstants_1.ZERO);
1228
+ }
1229
+ }
1230
+ if (freeCollateralDelta.eq(numericConstants_1.ZERO)) {
1231
+ return new _1.BN(-1);
1232
+ }
1233
+ const liqPriceDelta = freeCollateral
1234
+ .mul(numericConstants_1.QUOTE_PRECISION)
1235
+ .div(freeCollateralDelta);
1236
+ const liqPrice = oraclePrice.sub(liqPriceDelta);
1237
+ if (liqPrice.lt(numericConstants_1.ZERO)) {
1238
+ return new _1.BN(-1);
1239
+ }
1240
+ return liqPrice;
1241
+ }
1242
+ calculateEntriesEffectOnFreeCollateral(market, oraclePrice, perpPosition, positionBaseSizeChange, estimatedEntryPrice, includeOpenOrders) {
1243
+ let freeCollateralChange = numericConstants_1.ZERO;
1244
+ // update free collateral to account for change in pnl from new position
1245
+ if (!estimatedEntryPrice.eq(numericConstants_1.ZERO) && !positionBaseSizeChange.eq(numericConstants_1.ZERO)) {
1246
+ const costBasis = oraclePrice
1247
+ .mul(positionBaseSizeChange.abs())
1248
+ .div(numericConstants_1.BASE_PRECISION);
1249
+ const newPositionValue = estimatedEntryPrice
1250
+ .mul(positionBaseSizeChange.abs())
1251
+ .div(numericConstants_1.BASE_PRECISION);
1252
+ if (positionBaseSizeChange.gt(numericConstants_1.ZERO)) {
1253
+ freeCollateralChange = costBasis.sub(newPositionValue);
1254
+ }
1255
+ else {
1256
+ freeCollateralChange = newPositionValue.sub(costBasis);
1257
+ }
1258
+ // assume worst fee tier
1259
+ const takerFeeTier = this.driftClient.getStateAccount().perpFeeStructure.feeTiers[0];
1260
+ const takerFee = newPositionValue
1261
+ .muln(takerFeeTier.feeNumerator)
1262
+ .divn(takerFeeTier.feeDenominator);
1263
+ freeCollateralChange = freeCollateralChange.sub(takerFee);
1264
+ }
1265
+ const calculateMarginRequirement = (perpPosition) => {
1266
+ let baseAssetAmount;
1267
+ let liabilityValue;
1268
+ if (includeOpenOrders) {
1269
+ const { worstCaseBaseAssetAmount, worstCaseLiabilityValue } = (0, _1.calculateWorstCasePerpLiabilityValue)(perpPosition, market, oraclePrice);
1270
+ baseAssetAmount = worstCaseBaseAssetAmount;
1271
+ liabilityValue = worstCaseLiabilityValue;
1272
+ }
1273
+ else {
1274
+ baseAssetAmount = perpPosition.baseAssetAmount;
1275
+ liabilityValue = (0, _1.calculatePerpLiabilityValue)(baseAssetAmount, oraclePrice, (0, types_1.isVariant)(market.contractType, 'prediction'));
1276
+ }
1277
+ const marginRatio = (0, _1.calculateMarketMarginRatio)(market, baseAssetAmount.abs(), 'Maintenance', this.getUserAccount().maxMarginRatio, this.isHighLeverageMode());
1278
+ return liabilityValue.mul(new _1.BN(marginRatio)).div(numericConstants_1.MARGIN_PRECISION);
1279
+ };
1280
+ const freeCollateralConsumptionBefore = calculateMarginRequirement(perpPosition);
1281
+ const perpPositionAfter = Object.assign({}, perpPosition);
1282
+ perpPositionAfter.baseAssetAmount = perpPositionAfter.baseAssetAmount.add(positionBaseSizeChange);
1283
+ const freeCollateralConsumptionAfter = calculateMarginRequirement(perpPositionAfter);
1284
+ return freeCollateralChange.sub(freeCollateralConsumptionAfter.sub(freeCollateralConsumptionBefore));
1285
+ }
1286
+ calculateFreeCollateralDeltaForPerp(market, perpPosition, positionBaseSizeChange, oraclePrice, marginCategory = 'Maintenance', includeOpenOrders = false) {
1287
+ const baseAssetAmount = includeOpenOrders
1288
+ ? (0, margin_1.calculateWorstCaseBaseAssetAmount)(perpPosition, market, oraclePrice)
1289
+ : perpPosition.baseAssetAmount;
1290
+ // zero if include orders == false
1291
+ const orderBaseAssetAmount = baseAssetAmount.sub(perpPosition.baseAssetAmount);
1292
+ const proposedBaseAssetAmount = baseAssetAmount.add(positionBaseSizeChange);
1293
+ const marginRatio = (0, _1.calculateMarketMarginRatio)(market, proposedBaseAssetAmount.abs(), marginCategory, this.getUserAccount().maxMarginRatio, this.isHighLeverageMode());
1294
+ const marginRatioQuotePrecision = new _1.BN(marginRatio)
1295
+ .mul(numericConstants_1.QUOTE_PRECISION)
1296
+ .div(numericConstants_1.MARGIN_PRECISION);
1297
+ if (proposedBaseAssetAmount.eq(numericConstants_1.ZERO)) {
1298
+ return undefined;
1299
+ }
1300
+ let freeCollateralDelta = numericConstants_1.ZERO;
1301
+ if ((0, types_1.isVariant)(market.contractType, 'prediction')) {
1302
+ // for prediction market, increase in pnl and margin requirement will net out for position
1303
+ // open order margin requirement will change with price though
1304
+ if (orderBaseAssetAmount.gt(numericConstants_1.ZERO)) {
1305
+ freeCollateralDelta = marginRatioQuotePrecision.neg();
1306
+ }
1307
+ else if (orderBaseAssetAmount.lt(numericConstants_1.ZERO)) {
1308
+ freeCollateralDelta = marginRatioQuotePrecision;
1309
+ }
1310
+ }
1311
+ else {
1312
+ if (proposedBaseAssetAmount.gt(numericConstants_1.ZERO)) {
1313
+ freeCollateralDelta = numericConstants_1.QUOTE_PRECISION.sub(marginRatioQuotePrecision)
1314
+ .mul(proposedBaseAssetAmount)
1315
+ .div(numericConstants_1.BASE_PRECISION);
1316
+ }
1317
+ else {
1318
+ freeCollateralDelta = numericConstants_1.QUOTE_PRECISION.neg()
1319
+ .sub(marginRatioQuotePrecision)
1320
+ .mul(proposedBaseAssetAmount.abs())
1321
+ .div(numericConstants_1.BASE_PRECISION);
1322
+ }
1323
+ if (!orderBaseAssetAmount.eq(numericConstants_1.ZERO)) {
1324
+ freeCollateralDelta = freeCollateralDelta.sub(marginRatioQuotePrecision
1325
+ .mul(orderBaseAssetAmount.abs())
1326
+ .div(numericConstants_1.BASE_PRECISION));
1327
+ }
1328
+ }
1329
+ return freeCollateralDelta;
1330
+ }
1331
+ calculateFreeCollateralDeltaForSpot(market, signedTokenAmount, marginCategory = 'Maintenance') {
1332
+ const tokenPrecision = new _1.BN(Math.pow(10, market.decimals));
1333
+ if (signedTokenAmount.gt(numericConstants_1.ZERO)) {
1334
+ const assetWeight = (0, spotBalance_1.calculateAssetWeight)(signedTokenAmount, this.driftClient.getOracleDataForSpotMarket(market.marketIndex).price, market, marginCategory);
1335
+ return numericConstants_1.QUOTE_PRECISION.mul(assetWeight)
1336
+ .div(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION)
1337
+ .mul(signedTokenAmount)
1338
+ .div(tokenPrecision);
1339
+ }
1340
+ else {
1341
+ const liabilityWeight = (0, spotBalance_1.calculateLiabilityWeight)(signedTokenAmount.abs(), market, marginCategory);
1342
+ return numericConstants_1.QUOTE_PRECISION.neg()
1343
+ .mul(liabilityWeight)
1344
+ .div(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION)
1345
+ .mul(signedTokenAmount.abs())
1346
+ .div(tokenPrecision);
1347
+ }
1348
+ }
1349
+ /**
1350
+ * Calculates the estimated liquidation price for a position after closing a quote amount of the position.
1351
+ * @param positionMarketIndex
1352
+ * @param closeQuoteAmount
1353
+ * @returns : Precision PRICE_PRECISION
1354
+ */
1355
+ liquidationPriceAfterClose(positionMarketIndex, closeQuoteAmount, estimatedEntryPrice = numericConstants_1.ZERO) {
1356
+ const currentPosition = this.getPerpPositionWithLPSettle(positionMarketIndex, undefined, true)[0] || this.getEmptyPosition(positionMarketIndex);
1357
+ const closeBaseAmount = currentPosition.baseAssetAmount
1358
+ .mul(closeQuoteAmount)
1359
+ .div(currentPosition.quoteAssetAmount.abs())
1360
+ .add(currentPosition.baseAssetAmount
1361
+ .mul(closeQuoteAmount)
1362
+ .mod(currentPosition.quoteAssetAmount.abs()))
1363
+ .neg();
1364
+ return this.liquidationPrice(positionMarketIndex, closeBaseAmount, estimatedEntryPrice);
1365
+ }
1366
+ getMarginUSDCRequiredForTrade(targetMarketIndex, baseSize, estEntryPrice) {
1367
+ return (0, margin_1.calculateMarginUSDCRequiredForTrade)(this.driftClient, targetMarketIndex, baseSize, this.getUserAccount().maxMarginRatio, undefined, estEntryPrice);
1368
+ }
1369
+ getCollateralDepositRequiredForTrade(targetMarketIndex, baseSize, collateralIndex) {
1370
+ return (0, margin_1.calculateCollateralDepositRequiredForTrade)(this.driftClient, targetMarketIndex, baseSize, collateralIndex, this.getUserAccount().maxMarginRatio, false // assume user cant be high leverage if they havent created user account ?
1371
+ );
1372
+ }
1373
+ /**
1374
+ * Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
1375
+ *
1376
+ * To Calculate Max Quote Available:
1377
+ *
1378
+ * Case 1: SameSide
1379
+ * => Remaining quote to get to maxLeverage
1380
+ *
1381
+ * Case 2: NOT SameSide && currentLeverage <= maxLeverage
1382
+ * => Current opposite position x2 + remaining to get to maxLeverage
1383
+ *
1384
+ * Case 3: NOT SameSide && currentLeverage > maxLeverage && otherPositions - currentPosition > maxLeverage
1385
+ * => strictly reduce current position size
1386
+ *
1387
+ * Case 4: NOT SameSide && currentLeverage > maxLeverage && otherPositions - currentPosition < maxLeverage
1388
+ * => current position + remaining to get to maxLeverage
1389
+ *
1390
+ * @param targetMarketIndex
1391
+ * @param tradeSide
1392
+ * @param isLp
1393
+ * @returns { tradeSize: BN, oppositeSideTradeSize: BN} : Precision QUOTE_PRECISION
1394
+ */
1395
+ getMaxTradeSizeUSDCForPerp(targetMarketIndex, tradeSide, isLp = false) {
1396
+ let tradeSize = numericConstants_1.ZERO;
1397
+ let oppositeSideTradeSize = numericConstants_1.ZERO;
1398
+ const currentPosition = this.getPerpPositionWithLPSettle(targetMarketIndex, undefined, true)[0] ||
1399
+ this.getEmptyPosition(targetMarketIndex);
1400
+ const targetSide = (0, types_1.isVariant)(tradeSide, 'short') ? 'short' : 'long';
1401
+ const currentPositionSide = (currentPosition === null || currentPosition === void 0 ? void 0 : currentPosition.baseAssetAmount.isNeg())
1402
+ ? 'short'
1403
+ : 'long';
1404
+ const targetingSameSide = !currentPosition
1405
+ ? true
1406
+ : targetSide === currentPositionSide;
1407
+ const oracleData = this.getOracleDataForPerpMarket(targetMarketIndex);
1408
+ const marketAccount = this.driftClient.getPerpMarketAccount(targetMarketIndex);
1409
+ const lpBuffer = isLp
1410
+ ? oracleData.price
1411
+ .mul(marketAccount.amm.orderStepSize)
1412
+ .div(numericConstants_1.AMM_RESERVE_PRECISION)
1413
+ : numericConstants_1.ZERO;
1414
+ // add any position we have on the opposite side of the current trade, because we can "flip" the size of this position without taking any extra leverage.
1415
+ const oppositeSizeLiabilityValue = targetingSameSide
1416
+ ? numericConstants_1.ZERO
1417
+ : (0, _1.calculatePerpLiabilityValue)(currentPosition.baseAssetAmount, oracleData.price, (0, types_1.isVariant)(marketAccount.contractType, 'prediction'));
1418
+ const maxPositionSize = this.getPerpBuyingPower(targetMarketIndex, lpBuffer);
1419
+ if (maxPositionSize.gte(numericConstants_1.ZERO)) {
1420
+ if (oppositeSizeLiabilityValue.eq(numericConstants_1.ZERO)) {
1421
+ // case 1 : Regular trade where current total position less than max, and no opposite position to account for
1422
+ // do nothing
1423
+ tradeSize = maxPositionSize;
1424
+ }
1425
+ else {
1426
+ // case 2 : trade where current total position less than max, but need to account for flipping the current position over to the other side
1427
+ tradeSize = maxPositionSize.add(oppositeSizeLiabilityValue);
1428
+ oppositeSideTradeSize = oppositeSizeLiabilityValue;
1429
+ }
1430
+ }
1431
+ else {
1432
+ // current leverage is greater than max leverage - can only reduce position size
1433
+ if (!targetingSameSide) {
1434
+ const market = this.driftClient.getPerpMarketAccount(targetMarketIndex);
1435
+ const perpLiabilityValue = (0, _1.calculatePerpLiabilityValue)(currentPosition.baseAssetAmount, oracleData.price, (0, types_1.isVariant)(market.contractType, 'prediction'));
1436
+ const totalCollateral = this.getTotalCollateral();
1437
+ const marginRequirement = this.getInitialMarginRequirement();
1438
+ const marginFreedByClosing = perpLiabilityValue
1439
+ .mul(new _1.BN(market.marginRatioInitial))
1440
+ .div(numericConstants_1.MARGIN_PRECISION);
1441
+ const marginRequirementAfterClosing = marginRequirement.sub(marginFreedByClosing);
1442
+ if (marginRequirementAfterClosing.gt(totalCollateral)) {
1443
+ oppositeSideTradeSize = perpLiabilityValue;
1444
+ }
1445
+ else {
1446
+ const freeCollateralAfterClose = totalCollateral.sub(marginRequirementAfterClosing);
1447
+ const buyingPowerAfterClose = this.getPerpBuyingPowerFromFreeCollateralAndBaseAssetAmount(targetMarketIndex, freeCollateralAfterClose, numericConstants_1.ZERO);
1448
+ oppositeSideTradeSize = perpLiabilityValue;
1449
+ tradeSize = buyingPowerAfterClose;
1450
+ }
1451
+ }
1452
+ else {
1453
+ // do nothing if targetting same side
1454
+ tradeSize = maxPositionSize;
1455
+ }
1456
+ }
1457
+ return { tradeSize, oppositeSideTradeSize };
1458
+ }
1459
+ /**
1460
+ * Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
1461
+ *
1462
+ * @param targetMarketIndex
1463
+ * @param direction
1464
+ * @param currentQuoteAssetValue
1465
+ * @param currentSpotMarketNetValue
1466
+ * @returns tradeSizeAllowed : Precision QUOTE_PRECISION
1467
+ */
1468
+ getMaxTradeSizeUSDCForSpot(targetMarketIndex, direction, currentQuoteAssetValue, currentSpotMarketNetValue) {
1469
+ const market = this.driftClient.getSpotMarketAccount(targetMarketIndex);
1470
+ const oraclePrice = this.driftClient.getOracleDataForSpotMarket(targetMarketIndex).price;
1471
+ currentQuoteAssetValue = this.getSpotMarketAssetValue(numericConstants_1.QUOTE_SPOT_MARKET_INDEX);
1472
+ currentSpotMarketNetValue =
1473
+ currentSpotMarketNetValue !== null && currentSpotMarketNetValue !== void 0 ? currentSpotMarketNetValue : this.getSpotPositionValue(targetMarketIndex);
1474
+ let freeCollateral = this.getFreeCollateral();
1475
+ const marginRatio = (0, _1.calculateSpotMarketMarginRatio)(market, oraclePrice, 'Initial', numericConstants_1.ZERO, (0, types_1.isVariant)(direction, 'long')
1476
+ ? _1.SpotBalanceType.DEPOSIT
1477
+ : _1.SpotBalanceType.BORROW, this.getUserAccount().maxMarginRatio);
1478
+ let tradeAmount = numericConstants_1.ZERO;
1479
+ if (this.getUserAccount().isMarginTradingEnabled) {
1480
+ // if the user is buying/selling and already short/long, need to account for closing out short/long
1481
+ if ((0, types_1.isVariant)(direction, 'long') && currentSpotMarketNetValue.lt(numericConstants_1.ZERO)) {
1482
+ tradeAmount = currentSpotMarketNetValue.abs();
1483
+ const marginRatio = (0, _1.calculateSpotMarketMarginRatio)(market, oraclePrice, 'Initial', this.getTokenAmount(targetMarketIndex).abs(), _1.SpotBalanceType.BORROW, this.getUserAccount().maxMarginRatio);
1484
+ freeCollateral = freeCollateral.add(tradeAmount.mul(new _1.BN(marginRatio)).div(numericConstants_1.MARGIN_PRECISION));
1485
+ }
1486
+ else if ((0, types_1.isVariant)(direction, 'short') &&
1487
+ currentSpotMarketNetValue.gt(numericConstants_1.ZERO)) {
1488
+ tradeAmount = currentSpotMarketNetValue;
1489
+ const marginRatio = (0, _1.calculateSpotMarketMarginRatio)(market, oraclePrice, 'Initial', this.getTokenAmount(targetMarketIndex), _1.SpotBalanceType.DEPOSIT, this.getUserAccount().maxMarginRatio);
1490
+ freeCollateral = freeCollateral.add(tradeAmount.mul(new _1.BN(marginRatio)).div(numericConstants_1.MARGIN_PRECISION));
1491
+ }
1492
+ tradeAmount = tradeAmount.add(freeCollateral.mul(numericConstants_1.MARGIN_PRECISION).div(new _1.BN(marginRatio)));
1493
+ }
1494
+ else if ((0, types_1.isVariant)(direction, 'long')) {
1495
+ tradeAmount = _1.BN.min(currentQuoteAssetValue, freeCollateral.mul(numericConstants_1.MARGIN_PRECISION).div(new _1.BN(marginRatio)));
1496
+ }
1497
+ else {
1498
+ tradeAmount = _1.BN.max(numericConstants_1.ZERO, currentSpotMarketNetValue);
1499
+ }
1500
+ return tradeAmount;
1501
+ }
1502
+ /**
1503
+ * Calculates the max amount of token that can be swapped from inMarket to outMarket
1504
+ * Assumes swap happens at oracle price
1505
+ *
1506
+ * @param inMarketIndex
1507
+ * @param outMarketIndex
1508
+ * @param calculateSwap function to similate in to out swa
1509
+ * @param iterationLimit how long to run appromixation before erroring out
1510
+ */
1511
+ getMaxSwapAmount({ inMarketIndex, outMarketIndex, calculateSwap, iterationLimit = 1000, }) {
1512
+ const inMarket = this.driftClient.getSpotMarketAccount(inMarketIndex);
1513
+ const outMarket = this.driftClient.getSpotMarketAccount(outMarketIndex);
1514
+ const inOraclePriceData = this.getOracleDataForSpotMarket(inMarketIndex);
1515
+ const inOraclePrice = inOraclePriceData.price;
1516
+ const outOraclePriceData = this.getOracleDataForSpotMarket(outMarketIndex);
1517
+ const outOraclePrice = outOraclePriceData.price;
1518
+ const inStrictOraclePrice = new strictOraclePrice_1.StrictOraclePrice(inOraclePrice);
1519
+ const outStrictOraclePrice = new strictOraclePrice_1.StrictOraclePrice(outOraclePrice);
1520
+ const inPrecision = new _1.BN(10 ** inMarket.decimals);
1521
+ const outPrecision = new _1.BN(10 ** outMarket.decimals);
1522
+ const inSpotPosition = this.getSpotPosition(inMarketIndex) ||
1523
+ this.getEmptySpotPosition(inMarketIndex);
1524
+ const outSpotPosition = this.getSpotPosition(outMarketIndex) ||
1525
+ this.getEmptySpotPosition(outMarketIndex);
1526
+ const freeCollateral = this.getFreeCollateral();
1527
+ const inContributionInitial = this.calculateSpotPositionFreeCollateralContribution(inSpotPosition, inStrictOraclePrice);
1528
+ const { totalAssetValue: inTotalAssetValueInitial, totalLiabilityValue: inTotalLiabilityValueInitial, } = this.calculateSpotPositionLeverageContribution(inSpotPosition, inStrictOraclePrice);
1529
+ const outContributionInitial = this.calculateSpotPositionFreeCollateralContribution(outSpotPosition, outStrictOraclePrice);
1530
+ const { totalAssetValue: outTotalAssetValueInitial, totalLiabilityValue: outTotalLiabilityValueInitial, } = this.calculateSpotPositionLeverageContribution(outSpotPosition, outStrictOraclePrice);
1531
+ const initialContribution = inContributionInitial.add(outContributionInitial);
1532
+ const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } = this.getLeverageComponents();
1533
+ if (!calculateSwap) {
1534
+ calculateSwap = (inSwap) => {
1535
+ return inSwap
1536
+ .mul(outPrecision)
1537
+ .mul(inOraclePrice)
1538
+ .div(outOraclePrice)
1539
+ .div(inPrecision);
1540
+ };
1541
+ }
1542
+ let inSwap = numericConstants_1.ZERO;
1543
+ let outSwap = numericConstants_1.ZERO;
1544
+ const inTokenAmount = this.getTokenAmount(inMarketIndex);
1545
+ const outTokenAmount = this.getTokenAmount(outMarketIndex);
1546
+ const inAssetWeight = (0, spotBalance_1.calculateAssetWeight)(inTokenAmount, inOraclePriceData.price, inMarket, 'Initial');
1547
+ const outAssetWeight = (0, spotBalance_1.calculateAssetWeight)(outTokenAmount, outOraclePriceData.price, outMarket, 'Initial');
1548
+ const outSaferThanIn =
1549
+ // selling asset to close borrow
1550
+ (inTokenAmount.gt(numericConstants_1.ZERO) && outTokenAmount.lt(numericConstants_1.ZERO)) ||
1551
+ // buying asset with higher initial asset weight
1552
+ inAssetWeight.lt(outAssetWeight);
1553
+ if (freeCollateral.lt(numericConstants_1.PRICE_PRECISION.divn(100))) {
1554
+ if (outSaferThanIn && inTokenAmount.gt(numericConstants_1.ZERO)) {
1555
+ inSwap = inTokenAmount;
1556
+ outSwap = calculateSwap(inSwap);
1557
+ }
1558
+ }
1559
+ else {
1560
+ let minSwap = numericConstants_1.ZERO;
1561
+ let maxSwap = _1.BN.max(freeCollateral.mul(inPrecision).mul(new _1.BN(100)).div(inOraclePrice), // 100x current free collateral
1562
+ inTokenAmount.abs().mul(new _1.BN(10)) // 10x current position
1563
+ );
1564
+ inSwap = maxSwap.div(numericConstants_1.TWO);
1565
+ const error = freeCollateral.div(new _1.BN(10000));
1566
+ let i = 0;
1567
+ let freeCollateralAfter = freeCollateral;
1568
+ while (freeCollateralAfter.gt(error) || freeCollateralAfter.isNeg()) {
1569
+ outSwap = calculateSwap(inSwap);
1570
+ const inPositionAfter = this.cloneAndUpdateSpotPosition(inSpotPosition, inSwap.neg(), inMarket);
1571
+ const outPositionAfter = this.cloneAndUpdateSpotPosition(outSpotPosition, outSwap, outMarket);
1572
+ const inContributionAfter = this.calculateSpotPositionFreeCollateralContribution(inPositionAfter, inStrictOraclePrice);
1573
+ const outContributionAfter = this.calculateSpotPositionFreeCollateralContribution(outPositionAfter, outStrictOraclePrice);
1574
+ const contributionAfter = inContributionAfter.add(outContributionAfter);
1575
+ const contributionDelta = contributionAfter.sub(initialContribution);
1576
+ freeCollateralAfter = freeCollateral.add(contributionDelta);
1577
+ if (freeCollateralAfter.gt(error)) {
1578
+ minSwap = inSwap;
1579
+ inSwap = minSwap.add(maxSwap).div(numericConstants_1.TWO);
1580
+ }
1581
+ else if (freeCollateralAfter.isNeg()) {
1582
+ maxSwap = inSwap;
1583
+ inSwap = minSwap.add(maxSwap).div(numericConstants_1.TWO);
1584
+ }
1585
+ if (i++ > iterationLimit) {
1586
+ console.log('getMaxSwapAmount iteration limit reached');
1587
+ break;
1588
+ }
1589
+ }
1590
+ }
1591
+ const inPositionAfter = this.cloneAndUpdateSpotPosition(inSpotPosition, inSwap.neg(), inMarket);
1592
+ const outPositionAfter = this.cloneAndUpdateSpotPosition(outSpotPosition, outSwap, outMarket);
1593
+ const { totalAssetValue: inTotalAssetValueAfter, totalLiabilityValue: inTotalLiabilityValueAfter, } = this.calculateSpotPositionLeverageContribution(inPositionAfter, inStrictOraclePrice);
1594
+ const { totalAssetValue: outTotalAssetValueAfter, totalLiabilityValue: outTotalLiabilityValueAfter, } = this.calculateSpotPositionLeverageContribution(outPositionAfter, outStrictOraclePrice);
1595
+ const spotAssetValueDelta = inTotalAssetValueAfter
1596
+ .add(outTotalAssetValueAfter)
1597
+ .sub(inTotalAssetValueInitial)
1598
+ .sub(outTotalAssetValueInitial);
1599
+ const spotLiabilityValueDelta = inTotalLiabilityValueAfter
1600
+ .add(outTotalLiabilityValueAfter)
1601
+ .sub(inTotalLiabilityValueInitial)
1602
+ .sub(outTotalLiabilityValueInitial);
1603
+ const spotAssetValueAfter = spotAssetValue.add(spotAssetValueDelta);
1604
+ const spotLiabilityValueAfter = spotLiabilityValue.add(spotLiabilityValueDelta);
1605
+ const leverage = this.calculateLeverageFromComponents({
1606
+ perpLiabilityValue,
1607
+ perpPnl,
1608
+ spotAssetValue: spotAssetValueAfter,
1609
+ spotLiabilityValue: spotLiabilityValueAfter,
1610
+ });
1611
+ return { inAmount: inSwap, outAmount: outSwap, leverage };
1612
+ }
1613
+ cloneAndUpdateSpotPosition(position, tokenAmount, market) {
1614
+ const clonedPosition = Object.assign({}, position);
1615
+ if (tokenAmount.eq(numericConstants_1.ZERO)) {
1616
+ return clonedPosition;
1617
+ }
1618
+ const preTokenAmount = (0, _1.getSignedTokenAmount)((0, spotBalance_1.getTokenAmount)(position.scaledBalance, market, position.balanceType), position.balanceType);
1619
+ if ((0, _1.sigNum)(preTokenAmount).eq((0, _1.sigNum)(tokenAmount))) {
1620
+ const scaledBalanceDelta = (0, _1.getBalance)(tokenAmount.abs(), market, position.balanceType);
1621
+ clonedPosition.scaledBalance =
1622
+ clonedPosition.scaledBalance.add(scaledBalanceDelta);
1623
+ return clonedPosition;
1624
+ }
1625
+ const updateDirection = tokenAmount.isNeg()
1626
+ ? _1.SpotBalanceType.BORROW
1627
+ : _1.SpotBalanceType.DEPOSIT;
1628
+ if (tokenAmount.abs().gte(preTokenAmount.abs())) {
1629
+ clonedPosition.scaledBalance = (0, _1.getBalance)(tokenAmount.abs().sub(preTokenAmount.abs()), market, updateDirection);
1630
+ clonedPosition.balanceType = updateDirection;
1631
+ }
1632
+ else {
1633
+ const scaledBalanceDelta = (0, _1.getBalance)(tokenAmount.abs(), market, position.balanceType);
1634
+ clonedPosition.scaledBalance =
1635
+ clonedPosition.scaledBalance.sub(scaledBalanceDelta);
1636
+ }
1637
+ return clonedPosition;
1638
+ }
1639
+ calculateSpotPositionFreeCollateralContribution(spotPosition, strictOraclePrice) {
1640
+ const marginCategory = 'Initial';
1641
+ const spotMarketAccount = this.driftClient.getSpotMarketAccount(spotPosition.marketIndex);
1642
+ const { freeCollateralContribution } = (0, spotPosition_1.getWorstCaseTokenAmounts)(spotPosition, spotMarketAccount, strictOraclePrice, marginCategory, this.getUserAccount().maxMarginRatio);
1643
+ return freeCollateralContribution;
1644
+ }
1645
+ calculateSpotPositionLeverageContribution(spotPosition, strictOraclePrice) {
1646
+ let totalAssetValue = numericConstants_1.ZERO;
1647
+ let totalLiabilityValue = numericConstants_1.ZERO;
1648
+ const spotMarketAccount = this.driftClient.getSpotMarketAccount(spotPosition.marketIndex);
1649
+ const { tokenValue, ordersValue } = (0, spotPosition_1.getWorstCaseTokenAmounts)(spotPosition, spotMarketAccount, strictOraclePrice, 'Initial', this.getUserAccount().maxMarginRatio);
1650
+ if (tokenValue.gte(numericConstants_1.ZERO)) {
1651
+ totalAssetValue = tokenValue;
1652
+ }
1653
+ else {
1654
+ totalLiabilityValue = tokenValue.abs();
1655
+ }
1656
+ if (ordersValue.gt(numericConstants_1.ZERO)) {
1657
+ totalAssetValue = totalAssetValue.add(ordersValue);
1658
+ }
1659
+ else {
1660
+ totalLiabilityValue = totalLiabilityValue.add(ordersValue.abs());
1661
+ }
1662
+ return {
1663
+ totalAssetValue,
1664
+ totalLiabilityValue,
1665
+ };
1666
+ }
1667
+ /**
1668
+ * Estimates what the user leverage will be after swap
1669
+ * @param inMarketIndex
1670
+ * @param outMarketIndex
1671
+ * @param inAmount
1672
+ * @param outAmount
1673
+ */
1674
+ accountLeverageAfterSwap({ inMarketIndex, outMarketIndex, inAmount, outAmount, }) {
1675
+ const inMarket = this.driftClient.getSpotMarketAccount(inMarketIndex);
1676
+ const outMarket = this.driftClient.getSpotMarketAccount(outMarketIndex);
1677
+ const inOraclePriceData = this.getOracleDataForSpotMarket(inMarketIndex);
1678
+ const inOraclePrice = inOraclePriceData.price;
1679
+ const outOraclePriceData = this.getOracleDataForSpotMarket(outMarketIndex);
1680
+ const outOraclePrice = outOraclePriceData.price;
1681
+ const inStrictOraclePrice = new strictOraclePrice_1.StrictOraclePrice(inOraclePrice);
1682
+ const outStrictOraclePrice = new strictOraclePrice_1.StrictOraclePrice(outOraclePrice);
1683
+ const inSpotPosition = this.getSpotPosition(inMarketIndex) ||
1684
+ this.getEmptySpotPosition(inMarketIndex);
1685
+ const outSpotPosition = this.getSpotPosition(outMarketIndex) ||
1686
+ this.getEmptySpotPosition(outMarketIndex);
1687
+ const { totalAssetValue: inTotalAssetValueInitial, totalLiabilityValue: inTotalLiabilityValueInitial, } = this.calculateSpotPositionLeverageContribution(inSpotPosition, inStrictOraclePrice);
1688
+ const { totalAssetValue: outTotalAssetValueInitial, totalLiabilityValue: outTotalLiabilityValueInitial, } = this.calculateSpotPositionLeverageContribution(outSpotPosition, outStrictOraclePrice);
1689
+ const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } = this.getLeverageComponents();
1690
+ const inPositionAfter = this.cloneAndUpdateSpotPosition(inSpotPosition, inAmount.abs().neg(), inMarket);
1691
+ const outPositionAfter = this.cloneAndUpdateSpotPosition(outSpotPosition, outAmount.abs(), outMarket);
1692
+ const { totalAssetValue: inTotalAssetValueAfter, totalLiabilityValue: inTotalLiabilityValueAfter, } = this.calculateSpotPositionLeverageContribution(inPositionAfter, inStrictOraclePrice);
1693
+ const { totalAssetValue: outTotalAssetValueAfter, totalLiabilityValue: outTotalLiabilityValueAfter, } = this.calculateSpotPositionLeverageContribution(outPositionAfter, outStrictOraclePrice);
1694
+ const spotAssetValueDelta = inTotalAssetValueAfter
1695
+ .add(outTotalAssetValueAfter)
1696
+ .sub(inTotalAssetValueInitial)
1697
+ .sub(outTotalAssetValueInitial);
1698
+ const spotLiabilityValueDelta = inTotalLiabilityValueAfter
1699
+ .add(outTotalLiabilityValueAfter)
1700
+ .sub(inTotalLiabilityValueInitial)
1701
+ .sub(outTotalLiabilityValueInitial);
1702
+ const spotAssetValueAfter = spotAssetValue.add(spotAssetValueDelta);
1703
+ const spotLiabilityValueAfter = spotLiabilityValue.add(spotLiabilityValueDelta);
1704
+ return this.calculateLeverageFromComponents({
1705
+ perpLiabilityValue,
1706
+ perpPnl,
1707
+ spotAssetValue: spotAssetValueAfter,
1708
+ spotLiabilityValue: spotLiabilityValueAfter,
1709
+ });
1710
+ }
1711
+ // TODO - should this take the price impact of the trade into account for strict accuracy?
1712
+ /**
1713
+ * Returns the leverage ratio for the account after adding (or subtracting) the given quote size to the given position
1714
+ * @param targetMarketIndex
1715
+ * @param: targetMarketType
1716
+ * @param tradeQuoteAmount
1717
+ * @param tradeSide
1718
+ * @param includeOpenOrders
1719
+ * @returns leverageRatio : Precision TEN_THOUSAND
1720
+ */
1721
+ accountLeverageRatioAfterTrade(targetMarketIndex, targetMarketType, tradeQuoteAmount, tradeSide, includeOpenOrders = true) {
1722
+ const tradeIsPerp = (0, types_1.isVariant)(targetMarketType, 'perp');
1723
+ if (!tradeIsPerp) {
1724
+ // calculate new asset/liability values for base and quote market to find new account leverage
1725
+ const totalLiabilityValue = this.getTotalLiabilityValue();
1726
+ const totalAssetValue = this.getTotalAssetValue();
1727
+ const spotLiabilityValue = this.getSpotMarketLiabilityValue(undefined, undefined, undefined, includeOpenOrders);
1728
+ const currentQuoteAssetValue = this.getSpotMarketAssetValue(numericConstants_1.QUOTE_SPOT_MARKET_INDEX, undefined, includeOpenOrders);
1729
+ const currentQuoteLiabilityValue = this.getSpotMarketLiabilityValue(numericConstants_1.QUOTE_SPOT_MARKET_INDEX, undefined, undefined, includeOpenOrders);
1730
+ const currentQuoteValue = currentQuoteAssetValue.sub(currentQuoteLiabilityValue);
1731
+ const currentSpotMarketAssetValue = this.getSpotMarketAssetValue(targetMarketIndex, undefined, includeOpenOrders);
1732
+ const currentSpotMarketLiabilityValue = this.getSpotMarketLiabilityValue(targetMarketIndex, undefined, undefined, includeOpenOrders);
1733
+ const currentSpotMarketNetValue = currentSpotMarketAssetValue.sub(currentSpotMarketLiabilityValue);
1734
+ let assetValueToAdd = numericConstants_1.ZERO;
1735
+ let liabilityValueToAdd = numericConstants_1.ZERO;
1736
+ const newQuoteNetValue = tradeSide == _1.PositionDirection.SHORT
1737
+ ? currentQuoteValue.add(tradeQuoteAmount)
1738
+ : currentQuoteValue.sub(tradeQuoteAmount);
1739
+ const newQuoteAssetValue = _1.BN.max(newQuoteNetValue, numericConstants_1.ZERO);
1740
+ const newQuoteLiabilityValue = _1.BN.min(newQuoteNetValue, numericConstants_1.ZERO).abs();
1741
+ assetValueToAdd = assetValueToAdd.add(newQuoteAssetValue.sub(currentQuoteAssetValue));
1742
+ liabilityValueToAdd = liabilityValueToAdd.add(newQuoteLiabilityValue.sub(currentQuoteLiabilityValue));
1743
+ const newSpotMarketNetValue = tradeSide == _1.PositionDirection.LONG
1744
+ ? currentSpotMarketNetValue.add(tradeQuoteAmount)
1745
+ : currentSpotMarketNetValue.sub(tradeQuoteAmount);
1746
+ const newSpotMarketAssetValue = _1.BN.max(newSpotMarketNetValue, numericConstants_1.ZERO);
1747
+ const newSpotMarketLiabilityValue = _1.BN.min(newSpotMarketNetValue, numericConstants_1.ZERO).abs();
1748
+ assetValueToAdd = assetValueToAdd.add(newSpotMarketAssetValue.sub(currentSpotMarketAssetValue));
1749
+ liabilityValueToAdd = liabilityValueToAdd.add(newSpotMarketLiabilityValue.sub(currentSpotMarketLiabilityValue));
1750
+ const totalAssetValueAfterTrade = totalAssetValue.add(assetValueToAdd);
1751
+ const totalSpotLiabilityValueAfterTrade = spotLiabilityValue.add(liabilityValueToAdd);
1752
+ const totalLiabilityValueAfterTrade = totalLiabilityValue.add(liabilityValueToAdd);
1753
+ const netAssetValueAfterTrade = totalAssetValueAfterTrade.sub(totalSpotLiabilityValueAfterTrade);
1754
+ if (netAssetValueAfterTrade.eq(numericConstants_1.ZERO)) {
1755
+ return numericConstants_1.ZERO;
1756
+ }
1757
+ const newLeverage = totalLiabilityValueAfterTrade
1758
+ .mul(numericConstants_1.TEN_THOUSAND)
1759
+ .div(netAssetValueAfterTrade);
1760
+ return newLeverage;
1761
+ }
1762
+ const currentPosition = this.getPerpPositionWithLPSettle(targetMarketIndex)[0] ||
1763
+ this.getEmptyPosition(targetMarketIndex);
1764
+ const perpMarket = this.driftClient.getPerpMarketAccount(targetMarketIndex);
1765
+ const oracleData = this.getOracleDataForPerpMarket(targetMarketIndex);
1766
+ let {
1767
+ // eslint-disable-next-line prefer-const
1768
+ worstCaseBaseAssetAmount: worstCaseBase, worstCaseLiabilityValue: currentPositionQuoteAmount, } = (0, _1.calculateWorstCasePerpLiabilityValue)(currentPosition, perpMarket, oracleData.price);
1769
+ // current side is short if position base asset amount is negative OR there is no position open but open orders are short
1770
+ const currentSide = currentPosition.baseAssetAmount.isNeg() ||
1771
+ (currentPosition.baseAssetAmount.eq(numericConstants_1.ZERO) && worstCaseBase.isNeg())
1772
+ ? _1.PositionDirection.SHORT
1773
+ : _1.PositionDirection.LONG;
1774
+ if (currentSide === _1.PositionDirection.SHORT)
1775
+ currentPositionQuoteAmount = currentPositionQuoteAmount.neg();
1776
+ if (tradeSide === _1.PositionDirection.SHORT)
1777
+ tradeQuoteAmount = tradeQuoteAmount.neg();
1778
+ const currentPerpPositionAfterTrade = currentPositionQuoteAmount
1779
+ .add(tradeQuoteAmount)
1780
+ .abs();
1781
+ const totalPositionAfterTradeExcludingTargetMarket = this.getTotalPerpPositionValueExcludingMarket(targetMarketIndex, undefined, undefined, includeOpenOrders);
1782
+ const totalAssetValue = this.getTotalAssetValue();
1783
+ const totalPerpPositionLiability = currentPerpPositionAfterTrade
1784
+ .add(totalPositionAfterTradeExcludingTargetMarket)
1785
+ .abs();
1786
+ const totalSpotLiability = this.getSpotMarketLiabilityValue(undefined, undefined, undefined, includeOpenOrders);
1787
+ const totalLiabilitiesAfterTrade = totalPerpPositionLiability.add(totalSpotLiability);
1788
+ const netAssetValue = totalAssetValue.sub(totalSpotLiability);
1789
+ if (netAssetValue.eq(numericConstants_1.ZERO)) {
1790
+ return numericConstants_1.ZERO;
1791
+ }
1792
+ const newLeverage = totalLiabilitiesAfterTrade
1793
+ .mul(numericConstants_1.TEN_THOUSAND)
1794
+ .div(netAssetValue);
1795
+ return newLeverage;
1796
+ }
1797
+ getUserFeeTier(marketType, now) {
1798
+ const state = this.driftClient.getStateAccount();
1799
+ let feeTierIndex = 0;
1800
+ if ((0, types_1.isVariant)(marketType, 'perp')) {
1801
+ if (this.isHighLeverageMode()) {
1802
+ return state.perpFeeStructure.feeTiers[0];
1803
+ }
1804
+ const userStatsAccount = this.driftClient
1805
+ .getUserStats()
1806
+ .getAccount();
1807
+ const total30dVolume = (0, _1.getUser30dRollingVolumeEstimate)(userStatsAccount, now);
1808
+ const stakedQuoteAssetAmount = userStatsAccount.ifStakedQuoteAssetAmount;
1809
+ const volumeTiers = [
1810
+ new _1.BN(100000000).mul(numericConstants_1.QUOTE_PRECISION),
1811
+ new _1.BN(50000000).mul(numericConstants_1.QUOTE_PRECISION),
1812
+ new _1.BN(10000000).mul(numericConstants_1.QUOTE_PRECISION),
1813
+ new _1.BN(5000000).mul(numericConstants_1.QUOTE_PRECISION),
1814
+ new _1.BN(1000000).mul(numericConstants_1.QUOTE_PRECISION),
1815
+ ];
1816
+ const stakedTiers = [
1817
+ new _1.BN(10000).mul(numericConstants_1.QUOTE_PRECISION),
1818
+ new _1.BN(5000).mul(numericConstants_1.QUOTE_PRECISION),
1819
+ new _1.BN(2000).mul(numericConstants_1.QUOTE_PRECISION),
1820
+ new _1.BN(1000).mul(numericConstants_1.QUOTE_PRECISION),
1821
+ new _1.BN(500).mul(numericConstants_1.QUOTE_PRECISION),
1822
+ ];
1823
+ for (let i = 0; i < volumeTiers.length; i++) {
1824
+ if (total30dVolume.gte(volumeTiers[i]) ||
1825
+ stakedQuoteAssetAmount.gte(stakedTiers[i])) {
1826
+ feeTierIndex = 5 - i;
1827
+ break;
1828
+ }
1829
+ }
1830
+ return state.perpFeeStructure.feeTiers[feeTierIndex];
1831
+ }
1832
+ return state.spotFeeStructure.feeTiers[feeTierIndex];
1833
+ }
1834
+ /**
1835
+ * Calculates how much perp fee will be taken for a given sized trade
1836
+ * @param quoteAmount
1837
+ * @returns feeForQuote : Precision QUOTE_PRECISION
1838
+ */
1839
+ calculateFeeForQuoteAmount(quoteAmount, marketIndex) {
1840
+ if (marketIndex !== undefined) {
1841
+ const takerFeeMultiplier = this.driftClient.getMarketFees(_1.MarketType.PERP, marketIndex, this).takerFee;
1842
+ const feeAmountNum = _1.BigNum.from(quoteAmount, numericConstants_1.QUOTE_PRECISION_EXP).toNum() *
1843
+ takerFeeMultiplier;
1844
+ return _1.BigNum.fromPrint(feeAmountNum.toString(), numericConstants_1.QUOTE_PRECISION_EXP).val;
1845
+ }
1846
+ else {
1847
+ const feeTier = this.getUserFeeTier(_1.MarketType.PERP);
1848
+ return quoteAmount
1849
+ .mul(new _1.BN(feeTier.feeNumerator))
1850
+ .div(new _1.BN(feeTier.feeDenominator));
1851
+ }
1852
+ }
1853
+ /**
1854
+ * Calculates a user's max withdrawal amounts for a spot market. If reduceOnly is true,
1855
+ * it will return the max withdrawal amount without opening a liability for the user
1856
+ * @param marketIndex
1857
+ * @returns withdrawalLimit : Precision is the token precision for the chosen SpotMarket
1858
+ */
1859
+ getWithdrawalLimit(marketIndex, reduceOnly) {
1860
+ const nowTs = new _1.BN(Math.floor(Date.now() / 1000));
1861
+ const spotMarket = this.driftClient.getSpotMarketAccount(marketIndex);
1862
+ // eslint-disable-next-line prefer-const
1863
+ let { borrowLimit, withdrawLimit } = (0, spotBalance_1.calculateWithdrawLimit)(spotMarket, nowTs);
1864
+ const freeCollateral = this.getFreeCollateral();
1865
+ const initialMarginRequirement = this.getInitialMarginRequirement();
1866
+ const oracleData = this.getOracleDataForSpotMarket(marketIndex);
1867
+ const precisionIncrease = numericConstants_1.TEN.pow(new _1.BN(spotMarket.decimals - 6));
1868
+ const { canBypass, depositAmount: userDepositAmount } = this.canBypassWithdrawLimits(marketIndex);
1869
+ if (canBypass) {
1870
+ withdrawLimit = _1.BN.max(withdrawLimit, userDepositAmount);
1871
+ }
1872
+ const assetWeight = (0, spotBalance_1.calculateAssetWeight)(userDepositAmount, oracleData.price, spotMarket, 'Initial');
1873
+ let amountWithdrawable;
1874
+ if (assetWeight.eq(numericConstants_1.ZERO)) {
1875
+ amountWithdrawable = userDepositAmount;
1876
+ }
1877
+ else if (initialMarginRequirement.eq(numericConstants_1.ZERO)) {
1878
+ amountWithdrawable = userDepositAmount;
1879
+ }
1880
+ else {
1881
+ amountWithdrawable = (0, _1.divCeil)((0, _1.divCeil)(freeCollateral.mul(numericConstants_1.MARGIN_PRECISION), assetWeight).mul(numericConstants_1.PRICE_PRECISION), oracleData.price).mul(precisionIncrease);
1882
+ }
1883
+ const maxWithdrawValue = _1.BN.min(_1.BN.min(amountWithdrawable, userDepositAmount), withdrawLimit.abs());
1884
+ if (reduceOnly) {
1885
+ return _1.BN.max(maxWithdrawValue, numericConstants_1.ZERO);
1886
+ }
1887
+ else {
1888
+ const weightedAssetValue = this.getSpotMarketAssetValue(marketIndex, 'Initial', false);
1889
+ const freeCollatAfterWithdraw = userDepositAmount.gt(numericConstants_1.ZERO)
1890
+ ? freeCollateral.sub(weightedAssetValue)
1891
+ : freeCollateral;
1892
+ const maxLiabilityAllowed = freeCollatAfterWithdraw
1893
+ .mul(numericConstants_1.MARGIN_PRECISION)
1894
+ .div(new _1.BN(spotMarket.initialLiabilityWeight))
1895
+ .mul(numericConstants_1.PRICE_PRECISION)
1896
+ .div(oracleData.price)
1897
+ .mul(precisionIncrease);
1898
+ const maxBorrowValue = _1.BN.min(maxWithdrawValue.add(maxLiabilityAllowed), borrowLimit.abs());
1899
+ return _1.BN.max(maxBorrowValue, numericConstants_1.ZERO);
1900
+ }
1901
+ }
1902
+ canBypassWithdrawLimits(marketIndex) {
1903
+ const spotMarket = this.driftClient.getSpotMarketAccount(marketIndex);
1904
+ const maxDepositAmount = spotMarket.withdrawGuardThreshold.div(new _1.BN(10));
1905
+ const position = this.getSpotPosition(marketIndex);
1906
+ const netDeposits = this.getUserAccount().totalDeposits.sub(this.getUserAccount().totalWithdraws);
1907
+ if (!position) {
1908
+ return {
1909
+ canBypass: false,
1910
+ maxDepositAmount,
1911
+ depositAmount: numericConstants_1.ZERO,
1912
+ netDeposits,
1913
+ };
1914
+ }
1915
+ if ((0, types_1.isVariant)(position.balanceType, 'borrow')) {
1916
+ return {
1917
+ canBypass: false,
1918
+ maxDepositAmount,
1919
+ netDeposits,
1920
+ depositAmount: numericConstants_1.ZERO,
1921
+ };
1922
+ }
1923
+ const depositAmount = (0, spotBalance_1.getTokenAmount)(position.scaledBalance, spotMarket, _1.SpotBalanceType.DEPOSIT);
1924
+ if (netDeposits.lt(numericConstants_1.ZERO)) {
1925
+ return {
1926
+ canBypass: false,
1927
+ maxDepositAmount,
1928
+ depositAmount,
1929
+ netDeposits,
1930
+ };
1931
+ }
1932
+ return {
1933
+ canBypass: depositAmount.lt(maxDepositAmount),
1934
+ maxDepositAmount,
1935
+ netDeposits,
1936
+ depositAmount,
1937
+ };
1938
+ }
1939
+ canMakeIdle(slot) {
1940
+ const userAccount = this.getUserAccount();
1941
+ if (userAccount.idle) {
1942
+ return false;
1943
+ }
1944
+ const { totalAssetValue, totalLiabilityValue } = this.getSpotMarketAssetAndLiabilityValue();
1945
+ const equity = totalAssetValue.sub(totalLiabilityValue);
1946
+ let slotsBeforeIdle;
1947
+ if (equity.lt(numericConstants_1.QUOTE_PRECISION.muln(1000))) {
1948
+ slotsBeforeIdle = new _1.BN(9000); // 1 hour
1949
+ }
1950
+ else {
1951
+ slotsBeforeIdle = new _1.BN(1512000); // 1 week
1952
+ }
1953
+ const userLastActiveSlot = userAccount.lastActiveSlot;
1954
+ const slotsSinceLastActive = slot.sub(userLastActiveSlot);
1955
+ if (slotsSinceLastActive.lt(slotsBeforeIdle)) {
1956
+ return false;
1957
+ }
1958
+ if (this.isBeingLiquidated()) {
1959
+ return false;
1960
+ }
1961
+ for (const perpPosition of userAccount.perpPositions) {
1962
+ if (!(0, position_1.positionIsAvailable)(perpPosition)) {
1963
+ return false;
1964
+ }
1965
+ }
1966
+ for (const spotPosition of userAccount.spotPositions) {
1967
+ if ((0, types_1.isVariant)(spotPosition.balanceType, 'borrow') &&
1968
+ spotPosition.scaledBalance.gt(numericConstants_1.ZERO)) {
1969
+ return false;
1970
+ }
1971
+ if (spotPosition.openOrders !== 0) {
1972
+ return false;
1973
+ }
1974
+ }
1975
+ for (const order of userAccount.orders) {
1976
+ if (!(0, types_1.isVariant)(order.status, 'init')) {
1977
+ return false;
1978
+ }
1979
+ }
1980
+ return true;
1981
+ }
1982
+ getSafestTiers() {
1983
+ let safestPerpTier = 4;
1984
+ let safestSpotTier = 4;
1985
+ for (const perpPosition of this.getActivePerpPositions()) {
1986
+ safestPerpTier = Math.min(safestPerpTier, (0, tiers_1.getPerpMarketTierNumber)(this.driftClient.getPerpMarketAccount(perpPosition.marketIndex)));
1987
+ }
1988
+ for (const spotPosition of this.getActiveSpotPositions()) {
1989
+ if ((0, types_1.isVariant)(spotPosition.balanceType, 'deposit')) {
1990
+ continue;
1991
+ }
1992
+ safestSpotTier = Math.min(safestSpotTier, (0, tiers_1.getSpotMarketTierNumber)(this.driftClient.getSpotMarketAccount(spotPosition.marketIndex)));
1993
+ }
1994
+ return {
1995
+ perpTier: safestPerpTier,
1996
+ spotTier: safestSpotTier,
1997
+ };
1998
+ }
1999
+ getPerpPositionHealth({ marginCategory, perpPosition, oraclePriceData, quoteOraclePriceData, }) {
2000
+ const settledLpPosition = this.getPerpPositionWithLPSettle(perpPosition.marketIndex, perpPosition)[0];
2001
+ const perpMarket = this.driftClient.getPerpMarketAccount(perpPosition.marketIndex);
2002
+ const _oraclePriceData = oraclePriceData ||
2003
+ this.driftClient.getOracleDataForPerpMarket(perpMarket.marketIndex);
2004
+ const oraclePrice = _oraclePriceData.price;
2005
+ const { worstCaseBaseAssetAmount: worstCaseBaseAmount, worstCaseLiabilityValue, } = (0, _1.calculateWorstCasePerpLiabilityValue)(settledLpPosition, perpMarket, oraclePrice);
2006
+ const marginRatio = new _1.BN((0, _1.calculateMarketMarginRatio)(perpMarket, worstCaseBaseAmount.abs(), marginCategory, this.getUserAccount().maxMarginRatio, this.isHighLeverageMode()));
2007
+ const _quoteOraclePriceData = quoteOraclePriceData ||
2008
+ this.driftClient.getOracleDataForSpotMarket(numericConstants_1.QUOTE_SPOT_MARKET_INDEX);
2009
+ let marginRequirement = worstCaseLiabilityValue
2010
+ .mul(_quoteOraclePriceData.price)
2011
+ .div(numericConstants_1.PRICE_PRECISION)
2012
+ .mul(marginRatio)
2013
+ .div(numericConstants_1.MARGIN_PRECISION);
2014
+ marginRequirement = marginRequirement.add(new _1.BN(perpPosition.openOrders).mul(numericConstants_1.OPEN_ORDER_MARGIN_REQUIREMENT));
2015
+ if (perpPosition.lpShares.gt(numericConstants_1.ZERO)) {
2016
+ marginRequirement = marginRequirement.add(_1.BN.max(numericConstants_1.QUOTE_PRECISION, oraclePrice
2017
+ .mul(perpMarket.amm.orderStepSize)
2018
+ .mul(numericConstants_1.QUOTE_PRECISION)
2019
+ .div(numericConstants_1.AMM_RESERVE_PRECISION)
2020
+ .div(numericConstants_1.PRICE_PRECISION)));
2021
+ }
2022
+ return {
2023
+ marketIndex: perpMarket.marketIndex,
2024
+ size: worstCaseBaseAmount,
2025
+ value: worstCaseLiabilityValue,
2026
+ weight: marginRatio,
2027
+ weightedValue: marginRequirement,
2028
+ };
2029
+ }
2030
+ getHealthComponents({ marginCategory, }) {
2031
+ const healthComponents = {
2032
+ deposits: [],
2033
+ borrows: [],
2034
+ perpPositions: [],
2035
+ perpPnl: [],
2036
+ };
2037
+ for (const perpPosition of this.getActivePerpPositions()) {
2038
+ const perpMarket = this.driftClient.getPerpMarketAccount(perpPosition.marketIndex);
2039
+ const oraclePriceData = this.driftClient.getOracleDataForPerpMarket(perpMarket.marketIndex);
2040
+ const quoteOraclePriceData = this.driftClient.getOracleDataForSpotMarket(numericConstants_1.QUOTE_SPOT_MARKET_INDEX);
2041
+ healthComponents.perpPositions.push(this.getPerpPositionHealth({
2042
+ marginCategory,
2043
+ perpPosition,
2044
+ oraclePriceData,
2045
+ quoteOraclePriceData,
2046
+ }));
2047
+ const quoteSpotMarket = this.driftClient.getSpotMarketAccount(perpMarket.quoteSpotMarketIndex);
2048
+ const settledPerpPosition = this.getPerpPositionWithLPSettle(perpPosition.marketIndex, perpPosition)[0];
2049
+ const positionUnrealizedPnl = (0, _1.calculatePositionPNL)(perpMarket, settledPerpPosition, true, oraclePriceData);
2050
+ let pnlWeight;
2051
+ if (positionUnrealizedPnl.gt(numericConstants_1.ZERO)) {
2052
+ pnlWeight = (0, _1.calculateUnrealizedAssetWeight)(perpMarket, quoteSpotMarket, positionUnrealizedPnl, marginCategory, oraclePriceData);
2053
+ }
2054
+ else {
2055
+ pnlWeight = numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION;
2056
+ }
2057
+ const pnlValue = positionUnrealizedPnl
2058
+ .mul(quoteOraclePriceData.price)
2059
+ .div(numericConstants_1.PRICE_PRECISION);
2060
+ const wegithedPnlValue = pnlValue
2061
+ .mul(pnlWeight)
2062
+ .div(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION);
2063
+ healthComponents.perpPnl.push({
2064
+ marketIndex: perpMarket.marketIndex,
2065
+ size: positionUnrealizedPnl,
2066
+ value: pnlValue,
2067
+ weight: pnlWeight,
2068
+ weightedValue: wegithedPnlValue,
2069
+ });
2070
+ }
2071
+ let netQuoteValue = numericConstants_1.ZERO;
2072
+ for (const spotPosition of this.getActiveSpotPositions()) {
2073
+ const spotMarketAccount = this.driftClient.getSpotMarketAccount(spotPosition.marketIndex);
2074
+ const oraclePriceData = this.getOracleDataForSpotMarket(spotPosition.marketIndex);
2075
+ const strictOraclePrice = new strictOraclePrice_1.StrictOraclePrice(oraclePriceData.price);
2076
+ if (spotPosition.marketIndex === numericConstants_1.QUOTE_SPOT_MARKET_INDEX) {
2077
+ const tokenAmount = (0, _1.getSignedTokenAmount)((0, spotBalance_1.getTokenAmount)(spotPosition.scaledBalance, spotMarketAccount, spotPosition.balanceType), spotPosition.balanceType);
2078
+ netQuoteValue = netQuoteValue.add(tokenAmount);
2079
+ continue;
2080
+ }
2081
+ const { tokenAmount: worstCaseTokenAmount, tokenValue: tokenValue, weight, weightedTokenValue: weightedTokenValue, ordersValue: ordersValue, } = (0, spotPosition_1.getWorstCaseTokenAmounts)(spotPosition, spotMarketAccount, strictOraclePrice, marginCategory, this.getUserAccount().maxMarginRatio);
2082
+ netQuoteValue = netQuoteValue.add(ordersValue);
2083
+ const baseAssetValue = tokenValue.abs();
2084
+ const weightedValue = weightedTokenValue.abs();
2085
+ if (weightedTokenValue.lt(numericConstants_1.ZERO)) {
2086
+ healthComponents.borrows.push({
2087
+ marketIndex: spotMarketAccount.marketIndex,
2088
+ size: worstCaseTokenAmount,
2089
+ value: baseAssetValue,
2090
+ weight: weight,
2091
+ weightedValue: weightedValue,
2092
+ });
2093
+ }
2094
+ else {
2095
+ healthComponents.deposits.push({
2096
+ marketIndex: spotMarketAccount.marketIndex,
2097
+ size: worstCaseTokenAmount,
2098
+ value: baseAssetValue,
2099
+ weight: weight,
2100
+ weightedValue: weightedValue,
2101
+ });
2102
+ }
2103
+ }
2104
+ if (!netQuoteValue.eq(numericConstants_1.ZERO)) {
2105
+ const spotMarketAccount = this.driftClient.getQuoteSpotMarketAccount();
2106
+ const oraclePriceData = this.getOracleDataForSpotMarket(numericConstants_1.QUOTE_SPOT_MARKET_INDEX);
2107
+ const baseAssetValue = (0, _1.getTokenValue)(netQuoteValue, spotMarketAccount.decimals, oraclePriceData);
2108
+ const { weight, weightedTokenValue } = (0, spotPosition_1.calculateWeightedTokenValue)(netQuoteValue, baseAssetValue, oraclePriceData.price, spotMarketAccount, marginCategory, this.getUserAccount().maxMarginRatio);
2109
+ if (netQuoteValue.lt(numericConstants_1.ZERO)) {
2110
+ healthComponents.borrows.push({
2111
+ marketIndex: spotMarketAccount.marketIndex,
2112
+ size: netQuoteValue,
2113
+ value: baseAssetValue.abs(),
2114
+ weight: weight,
2115
+ weightedValue: weightedTokenValue.abs(),
2116
+ });
2117
+ }
2118
+ else {
2119
+ healthComponents.deposits.push({
2120
+ marketIndex: spotMarketAccount.marketIndex,
2121
+ size: netQuoteValue,
2122
+ value: baseAssetValue,
2123
+ weight: weight,
2124
+ weightedValue: weightedTokenValue,
2125
+ });
2126
+ }
2127
+ }
2128
+ return healthComponents;
2129
+ }
2130
+ /**
2131
+ * Get the total position value, excluding any position coming from the given target market
2132
+ * @param marketToIgnore
2133
+ * @returns positionValue : Precision QUOTE_PRECISION
2134
+ */
2135
+ getTotalPerpPositionValueExcludingMarket(marketToIgnore, marginCategory, liquidationBuffer, includeOpenOrders) {
2136
+ const currentPerpPosition = this.getPerpPositionWithLPSettle(marketToIgnore, undefined, !!marginCategory)[0] || this.getEmptyPosition(marketToIgnore);
2137
+ const oracleData = this.getOracleDataForPerpMarket(marketToIgnore);
2138
+ let currentPerpPositionValueUSDC = numericConstants_1.ZERO;
2139
+ if (currentPerpPosition) {
2140
+ currentPerpPositionValueUSDC = this.getPerpLiabilityValue(marketToIgnore, oracleData, includeOpenOrders);
2141
+ }
2142
+ return this.getTotalPerpPositionLiability(marginCategory, liquidationBuffer, includeOpenOrders).sub(currentPerpPositionValueUSDC);
2143
+ }
2144
+ getOracleDataForPerpMarket(marketIndex) {
2145
+ return this.driftClient.getOracleDataForPerpMarket(marketIndex);
2146
+ }
2147
+ getOracleDataForSpotMarket(marketIndex) {
2148
+ return this.driftClient.getOracleDataForSpotMarket(marketIndex);
2149
+ }
2150
+ }
2151
+ exports.User = User;