@velocity-exchange/sdk 0.2.5 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1057) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/README.md +3 -3
  3. package/lib/browser/accounts/basicUserAccountSubscriber.d.ts +18 -0
  4. package/lib/browser/accounts/basicUserAccountSubscriber.js +18 -0
  5. package/lib/browser/accounts/basicUserStatsAccountSubscriber.d.ts +18 -0
  6. package/lib/browser/accounts/basicUserStatsAccountSubscriber.js +18 -0
  7. package/lib/browser/accounts/bulkAccountLoader.d.ts +52 -0
  8. package/lib/browser/accounts/bulkAccountLoader.js +51 -0
  9. package/lib/browser/accounts/bulkUserStatsSubscription.d.ts +9 -2
  10. package/lib/browser/accounts/bulkUserStatsSubscription.js +9 -2
  11. package/lib/browser/accounts/bulkUserSubscription.d.ts +8 -2
  12. package/lib/browser/accounts/bulkUserSubscription.js +8 -2
  13. package/lib/browser/accounts/customizedCadenceBulkAccountLoader.d.ts +37 -0
  14. package/lib/browser/accounts/customizedCadenceBulkAccountLoader.js +37 -0
  15. package/lib/browser/accounts/fetch.d.ts +59 -2
  16. package/lib/browser/accounts/fetch.js +57 -2
  17. package/lib/browser/accounts/grpcAccountSubscriber.d.ts +30 -0
  18. package/lib/browser/accounts/grpcAccountSubscriber.js +30 -0
  19. package/lib/browser/accounts/grpcInsuranceFundStakeAccountSubscriber.d.ts +16 -0
  20. package/lib/browser/accounts/grpcInsuranceFundStakeAccountSubscriber.js +16 -0
  21. package/lib/browser/accounts/grpcMultiAccountSubscriber.d.ts +60 -1
  22. package/lib/browser/accounts/grpcMultiAccountSubscriber.js +118 -37
  23. package/lib/browser/accounts/grpcMultiUserAccountSubscriber.d.ts +32 -0
  24. package/lib/browser/accounts/grpcMultiUserAccountSubscriber.js +40 -12
  25. package/lib/browser/accounts/grpcProgramAccountSubscriber.d.ts +33 -0
  26. package/lib/browser/accounts/grpcProgramAccountSubscriber.js +33 -0
  27. package/lib/browser/accounts/grpcUserAccountSubscriber.d.ts +15 -0
  28. package/lib/browser/accounts/grpcUserAccountSubscriber.js +15 -0
  29. package/lib/browser/accounts/grpcUserStatsAccountSubscriber.d.ts +15 -0
  30. package/lib/browser/accounts/grpcUserStatsAccountSubscriber.js +15 -0
  31. package/lib/browser/accounts/grpcVelocityClientAccountSubscriber.d.ts +41 -0
  32. package/lib/browser/accounts/grpcVelocityClientAccountSubscriber.js +41 -0
  33. package/lib/browser/accounts/grpcVelocityClientAccountSubscriberV2.d.ts +116 -0
  34. package/lib/browser/accounts/grpcVelocityClientAccountSubscriberV2.js +152 -1
  35. package/lib/browser/accounts/laserProgramAccountSubscriber.d.ts +34 -0
  36. package/lib/browser/accounts/laserProgramAccountSubscriber.js +34 -0
  37. package/lib/browser/accounts/oneShotUserAccountSubscriber.d.ts +19 -0
  38. package/lib/browser/accounts/oneShotUserAccountSubscriber.js +19 -0
  39. package/lib/browser/accounts/oneShotUserStatsAccountSubscriber.d.ts +19 -0
  40. package/lib/browser/accounts/oneShotUserStatsAccountSubscriber.js +19 -0
  41. package/lib/browser/accounts/pollingInsuranceFundStakeAccountSubscriber.d.ts +31 -0
  42. package/lib/browser/accounts/pollingInsuranceFundStakeAccountSubscriber.js +31 -0
  43. package/lib/browser/accounts/pollingOracleAccountSubscriber.d.ts +19 -0
  44. package/lib/browser/accounts/pollingOracleAccountSubscriber.js +21 -2
  45. package/lib/browser/accounts/pollingTokenAccountSubscriber.d.ts +22 -0
  46. package/lib/browser/accounts/pollingTokenAccountSubscriber.js +22 -0
  47. package/lib/browser/accounts/pollingUserAccountSubscriber.d.ts +32 -0
  48. package/lib/browser/accounts/pollingUserAccountSubscriber.js +32 -0
  49. package/lib/browser/accounts/pollingUserStatsAccountSubscriber.d.ts +22 -0
  50. package/lib/browser/accounts/pollingUserStatsAccountSubscriber.js +22 -0
  51. package/lib/browser/accounts/pollingVelocityClientAccountSubscriber.d.ts +83 -0
  52. package/lib/browser/accounts/pollingVelocityClientAccountSubscriber.js +84 -1
  53. package/lib/browser/accounts/testBulkAccountLoader.d.ts +8 -0
  54. package/lib/browser/accounts/testBulkAccountLoader.js +8 -0
  55. package/lib/browser/accounts/types.d.ts +149 -0
  56. package/lib/browser/accounts/types.js +13 -0
  57. package/lib/browser/accounts/utils.d.ts +18 -0
  58. package/lib/browser/accounts/utils.js +32 -16
  59. package/lib/browser/accounts/webSocketAccountSubscriber.d.ts +41 -0
  60. package/lib/browser/accounts/webSocketAccountSubscriber.js +41 -0
  61. package/lib/browser/accounts/webSocketAccountSubscriberV2.d.ts +31 -0
  62. package/lib/browser/accounts/webSocketAccountSubscriberV2.js +31 -23
  63. package/lib/browser/accounts/webSocketInsuranceFundStakeAccountSubscriber.d.ts +27 -0
  64. package/lib/browser/accounts/webSocketInsuranceFundStakeAccountSubscriber.js +27 -0
  65. package/lib/browser/accounts/webSocketProgramAccountSubscriber.d.ts +36 -0
  66. package/lib/browser/accounts/webSocketProgramAccountSubscriber.js +36 -0
  67. package/lib/browser/accounts/webSocketProgramAccountSubscriberV2.d.ts +21 -0
  68. package/lib/browser/accounts/webSocketProgramAccountSubscriberV2.js +25 -0
  69. package/lib/browser/accounts/webSocketProgramAccountsSubscriberV2.d.ts +21 -0
  70. package/lib/browser/accounts/webSocketProgramAccountsSubscriberV2.js +21 -0
  71. package/lib/browser/accounts/webSocketUserAccountSubscriber.d.ts +26 -0
  72. package/lib/browser/accounts/webSocketUserAccountSubscriber.js +26 -0
  73. package/lib/browser/accounts/webSocketUserStatsAccountSubsriber.d.ts +20 -0
  74. package/lib/browser/accounts/webSocketUserStatsAccountSubsriber.js +20 -0
  75. package/lib/browser/accounts/webSocketVelocityClientAccountSubscriber.d.ts +121 -0
  76. package/lib/browser/accounts/webSocketVelocityClientAccountSubscriber.js +123 -2
  77. package/lib/browser/accounts/webSocketVelocityClientAccountSubscriberV2.d.ts +96 -0
  78. package/lib/browser/accounts/webSocketVelocityClientAccountSubscriberV2.js +108 -0
  79. package/lib/browser/accounts/websocketProgramUserAccountSubscriber.d.ts +28 -0
  80. package/lib/browser/accounts/websocketProgramUserAccountSubscriber.js +33 -0
  81. package/lib/browser/addresses/marketAddresses.d.ts +10 -0
  82. package/lib/browser/addresses/marketAddresses.js +10 -0
  83. package/lib/browser/addresses/pda.d.ts +214 -2
  84. package/lib/browser/addresses/pda.js +217 -5
  85. package/lib/browser/adminClient.d.ts +2139 -5
  86. package/lib/browser/adminClient.js +2173 -11
  87. package/lib/browser/auctionSubscriber/auctionSubscriber.d.ts +15 -0
  88. package/lib/browser/auctionSubscriber/auctionSubscriber.js +15 -0
  89. package/lib/browser/auctionSubscriber/auctionSubscriberGrpc.d.ts +19 -0
  90. package/lib/browser/auctionSubscriber/auctionSubscriberGrpc.js +19 -0
  91. package/lib/browser/auctionSubscriber/index.d.ts +6 -0
  92. package/lib/browser/auctionSubscriber/index.js +6 -0
  93. package/lib/browser/auctionSubscriber/types.d.ts +7 -0
  94. package/lib/browser/blockhashSubscriber/BlockhashSubscriber.d.ts +33 -0
  95. package/lib/browser/blockhashSubscriber/BlockhashSubscriber.js +33 -0
  96. package/lib/browser/blockhashSubscriber/index.d.ts +5 -0
  97. package/lib/browser/blockhashSubscriber/index.js +5 -0
  98. package/lib/browser/blockhashSubscriber/types.d.ts +5 -0
  99. package/lib/browser/clock/clockSubscriber.d.ts +24 -0
  100. package/lib/browser/clock/clockSubscriber.js +22 -0
  101. package/lib/browser/config.d.ts +58 -4
  102. package/lib/browser/config.js +88 -21
  103. package/lib/browser/constants/numericConstants.d.ts +67 -0
  104. package/lib/browser/constants/numericConstants.js +68 -1
  105. package/lib/browser/constants/perpMarkets.d.ts +10 -0
  106. package/lib/browser/constants/perpMarkets.js +40 -908
  107. package/lib/browser/constants/spotMarkets.d.ts +13 -0
  108. package/lib/browser/constants/spotMarkets.js +16 -742
  109. package/lib/browser/constants/txConstants.d.ts +1 -0
  110. package/lib/browser/constants/txConstants.js +1 -0
  111. package/lib/browser/core/VelocityCore.d.ts +285 -8
  112. package/lib/browser/core/VelocityCore.js +281 -8
  113. package/lib/browser/core/instructions/deposit.d.ts +22 -0
  114. package/lib/browser/core/instructions/deposit.js +22 -0
  115. package/lib/browser/core/instructions/fill.d.ts +17 -0
  116. package/lib/browser/core/instructions/fill.js +17 -0
  117. package/lib/browser/core/instructions/funding.d.ts +12 -0
  118. package/lib/browser/core/instructions/funding.js +12 -0
  119. package/lib/browser/core/instructions/liquidation.d.ts +18 -0
  120. package/lib/browser/core/instructions/liquidation.js +18 -0
  121. package/lib/browser/core/instructions/orders.d.ts +28 -0
  122. package/lib/browser/core/instructions/orders.js +28 -0
  123. package/lib/browser/core/instructions/perpOrders.d.ts +106 -0
  124. package/lib/browser/core/instructions/perpOrders.js +106 -0
  125. package/lib/browser/core/instructions/settlement.d.ts +14 -0
  126. package/lib/browser/core/instructions/settlement.js +14 -0
  127. package/lib/browser/core/instructions/trigger.d.ts +15 -0
  128. package/lib/browser/core/instructions/trigger.js +15 -0
  129. package/lib/browser/core/instructions/withdraw.d.ts +21 -0
  130. package/lib/browser/core/instructions/withdraw.js +21 -0
  131. package/lib/browser/core/remainingAccounts.d.ts +47 -3
  132. package/lib/browser/core/remainingAccounts.js +20 -0
  133. package/lib/browser/core/signedMsg.d.ts +38 -0
  134. package/lib/browser/core/signedMsg.js +33 -0
  135. package/lib/browser/decode/customCoder.d.ts +39 -3
  136. package/lib/browser/decode/customCoder.js +45 -3
  137. package/lib/browser/decode/user.d.ts +22 -0
  138. package/lib/browser/decode/user.js +22 -0
  139. package/lib/browser/dlob/DLOB.d.ts +502 -53
  140. package/lib/browser/dlob/DLOB.js +540 -98
  141. package/lib/browser/dlob/DLOBNode.d.ts +86 -4
  142. package/lib/browser/dlob/DLOBNode.js +37 -4
  143. package/lib/browser/dlob/DLOBSubscriber.d.ts +39 -12
  144. package/lib/browser/dlob/DLOBSubscriber.js +42 -12
  145. package/lib/browser/dlob/NodeList.d.ts +69 -0
  146. package/lib/browser/dlob/NodeList.js +66 -0
  147. package/lib/browser/dlob/orderBookLevels.d.ts +106 -13
  148. package/lib/browser/dlob/orderBookLevels.js +84 -14
  149. package/lib/browser/dlob/types.d.ts +15 -0
  150. package/lib/browser/events/eventList.d.ts +14 -0
  151. package/lib/browser/events/eventList.js +14 -0
  152. package/lib/browser/events/eventSubscriber.d.ts +87 -10
  153. package/lib/browser/events/eventSubscriber.js +93 -8
  154. package/lib/browser/events/eventsServerLogProvider.d.ts +22 -0
  155. package/lib/browser/events/eventsServerLogProvider.js +27 -0
  156. package/lib/browser/events/fetchLogs.d.ts +31 -0
  157. package/lib/browser/events/fetchLogs.js +46 -1
  158. package/lib/browser/events/parse.d.ts +23 -0
  159. package/lib/browser/events/parse.js +23 -0
  160. package/lib/browser/events/pollingLogProvider.d.ts +24 -0
  161. package/lib/browser/events/pollingLogProvider.js +24 -0
  162. package/lib/browser/events/sort.d.ts +11 -0
  163. package/lib/browser/events/sort.js +12 -0
  164. package/lib/browser/events/txEventCache.d.ts +13 -3
  165. package/lib/browser/events/txEventCache.js +19 -7
  166. package/lib/browser/events/types.d.ts +118 -2
  167. package/lib/browser/events/types.js +11 -0
  168. package/lib/browser/events/webSocketLogProvider.d.ts +23 -0
  169. package/lib/browser/events/webSocketLogProvider.js +28 -0
  170. package/lib/browser/factory/oracleClient.js +2 -2
  171. package/lib/browser/idl/velocity.d.ts +50 -1
  172. package/lib/browser/idl/velocity.json +50 -1
  173. package/lib/browser/keypair.d.ts +8 -0
  174. package/lib/browser/keypair.js +8 -0
  175. package/lib/browser/marginCalculation.d.ts +134 -2
  176. package/lib/browser/marginCalculation.js +121 -0
  177. package/lib/browser/math/amm.d.ts +348 -29
  178. package/lib/browser/math/amm.js +310 -32
  179. package/lib/browser/math/auction.d.ts +95 -19
  180. package/lib/browser/math/auction.js +118 -28
  181. package/lib/browser/math/bankruptcy.d.ts +46 -0
  182. package/lib/browser/math/bankruptcy.js +89 -1
  183. package/lib/browser/math/builder.d.ts +64 -8
  184. package/lib/browser/math/builder.js +71 -9
  185. package/lib/browser/math/conversion.d.ts +21 -0
  186. package/lib/browser/math/conversion.js +21 -0
  187. package/lib/browser/math/exchangeStatus.d.ts +92 -0
  188. package/lib/browser/math/exchangeStatus.js +111 -1
  189. package/lib/browser/math/funding.d.ts +57 -20
  190. package/lib/browser/math/funding.js +63 -23
  191. package/lib/browser/math/insurance.d.ts +62 -0
  192. package/lib/browser/math/insurance.js +62 -0
  193. package/lib/browser/math/liquidation.d.ts +127 -11
  194. package/lib/browser/math/liquidation.js +182 -19
  195. package/lib/browser/math/margin.d.ts +79 -13
  196. package/lib/browser/math/margin.js +80 -14
  197. package/lib/browser/math/market.d.ts +135 -15
  198. package/lib/browser/math/market.js +145 -17
  199. package/lib/browser/math/oracles.d.ts +113 -0
  200. package/lib/browser/math/oracles.js +118 -1
  201. package/lib/browser/math/orders.d.ts +115 -7
  202. package/lib/browser/math/orders.js +133 -18
  203. package/lib/browser/math/position.d.ts +80 -33
  204. package/lib/browser/math/position.js +80 -33
  205. package/lib/browser/math/repeg.d.ts +48 -10
  206. package/lib/browser/math/repeg.js +48 -10
  207. package/lib/browser/math/spotBalance.d.ts +200 -5
  208. package/lib/browser/math/spotBalance.js +239 -10
  209. package/lib/browser/math/spotMarket.d.ts +36 -3
  210. package/lib/browser/math/spotMarket.js +36 -3
  211. package/lib/browser/math/spotPosition.d.ts +72 -0
  212. package/lib/browser/math/spotPosition.js +62 -0
  213. package/lib/browser/math/state.d.ts +31 -0
  214. package/lib/browser/math/state.js +32 -1
  215. package/lib/browser/math/superStake.d.ts +126 -2
  216. package/lib/browser/math/superStake.js +123 -3
  217. package/lib/browser/math/tiers.d.ts +29 -0
  218. package/lib/browser/math/tiers.js +29 -0
  219. package/lib/browser/math/trade.d.ts +102 -51
  220. package/lib/browser/math/trade.js +101 -55
  221. package/lib/browser/math/utils.d.ts +71 -9
  222. package/lib/browser/math/utils.js +71 -9
  223. package/lib/browser/memcmp.d.ts +94 -0
  224. package/lib/browser/memcmp.js +129 -7
  225. package/lib/browser/oracles/oracleClientCache.d.ts +16 -0
  226. package/lib/browser/oracles/oracleClientCache.js +16 -0
  227. package/lib/browser/oracles/oracleId.d.ts +31 -0
  228. package/lib/browser/oracles/oracleId.js +39 -8
  229. package/lib/browser/oracles/prelaunchOracleClient.d.ts +20 -0
  230. package/lib/browser/oracles/prelaunchOracleClient.js +20 -0
  231. package/lib/browser/oracles/pythClient.d.ts +31 -0
  232. package/lib/browser/oracles/pythClient.js +32 -1
  233. package/lib/browser/oracles/pythLazerClient.d.ts +34 -0
  234. package/lib/browser/oracles/pythLazerClient.js +35 -1
  235. package/lib/browser/oracles/quoteAssetOracleClient.d.ts +18 -0
  236. package/lib/browser/oracles/quoteAssetOracleClient.js +18 -0
  237. package/lib/browser/oracles/strictOraclePrice.d.ts +21 -0
  238. package/lib/browser/oracles/strictOraclePrice.js +21 -0
  239. package/lib/browser/oracles/types.d.ts +45 -0
  240. package/lib/browser/oracles/utils.d.ts +20 -0
  241. package/lib/browser/oracles/utils.js +20 -0
  242. package/lib/browser/orderParams.d.ts +42 -4
  243. package/lib/browser/orderParams.js +42 -4
  244. package/lib/browser/orderSubscriber/OrderSubscriber.d.ts +56 -0
  245. package/lib/browser/orderSubscriber/OrderSubscriber.js +67 -2
  246. package/lib/browser/orderSubscriber/PollingSubscription.d.ts +11 -0
  247. package/lib/browser/orderSubscriber/PollingSubscription.js +11 -0
  248. package/lib/browser/orderSubscriber/WebsocketSubscription.d.ts +18 -0
  249. package/lib/browser/orderSubscriber/WebsocketSubscription.js +18 -0
  250. package/lib/browser/orderSubscriber/grpcSubscription.d.ts +16 -0
  251. package/lib/browser/orderSubscriber/grpcSubscription.js +16 -0
  252. package/lib/browser/orderSubscriber/types.d.ts +9 -0
  253. package/lib/browser/priorityFee/averageOverSlotsStrategy.d.ts +1 -0
  254. package/lib/browser/priorityFee/averageOverSlotsStrategy.js +1 -0
  255. package/lib/browser/priorityFee/averageStrategy.d.ts +1 -0
  256. package/lib/browser/priorityFee/averageStrategy.js +1 -0
  257. package/lib/browser/priorityFee/ewmaStrategy.d.ts +10 -0
  258. package/lib/browser/priorityFee/ewmaStrategy.js +10 -0
  259. package/lib/browser/priorityFee/heliusPriorityFeeMethod.d.ts +13 -0
  260. package/lib/browser/priorityFee/heliusPriorityFeeMethod.js +9 -2
  261. package/lib/browser/priorityFee/maxOverSlotsStrategy.d.ts +1 -0
  262. package/lib/browser/priorityFee/maxOverSlotsStrategy.js +1 -0
  263. package/lib/browser/priorityFee/maxStrategy.d.ts +1 -0
  264. package/lib/browser/priorityFee/maxStrategy.js +1 -0
  265. package/lib/browser/priorityFee/priorityFeeSubscriber.d.ts +39 -0
  266. package/lib/browser/priorityFee/priorityFeeSubscriber.js +39 -0
  267. package/lib/browser/priorityFee/priorityFeeSubscriberMap.d.ts +20 -1
  268. package/lib/browser/priorityFee/priorityFeeSubscriberMap.js +21 -2
  269. package/lib/browser/priorityFee/solanaPriorityFeeMethod.d.ts +12 -0
  270. package/lib/browser/priorityFee/solanaPriorityFeeMethod.js +10 -0
  271. package/lib/browser/priorityFee/types.d.ts +32 -0
  272. package/lib/browser/priorityFee/types.js +5 -0
  273. package/lib/browser/priorityFee/velocityPriorityFeeMethod.d.ts +11 -0
  274. package/lib/browser/priorityFee/velocityPriorityFeeMethod.js +8 -0
  275. package/lib/browser/slot/SlotSubscriber.d.ts +18 -0
  276. package/lib/browser/slot/SlotSubscriber.js +16 -0
  277. package/lib/browser/slot/SlothashSubscriber.d.ts +26 -0
  278. package/lib/browser/slot/SlothashSubscriber.js +25 -1
  279. package/lib/browser/swift/swiftOrderSubscriber.js +2 -2
  280. package/lib/browser/tokenFaucet.d.ts +2 -2
  281. package/lib/browser/tokenFaucet.js +11 -4
  282. package/lib/browser/tx/baseTxSender.d.ts +163 -0
  283. package/lib/browser/tx/baseTxSender.js +174 -6
  284. package/lib/browser/tx/blockhashFetcher/baseBlockhashFetcher.d.ts +12 -0
  285. package/lib/browser/tx/blockhashFetcher/baseBlockhashFetcher.js +12 -0
  286. package/lib/browser/tx/blockhashFetcher/cachedBlockhashFetcher.d.ts +15 -0
  287. package/lib/browser/tx/blockhashFetcher/cachedBlockhashFetcher.js +15 -0
  288. package/lib/browser/tx/blockhashFetcher/types.d.ts +4 -0
  289. package/lib/browser/tx/fastSingleTxSender.d.ts +47 -0
  290. package/lib/browser/tx/fastSingleTxSender.js +48 -1
  291. package/lib/browser/tx/forwardOnlyTxSender.d.ts +48 -0
  292. package/lib/browser/tx/forwardOnlyTxSender.js +48 -0
  293. package/lib/browser/tx/reportTransactionError.d.ts +18 -6
  294. package/lib/browser/tx/reportTransactionError.js +18 -6
  295. package/lib/browser/tx/retryTxSender.d.ts +40 -0
  296. package/lib/browser/tx/retryTxSender.js +39 -0
  297. package/lib/browser/tx/txHandler.d.ts +146 -35
  298. package/lib/browser/tx/txHandler.js +132 -32
  299. package/lib/browser/tx/txParamProcessor.d.ts +47 -0
  300. package/lib/browser/tx/txParamProcessor.js +47 -0
  301. package/lib/browser/tx/types.d.ts +46 -0
  302. package/lib/browser/tx/types.js +5 -0
  303. package/lib/browser/tx/utils.d.ts +26 -0
  304. package/lib/browser/tx/utils.js +26 -0
  305. package/lib/browser/tx/whileValidTxSender.d.ts +82 -0
  306. package/lib/browser/tx/whileValidTxSender.js +81 -0
  307. package/lib/browser/types.d.ts +786 -13
  308. package/lib/browser/types.js +133 -9
  309. package/lib/browser/user.d.ts +645 -84
  310. package/lib/browser/user.js +779 -96
  311. package/lib/browser/userMap/PollingSubscription.d.ts +10 -0
  312. package/lib/browser/userMap/PollingSubscription.js +14 -2
  313. package/lib/browser/userMap/WebsocketSubscription.d.ts +9 -0
  314. package/lib/browser/userMap/WebsocketSubscription.js +9 -0
  315. package/lib/browser/userMap/grpcSubscription.d.ts +8 -0
  316. package/lib/browser/userMap/grpcSubscription.js +8 -0
  317. package/lib/browser/userMap/referrerMap.d.ts +72 -2
  318. package/lib/browser/userMap/referrerMap.js +84 -2
  319. package/lib/browser/userMap/revenueShareEscrowMap.d.ts +37 -10
  320. package/lib/browser/userMap/revenueShareEscrowMap.js +38 -11
  321. package/lib/browser/userMap/userMap.d.ts +81 -3
  322. package/lib/browser/userMap/userMap.js +81 -4
  323. package/lib/browser/userMap/userMapConfig.d.ts +23 -0
  324. package/lib/browser/userMap/userStatsMap.d.ts +22 -0
  325. package/lib/browser/userMap/userStatsMap.js +22 -0
  326. package/lib/browser/userName.d.ts +16 -0
  327. package/lib/browser/userName.js +16 -0
  328. package/lib/browser/userStats.d.ts +28 -1
  329. package/lib/browser/userStats.js +28 -1
  330. package/lib/browser/util/TransactionConfirmationManager.d.ts +33 -0
  331. package/lib/browser/util/TransactionConfirmationManager.js +33 -0
  332. package/lib/browser/util/chainClock.d.ts +24 -0
  333. package/lib/browser/util/chainClock.js +20 -0
  334. package/lib/browser/util/computeUnits.d.ts +32 -0
  335. package/lib/browser/util/computeUnits.js +32 -0
  336. package/lib/browser/util/digest.d.ts +17 -0
  337. package/lib/browser/util/digest.js +17 -0
  338. package/lib/browser/util/ed25519Utils.d.ts +12 -2
  339. package/lib/browser/util/ed25519Utils.js +12 -2
  340. package/lib/browser/util/promiseTimeout.d.ts +9 -0
  341. package/lib/browser/util/promiseTimeout.js +9 -0
  342. package/lib/browser/velocityClient.d.ts +3323 -216
  343. package/lib/browser/velocityClient.js +3428 -249
  344. package/lib/browser/wallet.d.ts +37 -0
  345. package/lib/browser/wallet.js +37 -0
  346. package/lib/node/accounts/basicUserAccountSubscriber.d.ts +18 -0
  347. package/lib/node/accounts/basicUserAccountSubscriber.d.ts.map +1 -1
  348. package/lib/node/accounts/basicUserAccountSubscriber.js +18 -0
  349. package/lib/node/accounts/basicUserStatsAccountSubscriber.d.ts +18 -0
  350. package/lib/node/accounts/basicUserStatsAccountSubscriber.d.ts.map +1 -1
  351. package/lib/node/accounts/basicUserStatsAccountSubscriber.js +18 -0
  352. package/lib/node/accounts/bulkAccountLoader.d.ts +52 -0
  353. package/lib/node/accounts/bulkAccountLoader.d.ts.map +1 -1
  354. package/lib/node/accounts/bulkAccountLoader.js +51 -0
  355. package/lib/node/accounts/bulkUserStatsSubscription.d.ts +9 -2
  356. package/lib/node/accounts/bulkUserStatsSubscription.d.ts.map +1 -1
  357. package/lib/node/accounts/bulkUserStatsSubscription.js +9 -2
  358. package/lib/node/accounts/bulkUserSubscription.d.ts +8 -2
  359. package/lib/node/accounts/bulkUserSubscription.d.ts.map +1 -1
  360. package/lib/node/accounts/bulkUserSubscription.js +8 -2
  361. package/lib/node/accounts/customizedCadenceBulkAccountLoader.d.ts +37 -0
  362. package/lib/node/accounts/customizedCadenceBulkAccountLoader.d.ts.map +1 -1
  363. package/lib/node/accounts/customizedCadenceBulkAccountLoader.js +37 -0
  364. package/lib/node/accounts/fetch.d.ts +59 -2
  365. package/lib/node/accounts/fetch.d.ts.map +1 -1
  366. package/lib/node/accounts/fetch.js +57 -2
  367. package/lib/node/accounts/grpcAccountSubscriber.d.ts +30 -0
  368. package/lib/node/accounts/grpcAccountSubscriber.d.ts.map +1 -1
  369. package/lib/node/accounts/grpcAccountSubscriber.js +30 -0
  370. package/lib/node/accounts/grpcInsuranceFundStakeAccountSubscriber.d.ts +16 -0
  371. package/lib/node/accounts/grpcInsuranceFundStakeAccountSubscriber.d.ts.map +1 -1
  372. package/lib/node/accounts/grpcInsuranceFundStakeAccountSubscriber.js +16 -0
  373. package/lib/node/accounts/grpcMultiAccountSubscriber.d.ts +60 -1
  374. package/lib/node/accounts/grpcMultiAccountSubscriber.d.ts.map +1 -1
  375. package/lib/node/accounts/grpcMultiAccountSubscriber.js +118 -37
  376. package/lib/node/accounts/grpcMultiUserAccountSubscriber.d.ts +32 -0
  377. package/lib/node/accounts/grpcMultiUserAccountSubscriber.d.ts.map +1 -1
  378. package/lib/node/accounts/grpcMultiUserAccountSubscriber.js +40 -12
  379. package/lib/node/accounts/grpcProgramAccountSubscriber.d.ts +33 -0
  380. package/lib/node/accounts/grpcProgramAccountSubscriber.d.ts.map +1 -1
  381. package/lib/node/accounts/grpcProgramAccountSubscriber.js +33 -0
  382. package/lib/node/accounts/grpcUserAccountSubscriber.d.ts +15 -0
  383. package/lib/node/accounts/grpcUserAccountSubscriber.d.ts.map +1 -1
  384. package/lib/node/accounts/grpcUserAccountSubscriber.js +15 -0
  385. package/lib/node/accounts/grpcUserStatsAccountSubscriber.d.ts +15 -0
  386. package/lib/node/accounts/grpcUserStatsAccountSubscriber.d.ts.map +1 -1
  387. package/lib/node/accounts/grpcUserStatsAccountSubscriber.js +15 -0
  388. package/lib/node/accounts/grpcVelocityClientAccountSubscriber.d.ts +41 -0
  389. package/lib/node/accounts/grpcVelocityClientAccountSubscriber.d.ts.map +1 -1
  390. package/lib/node/accounts/grpcVelocityClientAccountSubscriber.js +41 -0
  391. package/lib/node/accounts/grpcVelocityClientAccountSubscriberV2.d.ts +116 -0
  392. package/lib/node/accounts/grpcVelocityClientAccountSubscriberV2.d.ts.map +1 -1
  393. package/lib/node/accounts/grpcVelocityClientAccountSubscriberV2.js +152 -1
  394. package/lib/node/accounts/laserProgramAccountSubscriber.d.ts +34 -0
  395. package/lib/node/accounts/laserProgramAccountSubscriber.d.ts.map +1 -1
  396. package/lib/node/accounts/laserProgramAccountSubscriber.js +34 -0
  397. package/lib/node/accounts/oneShotUserAccountSubscriber.d.ts +19 -0
  398. package/lib/node/accounts/oneShotUserAccountSubscriber.d.ts.map +1 -1
  399. package/lib/node/accounts/oneShotUserAccountSubscriber.js +19 -0
  400. package/lib/node/accounts/oneShotUserStatsAccountSubscriber.d.ts +19 -0
  401. package/lib/node/accounts/oneShotUserStatsAccountSubscriber.d.ts.map +1 -1
  402. package/lib/node/accounts/oneShotUserStatsAccountSubscriber.js +19 -0
  403. package/lib/node/accounts/pollingInsuranceFundStakeAccountSubscriber.d.ts +31 -0
  404. package/lib/node/accounts/pollingInsuranceFundStakeAccountSubscriber.d.ts.map +1 -1
  405. package/lib/node/accounts/pollingInsuranceFundStakeAccountSubscriber.js +31 -0
  406. package/lib/node/accounts/pollingOracleAccountSubscriber.d.ts +19 -0
  407. package/lib/node/accounts/pollingOracleAccountSubscriber.d.ts.map +1 -1
  408. package/lib/node/accounts/pollingOracleAccountSubscriber.js +21 -2
  409. package/lib/node/accounts/pollingTokenAccountSubscriber.d.ts +22 -0
  410. package/lib/node/accounts/pollingTokenAccountSubscriber.d.ts.map +1 -1
  411. package/lib/node/accounts/pollingTokenAccountSubscriber.js +22 -0
  412. package/lib/node/accounts/pollingUserAccountSubscriber.d.ts +32 -0
  413. package/lib/node/accounts/pollingUserAccountSubscriber.d.ts.map +1 -1
  414. package/lib/node/accounts/pollingUserAccountSubscriber.js +32 -0
  415. package/lib/node/accounts/pollingUserStatsAccountSubscriber.d.ts +22 -0
  416. package/lib/node/accounts/pollingUserStatsAccountSubscriber.d.ts.map +1 -1
  417. package/lib/node/accounts/pollingUserStatsAccountSubscriber.js +22 -0
  418. package/lib/node/accounts/pollingVelocityClientAccountSubscriber.d.ts +83 -0
  419. package/lib/node/accounts/pollingVelocityClientAccountSubscriber.d.ts.map +1 -1
  420. package/lib/node/accounts/pollingVelocityClientAccountSubscriber.js +84 -1
  421. package/lib/node/accounts/testBulkAccountLoader.d.ts +8 -0
  422. package/lib/node/accounts/testBulkAccountLoader.d.ts.map +1 -1
  423. package/lib/node/accounts/testBulkAccountLoader.js +8 -0
  424. package/lib/node/accounts/types.d.ts +149 -0
  425. package/lib/node/accounts/types.d.ts.map +1 -1
  426. package/lib/node/accounts/types.js +13 -0
  427. package/lib/node/accounts/utils.d.ts +18 -0
  428. package/lib/node/accounts/utils.d.ts.map +1 -1
  429. package/lib/node/accounts/utils.js +32 -16
  430. package/lib/node/accounts/webSocketAccountSubscriber.d.ts +41 -0
  431. package/lib/node/accounts/webSocketAccountSubscriber.d.ts.map +1 -1
  432. package/lib/node/accounts/webSocketAccountSubscriber.js +41 -0
  433. package/lib/node/accounts/webSocketAccountSubscriberV2.d.ts +31 -0
  434. package/lib/node/accounts/webSocketAccountSubscriberV2.d.ts.map +1 -1
  435. package/lib/node/accounts/webSocketAccountSubscriberV2.js +31 -23
  436. package/lib/node/accounts/webSocketInsuranceFundStakeAccountSubscriber.d.ts +27 -0
  437. package/lib/node/accounts/webSocketInsuranceFundStakeAccountSubscriber.d.ts.map +1 -1
  438. package/lib/node/accounts/webSocketInsuranceFundStakeAccountSubscriber.js +27 -0
  439. package/lib/node/accounts/webSocketProgramAccountSubscriber.d.ts +36 -0
  440. package/lib/node/accounts/webSocketProgramAccountSubscriber.d.ts.map +1 -1
  441. package/lib/node/accounts/webSocketProgramAccountSubscriber.js +36 -0
  442. package/lib/node/accounts/webSocketProgramAccountSubscriberV2.d.ts +21 -0
  443. package/lib/node/accounts/webSocketProgramAccountSubscriberV2.d.ts.map +1 -1
  444. package/lib/node/accounts/webSocketProgramAccountSubscriberV2.js +25 -0
  445. package/lib/node/accounts/webSocketProgramAccountsSubscriberV2.d.ts +21 -0
  446. package/lib/node/accounts/webSocketProgramAccountsSubscriberV2.d.ts.map +1 -1
  447. package/lib/node/accounts/webSocketProgramAccountsSubscriberV2.js +21 -0
  448. package/lib/node/accounts/webSocketUserAccountSubscriber.d.ts +26 -0
  449. package/lib/node/accounts/webSocketUserAccountSubscriber.d.ts.map +1 -1
  450. package/lib/node/accounts/webSocketUserAccountSubscriber.js +26 -0
  451. package/lib/node/accounts/webSocketUserStatsAccountSubsriber.d.ts +20 -0
  452. package/lib/node/accounts/webSocketUserStatsAccountSubsriber.d.ts.map +1 -1
  453. package/lib/node/accounts/webSocketUserStatsAccountSubsriber.js +20 -0
  454. package/lib/node/accounts/webSocketVelocityClientAccountSubscriber.d.ts +121 -0
  455. package/lib/node/accounts/webSocketVelocityClientAccountSubscriber.d.ts.map +1 -1
  456. package/lib/node/accounts/webSocketVelocityClientAccountSubscriber.js +123 -2
  457. package/lib/node/accounts/webSocketVelocityClientAccountSubscriberV2.d.ts +96 -0
  458. package/lib/node/accounts/webSocketVelocityClientAccountSubscriberV2.d.ts.map +1 -1
  459. package/lib/node/accounts/webSocketVelocityClientAccountSubscriberV2.js +108 -0
  460. package/lib/node/accounts/websocketProgramUserAccountSubscriber.d.ts +28 -0
  461. package/lib/node/accounts/websocketProgramUserAccountSubscriber.d.ts.map +1 -1
  462. package/lib/node/accounts/websocketProgramUserAccountSubscriber.js +33 -0
  463. package/lib/node/addresses/marketAddresses.d.ts +10 -0
  464. package/lib/node/addresses/marketAddresses.d.ts.map +1 -1
  465. package/lib/node/addresses/marketAddresses.js +10 -0
  466. package/lib/node/addresses/pda.d.ts +214 -2
  467. package/lib/node/addresses/pda.d.ts.map +1 -1
  468. package/lib/node/addresses/pda.js +217 -5
  469. package/lib/node/adminClient.d.ts +2139 -5
  470. package/lib/node/adminClient.d.ts.map +1 -1
  471. package/lib/node/adminClient.js +2173 -11
  472. package/lib/node/auctionSubscriber/auctionSubscriber.d.ts +15 -0
  473. package/lib/node/auctionSubscriber/auctionSubscriber.d.ts.map +1 -1
  474. package/lib/node/auctionSubscriber/auctionSubscriber.js +15 -0
  475. package/lib/node/auctionSubscriber/auctionSubscriberGrpc.d.ts +19 -0
  476. package/lib/node/auctionSubscriber/auctionSubscriberGrpc.d.ts.map +1 -1
  477. package/lib/node/auctionSubscriber/auctionSubscriberGrpc.js +19 -0
  478. package/lib/node/auctionSubscriber/index.d.ts +6 -0
  479. package/lib/node/auctionSubscriber/index.d.ts.map +1 -1
  480. package/lib/node/auctionSubscriber/index.js +6 -0
  481. package/lib/node/auctionSubscriber/types.d.ts +7 -0
  482. package/lib/node/auctionSubscriber/types.d.ts.map +1 -1
  483. package/lib/node/blockhashSubscriber/BlockhashSubscriber.d.ts +33 -0
  484. package/lib/node/blockhashSubscriber/BlockhashSubscriber.d.ts.map +1 -1
  485. package/lib/node/blockhashSubscriber/BlockhashSubscriber.js +33 -0
  486. package/lib/node/blockhashSubscriber/index.d.ts +5 -0
  487. package/lib/node/blockhashSubscriber/index.d.ts.map +1 -1
  488. package/lib/node/blockhashSubscriber/index.js +5 -0
  489. package/lib/node/blockhashSubscriber/types.d.ts +5 -0
  490. package/lib/node/blockhashSubscriber/types.d.ts.map +1 -1
  491. package/lib/node/clock/clockSubscriber.d.ts +24 -0
  492. package/lib/node/clock/clockSubscriber.d.ts.map +1 -1
  493. package/lib/node/clock/clockSubscriber.js +22 -0
  494. package/lib/node/config.d.ts +58 -4
  495. package/lib/node/config.d.ts.map +1 -1
  496. package/lib/node/config.js +88 -21
  497. package/lib/node/constants/numericConstants.d.ts +67 -0
  498. package/lib/node/constants/numericConstants.d.ts.map +1 -1
  499. package/lib/node/constants/numericConstants.js +68 -1
  500. package/lib/node/constants/perpMarkets.d.ts +10 -0
  501. package/lib/node/constants/perpMarkets.d.ts.map +1 -1
  502. package/lib/node/constants/perpMarkets.js +40 -908
  503. package/lib/node/constants/spotMarkets.d.ts +13 -0
  504. package/lib/node/constants/spotMarkets.d.ts.map +1 -1
  505. package/lib/node/constants/spotMarkets.js +16 -742
  506. package/lib/node/constants/txConstants.d.ts +1 -0
  507. package/lib/node/constants/txConstants.d.ts.map +1 -1
  508. package/lib/node/constants/txConstants.js +1 -0
  509. package/lib/node/core/VelocityCore.d.ts +285 -8
  510. package/lib/node/core/VelocityCore.d.ts.map +1 -1
  511. package/lib/node/core/VelocityCore.js +281 -8
  512. package/lib/node/core/instructions/deposit.d.ts +22 -0
  513. package/lib/node/core/instructions/deposit.d.ts.map +1 -1
  514. package/lib/node/core/instructions/deposit.js +22 -0
  515. package/lib/node/core/instructions/fill.d.ts +17 -0
  516. package/lib/node/core/instructions/fill.d.ts.map +1 -1
  517. package/lib/node/core/instructions/fill.js +17 -0
  518. package/lib/node/core/instructions/funding.d.ts +12 -0
  519. package/lib/node/core/instructions/funding.d.ts.map +1 -1
  520. package/lib/node/core/instructions/funding.js +12 -0
  521. package/lib/node/core/instructions/liquidation.d.ts +18 -0
  522. package/lib/node/core/instructions/liquidation.d.ts.map +1 -1
  523. package/lib/node/core/instructions/liquidation.js +18 -0
  524. package/lib/node/core/instructions/orders.d.ts +28 -0
  525. package/lib/node/core/instructions/orders.d.ts.map +1 -1
  526. package/lib/node/core/instructions/orders.js +28 -0
  527. package/lib/node/core/instructions/perpOrders.d.ts +106 -0
  528. package/lib/node/core/instructions/perpOrders.d.ts.map +1 -1
  529. package/lib/node/core/instructions/perpOrders.js +106 -0
  530. package/lib/node/core/instructions/settlement.d.ts +14 -0
  531. package/lib/node/core/instructions/settlement.d.ts.map +1 -1
  532. package/lib/node/core/instructions/settlement.js +14 -0
  533. package/lib/node/core/instructions/trigger.d.ts +15 -0
  534. package/lib/node/core/instructions/trigger.d.ts.map +1 -1
  535. package/lib/node/core/instructions/trigger.js +15 -0
  536. package/lib/node/core/instructions/withdraw.d.ts +21 -0
  537. package/lib/node/core/instructions/withdraw.d.ts.map +1 -1
  538. package/lib/node/core/instructions/withdraw.js +21 -0
  539. package/lib/node/core/remainingAccounts.d.ts +47 -3
  540. package/lib/node/core/remainingAccounts.d.ts.map +1 -1
  541. package/lib/node/core/remainingAccounts.js +20 -0
  542. package/lib/node/core/signedMsg.d.ts +38 -0
  543. package/lib/node/core/signedMsg.d.ts.map +1 -1
  544. package/lib/node/core/signedMsg.js +33 -0
  545. package/lib/node/decode/customCoder.d.ts +39 -3
  546. package/lib/node/decode/customCoder.d.ts.map +1 -1
  547. package/lib/node/decode/customCoder.js +45 -3
  548. package/lib/node/decode/user.d.ts +22 -0
  549. package/lib/node/decode/user.d.ts.map +1 -1
  550. package/lib/node/decode/user.js +22 -0
  551. package/lib/node/dlob/DLOB.d.ts +502 -53
  552. package/lib/node/dlob/DLOB.d.ts.map +1 -1
  553. package/lib/node/dlob/DLOB.js +540 -98
  554. package/lib/node/dlob/DLOBNode.d.ts +86 -4
  555. package/lib/node/dlob/DLOBNode.d.ts.map +1 -1
  556. package/lib/node/dlob/DLOBNode.js +37 -4
  557. package/lib/node/dlob/DLOBSubscriber.d.ts +39 -12
  558. package/lib/node/dlob/DLOBSubscriber.d.ts.map +1 -1
  559. package/lib/node/dlob/DLOBSubscriber.js +42 -12
  560. package/lib/node/dlob/NodeList.d.ts +69 -0
  561. package/lib/node/dlob/NodeList.d.ts.map +1 -1
  562. package/lib/node/dlob/NodeList.js +66 -0
  563. package/lib/node/dlob/orderBookLevels.d.ts +106 -13
  564. package/lib/node/dlob/orderBookLevels.d.ts.map +1 -1
  565. package/lib/node/dlob/orderBookLevels.js +84 -14
  566. package/lib/node/dlob/types.d.ts +15 -0
  567. package/lib/node/dlob/types.d.ts.map +1 -1
  568. package/lib/node/events/eventList.d.ts +14 -0
  569. package/lib/node/events/eventList.d.ts.map +1 -1
  570. package/lib/node/events/eventList.js +14 -0
  571. package/lib/node/events/eventSubscriber.d.ts +87 -10
  572. package/lib/node/events/eventSubscriber.d.ts.map +1 -1
  573. package/lib/node/events/eventSubscriber.js +93 -8
  574. package/lib/node/events/eventsServerLogProvider.d.ts +22 -0
  575. package/lib/node/events/eventsServerLogProvider.d.ts.map +1 -1
  576. package/lib/node/events/eventsServerLogProvider.js +27 -0
  577. package/lib/node/events/fetchLogs.d.ts +31 -0
  578. package/lib/node/events/fetchLogs.d.ts.map +1 -1
  579. package/lib/node/events/fetchLogs.js +46 -1
  580. package/lib/node/events/parse.d.ts +23 -0
  581. package/lib/node/events/parse.d.ts.map +1 -1
  582. package/lib/node/events/parse.js +23 -0
  583. package/lib/node/events/pollingLogProvider.d.ts +24 -0
  584. package/lib/node/events/pollingLogProvider.d.ts.map +1 -1
  585. package/lib/node/events/pollingLogProvider.js +24 -0
  586. package/lib/node/events/sort.d.ts +11 -0
  587. package/lib/node/events/sort.d.ts.map +1 -1
  588. package/lib/node/events/sort.js +12 -0
  589. package/lib/node/events/txEventCache.d.ts +13 -3
  590. package/lib/node/events/txEventCache.d.ts.map +1 -1
  591. package/lib/node/events/txEventCache.js +19 -7
  592. package/lib/node/events/types.d.ts +118 -2
  593. package/lib/node/events/types.d.ts.map +1 -1
  594. package/lib/node/events/types.js +11 -0
  595. package/lib/node/events/webSocketLogProvider.d.ts +23 -0
  596. package/lib/node/events/webSocketLogProvider.d.ts.map +1 -1
  597. package/lib/node/events/webSocketLogProvider.js +28 -0
  598. package/lib/node/factory/oracleClient.js +2 -2
  599. package/lib/node/idl/velocity.d.ts +50 -1
  600. package/lib/node/idl/velocity.d.ts.map +1 -1
  601. package/lib/node/idl/velocity.json +50 -1
  602. package/lib/node/keypair.d.ts +8 -0
  603. package/lib/node/keypair.d.ts.map +1 -1
  604. package/lib/node/keypair.js +8 -0
  605. package/lib/node/marginCalculation.d.ts +134 -2
  606. package/lib/node/marginCalculation.d.ts.map +1 -1
  607. package/lib/node/marginCalculation.js +121 -0
  608. package/lib/node/math/amm.d.ts +348 -29
  609. package/lib/node/math/amm.d.ts.map +1 -1
  610. package/lib/node/math/amm.js +310 -32
  611. package/lib/node/math/auction.d.ts +95 -19
  612. package/lib/node/math/auction.d.ts.map +1 -1
  613. package/lib/node/math/auction.js +118 -28
  614. package/lib/node/math/bankruptcy.d.ts +46 -0
  615. package/lib/node/math/bankruptcy.d.ts.map +1 -1
  616. package/lib/node/math/bankruptcy.js +89 -1
  617. package/lib/node/math/builder.d.ts +64 -8
  618. package/lib/node/math/builder.d.ts.map +1 -1
  619. package/lib/node/math/builder.js +71 -9
  620. package/lib/node/math/conversion.d.ts +21 -0
  621. package/lib/node/math/conversion.d.ts.map +1 -1
  622. package/lib/node/math/conversion.js +21 -0
  623. package/lib/node/math/exchangeStatus.d.ts +92 -0
  624. package/lib/node/math/exchangeStatus.d.ts.map +1 -1
  625. package/lib/node/math/exchangeStatus.js +111 -1
  626. package/lib/node/math/funding.d.ts +57 -20
  627. package/lib/node/math/funding.d.ts.map +1 -1
  628. package/lib/node/math/funding.js +63 -23
  629. package/lib/node/math/insurance.d.ts +62 -0
  630. package/lib/node/math/insurance.d.ts.map +1 -1
  631. package/lib/node/math/insurance.js +62 -0
  632. package/lib/node/math/liquidation.d.ts +127 -11
  633. package/lib/node/math/liquidation.d.ts.map +1 -1
  634. package/lib/node/math/liquidation.js +182 -19
  635. package/lib/node/math/margin.d.ts +79 -13
  636. package/lib/node/math/margin.d.ts.map +1 -1
  637. package/lib/node/math/margin.js +80 -14
  638. package/lib/node/math/market.d.ts +135 -15
  639. package/lib/node/math/market.d.ts.map +1 -1
  640. package/lib/node/math/market.js +145 -17
  641. package/lib/node/math/oracles.d.ts +113 -0
  642. package/lib/node/math/oracles.d.ts.map +1 -1
  643. package/lib/node/math/oracles.js +118 -1
  644. package/lib/node/math/orders.d.ts +115 -7
  645. package/lib/node/math/orders.d.ts.map +1 -1
  646. package/lib/node/math/orders.js +133 -18
  647. package/lib/node/math/position.d.ts +80 -33
  648. package/lib/node/math/position.d.ts.map +1 -1
  649. package/lib/node/math/position.js +80 -33
  650. package/lib/node/math/repeg.d.ts +48 -10
  651. package/lib/node/math/repeg.d.ts.map +1 -1
  652. package/lib/node/math/repeg.js +48 -10
  653. package/lib/node/math/spotBalance.d.ts +200 -5
  654. package/lib/node/math/spotBalance.d.ts.map +1 -1
  655. package/lib/node/math/spotBalance.js +239 -10
  656. package/lib/node/math/spotMarket.d.ts +36 -3
  657. package/lib/node/math/spotMarket.d.ts.map +1 -1
  658. package/lib/node/math/spotMarket.js +36 -3
  659. package/lib/node/math/spotPosition.d.ts +72 -0
  660. package/lib/node/math/spotPosition.d.ts.map +1 -1
  661. package/lib/node/math/spotPosition.js +62 -0
  662. package/lib/node/math/state.d.ts +31 -0
  663. package/lib/node/math/state.d.ts.map +1 -1
  664. package/lib/node/math/state.js +32 -1
  665. package/lib/node/math/superStake.d.ts +126 -2
  666. package/lib/node/math/superStake.d.ts.map +1 -1
  667. package/lib/node/math/superStake.js +123 -3
  668. package/lib/node/math/tiers.d.ts +29 -0
  669. package/lib/node/math/tiers.d.ts.map +1 -1
  670. package/lib/node/math/tiers.js +29 -0
  671. package/lib/node/math/trade.d.ts +102 -51
  672. package/lib/node/math/trade.d.ts.map +1 -1
  673. package/lib/node/math/trade.js +101 -55
  674. package/lib/node/math/utils.d.ts +71 -9
  675. package/lib/node/math/utils.d.ts.map +1 -1
  676. package/lib/node/math/utils.js +71 -9
  677. package/lib/node/memcmp.d.ts +94 -0
  678. package/lib/node/memcmp.d.ts.map +1 -1
  679. package/lib/node/memcmp.js +129 -7
  680. package/lib/node/oracles/oracleClientCache.d.ts +16 -0
  681. package/lib/node/oracles/oracleClientCache.d.ts.map +1 -1
  682. package/lib/node/oracles/oracleClientCache.js +16 -0
  683. package/lib/node/oracles/oracleId.d.ts +31 -0
  684. package/lib/node/oracles/oracleId.d.ts.map +1 -1
  685. package/lib/node/oracles/oracleId.js +39 -8
  686. package/lib/node/oracles/prelaunchOracleClient.d.ts +20 -0
  687. package/lib/node/oracles/prelaunchOracleClient.d.ts.map +1 -1
  688. package/lib/node/oracles/prelaunchOracleClient.js +20 -0
  689. package/lib/node/oracles/pythClient.d.ts +31 -0
  690. package/lib/node/oracles/pythClient.d.ts.map +1 -1
  691. package/lib/node/oracles/pythClient.js +32 -1
  692. package/lib/node/oracles/pythLazerClient.d.ts +34 -0
  693. package/lib/node/oracles/pythLazerClient.d.ts.map +1 -1
  694. package/lib/node/oracles/pythLazerClient.js +35 -1
  695. package/lib/node/oracles/quoteAssetOracleClient.d.ts +18 -0
  696. package/lib/node/oracles/quoteAssetOracleClient.d.ts.map +1 -1
  697. package/lib/node/oracles/quoteAssetOracleClient.js +18 -0
  698. package/lib/node/oracles/strictOraclePrice.d.ts +21 -0
  699. package/lib/node/oracles/strictOraclePrice.d.ts.map +1 -1
  700. package/lib/node/oracles/strictOraclePrice.js +21 -0
  701. package/lib/node/oracles/types.d.ts +45 -0
  702. package/lib/node/oracles/types.d.ts.map +1 -1
  703. package/lib/node/oracles/utils.d.ts +20 -0
  704. package/lib/node/oracles/utils.d.ts.map +1 -1
  705. package/lib/node/oracles/utils.js +20 -0
  706. package/lib/node/orderParams.d.ts +42 -4
  707. package/lib/node/orderParams.d.ts.map +1 -1
  708. package/lib/node/orderParams.js +42 -4
  709. package/lib/node/orderSubscriber/OrderSubscriber.d.ts +56 -0
  710. package/lib/node/orderSubscriber/OrderSubscriber.d.ts.map +1 -1
  711. package/lib/node/orderSubscriber/OrderSubscriber.js +67 -2
  712. package/lib/node/orderSubscriber/PollingSubscription.d.ts +11 -0
  713. package/lib/node/orderSubscriber/PollingSubscription.d.ts.map +1 -1
  714. package/lib/node/orderSubscriber/PollingSubscription.js +11 -0
  715. package/lib/node/orderSubscriber/WebsocketSubscription.d.ts +18 -0
  716. package/lib/node/orderSubscriber/WebsocketSubscription.d.ts.map +1 -1
  717. package/lib/node/orderSubscriber/WebsocketSubscription.js +18 -0
  718. package/lib/node/orderSubscriber/grpcSubscription.d.ts +16 -0
  719. package/lib/node/orderSubscriber/grpcSubscription.d.ts.map +1 -1
  720. package/lib/node/orderSubscriber/grpcSubscription.js +16 -0
  721. package/lib/node/orderSubscriber/types.d.ts +9 -0
  722. package/lib/node/orderSubscriber/types.d.ts.map +1 -1
  723. package/lib/node/priorityFee/averageOverSlotsStrategy.d.ts +1 -0
  724. package/lib/node/priorityFee/averageOverSlotsStrategy.d.ts.map +1 -1
  725. package/lib/node/priorityFee/averageOverSlotsStrategy.js +1 -0
  726. package/lib/node/priorityFee/averageStrategy.d.ts +1 -0
  727. package/lib/node/priorityFee/averageStrategy.d.ts.map +1 -1
  728. package/lib/node/priorityFee/averageStrategy.js +1 -0
  729. package/lib/node/priorityFee/ewmaStrategy.d.ts +10 -0
  730. package/lib/node/priorityFee/ewmaStrategy.d.ts.map +1 -1
  731. package/lib/node/priorityFee/ewmaStrategy.js +10 -0
  732. package/lib/node/priorityFee/heliusPriorityFeeMethod.d.ts +13 -0
  733. package/lib/node/priorityFee/heliusPriorityFeeMethod.d.ts.map +1 -1
  734. package/lib/node/priorityFee/heliusPriorityFeeMethod.js +9 -2
  735. package/lib/node/priorityFee/maxOverSlotsStrategy.d.ts +1 -0
  736. package/lib/node/priorityFee/maxOverSlotsStrategy.d.ts.map +1 -1
  737. package/lib/node/priorityFee/maxOverSlotsStrategy.js +1 -0
  738. package/lib/node/priorityFee/maxStrategy.d.ts +1 -0
  739. package/lib/node/priorityFee/maxStrategy.d.ts.map +1 -1
  740. package/lib/node/priorityFee/maxStrategy.js +1 -0
  741. package/lib/node/priorityFee/priorityFeeSubscriber.d.ts +39 -0
  742. package/lib/node/priorityFee/priorityFeeSubscriber.d.ts.map +1 -1
  743. package/lib/node/priorityFee/priorityFeeSubscriber.js +39 -0
  744. package/lib/node/priorityFee/priorityFeeSubscriberMap.d.ts +20 -1
  745. package/lib/node/priorityFee/priorityFeeSubscriberMap.d.ts.map +1 -1
  746. package/lib/node/priorityFee/priorityFeeSubscriberMap.js +21 -2
  747. package/lib/node/priorityFee/solanaPriorityFeeMethod.d.ts +12 -0
  748. package/lib/node/priorityFee/solanaPriorityFeeMethod.d.ts.map +1 -1
  749. package/lib/node/priorityFee/solanaPriorityFeeMethod.js +10 -0
  750. package/lib/node/priorityFee/types.d.ts +32 -0
  751. package/lib/node/priorityFee/types.d.ts.map +1 -1
  752. package/lib/node/priorityFee/types.js +5 -0
  753. package/lib/node/priorityFee/velocityPriorityFeeMethod.d.ts +11 -0
  754. package/lib/node/priorityFee/velocityPriorityFeeMethod.d.ts.map +1 -1
  755. package/lib/node/priorityFee/velocityPriorityFeeMethod.js +8 -0
  756. package/lib/node/slot/SlotSubscriber.d.ts +18 -0
  757. package/lib/node/slot/SlotSubscriber.d.ts.map +1 -1
  758. package/lib/node/slot/SlotSubscriber.js +16 -0
  759. package/lib/node/slot/SlothashSubscriber.d.ts +26 -0
  760. package/lib/node/slot/SlothashSubscriber.d.ts.map +1 -1
  761. package/lib/node/slot/SlothashSubscriber.js +25 -1
  762. package/lib/node/swift/swiftOrderSubscriber.js +2 -2
  763. package/lib/node/tokenFaucet.d.ts +2 -2
  764. package/lib/node/tokenFaucet.d.ts.map +1 -1
  765. package/lib/node/tokenFaucet.js +11 -4
  766. package/lib/node/tx/baseTxSender.d.ts +163 -0
  767. package/lib/node/tx/baseTxSender.d.ts.map +1 -1
  768. package/lib/node/tx/baseTxSender.js +174 -6
  769. package/lib/node/tx/blockhashFetcher/baseBlockhashFetcher.d.ts +12 -0
  770. package/lib/node/tx/blockhashFetcher/baseBlockhashFetcher.d.ts.map +1 -1
  771. package/lib/node/tx/blockhashFetcher/baseBlockhashFetcher.js +12 -0
  772. package/lib/node/tx/blockhashFetcher/cachedBlockhashFetcher.d.ts +15 -0
  773. package/lib/node/tx/blockhashFetcher/cachedBlockhashFetcher.d.ts.map +1 -1
  774. package/lib/node/tx/blockhashFetcher/cachedBlockhashFetcher.js +15 -0
  775. package/lib/node/tx/blockhashFetcher/types.d.ts +4 -0
  776. package/lib/node/tx/blockhashFetcher/types.d.ts.map +1 -1
  777. package/lib/node/tx/fastSingleTxSender.d.ts +47 -0
  778. package/lib/node/tx/fastSingleTxSender.d.ts.map +1 -1
  779. package/lib/node/tx/fastSingleTxSender.js +48 -1
  780. package/lib/node/tx/forwardOnlyTxSender.d.ts +48 -0
  781. package/lib/node/tx/forwardOnlyTxSender.d.ts.map +1 -1
  782. package/lib/node/tx/forwardOnlyTxSender.js +48 -0
  783. package/lib/node/tx/reportTransactionError.d.ts +18 -6
  784. package/lib/node/tx/reportTransactionError.d.ts.map +1 -1
  785. package/lib/node/tx/reportTransactionError.js +18 -6
  786. package/lib/node/tx/retryTxSender.d.ts +40 -0
  787. package/lib/node/tx/retryTxSender.d.ts.map +1 -1
  788. package/lib/node/tx/retryTxSender.js +39 -0
  789. package/lib/node/tx/txHandler.d.ts +146 -35
  790. package/lib/node/tx/txHandler.d.ts.map +1 -1
  791. package/lib/node/tx/txHandler.js +132 -32
  792. package/lib/node/tx/txParamProcessor.d.ts +47 -0
  793. package/lib/node/tx/txParamProcessor.d.ts.map +1 -1
  794. package/lib/node/tx/txParamProcessor.js +47 -0
  795. package/lib/node/tx/types.d.ts +46 -0
  796. package/lib/node/tx/types.d.ts.map +1 -1
  797. package/lib/node/tx/types.js +5 -0
  798. package/lib/node/tx/utils.d.ts +26 -0
  799. package/lib/node/tx/utils.d.ts.map +1 -1
  800. package/lib/node/tx/utils.js +26 -0
  801. package/lib/node/tx/whileValidTxSender.d.ts +82 -0
  802. package/lib/node/tx/whileValidTxSender.d.ts.map +1 -1
  803. package/lib/node/tx/whileValidTxSender.js +81 -0
  804. package/lib/node/types.d.ts +786 -13
  805. package/lib/node/types.d.ts.map +1 -1
  806. package/lib/node/types.js +133 -9
  807. package/lib/node/user.d.ts +645 -84
  808. package/lib/node/user.d.ts.map +1 -1
  809. package/lib/node/user.js +779 -96
  810. package/lib/node/userMap/PollingSubscription.d.ts +10 -0
  811. package/lib/node/userMap/PollingSubscription.d.ts.map +1 -1
  812. package/lib/node/userMap/PollingSubscription.js +14 -2
  813. package/lib/node/userMap/WebsocketSubscription.d.ts +9 -0
  814. package/lib/node/userMap/WebsocketSubscription.d.ts.map +1 -1
  815. package/lib/node/userMap/WebsocketSubscription.js +9 -0
  816. package/lib/node/userMap/grpcSubscription.d.ts +8 -0
  817. package/lib/node/userMap/grpcSubscription.d.ts.map +1 -1
  818. package/lib/node/userMap/grpcSubscription.js +8 -0
  819. package/lib/node/userMap/referrerMap.d.ts +72 -2
  820. package/lib/node/userMap/referrerMap.d.ts.map +1 -1
  821. package/lib/node/userMap/referrerMap.js +84 -2
  822. package/lib/node/userMap/revenueShareEscrowMap.d.ts +37 -10
  823. package/lib/node/userMap/revenueShareEscrowMap.d.ts.map +1 -1
  824. package/lib/node/userMap/revenueShareEscrowMap.js +38 -11
  825. package/lib/node/userMap/userMap.d.ts +81 -3
  826. package/lib/node/userMap/userMap.d.ts.map +1 -1
  827. package/lib/node/userMap/userMap.js +81 -4
  828. package/lib/node/userMap/userMapConfig.d.ts +23 -0
  829. package/lib/node/userMap/userMapConfig.d.ts.map +1 -1
  830. package/lib/node/userMap/userStatsMap.d.ts +22 -0
  831. package/lib/node/userMap/userStatsMap.d.ts.map +1 -1
  832. package/lib/node/userMap/userStatsMap.js +22 -0
  833. package/lib/node/userName.d.ts +16 -0
  834. package/lib/node/userName.d.ts.map +1 -1
  835. package/lib/node/userName.js +16 -0
  836. package/lib/node/userStats.d.ts +28 -1
  837. package/lib/node/userStats.d.ts.map +1 -1
  838. package/lib/node/userStats.js +28 -1
  839. package/lib/node/util/TransactionConfirmationManager.d.ts +33 -0
  840. package/lib/node/util/TransactionConfirmationManager.d.ts.map +1 -1
  841. package/lib/node/util/TransactionConfirmationManager.js +33 -0
  842. package/lib/node/util/chainClock.d.ts +24 -0
  843. package/lib/node/util/chainClock.d.ts.map +1 -1
  844. package/lib/node/util/chainClock.js +20 -0
  845. package/lib/node/util/computeUnits.d.ts +32 -0
  846. package/lib/node/util/computeUnits.d.ts.map +1 -1
  847. package/lib/node/util/computeUnits.js +32 -0
  848. package/lib/node/util/digest.d.ts +17 -0
  849. package/lib/node/util/digest.d.ts.map +1 -1
  850. package/lib/node/util/digest.js +17 -0
  851. package/lib/node/util/ed25519Utils.d.ts +12 -2
  852. package/lib/node/util/ed25519Utils.d.ts.map +1 -1
  853. package/lib/node/util/ed25519Utils.js +12 -2
  854. package/lib/node/util/promiseTimeout.d.ts +9 -0
  855. package/lib/node/util/promiseTimeout.d.ts.map +1 -1
  856. package/lib/node/util/promiseTimeout.js +9 -0
  857. package/lib/node/velocityClient.d.ts +3323 -216
  858. package/lib/node/velocityClient.d.ts.map +1 -1
  859. package/lib/node/velocityClient.js +3428 -249
  860. package/lib/node/wallet.d.ts +37 -0
  861. package/lib/node/wallet.d.ts.map +1 -1
  862. package/lib/node/wallet.js +37 -0
  863. package/package.json +2 -1
  864. package/src/accounts/basicUserAccountSubscriber.ts +18 -0
  865. package/src/accounts/basicUserStatsAccountSubscriber.ts +18 -0
  866. package/src/accounts/bulkAccountLoader.ts +52 -0
  867. package/src/accounts/bulkUserStatsSubscription.ts +9 -2
  868. package/src/accounts/bulkUserSubscription.ts +8 -2
  869. package/src/accounts/customizedCadenceBulkAccountLoader.ts +37 -0
  870. package/src/accounts/fetch.ts +59 -2
  871. package/src/accounts/grpcAccountSubscriber.ts +30 -0
  872. package/src/accounts/grpcInsuranceFundStakeAccountSubscriber.ts +16 -0
  873. package/src/accounts/grpcMultiAccountSubscriber.ts +121 -38
  874. package/src/accounts/grpcMultiUserAccountSubscriber.ts +49 -11
  875. package/src/accounts/grpcProgramAccountSubscriber.ts +33 -0
  876. package/src/accounts/grpcUserAccountSubscriber.ts +15 -0
  877. package/src/accounts/grpcUserStatsAccountSubscriber.ts +15 -0
  878. package/src/accounts/grpcVelocityClientAccountSubscriber.ts +41 -0
  879. package/src/accounts/grpcVelocityClientAccountSubscriberV2.ts +160 -1
  880. package/src/accounts/laserProgramAccountSubscriber.ts +34 -0
  881. package/src/accounts/oneShotUserAccountSubscriber.ts +19 -0
  882. package/src/accounts/oneShotUserStatsAccountSubscriber.ts +19 -0
  883. package/src/accounts/pollingInsuranceFundStakeAccountSubscriber.ts +31 -0
  884. package/src/accounts/pollingOracleAccountSubscriber.ts +21 -2
  885. package/src/accounts/pollingTokenAccountSubscriber.ts +22 -0
  886. package/src/accounts/pollingUserAccountSubscriber.ts +32 -0
  887. package/src/accounts/pollingUserStatsAccountSubscriber.ts +22 -0
  888. package/src/accounts/pollingVelocityClientAccountSubscriber.ts +84 -1
  889. package/src/accounts/testBulkAccountLoader.ts +8 -0
  890. package/src/accounts/types.ts +149 -0
  891. package/src/accounts/utils.ts +42 -24
  892. package/src/accounts/webSocketAccountSubscriber.ts +41 -0
  893. package/src/accounts/webSocketAccountSubscriberV2.ts +31 -23
  894. package/src/accounts/webSocketInsuranceFundStakeAccountSubscriber.ts +27 -0
  895. package/src/accounts/webSocketProgramAccountSubscriber.ts +36 -0
  896. package/src/accounts/webSocketProgramAccountSubscriberV2.ts +26 -0
  897. package/src/accounts/webSocketProgramAccountsSubscriberV2.ts +21 -0
  898. package/src/accounts/webSocketUserAccountSubscriber.ts +26 -0
  899. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +20 -0
  900. package/src/accounts/webSocketVelocityClientAccountSubscriber.ts +127 -2
  901. package/src/accounts/webSocketVelocityClientAccountSubscriberV2.ts +110 -0
  902. package/src/accounts/websocketProgramUserAccountSubscriber.ts +33 -0
  903. package/src/addresses/marketAddresses.ts +10 -0
  904. package/src/addresses/pda.ts +228 -12
  905. package/src/adminClient.ts +2184 -4
  906. package/src/auctionSubscriber/auctionSubscriber.ts +15 -0
  907. package/src/auctionSubscriber/auctionSubscriberGrpc.ts +19 -0
  908. package/src/auctionSubscriber/index.ts +6 -0
  909. package/src/auctionSubscriber/types.ts +7 -0
  910. package/src/blockhashSubscriber/BlockhashSubscriber.ts +33 -0
  911. package/src/blockhashSubscriber/index.ts +5 -0
  912. package/src/blockhashSubscriber/types.ts +5 -4
  913. package/src/clock/clockSubscriber.ts +24 -0
  914. package/src/config.ts +109 -22
  915. package/src/constants/numericConstants.ts +70 -0
  916. package/src/constants/perpMarkets.ts +45 -960
  917. package/src/constants/spotMarkets.ts +23 -793
  918. package/src/constants/txConstants.ts +1 -0
  919. package/src/core/VelocityCore.ts +286 -8
  920. package/src/core/instructions/deposit.ts +22 -0
  921. package/src/core/instructions/fill.ts +17 -0
  922. package/src/core/instructions/funding.ts +12 -0
  923. package/src/core/instructions/liquidation.ts +18 -0
  924. package/src/core/instructions/orders.ts +28 -0
  925. package/src/core/instructions/perpOrders.ts +106 -0
  926. package/src/core/instructions/settlement.ts +14 -0
  927. package/src/core/instructions/trigger.ts +15 -0
  928. package/src/core/instructions/withdraw.ts +21 -0
  929. package/src/core/remainingAccounts.ts +47 -3
  930. package/src/core/signedMsg.ts +38 -0
  931. package/src/decode/customCoder.ts +46 -3
  932. package/src/decode/user.ts +22 -0
  933. package/src/dlob/DLOB.ts +668 -97
  934. package/src/dlob/DLOBNode.ts +98 -6
  935. package/src/dlob/DLOBSubscriber.ts +49 -12
  936. package/src/dlob/NodeList.ts +69 -0
  937. package/src/dlob/orderBookLevels.ts +108 -14
  938. package/src/dlob/types.ts +15 -0
  939. package/src/events/eventList.ts +14 -0
  940. package/src/events/eventSubscriber.ts +100 -19
  941. package/src/events/eventsServerLogProvider.ts +28 -0
  942. package/src/events/fetchLogs.ts +52 -2
  943. package/src/events/parse.ts +23 -0
  944. package/src/events/pollingLogProvider.ts +24 -0
  945. package/src/events/sort.ts +12 -0
  946. package/src/events/txEventCache.ts +19 -7
  947. package/src/events/types.ts +131 -11
  948. package/src/events/webSocketLogProvider.ts +29 -0
  949. package/src/factory/oracleClient.ts +2 -2
  950. package/src/idl/velocity.json +50 -1
  951. package/src/idl/velocity.ts +50 -1
  952. package/src/keypair.ts +8 -0
  953. package/src/marginCalculation.ts +153 -2
  954. package/src/math/amm.ts +371 -36
  955. package/src/math/auction.ts +139 -30
  956. package/src/math/bankruptcy.ts +104 -1
  957. package/src/math/builder.ts +74 -8
  958. package/src/math/conversion.ts +21 -0
  959. package/src/math/exchangeStatus.ts +125 -0
  960. package/src/math/funding.ts +63 -23
  961. package/src/math/insurance.ts +62 -0
  962. package/src/math/liquidation.ts +227 -17
  963. package/src/math/margin.ts +80 -14
  964. package/src/math/market.ts +148 -17
  965. package/src/math/oracles.ts +124 -0
  966. package/src/math/orders.ts +144 -18
  967. package/src/math/position.ts +80 -33
  968. package/src/math/repeg.ts +48 -10
  969. package/src/math/spotBalance.ts +252 -12
  970. package/src/math/spotMarket.ts +36 -3
  971. package/src/math/spotPosition.ts +72 -0
  972. package/src/math/state.ts +32 -1
  973. package/src/math/superStake.ts +126 -3
  974. package/src/math/tiers.ts +29 -0
  975. package/src/math/trade.ts +125 -55
  976. package/src/math/utils.ts +71 -9
  977. package/src/memcmp.ts +131 -7
  978. package/src/oracles/oracleClientCache.ts +16 -0
  979. package/src/oracles/oracleId.ts +39 -6
  980. package/src/oracles/prelaunchOracleClient.ts +20 -0
  981. package/src/oracles/pythClient.ts +32 -1
  982. package/src/oracles/pythLazerClient.ts +35 -1
  983. package/src/oracles/quoteAssetOracleClient.ts +18 -0
  984. package/src/oracles/strictOraclePrice.ts +21 -0
  985. package/src/oracles/types.ts +45 -0
  986. package/src/oracles/utils.ts +20 -0
  987. package/src/orderParams.ts +42 -4
  988. package/src/orderSubscriber/OrderSubscriber.ts +74 -2
  989. package/src/orderSubscriber/PollingSubscription.ts +11 -0
  990. package/src/orderSubscriber/WebsocketSubscription.ts +18 -0
  991. package/src/orderSubscriber/grpcSubscription.ts +16 -0
  992. package/src/orderSubscriber/types.ts +9 -0
  993. package/src/priorityFee/averageOverSlotsStrategy.ts +1 -0
  994. package/src/priorityFee/averageStrategy.ts +1 -0
  995. package/src/priorityFee/ewmaStrategy.ts +10 -0
  996. package/src/priorityFee/heliusPriorityFeeMethod.ts +13 -2
  997. package/src/priorityFee/maxOverSlotsStrategy.ts +1 -0
  998. package/src/priorityFee/maxStrategy.ts +1 -0
  999. package/src/priorityFee/priorityFeeSubscriber.ts +39 -0
  1000. package/src/priorityFee/priorityFeeSubscriberMap.ts +21 -2
  1001. package/src/priorityFee/solanaPriorityFeeMethod.ts +12 -0
  1002. package/src/priorityFee/types.ts +33 -15
  1003. package/src/priorityFee/velocityPriorityFeeMethod.ts +11 -0
  1004. package/src/slot/SlotSubscriber.ts +18 -0
  1005. package/src/slot/SlothashSubscriber.ts +27 -1
  1006. package/src/swift/swiftOrderSubscriber.ts +2 -2
  1007. package/src/tokenFaucet.ts +10 -7
  1008. package/src/tx/baseTxSender.ts +185 -5
  1009. package/src/tx/blockhashFetcher/baseBlockhashFetcher.ts +12 -0
  1010. package/src/tx/blockhashFetcher/cachedBlockhashFetcher.ts +15 -0
  1011. package/src/tx/blockhashFetcher/types.ts +4 -0
  1012. package/src/tx/fastSingleTxSender.ts +58 -4
  1013. package/src/tx/forwardOnlyTxSender.ts +48 -0
  1014. package/src/tx/reportTransactionError.ts +18 -6
  1015. package/src/tx/retryTxSender.ts +40 -0
  1016. package/src/tx/txHandler.ts +146 -35
  1017. package/src/tx/txParamProcessor.ts +47 -0
  1018. package/src/tx/types.ts +46 -0
  1019. package/src/tx/utils.ts +26 -0
  1020. package/src/tx/whileValidTxSender.ts +82 -0
  1021. package/src/types.ts +783 -22
  1022. package/src/user.ts +869 -110
  1023. package/src/userMap/PollingSubscription.ts +16 -2
  1024. package/src/userMap/WebsocketSubscription.ts +9 -0
  1025. package/src/userMap/grpcSubscription.ts +8 -0
  1026. package/src/userMap/referrerMap.ts +92 -3
  1027. package/src/userMap/revenueShareEscrowMap.ts +38 -11
  1028. package/src/userMap/userMap.ts +82 -4
  1029. package/src/userMap/userMapConfig.ts +23 -10
  1030. package/src/userMap/userStatsMap.ts +22 -0
  1031. package/src/userName.ts +16 -0
  1032. package/src/userStats.ts +28 -1
  1033. package/src/util/TransactionConfirmationManager.ts +33 -0
  1034. package/src/util/chainClock.ts +24 -0
  1035. package/src/util/computeUnits.ts +32 -0
  1036. package/src/util/digest.ts +17 -0
  1037. package/src/util/ed25519Utils.ts +12 -2
  1038. package/src/util/promiseTimeout.ts +9 -0
  1039. package/src/velocityClient.ts +3456 -254
  1040. package/src/wallet.ts +37 -0
  1041. package/tests/VelocityCore/builder_escrow.test.ts +121 -0
  1042. package/tests/amm/test.ts +102 -0
  1043. package/tests/builder/builderFee.test.ts +42 -0
  1044. package/tests/dlob/helpers.ts +1 -0
  1045. package/tests/dlob/tickSizeStandardization.ts +545 -0
  1046. package/tests/exchangeStatus/test.ts +45 -0
  1047. package/tests/liquidation/test.ts +125 -0
  1048. package/tests/oracles/mmOracleGate.test.ts +379 -0
  1049. package/tests/oracles/pythPegSnap.test.ts +76 -0
  1050. package/tests/sdkParity/enumParity.test.ts +84 -0
  1051. package/tests/sdkParity/marginCategoryFill.test.ts +143 -0
  1052. package/tests/sdkParity/memcmpOffsets.test.ts +139 -0
  1053. package/tests/spot/test.ts +55 -0
  1054. package/tests/user/bankruptcy.ts +165 -0
  1055. package/tests/user/feeAndWithdrawLimits.ts +284 -0
  1056. package/tests/user/getMarginCalculation.ts +226 -1
  1057. package/tests/user/test.ts +8 -4
package/src/user.ts CHANGED
@@ -8,8 +8,8 @@
8
8
  * - Health factor and liquidation threshold checks.
9
9
  * - Subscribes to and caches the latest `User` account state from chain.
10
10
  *
11
- * To send instructions (deposit, place order, etc.) use {@link VelocityClient}.
12
- * For referral/volume stats see {@link UserStats} (userStats.ts).
11
+ * To send instructions (deposit, place order, etc.) use `VelocityClient`.
12
+ * For referral/volume stats see `UserStats` (userStats.ts).
13
13
  */
14
14
  import { PublicKey } from '@solana/web3.js';
15
15
  import { EventEmitter } from 'events';
@@ -21,6 +21,7 @@ import {
21
21
  isVariant,
22
22
  MarginCategory,
23
23
  Order,
24
+ OrderParams,
24
25
  PerpMarketAccount,
25
26
  PerpPosition,
26
27
  ReferrerStatus,
@@ -42,6 +43,8 @@ import {
42
43
  DUST_POSITION_SIZE,
43
44
  FIVE_MINUTE,
44
45
  MARGIN_PRECISION,
46
+ MAX_POSITIVE_UPNL_FOR_INITIAL_MARGIN,
47
+ ONE,
45
48
  OPEN_ORDER_MARGIN_REQUIREMENT,
46
49
  PRICE_PRECISION,
47
50
  QUOTE_PRECISION,
@@ -88,6 +91,7 @@ import {
88
91
  SpotMarketAccount,
89
92
  } from './types';
90
93
  import { standardizeBaseAssetAmount } from './math/orders';
94
+ import { calculateBuilderFee, hasBuilderParams } from './math/builder';
91
95
  import { WebSocketProgramUserAccountSubscriber } from './accounts/websocketProgramUserAccountSubscriber';
92
96
  import {
93
97
  calculateAssetWeight,
@@ -128,6 +132,29 @@ import {
128
132
 
129
133
  export type MarginType = 'Cross' | 'Isolated';
130
134
 
135
+ /**
136
+ * Ports `get_proportion_u128` (math/helpers.rs) for the referee fee discount
137
+ * calculation. The Rust version routes large operands through a wider U192
138
+ * type purely to avoid u128 overflow; BN has no such ceiling, so that branch
139
+ * is elided here since it produces the same numeric result.
140
+ */
141
+ function getProportion128(value: BN, numerator: BN, denominator: BN): BN {
142
+ if (numerator.eq(denominator)) {
143
+ return value;
144
+ }
145
+
146
+ if (numerator.gt(denominator.div(TWO)) && denominator.gt(numerator)) {
147
+ // ceiling division, mirroring standardize_value_with_remainder_i128
148
+ const scaled = value.mul(denominator.sub(numerator));
149
+ const remainder = scaled.mod(denominator);
150
+ const floorDiv = scaled.div(denominator);
151
+ const ceilDiv = remainder.isZero() ? floorDiv : floorDiv.add(ONE);
152
+ return value.sub(ceilDiv);
153
+ }
154
+
155
+ return value.mul(numerator).div(denominator);
156
+ }
157
+
131
158
  export class User {
132
159
  velocityClient: VelocityClient;
133
160
  userAccountPublicKey: PublicKey;
@@ -135,6 +162,7 @@ export class User {
135
162
  _isSubscribed = false;
136
163
  eventEmitter: StrictEventEmitter<EventEmitter, UserAccountEvents>;
137
164
 
165
+ /** True only when both `subscribe()` has completed and the underlying `accountSubscriber` itself reports subscribed. */
138
166
  public get isSubscribed() {
139
167
  return this._isSubscribed && this.accountSubscriber.isSubscribed;
140
168
  }
@@ -143,6 +171,7 @@ export class User {
143
171
  this._isSubscribed = val;
144
172
  }
145
173
 
174
+ /** Constructs a `User` for the account at `config.userAccountPublicKey`, wiring up the account subscriber selected by `config.accountSubscription` (`'websocket'`/`'polling'`/`'grpc'`/`'custom'`). Does not fetch or subscribe — call `subscribe()` next. */
146
175
  public constructor(config: UserConfig) {
147
176
  // Type-system guarantees at least one of the two is supplied.
148
177
  const velocityClient = config.velocityClient!;
@@ -204,21 +233,24 @@ export class User {
204
233
  }
205
234
 
206
235
  /**
207
- * Subscribe to User state accounts
208
- * @returns SusbcriptionSuccess result
236
+ * Subscribes to this `User` account (websocket/polling/gRPC/custom per
237
+ * `UserConfig.accountSubscription`) and awaits the initial account fetch.
238
+ * Must resolve before any `get*`/margin/PnL accessor is called — those
239
+ * throw `NotSubscribedError` until this has completed.
240
+ * @param userAccount Optional pre-fetched account to seed the subscriber with, skipping the initial RPC fetch.
241
+ * @returns True once the underlying subscriber reports subscribed.
209
242
  */
210
243
  public async subscribe(userAccount?: UserAccount): Promise<boolean> {
211
244
  this.isSubscribed = await this.accountSubscriber.subscribe(userAccount);
212
245
  return this.isSubscribed;
213
246
  }
214
247
 
215
- /**
216
- * Forces the accountSubscriber to fetch account updates from rpc
217
- */
248
+ /** Forces the account subscriber to re-fetch the `User` account from RPC (bypassing any push/poll cadence). */
218
249
  public async fetchAccounts(): Promise<void> {
219
250
  await this.accountSubscriber.fetch();
220
251
  }
221
252
 
253
+ /** Removes all event listeners and tears down the account subscription. */
222
254
  public async unsubscribe(): Promise<void> {
223
255
  this.eventEmitter.removeAllListeners();
224
256
  await this.accountSubscriber.unsubscribe();
@@ -229,7 +261,7 @@ export class User {
229
261
  * Returns the cached user account.
230
262
  *
231
263
  * - **Throws** `NotSubscribedError` if the subscriber has not been subscribed
232
- * yet — reading the account before {@link subscribe} resolves is a
264
+ * yet — reading the account before `subscribe()` resolves is a
233
265
  * programming error, not a missing-account condition.
234
266
  * - Returns `undefined` when subscribed but no account was found on chain.
235
267
  * Because `subscribe()` awaits the initial fetch, an `undefined` here means
@@ -241,13 +273,14 @@ export class User {
241
273
  }
242
274
 
243
275
  /**
244
- * Like {@link getUserAccount} but throws instead of returning `undefined`
276
+ * Like `getUserAccount` but throws instead of returning `undefined`
245
277
  * when the account was not found. Use at call sites that structurally
246
278
  * require the account to exist. (Still propagates `NotSubscribedError` when
247
279
  * called before subscribing.)
248
280
  *
249
- * Delegates to {@link getUserAccount} (rather than the subscriber directly)
281
+ * Delegates to `getUserAccount` (rather than the subscriber directly)
250
282
  * so callers that override `getUserAccount` see the override here too.
283
+ * @returns The current `UserAccount`.
251
284
  */
252
285
  public getUserAccountOrThrow(): UserAccount {
253
286
  const userAccount = this.getUserAccount();
@@ -259,18 +292,29 @@ export class User {
259
292
  return userAccount;
260
293
  }
261
294
 
295
+ /**
296
+ * Bypasses the cached subscriber state and force-fetches the `User` account
297
+ * directly from the RPC (via `fetchAccounts`), then returns the freshly
298
+ * cached value. Useful right after sending a transaction, when the
299
+ * websocket/polling subscriber may not yet have observed the update.
300
+ * @returns The freshly fetched `UserAccount`, or `undefined` if the account does not exist on chain.
301
+ */
262
302
  public async forceGetUserAccount(): Promise<UserAccount | undefined> {
263
303
  await this.fetchAccounts();
264
304
  const account = this.accountSubscriber.getUserAccountAndSlot();
265
305
  return account?.data;
266
306
  }
267
307
 
308
+ /**
309
+ * Returns the cached user account together with the slot at which it was
310
+ * last observed. Same `undefined`/`NotSubscribedError` contract as `getUserAccount`.
311
+ */
268
312
  public getUserAccountAndSlot(): DataAndSlot<UserAccount> | undefined {
269
313
  return this.accountSubscriber.getUserAccountAndSlot();
270
314
  }
271
315
 
272
316
  /**
273
- * Like {@link getUserAccountAndSlot} but throws instead of returning
317
+ * Like `getUserAccountAndSlot` but throws instead of returning
274
318
  * `undefined` when the account was not found. Use at call sites that
275
319
  * structurally require the account to exist. (Still propagates
276
320
  * `NotSubscribedError` when called before subscribing.)
@@ -282,6 +326,16 @@ export class User {
282
326
  );
283
327
  }
284
328
 
329
+ /**
330
+ * Finds the perp position for `marketIndex` on an explicit `userAccount`
331
+ * snapshot rather than the cached account. Only matches "active" positions
332
+ * (see `getActivePerpPositionsForUserAccount`) — a market the user has never
333
+ * touched (or has fully closed and settled) returns `undefined` even though
334
+ * the on-chain array always has a fixed-size slot for every market.
335
+ * @param userAccount Account snapshot to search (does not have to be the subscribed account).
336
+ * @param marketIndex Perp market index to look up.
337
+ * @returns The matching `PerpPosition`, or `undefined` if the user has no active position in that market.
338
+ */
285
339
  public getPerpPositionForUserAccount(
286
340
  userAccount: UserAccount,
287
341
  marketIndex: number
@@ -301,6 +355,12 @@ export class User {
301
355
  return this.getPerpPositionForUserAccount(userAccount, marketIndex);
302
356
  }
303
357
 
358
+ /**
359
+ * Like `getPerpPosition`, but returns a zeroed-out placeholder position
360
+ * (see `getEmptyPosition`) instead of `undefined` when the user has no
361
+ * active position in `marketIndex`. Convenient for math helpers that need a
362
+ * `PerpPosition` shape unconditionally (e.g. buying-power/leverage calcs).
363
+ */
304
364
  public getPerpPositionOrEmpty(marketIndex: number): PerpPosition {
305
365
  const userAccount = this.getUserAccountOrThrow();
306
366
  return (
@@ -309,6 +369,10 @@ export class User {
309
369
  );
310
370
  }
311
371
 
372
+ /**
373
+ * Like `getPerpPosition`, but throws instead of returning `undefined` when
374
+ * the user has no active position in `marketIndex`.
375
+ */
312
376
  public getPerpPositionOrThrow(marketIndex: number): PerpPosition {
313
377
  const position = this.getPerpPosition(marketIndex);
314
378
  if (!position) {
@@ -317,6 +381,10 @@ export class User {
317
381
  return position;
318
382
  }
319
383
 
384
+ /**
385
+ * Like `getPerpPosition`, but also returns the slot at which the underlying
386
+ * `UserAccount` was observed.
387
+ */
320
388
  public getPerpPositionAndSlot(
321
389
  marketIndex: number
322
390
  ): DataAndSlot<PerpPosition | undefined> {
@@ -331,6 +399,14 @@ export class User {
331
399
  };
332
400
  }
333
401
 
402
+ /**
403
+ * Finds the spot position for `marketIndex` on an explicit `userAccount`
404
+ * snapshot. Unlike `getPerpPositionForUserAccount`, this does not filter to
405
+ * "active" positions first — it returns whatever fixed-size slot entry
406
+ * exists for that market index, even if the position is empty/available.
407
+ * @param userAccount Account snapshot to search (does not have to be the subscribed account).
408
+ * @param marketIndex Spot market index to look up.
409
+ */
334
410
  public getSpotPositionForUserAccount(
335
411
  userAccount: UserAccount,
336
412
  marketIndex: number
@@ -350,6 +426,10 @@ export class User {
350
426
  return this.getSpotPositionForUserAccount(userAccount, marketIndex);
351
427
  }
352
428
 
429
+ /**
430
+ * Like `getSpotPosition`, but also returns the slot at which the underlying
431
+ * `UserAccount` was observed.
432
+ */
353
433
  public getSpotPositionAndSlot(
354
434
  marketIndex: number
355
435
  ): DataAndSlot<SpotPosition | undefined> {
@@ -364,6 +444,7 @@ export class User {
364
444
  };
365
445
  }
366
446
 
447
+ /** Returns a zeroed-out (no deposit/borrow) placeholder `SpotPosition` for `marketIndex`. */
367
448
  getEmptySpotPosition(marketIndex: number): SpotPosition {
368
449
  return {
369
450
  marketIndex,
@@ -381,6 +462,7 @@ export class User {
381
462
  * Positive if it is a deposit, negative if it is a borrow.
382
463
  *
383
464
  * @param marketIndex
465
+ * @returns Signed token amount, in the spot market's own token decimals (not QUOTE_PRECISION). `ZERO` if the user has no position in the market.
384
466
  */
385
467
  public getTokenAmount(marketIndex: number): BN {
386
468
  const spotPosition = this.getSpotPosition(marketIndex);
@@ -399,6 +481,7 @@ export class User {
399
481
  );
400
482
  }
401
483
 
484
+ /** Returns a zeroed-out placeholder `PerpPosition` for `marketIndex` (no size, no orders, cross margin). */
402
485
  public getEmptyPosition(marketIndex: number): PerpPosition {
403
486
  return {
404
487
  baseAssetAmount: ZERO,
@@ -418,10 +501,19 @@ export class User {
418
501
  };
419
502
  }
420
503
 
504
+ /** Returns true if `position` has no size and no open orders (a market slot that can be treated as unused). */
421
505
  public isPositionEmpty(position: PerpPosition): boolean {
422
506
  return position.baseAssetAmount.eq(ZERO) && position.openOrders === 0;
423
507
  }
424
508
 
509
+ /**
510
+ * Returns the isolated-margin quote deposit backing a given perp position,
511
+ * i.e. `PerpPosition.isolatedPositionScaledBalance` converted to a token
512
+ * amount. This is the collateral segregated to that single isolated
513
+ * position, separate from the user's cross-margin free collateral.
514
+ * @param perpMarketIndex
515
+ * @returns Quote token amount (the quote spot market's own decimals). `ZERO` if the user has no position or no isolated deposit in the market.
516
+ */
425
517
  public getIsolatePerpPositionTokenAmount(perpMarketIndex: number): BN {
426
518
  const perpPosition = this.getPerpPosition(perpMarketIndex);
427
519
  if (!perpPosition) return ZERO;
@@ -442,6 +534,7 @@ export class User {
442
534
 
443
535
  /**
444
536
  * Returns the total USD value of deposits across all isolated perp positions.
537
+ * @returns Precision QUOTE_PRECISION (1e6).
445
538
  */
446
539
  public getTotalIsolatedPositionDeposits(): BN {
447
540
  return this.getActivePerpPositions().reduce((total, perpPosition) => {
@@ -475,11 +568,13 @@ export class User {
475
568
  }, ZERO);
476
569
  }
477
570
 
571
+ /** Returns a shallow copy of `position`. Mutating the clone does not affect the cached account. */
478
572
  public getClonedPosition(position: PerpPosition): PerpPosition {
479
573
  const clonedPosition = Object.assign({}, position);
480
574
  return clonedPosition;
481
575
  }
482
576
 
577
+ /** Finds an order by its program-assigned `orderId` on an explicit `userAccount` snapshot. */
483
578
  public getOrderForUserAccount(
484
579
  userAccount: UserAccount,
485
580
  orderId: number
@@ -488,14 +583,16 @@ export class User {
488
583
  }
489
584
 
490
585
  /**
586
+ * Finds an order in the cached `UserAccount` by its program-assigned `orderId`.
491
587
  * @param orderId
492
- * @returns Order
588
+ * @returns The matching `Order`, or `undefined` if no order with that id exists.
493
589
  */
494
590
  public getOrder(orderId: number): Order | undefined {
495
591
  const userAccount = this.getUserAccountOrThrow();
496
592
  return this.getOrderForUserAccount(userAccount, orderId);
497
593
  }
498
594
 
595
+ /** Like `getOrder`, but also returns the slot at which the underlying `UserAccount` was observed. */
499
596
  public getOrderAndSlot(orderId: number): DataAndSlot<Order | undefined> {
500
597
  const userAccount = this.getUserAccountAndSlotOrThrow();
501
598
  const order = this.getOrderForUserAccount(userAccount.data, orderId);
@@ -505,6 +602,11 @@ export class User {
505
602
  };
506
603
  }
507
604
 
605
+ /**
606
+ * Finds an order by its caller-assigned `userOrderId` (a client-chosen tag,
607
+ * distinct from the program-assigned `orderId`) on an explicit `userAccount`
608
+ * snapshot.
609
+ */
508
610
  public getOrderByUserIdForUserAccount(
509
611
  userAccount: UserAccount,
510
612
  userOrderId: number
@@ -515,14 +617,17 @@ export class User {
515
617
  }
516
618
 
517
619
  /**
620
+ * Finds an order in the cached `UserAccount` by its caller-assigned
621
+ * `userOrderId` (a client-chosen tag, distinct from the program-assigned `orderId`).
518
622
  * @param userOrderId
519
- * @returns Order
623
+ * @returns The matching `Order`, or `undefined` if no order with that tag exists.
520
624
  */
521
625
  public getOrderByUserOrderId(userOrderId: number): Order | undefined {
522
626
  const userAccount = this.getUserAccountOrThrow();
523
627
  return this.getOrderByUserIdForUserAccount(userAccount, userOrderId);
524
628
  }
525
629
 
630
+ /** Like `getOrderByUserOrderId`, but also returns the slot at which the underlying `UserAccount` was observed. */
526
631
  public getOrderByUserOrderIdAndSlot(
527
632
  userOrderId: number
528
633
  ): DataAndSlot<Order | undefined> {
@@ -537,6 +642,11 @@ export class User {
537
642
  };
538
643
  }
539
644
 
645
+ /**
646
+ * Filters an explicit `userAccount` snapshot's orders down to those with
647
+ * `OrderStatus.Open`.
648
+ * @returns `undefined` if `userAccount` is `undefined` (i.e. no account loaded), otherwise the array of open orders (possibly empty).
649
+ */
540
650
  public getOpenOrdersForUserAccount(
541
651
  userAccount?: UserAccount
542
652
  ): Order[] | undefined {
@@ -545,11 +655,13 @@ export class User {
545
655
  );
546
656
  }
547
657
 
658
+ /** Returns all of the user's orders with `OrderStatus.Open`. Empty array (not `undefined`) if there are none or no account is loaded. */
548
659
  public getOpenOrders(): Order[] {
549
660
  const userAccount = this.getUserAccount();
550
661
  return this.getOpenOrdersForUserAccount(userAccount) ?? [];
551
662
  }
552
663
 
664
+ /** Like `getOpenOrders`, but also returns the slot at which the underlying `UserAccount` was observed. */
553
665
  public getOpenOrdersAndSlot(): DataAndSlot<Order[]> {
554
666
  const userAccount = this.getUserAccountAndSlotOrThrow();
555
667
  const openOrders = this.getOpenOrdersForUserAccount(userAccount.data) ?? [];
@@ -559,10 +671,12 @@ export class User {
559
671
  };
560
672
  }
561
673
 
674
+ /** Returns this `User`'s account address (does not require the account to be subscribed or to exist on chain). */
562
675
  public getUserAccountPublicKey(): PublicKey {
563
676
  return this.userAccountPublicKey;
564
677
  }
565
678
 
679
+ /** Checks directly via RPC (bypassing the subscriber cache) whether the `User` account exists on chain. */
566
680
  public async exists(): Promise<boolean> {
567
681
  const userAccountRPCResponse =
568
682
  await this.velocityClient.connection.getParsedAccountInfo(
@@ -572,9 +686,9 @@ export class User {
572
686
  }
573
687
 
574
688
  /**
575
- * calculates the total open bids/asks in a perp market (including lps)
576
- * @returns : open bids
577
- * @returns : open asks
689
+ * Returns the position's total resting open-order bid/ask size in a perp market.
690
+ * @param marketIndex
691
+ * @returns Tuple of `[openBids, openAsks]`, both `BASE_PRECISION` (1e9). Throws (via `getPerpPositionOrThrow`) if the user has no active position in `marketIndex`.
578
692
  */
579
693
  public getPerpBidAsks(marketIndex: number): [BN, BN] {
580
694
  const position = this.getPerpPositionOrThrow(marketIndex);
@@ -587,7 +701,17 @@ export class User {
587
701
 
588
702
  /**
589
703
  * calculates Buying Power = free collateral / initial margin ratio
590
- * @returns : Precision QUOTE_PRECISION
704
+ *
705
+ * For `positionType: 'isolated'`, the buying power is capped by the
706
+ * lesser of (a) the user's cross free collateral and (b) the free quote
707
+ * asset value in the perp's quote spot market — mirroring that an isolated
708
+ * position can only draw down as much quote collateral as is actually
709
+ * available to isolate into it.
710
+ * @param marketIndex Perp market to size buying power for.
711
+ * @param collateralBuffer Amount (QUOTE_PRECISION) subtracted from free collateral before sizing, e.g. to reserve for fees. Defaults to zero.
712
+ * @param maxMarginRatio Optional override for the max margin ratio component (see `resolveMaxMarginRatio`); defaults to the position's/user's configured ratio.
713
+ * @param positionType Whether to size for a cross or isolated-margin position. Defaults to `'cross'`.
714
+ * @returns Precision QUOTE_PRECISION (1e6).
591
715
  */
592
716
  public getPerpBuyingPower(
593
717
  marketIndex: number,
@@ -657,6 +781,17 @@ export class User {
657
781
  );
658
782
  }
659
783
 
784
+ /**
785
+ * Converts a free-collateral amount directly into buying power for a perp
786
+ * market, given the (hypothetical) resulting base position size — used
787
+ * internally so the margin ratio (which can vary with position size via the
788
+ * IMF factor) reflects the post-trade size rather than the current size.
789
+ * @param marketIndex
790
+ * @param freeCollateral QUOTE_PRECISION (1e6).
791
+ * @param baseAssetAmount Base size, BASE_PRECISION (1e9), used only to select the applicable margin ratio.
792
+ * @param perpMarketMaxMarginRatio Optional max-margin-ratio override, see `resolveMaxMarginRatio`.
793
+ * @returns Precision QUOTE_PRECISION (1e6).
794
+ */
660
795
  getPerpBuyingPowerFromFreeCollateralAndBaseAssetAmount(
661
796
  marketIndex: number,
662
797
  freeCollateral: BN,
@@ -676,7 +811,15 @@ export class User {
676
811
 
677
812
  /**
678
813
  * calculates Free Collateral = Total collateral - margin requirement
679
- * @returns : Precision QUOTE_PRECISION
814
+ *
815
+ * When `perpMarketIndex` is provided, returns the free collateral scoped to
816
+ * that market's isolated margin bucket (the isolated quote deposit plus its
817
+ * unrealized PnL, minus its own margin requirement) rather than the user's
818
+ * cross-margin free collateral. If the user has no isolated position open in
819
+ * that market, returns `ZERO` rather than throwing.
820
+ * @param marginCategory `'Initial'` or `'Maintenance'`. Defaults to `'Initial'`; `'Initial'` also enables strict (TWAP-bounded) oracle pricing.
821
+ * @param perpMarketIndex Optional isolated perp market to scope the calculation to; omit for cross margin.
822
+ * @returns Precision QUOTE_PRECISION (1e6). Can be negative (deficit).
680
823
  */
681
824
  public getFreeCollateral(
682
825
  marginCategory: MarginCategory = 'Initial',
@@ -711,13 +854,22 @@ export class User {
711
854
  /**
712
855
  * Calculates the margin requirement based on the specified parameters.
713
856
  *
857
+ * When `perpMarketIndex` is passed, returns the isolated margin requirement
858
+ * for that market's isolated position only (`ZERO` if none exists) rather
859
+ * than the cross-margin requirement. `liquidationBuffer`, when non-zero,
860
+ * selects the buffered variant (`marginRequirementPlusBuffer` /
861
+ * `MarginContext.liquidation`), which pads the requirement to build in the
862
+ * state account's `liquidationMarginBufferRatio` — the same buffer keepers
863
+ * apply so a position doesn't get flagged for liquidation and immediately
864
+ * clear again.
865
+ *
714
866
  * @param marginCategory - The category of margin to calculate ('Initial' or 'Maintenance').
715
- * @param liquidationBuffer - Optional buffer amount to consider during liquidation scenarios.
716
- * @param strict - Optional flag to enforce strict margin calculations.
717
- * @param includeOpenOrders - Optional flag to include open orders in the margin calculation.
718
- * @param perpMarketIndex - Optional index of the perpetual market. Required if marginType is 'Isolated'.
867
+ * @param liquidationBuffer - Optional buffer amount (MARGIN_PRECISION, 1e4, added to the margin ratio) to consider during liquidation scenarios.
868
+ * @param strict - Optional flag to enforce strict (TWAP-bounded) oracle pricing.
869
+ * @param includeOpenOrders - Optional flag to include open orders' worst-case margin impact.
870
+ * @param perpMarketIndex - Optional index of the perpetual market. Scopes the result to that market's isolated position.
719
871
  *
720
- * @returns The calculated margin requirement as a BN (BigNumber).
872
+ * @returns The calculated margin requirement, QUOTE_PRECISION (1e6).
721
873
  */
722
874
  public getMarginRequirement(
723
875
  marginCategory: MarginCategory,
@@ -769,7 +921,12 @@ export class User {
769
921
  }
770
922
 
771
923
  /**
772
- * @returns The initial margin requirement in USDC. : QUOTE_PRECISION
924
+ * Initial margin requirement the collateral needed to open/maintain a
925
+ * position at initial (as opposed to maintenance) margin ratios, using
926
+ * strict (TWAP-bounded) oracle pricing. This is what gates new orders and
927
+ * increases in leverage.
928
+ * @param perpMarketIndex Optional isolated perp market to scope to; omit for the cross-margin requirement.
929
+ * @returns The initial margin requirement in USDC. : QUOTE_PRECISION (1e6)
773
930
  */
774
931
  public getInitialMarginRequirement(perpMarketIndex?: number): BN {
775
932
  return this.getMarginRequirement(
@@ -782,7 +939,12 @@ export class User {
782
939
  }
783
940
 
784
941
  /**
785
- * @returns The maintenance margin requirement in USDC. : QUOTE_PRECISION
942
+ * Maintenance margin requirement the minimum collateral below which the
943
+ * position becomes eligible for liquidation. Uses non-strict oracle pricing
944
+ * and includes open orders' worst-case impact by default.
945
+ * @param liquidationBuffer Optional buffer (MARGIN_PRECISION, 1e4) added to the margin ratio, mirroring the state account's `liquidationMarginBufferRatio`.
946
+ * @param perpMarketIndex Optional isolated perp market to scope to; omit for the cross-margin requirement.
947
+ * @returns The maintenance margin requirement in USDC. : QUOTE_PRECISION (1e6)
786
948
  */
787
949
  public getMaintenanceMarginRequirement(
788
950
  liquidationBuffer?: BN,
@@ -797,6 +959,12 @@ export class User {
797
959
  );
798
960
  }
799
961
 
962
+ /**
963
+ * Filters an explicit `userAccount` snapshot's fixed-size perp position
964
+ * array down to slots that are actually "active": nonzero base or quote
965
+ * amount, an outstanding open order count, or a nonzero isolated-margin
966
+ * quote deposit (a position can be flat but still isolated-funded).
967
+ */
800
968
  public getActivePerpPositionsForUserAccount(
801
969
  userAccount: UserAccount
802
970
  ): PerpPosition[] {
@@ -809,10 +977,12 @@ export class User {
809
977
  );
810
978
  }
811
979
 
980
+ /** Returns the cached account's active perp positions. See `getActivePerpPositionsForUserAccount` for the activity criteria. */
812
981
  public getActivePerpPositions(): PerpPosition[] {
813
982
  const userAccount = this.getUserAccountOrThrow();
814
983
  return this.getActivePerpPositionsForUserAccount(userAccount);
815
984
  }
985
+ /** Like `getActivePerpPositions`, but also returns the slot at which the underlying `UserAccount` was observed. */
816
986
  public getActivePerpPositionsAndSlot(): DataAndSlot<PerpPosition[]> {
817
987
  const userAccount = this.getUserAccountAndSlotOrThrow();
818
988
  const positions = this.getActivePerpPositionsForUserAccount(
@@ -824,6 +994,7 @@ export class User {
824
994
  };
825
995
  }
826
996
 
997
+ /** Filters an explicit `userAccount` snapshot's spot positions to those that are not `isSpotPositionAvailable` (i.e. have a nonzero balance, orders, or cumulative deposits). */
827
998
  public getActiveSpotPositionsForUserAccount(
828
999
  userAccount: UserAccount
829
1000
  ): SpotPosition[] {
@@ -832,10 +1003,12 @@ export class User {
832
1003
  );
833
1004
  }
834
1005
 
1006
+ /** Returns the cached account's active spot positions. See `getActiveSpotPositionsForUserAccount` for the activity criteria. */
835
1007
  public getActiveSpotPositions(): SpotPosition[] {
836
1008
  const userAccount = this.getUserAccountOrThrow();
837
1009
  return this.getActiveSpotPositionsForUserAccount(userAccount);
838
1010
  }
1011
+ /** Like `getActiveSpotPositions`, but also returns the slot at which the underlying `UserAccount` was observed. */
839
1012
  public getActiveSpotPositionsAndSlot(): DataAndSlot<SpotPosition[]> {
840
1013
  const userAccount = this.getUserAccountAndSlotOrThrow();
841
1014
  const positions = this.getActiveSpotPositionsForUserAccount(
@@ -848,8 +1021,25 @@ export class User {
848
1021
  }
849
1022
 
850
1023
  /**
851
- * calculates unrealized position price pnl
852
- * @returns : Precision QUOTE_PRECISION
1024
+ * Calculates unrealized position price PnL, summed across all active perp
1025
+ * positions (or a single one if `marketIndex` is given).
1026
+ *
1027
+ * When `withWeightMarginCategory` is supplied, the PnL is asset-weighted
1028
+ * for margin purposes: profitable positions are scaled down by
1029
+ * `calculateUnrealizedAssetWeight` (an unrealized gain is a less-trusted
1030
+ * asset than settled collateral), and — for `'Initial'` margin specifically
1031
+ * — the *per-position* weighted gain is additionally capped at
1032
+ * `MAX_POSITIVE_UPNL_FOR_INITIAL_MARGIN` (**$100**, QUOTE_PRECISION), a
1033
+ * safety guard against a single dangerously-configured or manipulated
1034
+ * market inflating buying power. Losses are never capped, and a
1035
+ * `liquidationBuffer` (if provided) further inflates negative PnL to
1036
+ * mirror the on-chain liquidation-buffer treatment.
1037
+ * @param withFunding If true, includes unsettled funding in each position's PnL.
1038
+ * @param marketIndex Optional single perp market to scope to; omit to sum across all active positions.
1039
+ * @param withWeightMarginCategory Optional `'Initial'` or `'Maintenance'` — applies the asset-weighting (and, for `'Initial'`, the $100-per-position cap) described above. Omit for raw, unweighted PnL.
1040
+ * @param strict Use the worse of live oracle price vs 5-minute TWAP per position (gains use the lower price, losses use the higher price). Defaults to false.
1041
+ * @param liquidationBuffer Optional buffer (MARGIN_PRECISION, 1e4) that further penalizes negative PnL; only applied when `withWeightMarginCategory` is set.
1042
+ * @returns : Precision QUOTE_PRECISION (1e6)
853
1043
  */
854
1044
  public getUnrealizedPNL(
855
1045
  withFunding?: boolean,
@@ -918,6 +1108,14 @@ export class User {
918
1108
  .div(new BN(SPOT_MARKET_WEIGHT_PRECISION));
919
1109
  }
920
1110
 
1111
+ if (withWeightMarginCategory === 'Initial') {
1112
+ // safety guard for dangerously configured perp market
1113
+ positionUnrealizedPnl = BN.min(
1114
+ positionUnrealizedPnl,
1115
+ MAX_POSITIVE_UPNL_FOR_INITIAL_MARGIN
1116
+ );
1117
+ }
1118
+
921
1119
  if (liquidationBuffer && positionUnrealizedPnl.lt(ZERO)) {
922
1120
  positionUnrealizedPnl = positionUnrealizedPnl.add(
923
1121
  positionUnrealizedPnl.mul(liquidationBuffer).div(MARGIN_PRECISION)
@@ -930,8 +1128,11 @@ export class User {
930
1128
  }
931
1129
 
932
1130
  /**
933
- * calculates unrealized funding payment pnl
934
- * @returns : Precision QUOTE_PRECISION
1131
+ * Calculates unrealized funding payment PnL — the funding accrued since
1132
+ * each position's `lastCumulativeFundingRate` was last settled, not yet
1133
+ * reflected in `quoteAssetAmount`.
1134
+ * @param marketIndex Optional single perp market to scope to; omit to sum across all positions.
1135
+ * @returns : Precision QUOTE_PRECISION (1e6)
935
1136
  */
936
1137
  public getUnrealizedFundingPNL(marketIndex?: number): BN {
937
1138
  return this.getUserAccountOrThrow()
@@ -946,6 +1147,20 @@ export class User {
946
1147
  }, ZERO);
947
1148
  }
948
1149
 
1150
+ /**
1151
+ * Computes the combined weighted asset value and weighted liability value
1152
+ * across the user's spot positions (worst-case, including open-order
1153
+ * exposure by default), plus the net quote balance. This is the core spot
1154
+ * side of the margin system that `getTotalCollateral`/`getMarginRequirement`
1155
+ * build on.
1156
+ * @param marketIndex Optional single spot market to scope to; omit to sum across all spot markets.
1157
+ * @param marginCategory `'Initial'` or `'Maintenance'` asset/liability weights; omit for unweighted (100%) values.
1158
+ * @param liquidationBuffer Optional buffer (MARGIN_PRECISION, 1e4) added to the liability weight side.
1159
+ * @param includeOpenOrders If false, ignores open bids/asks and only counts the current balance (faster, less conservative).
1160
+ * @param strict Use the worse of live oracle price vs 5-minute TWAP. Defaults to false.
1161
+ * @param now Unix timestamp (seconds) used for TWAP staleness when `strict` is set; defaults to current time.
1162
+ * @returns `{ totalAssetValue, totalLiabilityValue }`, both QUOTE_PRECISION (1e6) and non-negative.
1163
+ */
949
1164
  public getSpotMarketAssetAndLiabilityValue(
950
1165
  marketIndex?: number,
951
1166
  marginCategory?: MarginCategory,
@@ -1142,6 +1357,7 @@ export class User {
1142
1357
  return { totalAssetValue, totalLiabilityValue };
1143
1358
  }
1144
1359
 
1360
+ /** Convenience wrapper around `getSpotMarketAssetAndLiabilityValue` returning only `totalLiabilityValue`. See that method for parameter semantics. Returns QUOTE_PRECISION (1e6). */
1145
1361
  public getSpotMarketLiabilityValue(
1146
1362
  marketIndex?: number,
1147
1363
  marginCategory?: MarginCategory,
@@ -1161,6 +1377,7 @@ export class User {
1161
1377
  return totalLiabilityValue;
1162
1378
  }
1163
1379
 
1380
+ /** Thin wrapper around the `math/spotBalance` `getSpotLiabilityValue` helper that supplies the user's `maxMarginRatio`. Returns QUOTE_PRECISION (1e6), negative. */
1164
1381
  getSpotLiabilityValue(
1165
1382
  tokenAmount: BN,
1166
1383
  strictOraclePrice: StrictOraclePrice,
@@ -1178,6 +1395,7 @@ export class User {
1178
1395
  );
1179
1396
  }
1180
1397
 
1398
+ /** Convenience wrapper around `getSpotMarketAssetAndLiabilityValue` returning only `totalAssetValue`. See that method for parameter semantics. Returns QUOTE_PRECISION (1e6), non-negative. */
1181
1399
  public getSpotMarketAssetValue(
1182
1400
  marketIndex?: number,
1183
1401
  marginCategory?: MarginCategory,
@@ -1196,6 +1414,7 @@ export class User {
1196
1414
  return totalAssetValue;
1197
1415
  }
1198
1416
 
1417
+ /** Thin wrapper around the `math/spotBalance` `getSpotAssetValue` helper that supplies the user's `maxMarginRatio`. Returns QUOTE_PRECISION (1e6), non-negative. */
1199
1418
  getSpotAssetValue(
1200
1419
  tokenAmount: BN,
1201
1420
  strictOraclePrice: StrictOraclePrice,
@@ -1211,6 +1430,7 @@ export class User {
1211
1430
  );
1212
1431
  }
1213
1432
 
1433
+ /** Net spot value (`totalAssetValue - totalLiabilityValue`) for a single spot market. See `getSpotMarketAssetAndLiabilityValue` for parameter semantics. Returns QUOTE_PRECISION (1e6), can be negative. */
1214
1434
  public getSpotPositionValue(
1215
1435
  marketIndex: number,
1216
1436
  marginCategory?: MarginCategory,
@@ -1231,6 +1451,12 @@ export class User {
1231
1451
  return totalAssetValue.sub(totalLiabilityValue);
1232
1452
  }
1233
1453
 
1454
+ /**
1455
+ * Net spot value (`totalAssetValue - totalLiabilityValue`) across all spot
1456
+ * markets combined.
1457
+ * @param withWeightMarginCategory Optional `'Initial'`/`'Maintenance'` weighting; omit for unweighted values.
1458
+ * @returns Precision QUOTE_PRECISION (1e6), can be negative.
1459
+ */
1234
1460
  public getNetSpotMarketValue(withWeightMarginCategory?: MarginCategory): BN {
1235
1461
  const { totalAssetValue, totalLiabilityValue } =
1236
1462
  this.getSpotMarketAssetAndLiabilityValue(
@@ -1245,6 +1471,24 @@ export class User {
1245
1471
  * calculates TotalCollateral: collateral + unrealized pnl
1246
1472
  * @returns : Precision QUOTE_PRECISION
1247
1473
  */
1474
+ /**
1475
+ * Calculates Total Collateral: net spot collateral value plus weighted
1476
+ * unrealized perp PnL (see `getUnrealizedPNL`'s `$100`-per-position cap
1477
+ * under `'Initial'` margin). This is the numerator side of the margin
1478
+ * system; `getFreeCollateral`/`getMarginRequirement` are derived from it.
1479
+ *
1480
+ * When `perpMarketIndex` is provided, returns the isolated total collateral
1481
+ * for that market's isolated position bucket instead of the cross-margin
1482
+ * total — and **throws** if the user has no isolated margin calculation for
1483
+ * that market (unlike `getFreeCollateral`, which swallows the same case and
1484
+ * returns `ZERO`).
1485
+ * @param marginCategory `'Initial'` or `'Maintenance'`. Defaults to `'Initial'`.
1486
+ * @param strict Use TWAP-bounded oracle pricing. Defaults to false.
1487
+ * @param includeOpenOrders Include open orders' worst-case impact. Defaults to true.
1488
+ * @param liquidationBuffer Optional buffer (MARGIN_PRECISION, 1e4); selects the buffered collateral variant when non-zero.
1489
+ * @param perpMarketIndex Optional isolated perp market to scope to.
1490
+ * @returns Precision QUOTE_PRECISION (1e6).
1491
+ */
1248
1492
  public getTotalCollateral(
1249
1493
  marginCategory: MarginCategory = 'Initial',
1250
1494
  strict = false,
@@ -1288,6 +1532,15 @@ export class User {
1288
1532
  return marginCalc.totalCollateral;
1289
1533
  }
1290
1534
 
1535
+ /**
1536
+ * Builds the liquidation-buffer map to pass into margin calculations while
1537
+ * a liquidation is in progress: `'cross'` is set to the state account's
1538
+ * `liquidationMarginBufferRatio` if cross margin is being liquidated, and
1539
+ * each isolated perp position currently flagged `BeingLiquidated` or
1540
+ * `Bankruptcy` gets the same buffer under its market index. Positions not
1541
+ * currently being liquidated are omitted (no buffer applied).
1542
+ * @returns Map from `'cross'` or a perp market index to the buffer amount (MARGIN_PRECISION, 1e4).
1543
+ */
1291
1544
  public getLiquidationBuffer(): Map<number | 'cross', BN> {
1292
1545
  const liquidationBufferMap = new Map<number | 'cross', BN>();
1293
1546
  if (this.isBeingLiquidated()) {
@@ -1315,8 +1568,19 @@ export class User {
1315
1568
  }
1316
1569
 
1317
1570
  /**
1318
- * calculates User Health by comparing total collateral and maint. margin requirement
1319
- * @returns : number (value from [0, 100])
1571
+ * Calculates a user's health score by comparing total collateral against
1572
+ * the maintenance margin requirement: `100 * (1 - maintenanceMarginReq / totalCollateral)`,
1573
+ * clamped to `[0, 100]` and rounded to the nearest integer. `100` means no
1574
+ * maintenance requirement (or a requirement of zero with non-negative
1575
+ * collateral); `0` means at or past the maintenance threshold (liquidatable)
1576
+ * or that collateral is non-positive.
1577
+ *
1578
+ * Short-circuits to `0` if the relevant scope is already flagged as being
1579
+ * liquidated: cross margin via `isCrossMarginBeingLiquidated` (when
1580
+ * `perpMarketIndex` is omitted), or the specific isolated position via
1581
+ * `isIsolatedPositionBeingLiquidated` (when `perpMarketIndex` is given).
1582
+ * @param perpMarketIndex Optional isolated perp market to scope health to; omit for the cross-margin account's health.
1583
+ * @returns Health, an integer in `[0, 100]`.
1320
1584
  */
1321
1585
  public getHealth(perpMarketIndex?: number): number {
1322
1586
  if (this.isCrossMarginBeingLiquidated() && !perpMarketIndex) {
@@ -1368,6 +1632,15 @@ export class User {
1368
1632
  return health;
1369
1633
  }
1370
1634
 
1635
+ /**
1636
+ * Computes a single perp position's margin-weighted liability value: worst-case
1637
+ * (or current, if `includeOpenOrders` is false) base amount, valued at the
1638
+ * oracle price (or `expiryPrice` if the market is in settlement, which also
1639
+ * zeroes the margin ratio), scaled by the applicable margin ratio for
1640
+ * `marginCategory`. Underlies `getPerpMarketLiabilityValue`,
1641
+ * `getTotalPerpPositionLiability`, and the leverage/liquidation-price math.
1642
+ * @returns Precision QUOTE_PRECISION (1e6); unweighted (raw notional, no margin ratio applied) if `marginCategory` is omitted.
1643
+ */
1371
1644
  calculateWeightedPerpPositionLiability(
1372
1645
  perpPosition: PerpPosition,
1373
1646
  marginCategory?: MarginCategory,
@@ -1461,8 +1734,15 @@ export class User {
1461
1734
  }
1462
1735
 
1463
1736
  /**
1464
- * calculates position value of a single perp market in margin system
1465
- * @returns : Precision QUOTE_PRECISION
1737
+ * Margin-weighted liability value of a single perp position. Thin wrapper
1738
+ * around `calculateWeightedPerpPositionLiability` for the position in
1739
+ * `marketIndex`; see that method for the worst-case/margin-ratio semantics.
1740
+ * @param marketIndex
1741
+ * @param marginCategory `'Initial'`/`'Maintenance'` margin ratio to apply; omit for the raw unweighted notional.
1742
+ * @param liquidationBuffer Optional buffer (MARGIN_PRECISION, 1e4) added to the margin ratio.
1743
+ * @param includeOpenOrders If true (recommended for margin checks), uses the worst-case base amount including open bids/asks.
1744
+ * @param strict Use TWAP-bounded quote pricing. Defaults to false.
1745
+ * @returns Precision QUOTE_PRECISION (1e6). Throws (via `getPerpPositionOrThrow`) if the user has no active position in `marketIndex`.
1466
1746
  */
1467
1747
  public getPerpMarketLiabilityValue(
1468
1748
  marketIndex: number,
@@ -1482,8 +1762,13 @@ export class User {
1482
1762
  }
1483
1763
 
1484
1764
  /**
1485
- * calculates sum of position value across all positions in margin system
1486
- * @returns : Precision QUOTE_PRECISION
1765
+ * Sums `calculateWeightedPerpPositionLiability` across every active perp
1766
+ * position the perp side of the margin requirement (see `getMarginRequirement`).
1767
+ * @param marginCategory `'Initial'`/`'Maintenance'` margin ratio to apply; omit for the raw unweighted notional.
1768
+ * @param liquidationBuffer Optional buffer (MARGIN_PRECISION, 1e4) added to the margin ratio.
1769
+ * @param includeOpenOrders If true, uses each position's worst-case base amount including open bids/asks.
1770
+ * @param strict Use TWAP-bounded quote pricing. Defaults to false.
1771
+ * @returns Precision QUOTE_PRECISION (1e6).
1487
1772
  */
1488
1773
  getTotalPerpPositionLiability(
1489
1774
  marginCategory?: MarginCategory,
@@ -1507,8 +1792,14 @@ export class User {
1507
1792
  }
1508
1793
 
1509
1794
  /**
1510
- * calculates position value based on oracle
1511
- * @returns : Precision QUOTE_PRECISION
1795
+ * Values a perp position's base-asset notional at a caller-supplied oracle
1796
+ * price rather than looking one up internally — useful for pricing against
1797
+ * a simulated/custom price. Returns `ZERO` (via `getPerpPositionOrEmpty`) if
1798
+ * the user has no position in `marketIndex`.
1799
+ * @param marketIndex
1800
+ * @param oraclePriceData Price to value the position at, PRICE_PRECISION (1e6). Caller-supplied so callers can pass a custom/simulated price.
1801
+ * @param includeOpenOrders If true, uses the worst-case base amount (including open bids/asks) instead of the current position size. Defaults to false.
1802
+ * @returns Precision QUOTE_PRECISION (1e6).
1512
1803
  */
1513
1804
  public getPerpPositionValue(
1514
1805
  marketIndex: number,
@@ -1528,8 +1819,13 @@ export class User {
1528
1819
  }
1529
1820
 
1530
1821
  /**
1531
- * calculates position liabiltiy value in margin system
1532
- * @returns : Precision QUOTE_PRECISION
1822
+ * Unweighted (no margin ratio applied) perp liability notional at a
1823
+ * caller-supplied oracle price. Returns `ZERO` (via `getPerpPositionOrEmpty`)
1824
+ * if the user has no position in `marketIndex`.
1825
+ * @param marketIndex
1826
+ * @param oraclePriceData Price to value the position at, PRICE_PRECISION (1e6).
1827
+ * @param includeOpenOrders If true, uses the worst-case (including open bids/asks) liability value; otherwise just the current position. Defaults to false.
1828
+ * @returns Precision QUOTE_PRECISION (1e6).
1533
1829
  */
1534
1830
  public getPerpLiabilityValue(
1535
1831
  marketIndex: number,
@@ -1555,6 +1851,7 @@ export class User {
1555
1851
  }
1556
1852
  }
1557
1853
 
1854
+ /** Returns `PositionDirection.LONG`/`SHORT` from the sign of `baseAssetAmount`, or `undefined` if the position is flat. */
1558
1855
  public getPositionSide(
1559
1856
  currentPosition: Pick<PerpPosition, 'baseAssetAmount'>
1560
1857
  ): PositionDirection | undefined {
@@ -1569,7 +1866,10 @@ export class User {
1569
1866
 
1570
1867
  /**
1571
1868
  * calculates average exit price (optionally for closing up to 100% of position)
1572
- * @returns : Precision PRICE_PRECISION
1869
+ * @param position Position to estimate the close for.
1870
+ * @param amountToClose Optional base amount (BASE_PRECISION, 1e9) to simulate closing; if omitted, closes the full position. Passing `ZERO` returns the current reserve price with zero PnL.
1871
+ * @param useAMMClose If true, values the close against the AMM's own reserves (`calculateBaseAssetValue`) instead of the oracle-referenced value (`calculateBaseAssetValueWithOracle`). Defaults to false.
1872
+ * @returns Tuple of `[exitPrice, pnl]` — exitPrice is PRICE_PRECISION (1e6), pnl is QUOTE_PRECISION (1e6).
1573
1873
  */
1574
1874
  public getPositionEstimatedExitPriceAndPnl(
1575
1875
  position: PerpPosition,
@@ -1633,7 +1933,9 @@ export class User {
1633
1933
 
1634
1934
  /**
1635
1935
  * calculates current user leverage which is (total liability size) / (net asset value)
1636
- * @returns : Precision TEN_THOUSAND
1936
+ * @param includeOpenOrders If true, sizes the perp liability using worst-case open-order exposure. Defaults to true.
1937
+ * @param perpMarketIndex Optional single isolated perp market to scope leverage to (uses that position's own isolated deposit + PnL as its asset value); omit for account-wide leverage.
1938
+ * @returns : Precision TEN_THOUSAND (1e4, i.e. `10000` = 1x leverage). `ZERO` if net asset value is zero.
1637
1939
  */
1638
1940
  public getLeverage(includeOpenOrders = true, perpMarketIndex?: number): BN {
1639
1941
  return this.calculateLeverageFromComponents(
@@ -1641,6 +1943,7 @@ export class User {
1641
1943
  );
1642
1944
  }
1643
1945
 
1946
+ /** Combines the components from `getLeverageComponents` into a single leverage ratio: `(perpLiability + spotLiability) / (spotAsset + perpPnl - spotLiability)`. Returns TEN_THOUSAND (1e4) precision; `ZERO` if net asset value is zero. */
1644
1947
  calculateLeverageFromComponents({
1645
1948
  perpLiabilityValue,
1646
1949
  perpPnl,
@@ -1663,6 +1966,18 @@ export class User {
1663
1966
  return totalLiabilityValue.mul(TEN_THOUSAND).div(netAssetValue);
1664
1967
  }
1665
1968
 
1969
+ /**
1970
+ * Gathers the four raw components (`perpLiabilityValue`, `perpPnl`,
1971
+ * `spotAssetValue`, `spotLiabilityValue`, all QUOTE_PRECISION/1e6) that
1972
+ * `calculateLeverageFromComponents` combines into a leverage ratio.
1973
+ *
1974
+ * When `perpMarketIndex` is given, scopes to a single isolated position:
1975
+ * `spotAssetValue` becomes that position's isolated quote deposit and
1976
+ * `spotLiabilityValue` is `ZERO` (isolated positions carry no spot
1977
+ * liability of their own). Otherwise sums across the whole account, and
1978
+ * folds in `getTotalIsolatedPositionDeposits` as additional spot asset
1979
+ * value when `marginCategory` is unweighted.
1980
+ */
1666
1981
  getLeverageComponents(
1667
1982
  includeOpenOrders = true,
1668
1983
  marginCategory: MarginCategory | undefined = undefined,
@@ -1756,6 +2071,13 @@ export class User {
1756
2071
  };
1757
2072
  }
1758
2073
 
2074
+ /**
2075
+ * Returns true if the user's deposit position in `spotMarketAccount` is
2076
+ * non-empty but worth less than `DUST_POSITION_SIZE` (QUOTE_PRECISION) —
2077
+ * i.e. too small to be economically worth withdrawing/settling. Only
2078
+ * evaluates deposits (returns false for borrows or an empty position).
2079
+ * @throws If the user has no spot position slot for the market (should not happen for a valid `SpotMarketAccount`).
2080
+ */
1759
2081
  isDustDepositPosition(spotMarketAccount: SpotMarketAccount): boolean {
1760
2082
  const marketIndex = spotMarketAccount.marketIndex;
1761
2083
 
@@ -1797,6 +2119,7 @@ export class User {
1797
2119
  return false;
1798
2120
  }
1799
2121
 
2122
+ /** Returns every spot market where the user holds a dust-sized deposit; see `isDustDepositPosition`. */
1800
2123
  getSpotMarketAccountsWithDustPosition() {
1801
2124
  const spotMarketAccounts = this.velocityClient.getSpotMarketAccounts();
1802
2125
 
@@ -1812,6 +2135,12 @@ export class User {
1812
2135
  return dustPositionAccounts;
1813
2136
  }
1814
2137
 
2138
+ /**
2139
+ * Sum of the user's total perp position liability (worst-case, open orders
2140
+ * included) and total spot liability value (worst-case, open orders included).
2141
+ * @param marginCategory Optional `'Initial'`/`'Maintenance'` weighting; omit for unweighted values.
2142
+ * @returns Precision QUOTE_PRECISION (1e6), non-negative.
2143
+ */
1815
2144
  getTotalLiabilityValue(marginCategory?: MarginCategory): BN {
1816
2145
  return this.getTotalPerpPositionLiability(
1817
2146
  marginCategory,
@@ -1827,6 +2156,13 @@ export class User {
1827
2156
  );
1828
2157
  }
1829
2158
 
2159
+ /**
2160
+ * Sum of the user's total spot asset value and total unrealized perp PnL
2161
+ * (with funding). When `marginCategory` is omitted (unweighted), also
2162
+ * includes `getTotalIsolatedPositionDeposits`.
2163
+ * @param marginCategory Optional `'Initial'`/`'Maintenance'` weighting; omit for unweighted values.
2164
+ * @returns Precision QUOTE_PRECISION (1e6), non-negative.
2165
+ */
1830
2166
  getTotalAssetValue(marginCategory?: MarginCategory): BN {
1831
2167
  const value = this.getSpotMarketAssetValue(
1832
2168
  undefined,
@@ -1839,6 +2175,11 @@ export class User {
1839
2175
  return value;
1840
2176
  }
1841
2177
 
2178
+ /**
2179
+ * Unweighted net USD value of the account: net spot market value, plus
2180
+ * unrealized (funding-inclusive) perp PnL, plus isolated position deposits.
2181
+ * @returns Precision QUOTE_PRECISION (1e6), can be negative.
2182
+ */
1842
2183
  getNetUsdValue(): BN {
1843
2184
  const netSpotValue = this.getNetSpotMarketValue();
1844
2185
  const unrealizedPnl = this.getUnrealizedPNL(true, undefined, undefined);
@@ -1847,9 +2188,11 @@ export class User {
1847
2188
  }
1848
2189
 
1849
2190
  /**
1850
- * Calculates the all time P&L of the user.
1851
- *
1852
- * Net withdraws + Net spot market value + Net unrealized P&L -
2191
+ * Calculates the all-time P&L of the user: current net USD value
2192
+ * (`getNetUsdValue`), plus lifetime total withdraws, minus lifetime total
2193
+ * deposits. Equivalent to "everything the account is worth now, plus
2194
+ * everything ever taken out, minus everything ever put in".
2195
+ * @returns Precision QUOTE_PRECISION (1e6), can be negative.
1853
2196
  */
1854
2197
  getTotalAllTimePnl(): BN {
1855
2198
  const netUsdValue = this.getNetUsdValue();
@@ -1864,8 +2207,8 @@ export class User {
1864
2207
  /**
1865
2208
  * calculates max allowable leverage exceeding hitting requirement category
1866
2209
  * for large sizes where imf factor activates, result is a lower bound
1867
- * @param marginCategory {Initial, Maintenance}
1868
- * @returns : Precision TEN_THOUSAND
2210
+ * @param marginCategory {Initial, Maintenance} — currently unused; the calculation always uses the max-tradeable-size ('Initial') buying power.
2211
+ * @returns : Precision TEN_THOUSAND (1e4, i.e. `10000` = 1x)
1869
2212
  */
1870
2213
  public getMaxLeverageForPerp(
1871
2214
  perpMarketIndex: number,
@@ -1906,8 +2249,8 @@ export class User {
1906
2249
  /**
1907
2250
  * calculates max allowable leverage exceeding hitting requirement category
1908
2251
  * @param spotMarketIndex
1909
- * @param direction
1910
- * @returns : Precision TEN_THOUSAND
2252
+ * @param direction Whether to simulate a long (deposit-increasing) or short (borrow-increasing) trade.
2253
+ * @returns : Precision TEN_THOUSAND (1e4, i.e. `10000` = 1x)
1911
2254
  */
1912
2255
  public getMaxLeverageForSpot(
1913
2256
  spotMarketIndex: number,
@@ -1997,7 +2340,7 @@ export class User {
1997
2340
 
1998
2341
  /**
1999
2342
  * calculates margin ratio: 1 / leverage
2000
- * @returns : Precision TEN_THOUSAND
2343
+ * @returns : Precision TEN_THOUSAND (1e4, i.e. `10000` = 100% margin ratio / 1x leverage). Returns `BN_MAX` if the account has no liabilities.
2001
2344
  */
2002
2345
  public getMarginRatio(): BN {
2003
2346
  const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } =
@@ -2015,6 +2358,10 @@ export class User {
2015
2358
  return netAssetValue.mul(TEN_THOUSAND).div(totalLiabilityValue);
2016
2359
  }
2017
2360
 
2361
+ /**
2362
+ * @deprecated Use `getLiquidationStatuses` for the full cross + per-isolated-market breakdown. This method returns only the cross-margin status (plus the same isolated map, for convenience) for backward compatibility.
2363
+ * @returns The cross-margin `AccountLiquidatableStatus`, plus `isolatedPositions` mapping each isolated perp market index to its own status.
2364
+ */
2018
2365
  public canBeLiquidated(): AccountLiquidatableStatus & {
2019
2366
  isolatedPositions: Map<number, AccountLiquidatableStatus>;
2020
2367
  } {
@@ -2044,6 +2391,14 @@ export class User {
2044
2391
  * Map keys:
2045
2392
  * - 'cross' for cross margin
2046
2393
  * - marketIndex (number) for each isolated perp position
2394
+ *
2395
+ * Each `canBeLiquidated` compares maintenance total collateral against the
2396
+ * maintenance margin requirement for that scope. If `marginCalc` is not
2397
+ * supplied, one is computed under `'Maintenance'` with the account's
2398
+ * current `getLiquidationBuffer()` applied — i.e. this defaults to the same
2399
+ * buffered check the on-chain liquidation instructions use, not a bare
2400
+ * maintenance-margin comparison.
2401
+ * @param marginCalc Optional pre-computed `MarginCalculation` to reuse (avoids recomputing margin across repeated calls).
2047
2402
  */
2048
2403
  public getLiquidationStatuses(
2049
2404
  marginCalc?: MarginCalculation
@@ -2084,6 +2439,7 @@ export class User {
2084
2439
  return result;
2085
2440
  }
2086
2441
 
2442
+ /** Returns true if cross margin or any isolated perp position is currently flagged as being liquidated or bankrupt. */
2087
2443
  public isBeingLiquidated(): boolean {
2088
2444
  return (
2089
2445
  this.isCrossMarginBeingLiquidated() ||
@@ -2091,6 +2447,7 @@ export class User {
2091
2447
  );
2092
2448
  }
2093
2449
 
2450
+ /** Returns true if the account-level `UserStatus` has `BEING_LIQUIDATED` or `BANKRUPT` set (cross margin, not per-isolated-position). */
2094
2451
  public isCrossMarginBeingLiquidated(): boolean {
2095
2452
  return (
2096
2453
  (this.getUserAccountOrThrow().status &
@@ -2105,6 +2462,7 @@ export class User {
2105
2462
  return calc.totalCollateral.lt(calc.marginRequirement);
2106
2463
  }
2107
2464
 
2465
+ /** Returns true if any active perp position has `PositionFlag.BeingLiquidated` or `PositionFlag.Bankruptcy` set. */
2108
2466
  public hasIsolatedPositionBeingLiquidated(): boolean {
2109
2467
  return this.getActivePerpPositions().some(
2110
2468
  (position) =>
@@ -2114,6 +2472,7 @@ export class User {
2114
2472
  );
2115
2473
  }
2116
2474
 
2475
+ /** Returns true if the specific perp position in `perpMarketIndex` has `PositionFlag.BeingLiquidated` or `PositionFlag.Bankruptcy` set. False (not throw) if the user has no position there. */
2117
2476
  public isIsolatedPositionBeingLiquidated(perpMarketIndex: number): boolean {
2118
2477
  const position = this.getActivePerpPositions().find(
2119
2478
  (position) => position.marketIndex === perpMarketIndex
@@ -2140,6 +2499,7 @@ export class User {
2140
2499
  return liquidatableIsolatedPositions;
2141
2500
  }
2142
2501
 
2502
+ /** Returns true if `isolatedMarginCalculation`'s collateral is below its margin requirement (no buffer). */
2143
2503
  public canIsolatedPositionMarginBeLiquidated(
2144
2504
  isolatedMarginCalculation: IsolatedMarginCalculation
2145
2505
  ): boolean {
@@ -2148,17 +2508,19 @@ export class User {
2148
2508
  );
2149
2509
  }
2150
2510
 
2511
+ /** Returns true if the account's `UserStatus` bitmask has `status` set. */
2151
2512
  public hasStatus(status: UserStatus): boolean {
2152
2513
  return (this.getUserAccountOrThrow().status & status) > 0;
2153
2514
  }
2154
2515
 
2516
+ /** Returns true if the account's `UserStatus` has `BANKRUPT` set (equity insufficient to cover liabilities; awaiting bankruptcy resolution). */
2155
2517
  public isBankrupt(): boolean {
2156
2518
  return (this.getUserAccountOrThrow().status & UserStatus.BANKRUPT) > 0;
2157
2519
  }
2158
2520
 
2159
2521
  /**
2160
2522
  * Checks if any user position cumulative funding differs from respective market cumulative funding
2161
- * @returns
2523
+ * @returns True if at least one non-flat perp position has stale `lastCumulativeFundingRate` relative to the market's current long/short cumulative funding rate.
2162
2524
  */
2163
2525
  public needsToSettleFundingPayment(): boolean {
2164
2526
  for (const userPosition of this.getUserAccountOrThrow().perpPositions) {
@@ -2186,9 +2548,16 @@ export class User {
2186
2548
  }
2187
2549
 
2188
2550
  /**
2189
- * Calculate the liquidation price of a spot position
2190
- * @param marketIndex
2191
- * @returns Precision : PRICE_PRECISION
2551
+ * Calculate the liquidation price of a spot position — the oracle price at
2552
+ * which maintenance free collateral would hit zero, extrapolating linearly
2553
+ * from the current free collateral and the position's per-unit-price
2554
+ * sensitivity (`calculateFreeCollateralDeltaForSpot`). If a perp market
2555
+ * shares the same oracle as this spot market, that perp position's
2556
+ * sensitivity is folded in too (scaled for any oracle-source unit
2557
+ * difference), since a single price move affects both simultaneously.
2558
+ * @param marketIndex Spot market to compute the liquidation price for.
2559
+ * @param positionBaseSizeChange Optional simulated change to the position size, in the spot market's own token decimals. Defaults to no change.
2560
+ * @returns Precision PRICE_PRECISION (1e6). Returns `new BN(-1)` as a sentinel when there is no position, the position (after `positionBaseSizeChange`) is flat, the price sensitivity is zero, or the computed liquidation price would be negative (position cannot be liquidated by a price move alone).
2192
2561
  */
2193
2562
  public spotLiquidationPrice(
2194
2563
  marketIndex: number,
@@ -2280,14 +2649,23 @@ export class User {
2280
2649
  }
2281
2650
 
2282
2651
  /**
2283
- * Calculate the liquidation price of a perp position, with optional parameter to calculate the liquidation price after a trade
2652
+ * Calculate the liquidation price of a perp position, with optional parameter to calculate the liquidation price after a trade.
2653
+ *
2654
+ * Like `spotLiquidationPrice`, this extrapolates linearly from current free
2655
+ * collateral (`totalCollateral - marginRequirement`, plus `offsetCollateral`)
2656
+ * and the position's price sensitivity; if a spot market shares the same
2657
+ * oracle, its sensitivity is folded in too. When `marginType === 'Isolated'`,
2658
+ * free collateral and the margin requirement are scoped to that market's
2659
+ * isolated bucket instead of the cross-margin account (and the spot-oracle
2660
+ * cross-contribution above is skipped).
2284
2661
  * @param marketIndex
2285
- * @param positionBaseSizeChange // change in position size to calculate liquidation price for : Precision 10^9
2286
- * @param estimatedEntryPrice
2287
- * @param marginCategory // allow Initial to be passed in if we are trying to calculate price for DLP de-risking
2288
- * @param includeOpenOrders
2289
- * @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)
2290
- * @returns Precision : PRICE_PRECISION
2662
+ * @param positionBaseSizeChange Change in position size to calculate the liquidation price for, standardized to the market's order step size. Precision BASE_PRECISION (1e9).
2663
+ * @param estimatedEntryPrice Entry price for `positionBaseSizeChange`, PRICE_PRECISION (1e6); only affects the result under `marginCategory: 'Maintenance'` (it adjusts free collateral for the estimated realized PnL and taker fee of entering at this price rather than at the oracle price).
2664
+ * @param marginCategory Allow `'Initial'` to be passed in if we are trying to calculate price for DLP de-risking. Defaults to `'Maintenance'` (the actual liquidation threshold).
2665
+ * @param includeOpenOrders Include open orders' worst-case exposure when sizing the position. Defaults to false.
2666
+ * @param offsetCollateral Allows calculating the liquidation price after this offset collateral (QUOTE_PRECISION, 1e6) 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). Defaults to zero.
2667
+ * @param marginType `'Isolated'` to scope the calculation to `marketIndex`'s isolated margin bucket; omit/`'Cross'` for the cross-margin account.
2668
+ * @returns Precision : PRICE_PRECISION (1e6). Returns `new BN(-1)` as a sentinel when there is no isolated margin calculation for the market (isolated mode), the price sensitivity is zero, or the computed price would be negative (position cannot be liquidated by a price move alone).
2291
2669
  */
2292
2670
  public liquidationPrice(
2293
2671
  marketIndex: number,
@@ -2452,6 +2830,16 @@ export class User {
2452
2830
  return liqPrice;
2453
2831
  }
2454
2832
 
2833
+ /**
2834
+ * Helper for `liquidationPrice`: estimates the net change to free collateral
2835
+ * from simultaneously (a) realizing PnL on `positionBaseSizeChange` entered
2836
+ * at `estimatedEntryPrice` (assuming the worst/taker fee tier) versus the
2837
+ * oracle price, and (b) the resulting change in margin requirement from the
2838
+ * new position size. Only component (a) applies under `'Maintenance'`
2839
+ * (matching `liquidationPrice`'s default); under other margin categories
2840
+ * only the margin-requirement delta is applied.
2841
+ * @returns Precision QUOTE_PRECISION (1e6); can be negative.
2842
+ */
2455
2843
  calculateEntriesEffectOnFreeCollateral(
2456
2844
  market: PerpMarketAccount,
2457
2845
  oraclePrice: BN,
@@ -2481,12 +2869,13 @@ export class User {
2481
2869
  freeCollateralChange = newPositionValue.sub(costBasis);
2482
2870
  }
2483
2871
 
2484
- // assume worst fee tier
2872
+ // assume worst fee tier; ceil-divide to match calculate_taker_fee's safe_div_ceil
2485
2873
  const takerFeeTier =
2486
2874
  this.velocityClient.getStateAccount().perpFeeStructure.feeTiers[0];
2487
- const takerFee = newPositionValue
2488
- .muln(takerFeeTier.feeNumerator)
2489
- .divn(takerFeeTier.feeDenominator);
2875
+ const takerFee = divCeil(
2876
+ newPositionValue.muln(takerFeeTier.feeNumerator),
2877
+ new BN(takerFeeTier.feeDenominator)
2878
+ );
2490
2879
  freeCollateralChange = freeCollateralChange.sub(takerFee);
2491
2880
  }
2492
2881
 
@@ -2540,6 +2929,14 @@ export class User {
2540
2929
  );
2541
2930
  }
2542
2931
 
2932
+ /**
2933
+ * Helper for `liquidationPrice`: the derivative of free collateral with
2934
+ * respect to the perp market's oracle price, for the proposed post-trade
2935
+ * position (`positionBaseSizeChange` applied to the current, or worst-case
2936
+ * if `includeOpenOrders`, base amount). Used as the linear-extrapolation
2937
+ * slope to solve for the price at which free collateral hits zero.
2938
+ * @returns Precision QUOTE_PRECISION (1e6) per unit of PRICE_PRECISION move, or `undefined` if the proposed position is flat (no defined liquidation price).
2939
+ */
2543
2940
  calculateFreeCollateralDeltaForPerp(
2544
2941
  market: PerpMarketAccount,
2545
2942
  perpPosition: PerpPosition,
@@ -2603,6 +3000,12 @@ export class User {
2603
3000
  return freeCollateralDelta;
2604
3001
  }
2605
3002
 
3003
+ /**
3004
+ * Helper for `spotLiquidationPrice`/`liquidationPrice`: the derivative of
3005
+ * free collateral with respect to the spot market's oracle price, for a
3006
+ * position of `signedTokenAmount` (positive = deposit, negative = borrow).
3007
+ * @returns Precision QUOTE_PRECISION (1e6) per unit of PRICE_PRECISION move.
3008
+ */
2606
3009
  calculateFreeCollateralDeltaForSpot(
2607
3010
  market: SpotMarketAccount,
2608
3011
  signedTokenAmount: BN,
@@ -2641,8 +3044,9 @@ export class User {
2641
3044
  /**
2642
3045
  * Calculates the estimated liquidation price for a position after closing a quote amount of the position.
2643
3046
  * @param positionMarketIndex
2644
- * @param closeQuoteAmount
2645
- * @returns : Precision PRICE_PRECISION
3047
+ * @param closeQuoteAmount Quote-denominated amount of the position to close, QUOTE_PRECISION (1e6). Converted proportionally to a base-size reduction via the position's current cost basis.
3048
+ * @param estimatedEntryPrice Forwarded to `liquidationPrice` as the entry price for the (negative, i.e. closing) size change. PRICE_PRECISION (1e6). Defaults to zero.
3049
+ * @returns : Precision PRICE_PRECISION (1e6). See `liquidationPrice` for the `-1` sentinel cases.
2646
3050
  */
2647
3051
  public liquidationPriceAfterClose(
2648
3052
  positionMarketIndex: number,
@@ -2668,6 +3072,13 @@ export class User {
2668
3072
  );
2669
3073
  }
2670
3074
 
3075
+ /**
3076
+ * Calculates the margin required to open a trade of `baseSize` in `targetMarketIndex`, scalar only — does not account for trade direction or existing positions/whether the trade is actually risk-increasing.
3077
+ * @param baseSize BASE_PRECISION (1e9).
3078
+ * @param estEntryPrice Optional entry price to value the trade at, PRICE_PRECISION (1e6); defaults to the oracle price.
3079
+ * @param perpMarketMaxMarginRatio Optional max-margin-ratio override, see `resolveMaxMarginRatio`.
3080
+ * @returns Precision QUOTE_PRECISION (1e6).
3081
+ */
2671
3082
  public getMarginUSDCRequiredForTrade(
2672
3083
  targetMarketIndex: number,
2673
3084
  baseSize: BN,
@@ -2684,6 +3095,16 @@ export class User {
2684
3095
  );
2685
3096
  }
2686
3097
 
3098
+ /**
3099
+ * Converts `getMarginUSDCRequiredForTrade`'s USDC margin requirement into
3100
+ * how much of `collateralIndex`'s token a user would need to deposit to
3101
+ * cover it, accounting for that collateral's scaled initial asset weight
3102
+ * (a lower-weighted asset requires proportionally more deposited).
3103
+ * @param baseSize BASE_PRECISION (1e9).
3104
+ * @param collateralIndex Spot market to size the deposit in.
3105
+ * @param perpMarketMaxMarginRatio Optional max-margin-ratio override, see `resolveMaxMarginRatio`.
3106
+ * @returns Token amount in `collateralIndex`'s own decimals.
3107
+ */
2687
3108
  public getCollateralDepositRequiredForTrade(
2688
3109
  targetMarketIndex: number,
2689
3110
  baseSize: BN,
@@ -2706,7 +3127,9 @@ export class User {
2706
3127
  * - oppositeSideTradeSize: the trade size for closing the opposite direction
2707
3128
  * @param targetMarketIndex
2708
3129
  * @param tradeSide
2709
- * @returns { tradeSize: BN, oppositeSideTradeSize: BN} : Precision QUOTE_PRECISION
3130
+ * @param maxMarginRatio Optional max-margin-ratio override, see `resolveMaxMarginRatio`.
3131
+ * @param positionType Whether to size for a cross or isolated-margin position (forwarded to `getPerpBuyingPower`). Defaults to `'cross'`.
3132
+ * @returns { tradeSize: BN, oppositeSideTradeSize: BN} : Precision QUOTE_PRECISION (1e6)
2710
3133
  */
2711
3134
  public getMaxTradeSizeUSDCForPerp(
2712
3135
  targetMarketIndex: number,
@@ -2847,10 +3270,10 @@ export class User {
2847
3270
  * Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
2848
3271
  *
2849
3272
  * @param targetMarketIndex
2850
- * @param direction
2851
- * @param currentQuoteAssetValue
2852
- * @param currentSpotMarketNetValue
2853
- * @returns tradeSizeAllowed : Precision QUOTE_PRECISION
3273
+ * @param direction Long (increase deposit / reduce borrow) or short (increase borrow / reduce deposit).
3274
+ * @param currentQuoteAssetValue Ignored — always recomputed internally from `getSpotMarketAssetValue(QUOTE_SPOT_MARKET_INDEX)`.
3275
+ * @param currentSpotMarketNetValue Optional pre-computed net value for `targetMarketIndex` (QUOTE_PRECISION, 1e6); if omitted, computed via `getSpotPositionValue`.
3276
+ * @returns tradeSizeAllowed : Precision QUOTE_PRECISION (1e6)
2854
3277
  */
2855
3278
  public getMaxTradeSizeUSDCForSpot(
2856
3279
  targetMarketIndex: number,
@@ -2937,8 +3360,9 @@ export class User {
2937
3360
  *
2938
3361
  * @param inMarketIndex
2939
3362
  * @param outMarketIndex
2940
- * @param calculateSwap function to similate in to out swa
2941
- * @param iterationLimit how long to run appromixation before erroring out
3363
+ * @param calculateSwap Optional function to simulate the in-to-out conversion (e.g. to model swap fees/slippage); defaults to a 1:1 oracle-price conversion.
3364
+ * @param iterationLimit How many binary-search iterations to run before erroring out. Defaults to 1000.
3365
+ * @returns `inAmount`/`outAmount` in each market's own token decimals, and the resulting `leverage` (TEN_THOUSAND, 1e4 precision) after the swap.
2942
3366
  */
2943
3367
  public getMaxSwapAmount({
2944
3368
  inMarketIndex,
@@ -3154,6 +3578,13 @@ export class User {
3154
3578
  return { inAmount: inSwap, outAmount: outSwap, leverage };
3155
3579
  }
3156
3580
 
3581
+ /**
3582
+ * Returns a cloned `SpotPosition` with `tokenAmount` (signed, positive =
3583
+ * deposit / negative = borrow) applied on top of the existing balance —
3584
+ * used to simulate the post-trade/post-swap position without mutating the
3585
+ * cached account.
3586
+ * @param tokenAmount Signed delta in `market`'s own token decimals.
3587
+ */
3157
3588
  public cloneAndUpdateSpotPosition(
3158
3589
  position: SpotPosition,
3159
3590
  tokenAmount: BN,
@@ -3204,6 +3635,7 @@ export class User {
3204
3635
  return clonedPosition;
3205
3636
  }
3206
3637
 
3638
+ /** Worst-case free-collateral contribution (under `'Initial'` margin) of a single spot position. Returns QUOTE_PRECISION (1e6). */
3207
3639
  calculateSpotPositionFreeCollateralContribution(
3208
3640
  spotPosition: SpotPosition,
3209
3641
  strictOraclePrice: StrictOraclePrice
@@ -3224,6 +3656,7 @@ export class User {
3224
3656
  return freeCollateralContribution;
3225
3657
  }
3226
3658
 
3659
+ /** Worst-case (under `'Initial'` margin) asset/liability value split of a single spot position, for use in leverage calculations. Both fields QUOTE_PRECISION (1e6), non-negative. */
3227
3660
  calculateSpotPositionLeverageContribution(
3228
3661
  spotPosition: SpotPosition,
3229
3662
  strictOraclePrice: StrictOraclePrice
@@ -3265,10 +3698,11 @@ export class User {
3265
3698
 
3266
3699
  /**
3267
3700
  * Estimates what the user leverage will be after swap
3268
- * @param inMarketIndex
3269
- * @param outMarketIndex
3270
- * @param inAmount
3271
- * @param outAmount
3701
+ * @param inMarketIndex Market being sold/paid from.
3702
+ * @param outMarketIndex Market being bought/received.
3703
+ * @param inAmount Amount removed from `inMarketIndex`, that market's own token decimals.
3704
+ * @param outAmount Amount added to `outMarketIndex`, that market's own token decimals.
3705
+ * @returns Precision TEN_THOUSAND (1e4, i.e. `10000` = 1x).
3272
3706
  */
3273
3707
  public accountLeverageAfterSwap({
3274
3708
  inMarketIndex,
@@ -3372,11 +3806,11 @@ export class User {
3372
3806
  /**
3373
3807
  * Returns the leverage ratio for the account after adding (or subtracting) the given quote size to the given position
3374
3808
  * @param targetMarketIndex
3375
- * @param: targetMarketType
3376
- * @param tradeQuoteAmount
3377
- * @param tradeSide
3378
- * @param includeOpenOrders
3379
- * @returns leverageRatio : Precision TEN_THOUSAND
3809
+ * @param targetMarketType Whether the trade is on a perp or spot market — the two use different valuation paths.
3810
+ * @param tradeQuoteAmount Quote size of the simulated trade, QUOTE_PRECISION (1e6).
3811
+ * @param tradeSide Direction of the simulated trade.
3812
+ * @param includeOpenOrders Include existing open orders' worst-case impact in both the before/after values. Defaults to true.
3813
+ * @returns leverageRatio : Precision TEN_THOUSAND (1e4, i.e. `10000` = 1x)
3380
3814
  */
3381
3815
  public accountLeverageRatioAfterTrade(
3382
3816
  targetMarketIndex: number,
@@ -3554,6 +3988,19 @@ export class User {
3554
3988
  return newLeverage;
3555
3989
  }
3556
3990
 
3991
+ /**
3992
+ * Looks up the user's fee tier from the state account's fee structure.
3993
+ *
3994
+ * For perp markets, the tier is selected by the user's rolling 30-day
3995
+ * volume (`getUser30dRollingVolumeEstimate`, QUOTE_PRECISION) against fixed
3996
+ * breakpoints — $2M, $10M, $20M, $80M, $200M — picking the lowest-index
3997
+ * tier whose breakpoint the user's volume is still under (tier 5, the
3998
+ * lowest fees, if volume meets or exceeds the top breakpoint). Spot markets
3999
+ * always use tier 0 (no volume-based discount).
4000
+ * @param marketType `MarketType.PERP` or `MarketType.SPOT`.
4001
+ * @param now Optional unix timestamp (seconds) to evaluate the rolling volume window as of; defaults to current time.
4002
+ * @returns The matching `FeeTier` (numerator/denominator fee fractions and referee-discount fractions).
4003
+ */
3557
4004
  public getUserFeeTier(marketType: MarketType, now?: BN) {
3558
4005
  const state = this.velocityClient.getStateAccount();
3559
4006
 
@@ -3590,16 +4037,36 @@ export class User {
3590
4037
  }
3591
4038
 
3592
4039
  /**
3593
- * Calculates how much perp fee will be taken for a given sized trade
3594
- * @param quoteAmount
3595
- * @returns feeForQuote : Precision QUOTE_PRECISION
4040
+ * Calculates how much perp fee will be taken for a given sized trade.
4041
+ *
4042
+ * When `marketIndex` is provided, delegates to `VelocityClient.getMarketFees`
4043
+ * for that specific market's taker-fee multiplier (which itself applies the
4044
+ * market's `feeAdjustment`, the referee discount, and — when `builderInfo` is
4045
+ * passed — the builder fee). Otherwise uses the volume-based fee tier from
4046
+ * `getUserFeeTier(MarketType.PERP)`; if the user is a referee (determined
4047
+ * from `UserStats.referrerStatus`'s `IsReferred` flag unless `isReferee` is
4048
+ * explicitly passed), the tier's `refereeFeeNumerator`/`refereeFeeDenominator`
4049
+ * proportion is subtracted from the fee as a discount, and — when `builderInfo`
4050
+ * carries a builder code — the builder fee (`quoteAmount * builderFeeTenthBps /
4051
+ * 100_000`) is added on top, mirroring the program's `builder_fee` (`math/fees.rs`).
4052
+ * @param quoteAmount Trade size, QUOTE_PRECISION (1e6).
4053
+ * @param marketIndex Optional perp market to use `VelocityClient.getMarketFees` for instead of the volume-tier fee structure.
4054
+ * @param isReferee Optional override for whether the referee discount applies; defaults to the user's actual `UserStats` referred status. Ignored on the `marketIndex` path (which reads referee status inside `getMarketFees`).
4055
+ * @param builderInfo Optional builder code; when it carries `builderIdx` + `builderFeeTenthBps`, the builder fee is added on top of the tiered fee.
4056
+ * @returns feeForQuote : Precision QUOTE_PRECISION (1e6)
3596
4057
  */
3597
- public calculateFeeForQuoteAmount(quoteAmount: BN, marketIndex?: number): BN {
4058
+ public calculatePerpTakerFee(
4059
+ quoteAmount: BN,
4060
+ marketIndex?: number,
4061
+ isReferee?: boolean,
4062
+ builderInfo?: Pick<OrderParams, 'builderIdx' | 'builderFeeTenthBps'>
4063
+ ): BN {
3598
4064
  if (marketIndex !== undefined) {
3599
4065
  const takerFeeMultiplier = this.velocityClient.getMarketFees(
3600
4066
  MarketType.PERP,
3601
4067
  marketIndex,
3602
- this
4068
+ this,
4069
+ builderInfo
3603
4070
  ).takerFee;
3604
4071
  const feeAmountNum =
3605
4072
  BigNum.from(quoteAmount, QUOTE_PRECISION_EXP).toNum() *
@@ -3607,16 +4074,53 @@ export class User {
3607
4074
  return BigNum.fromPrint(feeAmountNum.toString(), QUOTE_PRECISION_EXP).val;
3608
4075
  } else {
3609
4076
  const feeTier = this.getUserFeeTier(MarketType.PERP);
3610
- return quoteAmount
3611
- .mul(new BN(feeTier.feeNumerator))
3612
- .div(new BN(feeTier.feeDenominator));
4077
+ let fee = divCeil(
4078
+ quoteAmount.mul(new BN(feeTier.feeNumerator)),
4079
+ new BN(feeTier.feeDenominator)
4080
+ );
4081
+
4082
+ const isUserReferee =
4083
+ isReferee ??
4084
+ (this.velocityClient.getUserStatsOrThrow().getAccountOrThrow()
4085
+ .referrerStatus &
4086
+ ReferrerStatus.IsReferred) >
4087
+ 0;
4088
+
4089
+ if (isUserReferee) {
4090
+ const refereeDiscount = getProportion128(
4091
+ fee,
4092
+ new BN(feeTier.refereeFeeNumerator),
4093
+ new BN(feeTier.refereeFeeDenominator)
4094
+ );
4095
+ fee = fee.sub(refereeDiscount);
4096
+ }
4097
+
4098
+ // Builder fee (M12): charged on top of the tiered fee, on the raw quote
4099
+ // (independent of the referee discount), mirroring `builder_fee` in `math/fees.rs`.
4100
+ if (builderInfo && hasBuilderParams(builderInfo)) {
4101
+ fee = fee.add(
4102
+ calculateBuilderFee(quoteAmount, builderInfo.builderFeeTenthBps!)
4103
+ );
4104
+ }
4105
+
4106
+ return fee;
3613
4107
  }
3614
4108
  }
3615
4109
 
3616
4110
  /**
3617
4111
  * Calculates a user's max withdrawal amounts for a spot market. If reduceOnly is true,
3618
- * it will return the max withdrawal amount without opening a liability for the user
4112
+ * it will return the max withdrawal amount without opening a liability for the user.
4113
+ *
4114
+ * Combines three caps: the market-wide withdraw/borrow guard
4115
+ * (`calculateWithdrawLimit`, a rolling-window rate limit on the spot
4116
+ * market), the user's own deposit balance, and how much their free
4117
+ * collateral supports withdrawing/borrowing. If `canBypassWithdrawLimits`
4118
+ * returns `canBypass: true` (see that method), the market-wide withdraw
4119
+ * limit floor is raised to the user's full deposit amount — letting a
4120
+ * small, healthy, always-net-positive depositor withdraw in full even if
4121
+ * the market-wide guard would otherwise throttle them.
3619
4122
  * @param marketIndex
4123
+ * @param reduceOnly If true, caps the result so the withdrawal cannot open a borrow (never exceeds the user's current deposit). If false/omitted, may return an amount larger than the deposit, up to the user's max allowed new liability.
3620
4124
  * @returns withdrawalLimit : Precision is the token precision for the chosen SpotMarket
3621
4125
  */
3622
4126
  public getWithdrawalLimit(marketIndex: number, reduceOnly?: boolean): BN {
@@ -3708,6 +4212,24 @@ export class User {
3708
4212
  }
3709
4213
  }
3710
4214
 
4215
+ /**
4216
+ * Determines whether the user can bypass the spot market's rolling
4217
+ * withdraw-guard limit for `marketIndex`. `canBypass` is true only when
4218
+ * **all** of the following hold:
4219
+ * - The user currently holds a deposit (not a borrow) in the market.
4220
+ * - Their lifetime net deposits (`totalDeposits - totalWithdraws`) are
4221
+ * non-negative — they have never net-withdrawn more than they net-deposited.
4222
+ * - Their `cumulativeDeposits` for the position has never gone negative
4223
+ * (no history of having borrowed and repaid in this market).
4224
+ * - Their current deposit amount is below `maxDepositAmount`, i.e. 10% of
4225
+ * the spot market's `withdrawGuardThreshold`.
4226
+ *
4227
+ * This lets a small, well-behaved depositor withdraw their own funds in
4228
+ * full even while the market-wide withdraw guard is actively throttling
4229
+ * larger movements. Used by `getWithdrawalLimit`.
4230
+ * @param marketIndex
4231
+ * @returns `canBypass`; `netDeposits` (lifetime `totalDeposits - totalWithdraws`, QUOTE_PRECISION, 1e6); `depositAmount` and `maxDepositAmount`, both in the spot market's own token decimals.
4232
+ */
3711
4233
  public canBypassWithdrawLimits(marketIndex: number): {
3712
4234
  canBypass: boolean;
3713
4235
  netDeposits: BN;
@@ -3756,6 +4278,15 @@ export class User {
3756
4278
  };
3757
4279
  }
3758
4280
 
4281
+ if (position.cumulativeDeposits.lt(ZERO)) {
4282
+ return {
4283
+ canBypass: false,
4284
+ maxDepositAmount,
4285
+ depositAmount,
4286
+ netDeposits,
4287
+ };
4288
+ }
4289
+
3759
4290
  return {
3760
4291
  canBypass: depositAmount.lt(maxDepositAmount),
3761
4292
  maxDepositAmount,
@@ -3764,6 +4295,15 @@ export class User {
3764
4295
  };
3765
4296
  }
3766
4297
 
4298
+ /**
4299
+ * Determines whether the user can be marked idle (excluded from userMap
4300
+ * subscriptions by default, and skipped by most keeper crank passes) as of
4301
+ * `slot`. Requires: not already idle; inactive for the required window
4302
+ * since `lastActiveSlot` (1 hour / 9,000 slots if equity is under $1,000,
4303
+ * otherwise 1 week / 1,512,000 slots); not currently being liquidated; and
4304
+ * no open perp positions, borrows, spot open orders, or open orders of any kind.
4305
+ * @param slot Current slot to evaluate inactivity against.
4306
+ */
3767
4307
  public canMakeIdle(slot: BN): boolean {
3768
4308
  const userAccount = this.getUserAccountOrThrow();
3769
4309
  if (userAccount.idle) {
@@ -3819,6 +4359,20 @@ export class User {
3819
4359
  return true;
3820
4360
  }
3821
4361
 
4362
+ /**
4363
+ * Determines whether this `User` (sub)account can be deleted (checked
4364
+ * before sending a delete-user instruction, to give a friendlier error than
4365
+ * an on-chain revert). Returns `canDelete: false` with a `reason` string if
4366
+ * any of the following hold: it's a referrer's sub-account 0 (referrers
4367
+ * cannot delete their primary account); the account is bankrupt or being
4368
+ * liquidated; it has any non-empty perp/spot position or open order; or
4369
+ * (when the state account charges an initialize-user fee) the account is a
4370
+ * "fresh" account — younger than `ACCOUNT_AGE_DELETION_CUTOFF_SECONDS`,
4371
+ * measured from its earliest recorded filler/maker/taker volume timestamp —
4372
+ * that is not currently idle.
4373
+ * @param userStatsAccount Optional pre-fetched `UserStatsAccount`; defaults to `VelocityClient.getUserStatsOrThrow().getAccount()`.
4374
+ * @param now Optional unix timestamp (seconds) to evaluate account age against; defaults to current time.
4375
+ */
3822
4376
  public canBeDeleted(
3823
4377
  userStatsAccount?: UserStatsAccount,
3824
4378
  now?: BN
@@ -3890,6 +4444,17 @@ export class User {
3890
4444
  return { canDelete: true };
3891
4445
  }
3892
4446
 
4447
+ /**
4448
+ * Returns the numerically-lowest (i.e. safest) contract/asset tier across
4449
+ * the user's active positions — perp tiers from active perp positions,
4450
+ * spot tiers only from spot **borrows** (deposits are skipped, since asset
4451
+ * tier only restricts borrowing exposure). Defaults to `4` (the
4452
+ * second-riskiest tier index) when the user has no positions of that kind —
4453
+ * this is a permissive default intended for callers doing tier-safety
4454
+ * comparisons (see `perpTierIsAsSafeAs` in `math/tiers`), not a claim that
4455
+ * "no position" is itself a risky tier.
4456
+ * @returns Lower `perpTier`/`spotTier` numbers indicate a safer tier; see `math/tiers` (`getPerpMarketTierNumber`/`getSpotMarketTierNumber`) for the numbering.
4457
+ */
3893
4458
  public getSafestTiers(): { perpTier: number; spotTier: number } {
3894
4459
  let safestPerpTier = 4;
3895
4460
  let safestSpotTier = 4;
@@ -3926,6 +4491,21 @@ export class User {
3926
4491
  };
3927
4492
  }
3928
4493
 
4494
+ /**
4495
+ * Breaks down a single perp position's contribution to the margin system
4496
+ * as a `HealthComponent`: worst-case base size, its unweighted liability
4497
+ * value, the applicable margin ratio (`weight`), and the resulting
4498
+ * weighted margin requirement (`weightedValue`, which includes the
4499
+ * position's open-order margin add-on). Used to build up
4500
+ * `getHealthComponents`' `perpPositions` array (e.g. for UI breakdowns of
4501
+ * "what's consuming my margin").
4502
+ * @param marginCategory `'Initial'` or `'Maintenance'`.
4503
+ * @param perpPosition Position to evaluate.
4504
+ * @param oraclePriceData Optional oracle price override for the perp market; defaults to the live oracle price.
4505
+ * @param quoteOraclePriceData Optional oracle price override for the quote spot market; defaults to the live oracle price.
4506
+ * @param includeOpenOrders Include worst-case open-order exposure. Defaults to true.
4507
+ * @returns `size` is BASE_PRECISION (1e9); `value`/`weightedValue` are QUOTE_PRECISION (1e6); `weight` is MARGIN_PRECISION (1e4).
4508
+ */
3929
4509
  public getPerpPositionHealth({
3930
4510
  marginCategory,
3931
4511
  perpPosition,
@@ -4001,6 +4581,18 @@ export class User {
4001
4581
  };
4002
4582
  }
4003
4583
 
4584
+ /**
4585
+ * Builds a full breakdown of every component feeding into the user's
4586
+ * margin calculation, for UI/diagnostic display: `deposits` and `borrows`
4587
+ * (one `HealthComponent` per non-quote spot market with a nonzero
4588
+ * worst-case position, plus a synthetic entry for the net quote balance),
4589
+ * `perpPositions` (via `getPerpPositionHealth`, one per active perp
4590
+ * position), and `perpPnl` (each position's weighted unrealized PnL — see
4591
+ * `getUnrealizedPNL` for the `'Initial'`-margin $100 cap that also applies
4592
+ * here).
4593
+ * @param marginCategory `'Initial'` or `'Maintenance'` — determines which asset/liability weights are applied.
4594
+ * @returns `HealthComponents` with `size`/`value`/`weightedValue` in each entry using the same precisions as `getPerpPositionHealth`.
4595
+ */
4004
4596
  public getHealthComponents({
4005
4597
  marginCategory,
4006
4598
  }: {
@@ -4228,6 +4820,7 @@ export class User {
4228
4820
 
4229
4821
  /**
4230
4822
  * Get the active perp and spot positions of the user.
4823
+ * @returns Market indices only (not full position objects); see `getActivePerpPositions`/`getActiveSpotPositions` for the "active" criteria.
4231
4824
  */
4232
4825
  public getActivePositions(): {
4233
4826
  activePerpPositions: number[];
@@ -4251,6 +4844,25 @@ export class User {
4251
4844
  * Compute the full margin calculation for the user's account.
4252
4845
  * Prioritize using this function instead of calling getMarginRequirement or getTotalCollateral multiple times.
4253
4846
  * Consumers can use this to avoid duplicating work across separate calls.
4847
+ *
4848
+ * Mirrors the on-chain margin accumulation in `math/margin.rs`, splitting
4849
+ * contributions into cross-margin and per-market isolated buckets
4850
+ * (`MarginCalculation.isolatedMarginCalculations`, keyed by perp market
4851
+ * index — see `isPerpPositionIsolated`) and tracking whether the account
4852
+ * holds any isolated-tier liability (`withPerpIsolatedLiability` /
4853
+ * `withSpotIsolatedLiability`, consumed by
4854
+ * `validateAnyIsolatedTierRequirements`). A perp position's isolated
4855
+ * quote-deposit collateral only counts toward that position's own isolated
4856
+ * bucket, never the cross-margin total.
4857
+ *
4858
+ * Also enforces pool-id consistency: every spot/perp position's market must
4859
+ * match the user's `poolId`, **except** a pool-1 user is allowed to hold a
4860
+ * quote-asset deposit (not borrow) even though the quote spot market itself
4861
+ * belongs to pool 0 — throws `InvalidPoolId: ...` otherwise.
4862
+ * @param marginCategory `'Initial'` or `'Maintenance'`. Defaults to `'Initial'`.
4863
+ * @param opts.strict Apply TWAP-bounded (`StrictOraclePrice`) oracle pricing, mirroring the on-chain strict-price gating. Defaults to false.
4864
+ * @param opts.includeOpenOrders Include open orders' worst-case impact. Defaults to true.
4865
+ * @param opts.liquidationBufferMap Per-scope buffer (MARGIN_PRECISION, 1e4) to pad margin requirements with — `'cross'` for the cross-margin bucket, or a perp market index for that market's isolated bucket. See `getLiquidationBuffer`.
4254
4866
  */
4255
4867
  public getMarginCalculation(
4256
4868
  marginCategory: MarginCategory = 'Initial',
@@ -4286,15 +4898,36 @@ export class User {
4286
4898
  .setIsolatedMarginBuffers(isolatedMarginBuffers);
4287
4899
  const calc = new MarginCalculation(ctx);
4288
4900
 
4901
+ const userPoolId = this.getUserAccountOrThrow().poolId;
4902
+
4289
4903
  // SPOT POSITIONS
4290
4904
  for (const spotPosition of this.getUserAccountOrThrow().spotPositions) {
4291
4905
  if (isSpotPositionAvailable(spotPosition)) continue;
4292
4906
 
4293
4907
  const isQuote = spotPosition.marketIndex === QUOTE_SPOT_MARKET_INDEX;
4908
+ const isBorrow = isVariant(spotPosition.balanceType, 'borrow');
4294
4909
 
4295
4910
  const spotMarket = this.velocityClient.getSpotMarketAccountOrThrow(
4296
4911
  spotPosition.marketIndex
4297
4912
  );
4913
+
4914
+ // the pool-1/quote-deposit carve-out lets a pool-1 user *hold* a quote
4915
+ // deposit without matching the quote market's own pool id (no
4916
+ // InvalidPoolId throw); every other combination requires an exact pool
4917
+ // match. Note the deposit still contributes ZERO collateral in this case
4918
+ // (skipTokenValue below) — this faithfully mirrors margin.rs:319-321,
4919
+ // which sets token_value = 0 before add_cross_margin_total_collateral.
4920
+ let skipTokenValue = false;
4921
+ if (!(userPoolId === 1 && isQuote && !isBorrow)) {
4922
+ if (userPoolId !== spotMarket.poolId) {
4923
+ throw new Error(
4924
+ `InvalidPoolId: user pool id (${userPoolId}) does not match spot market pool id (${spotMarket.poolId}) for market index ${spotMarket.marketIndex}`
4925
+ );
4926
+ }
4927
+ } else {
4928
+ skipTokenValue = true;
4929
+ }
4930
+
4298
4931
  const oraclePriceData = this.getOracleDataForSpotMarket(
4299
4932
  spotPosition.marketIndex
4300
4933
  );
@@ -4317,25 +4950,25 @@ export class User {
4317
4950
  ),
4318
4951
  spotPosition.balanceType
4319
4952
  );
4953
+ // mirrors margin.rs's `market_index == 0` block: the quote market uses the
4954
+ // raw strict token value on both sides — no asset/liability weight, and the
4955
+ // cross-margin buffer is applied inside addCrossMarginRequirement (from
4956
+ // context.crossMarginBuffer), not folded into the value here
4957
+ const tokenValue = getStrictTokenValue(
4958
+ tokenAmount,
4959
+ spotMarket.decimals,
4960
+ strictOracle
4961
+ );
4320
4962
  if (isVariant(spotPosition.balanceType, 'deposit')) {
4321
4963
  // add deposit value to total collateral
4322
- const weightedTokenValue = this.getSpotAssetValue(
4323
- tokenAmount,
4324
- strictOracle,
4325
- spotMarket,
4326
- marginCategory
4964
+ calc.addCrossMarginTotalCollateral(
4965
+ skipTokenValue ? ZERO : tokenValue
4327
4966
  );
4328
- calc.addCrossMarginTotalCollateral(weightedTokenValue);
4329
4967
  } else {
4330
4968
  // borrow on quote contributes to margin requirement
4331
- const tokenValueAbs = this.getSpotLiabilityValue(
4332
- tokenAmount,
4333
- strictOracle,
4334
- spotMarket,
4335
- marginCategory,
4336
- liquidationBufferMap.get('cross') ?? new BN(0)
4337
- ).abs();
4969
+ const tokenValueAbs = tokenValue.abs();
4338
4970
  calc.addCrossMarginRequirement(tokenValueAbs, tokenValueAbs);
4971
+ calc.addSpotLiability();
4339
4972
  }
4340
4973
  continue;
4341
4974
  }
@@ -4362,6 +4995,8 @@ export class User {
4362
4995
  );
4363
4996
  }
4364
4997
 
4998
+ const isIsolatedSpotTier = isVariant(spotMarket.assetTier, 'isolated');
4999
+
4365
5000
  if (worstCaseTokenAmount.gt(ZERO)) {
4366
5001
  const baseAssetValue = this.getSpotAssetValue(
4367
5002
  worstCaseTokenAmount,
@@ -4385,6 +5020,15 @@ export class User {
4385
5020
  getSpotLiabilityValue.abs(),
4386
5021
  getSpotLiabilityValue.abs()
4387
5022
  );
5023
+ calc.addSpotLiability();
5024
+ calc.updateWithSpotIsolatedLiability(isIsolatedSpotTier);
5025
+ } else if (
5026
+ spotPosition.openOrders !== 0 ||
5027
+ !spotPosition.openBids.isZero() ||
5028
+ !spotPosition.openAsks.isZero()
5029
+ ) {
5030
+ calc.addSpotLiability();
5031
+ calc.updateWithSpotIsolatedLiability(isIsolatedSpotTier);
4388
5032
  }
4389
5033
 
4390
5034
  // orders value contributes to collateral or requirement
@@ -4401,6 +5045,13 @@ export class User {
4401
5045
  const market = this.velocityClient.getPerpMarketAccountOrThrow(
4402
5046
  marketPosition.marketIndex
4403
5047
  );
5048
+
5049
+ if (userPoolId !== market.poolId) {
5050
+ throw new Error(
5051
+ `InvalidPoolId: user pool id (${userPoolId}) does not match perp market pool id (${market.poolId}) for market index ${market.marketIndex}`
5052
+ );
5053
+ }
5054
+
4404
5055
  const quoteSpotMarket = this.velocityClient.getSpotMarketAccountOrThrow(
4405
5056
  market.quoteSpotMarketIndex
4406
5057
  );
@@ -4441,16 +5092,18 @@ export class User {
4441
5092
  marginRatio = ZERO;
4442
5093
  }
4443
5094
 
4444
- // convert liability to quote value and apply margin ratio
5095
+ // convert liability to quote value and apply margin ratio; since this is
5096
+ // a liability, use the larger of the twap and current quote price
4445
5097
  const quotePrice = strict
4446
5098
  ? BN.max(
4447
5099
  quoteOraclePriceData.price,
4448
5100
  quoteSpotMarket.historicalOracleData.lastOraclePriceTwap5Min
4449
5101
  )
4450
5102
  : quoteOraclePriceData.price;
4451
- let perpMarginRequirement = worstCaseLiabilityValue
5103
+ const worstCaseLiabilityValueQuote = worstCaseLiabilityValue
4452
5104
  .mul(quotePrice)
4453
- .div(PRICE_PRECISION)
5105
+ .div(PRICE_PRECISION);
5106
+ let perpMarginRequirement = worstCaseLiabilityValueQuote
4454
5107
  .mul(marginRatio)
4455
5108
  .div(MARGIN_PRECISION);
4456
5109
  // add open orders IM
@@ -4501,6 +5154,27 @@ export class User {
4501
5154
  }
4502
5155
  }
4503
5156
 
5157
+ if (marginCategory === 'Initial') {
5158
+ // safety guard for dangerously configured perp market
5159
+ positionUnrealizedPnl = BN.min(
5160
+ positionUnrealizedPnl,
5161
+ MAX_POSITIVE_UPNL_FOR_INITIAL_MARGIN
5162
+ );
5163
+ }
5164
+
5165
+ const hasPerpLiability =
5166
+ !marketPosition.baseAssetAmount.isZero() ||
5167
+ marketPosition.quoteAssetAmount.isNeg() ||
5168
+ marketPosition.openOrders !== 0 ||
5169
+ !marketPosition.openBids.isZero() ||
5170
+ !marketPosition.openAsks.isZero();
5171
+ if (hasPerpLiability) {
5172
+ calc.addPerpLiability();
5173
+ calc.updateWithPerpIsolatedLiability(
5174
+ isVariant(market.contractTier, 'isolated')
5175
+ );
5176
+ }
5177
+
4504
5178
  // Add perp contribution: isolated vs cross
4505
5179
  const isIsolated = this.isPerpPositionIsolated(marketPosition);
4506
5180
  if (isIsolated) {
@@ -4535,23 +5209,108 @@ export class User {
4535
5209
  market.marketIndex,
4536
5210
  depositValue,
4537
5211
  positionUnrealizedPnl,
4538
- worstCaseLiabilityValue,
5212
+ worstCaseLiabilityValueQuote,
4539
5213
  perpMarginRequirement
4540
5214
  );
4541
- calc.addPerpLiabilityValue(worstCaseLiabilityValue);
4542
5215
  } else {
4543
5216
  // cross: add to global requirement and collateral
4544
5217
  calc.addCrossMarginRequirement(
4545
5218
  perpMarginRequirement,
4546
- worstCaseLiabilityValue
5219
+ worstCaseLiabilityValueQuote
4547
5220
  );
4548
5221
  calc.addCrossMarginTotalCollateral(positionUnrealizedPnl);
4549
5222
  }
5223
+
5224
+ // mirrors margin.rs:616-617 — perp liability value accumulates for every
5225
+ // position regardless of the isolated/cross split, so it must run outside
5226
+ // the branch above (previously only the isolated branch accumulated it,
5227
+ // underreporting totalPerpLiabilityValue for cross positions)
5228
+ calc.addPerpLiabilityValue(worstCaseLiabilityValueQuote);
4550
5229
  }
4551
5230
  return calc;
4552
5231
  }
4553
5232
 
5233
+ /**
5234
+ * Returns true if `perpPosition` was opened/is held under isolated margin
5235
+ * (`PositionFlag.IsolatedPosition` set) — segregated to its own margin
5236
+ * bucket (see `getMarginCalculation`) rather than sharing cross-margin
5237
+ * collateral with the rest of the account.
5238
+ */
4554
5239
  public isPerpPositionIsolated(perpPosition: PerpPosition): boolean {
4555
5240
  return (perpPosition.positionFlag & PositionFlag.IsolatedPosition) !== 0;
4556
5241
  }
5242
+
5243
+ /**
5244
+ * Pre-flight check for `IsolatedAssetTierViolation`: mirrors
5245
+ * `validate_any_isolated_tier_requirements` in `math/margin.rs`. A user
5246
+ * holding an isolated-tier perp or spot liability may not simultaneously
5247
+ * carry other liabilities (besides a single usdc borrow, for a perp
5248
+ * isolated liability), unless they are reduce-only.
5249
+ *
5250
+ * Specifically, if `calculation.withPerpIsolatedLiability` is set (an
5251
+ * isolated-*contract-tier* perp liability exists) and the user is not
5252
+ * `UserStatus.REDUCE_ONLY`: more than one perp liability is invalid; margin
5253
+ * trading enabled is invalid; and any spot liability other than a single
5254
+ * USDC borrow is invalid. If `calculation.withSpotIsolatedLiability` is set
5255
+ * (an isolated-*asset-tier* spot liability exists) and not reduce-only: any
5256
+ * perp liability, or more than the one isolated-tier spot liability, is invalid.
5257
+ * @param calculation A `MarginCalculation` from `getMarginCalculation` (any margin category — only the isolated-liability flags and liability counts are read).
5258
+ * @returns `{ valid: true }` if the account satisfies isolated-tier requirements, else `{ valid: false, reason }` with a human-readable reason.
5259
+ */
5260
+ public validateAnyIsolatedTierRequirements(calculation: MarginCalculation): {
5261
+ valid: boolean;
5262
+ reason?: string;
5263
+ } {
5264
+ const userAccount = this.getUserAccountOrThrow();
5265
+ const isReduceOnly = this.hasStatus(UserStatus.REDUCE_ONLY);
5266
+
5267
+ if (calculation.withPerpIsolatedLiability && !isReduceOnly) {
5268
+ if (calculation.numPerpLiabilities > 1) {
5269
+ return {
5270
+ valid: false,
5271
+ reason:
5272
+ 'User attempting to increase perp liabilities above 1 with a isolated tier liability',
5273
+ };
5274
+ }
5275
+
5276
+ if (userAccount.isMarginTradingEnabled) {
5277
+ return {
5278
+ valid: false,
5279
+ reason:
5280
+ 'User attempting isolated tier liability with margin trading enabled',
5281
+ };
5282
+ }
5283
+
5284
+ if (calculation.numSpotLiabilities > 0) {
5285
+ const quoteSpotPosition = this.getSpotPosition(QUOTE_SPOT_MARKET_INDEX);
5286
+ const quoteIsBorrow =
5287
+ !!quoteSpotPosition &&
5288
+ isVariant(quoteSpotPosition.balanceType, 'borrow');
5289
+ if (!(calculation.numSpotLiabilities === 1 && quoteIsBorrow)) {
5290
+ return {
5291
+ valid: false,
5292
+ reason:
5293
+ 'User attempting to increase spot liabilities beyond usdc with a isolated tier liability',
5294
+ };
5295
+ }
5296
+ }
5297
+ }
5298
+
5299
+ if (calculation.withSpotIsolatedLiability && !isReduceOnly) {
5300
+ if (
5301
+ !(
5302
+ calculation.numPerpLiabilities === 0 &&
5303
+ calculation.numSpotLiabilities === 1
5304
+ )
5305
+ ) {
5306
+ return {
5307
+ valid: false,
5308
+ reason:
5309
+ 'User attempting to increase perp liabilities above 0 with a isolated tier liability',
5310
+ };
5311
+ }
5312
+ }
5313
+
5314
+ return { valid: true };
5315
+ }
4557
5316
  }