@velocity-exchange/sdk 0.4.0 → 0.6.1

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 (325) hide show
  1. package/README.md +3 -3
  2. package/lib/browser/adminClient.d.ts +52 -0
  3. package/lib/browser/adminClient.js +97 -0
  4. package/lib/browser/config.js +6 -7
  5. package/lib/browser/constants/numericConstants.d.ts +1 -1
  6. package/lib/browser/constants/numericConstants.js +1 -1
  7. package/lib/browser/decode/user.js +5 -1
  8. package/lib/browser/idl/velocity.d.ts +191 -15
  9. package/lib/browser/idl/velocity.json +192 -16
  10. package/lib/browser/orderSubscriber/OrderSubscriber.d.ts +1 -0
  11. package/lib/browser/orderSubscriber/OrderSubscriber.js +10 -4
  12. package/lib/browser/pyth/pythLazerSubscriber.js +37 -27
  13. package/lib/browser/types.d.ts +6 -0
  14. package/lib/browser/user.d.ts +20 -3
  15. package/lib/browser/user.js +52 -4
  16. package/lib/browser/velocityClient.d.ts +46 -10
  17. package/lib/browser/velocityClient.js +107 -35
  18. package/lib/node/adminClient.d.ts +52 -0
  19. package/lib/node/adminClient.d.ts.map +1 -1
  20. package/lib/node/adminClient.js +97 -0
  21. package/lib/node/config.d.ts.map +1 -1
  22. package/lib/node/config.js +6 -7
  23. package/lib/node/constants/numericConstants.d.ts +1 -1
  24. package/lib/node/constants/numericConstants.d.ts.map +1 -1
  25. package/lib/node/constants/numericConstants.js +1 -1
  26. package/lib/node/decode/user.d.ts.map +1 -1
  27. package/lib/node/decode/user.js +5 -1
  28. package/lib/node/idl/velocity.d.ts +191 -15
  29. package/lib/node/idl/velocity.d.ts.map +1 -1
  30. package/lib/node/idl/velocity.json +192 -16
  31. package/lib/node/orderSubscriber/OrderSubscriber.d.ts +1 -0
  32. package/lib/node/orderSubscriber/OrderSubscriber.d.ts.map +1 -1
  33. package/lib/node/orderSubscriber/OrderSubscriber.js +10 -4
  34. package/lib/node/pyth/pythLazerSubscriber.d.ts.map +1 -1
  35. package/lib/node/pyth/pythLazerSubscriber.js +37 -27
  36. package/lib/node/types.d.ts +6 -0
  37. package/lib/node/types.d.ts.map +1 -1
  38. package/lib/node/user.d.ts +20 -3
  39. package/lib/node/user.d.ts.map +1 -1
  40. package/lib/node/user.js +52 -4
  41. package/lib/node/velocityClient.d.ts +46 -10
  42. package/lib/node/velocityClient.d.ts.map +1 -1
  43. package/lib/node/velocityClient.js +107 -35
  44. package/package.json +7 -3
  45. package/.prettierignore +0 -1
  46. package/CHANGELOG.md +0 -132
  47. package/build-browser.js +0 -58
  48. package/bunfig.toml +0 -3
  49. package/esbuild-shims.js +0 -12
  50. package/scripts/deposit-isolated-positions.ts +0 -110
  51. package/scripts/find-flagged-users.ts +0 -213
  52. package/scripts/grpc-client-test-comparison.ts +0 -372
  53. package/scripts/grpc-multiuser-client-test-comparison.ts +0 -158
  54. package/scripts/postbuild.js +0 -95
  55. package/scripts/single-grpc-client-test.ts +0 -284
  56. package/scripts/withdraw-isolated-positions.ts +0 -174
  57. package/src/accounts/README_WebSocketAccountSubscriberV2.md +0 -95
  58. package/src/accounts/README_WebSocketProgramAccountSubscriberV2.md +0 -135
  59. package/src/accounts/basicUserAccountSubscriber.ts +0 -79
  60. package/src/accounts/basicUserStatsAccountSubscriber.ts +0 -87
  61. package/src/accounts/bulkAccountLoader.ts +0 -358
  62. package/src/accounts/bulkUserStatsSubscription.ts +0 -40
  63. package/src/accounts/bulkUserSubscription.ts +0 -39
  64. package/src/accounts/customizedCadenceBulkAccountLoader.ts +0 -250
  65. package/src/accounts/fetch.ts +0 -200
  66. package/src/accounts/grpcAccountSubscriber.ts +0 -225
  67. package/src/accounts/grpcInsuranceFundStakeAccountSubscriber.ts +0 -73
  68. package/src/accounts/grpcMultiAccountSubscriber.ts +0 -566
  69. package/src/accounts/grpcMultiUserAccountSubscriber.ts +0 -328
  70. package/src/accounts/grpcProgramAccountSubscriber.ts +0 -264
  71. package/src/accounts/grpcUserAccountSubscriber.ts +0 -63
  72. package/src/accounts/grpcUserStatsAccountSubscriber.ts +0 -65
  73. package/src/accounts/grpcVelocityClientAccountSubscriber.ts +0 -257
  74. package/src/accounts/grpcVelocityClientAccountSubscriberV2.ts +0 -941
  75. package/src/accounts/laserProgramAccountSubscriber.ts +0 -266
  76. package/src/accounts/oneShotUserAccountSubscriber.ts +0 -88
  77. package/src/accounts/oneShotUserStatsAccountSubscriber.ts +0 -94
  78. package/src/accounts/pollingInsuranceFundStakeAccountSubscriber.ts +0 -223
  79. package/src/accounts/pollingOracleAccountSubscriber.ts +0 -151
  80. package/src/accounts/pollingTokenAccountSubscriber.ts +0 -147
  81. package/src/accounts/pollingUserAccountSubscriber.ts +0 -198
  82. package/src/accounts/pollingUserStatsAccountSubscriber.ts +0 -180
  83. package/src/accounts/pollingVelocityClientAccountSubscriber.ts +0 -774
  84. package/src/accounts/testBulkAccountLoader.ts +0 -59
  85. package/src/accounts/types.ts +0 -428
  86. package/src/accounts/utils.ts +0 -90
  87. package/src/accounts/webSocketAccountSubscriber.ts +0 -304
  88. package/src/accounts/webSocketAccountSubscriberV2.ts +0 -536
  89. package/src/accounts/webSocketInsuranceFundStakeAccountSubscriber.ts +0 -171
  90. package/src/accounts/webSocketProgramAccountSubscriber.ts +0 -244
  91. package/src/accounts/webSocketProgramAccountSubscriberV2.ts +0 -1048
  92. package/src/accounts/webSocketProgramAccountsSubscriberV2.ts +0 -1042
  93. package/src/accounts/webSocketUserAccountSubscriber.ts +0 -139
  94. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +0 -131
  95. package/src/accounts/webSocketVelocityClientAccountSubscriber.ts +0 -865
  96. package/src/accounts/webSocketVelocityClientAccountSubscriberV2.ts +0 -897
  97. package/src/accounts/websocketProgramUserAccountSubscriber.ts +0 -127
  98. package/src/addresses/marketAddresses.ts +0 -28
  99. package/src/addresses/pda.ts +0 -620
  100. package/src/adminClient.ts +0 -8136
  101. package/src/assert/assert.ts +0 -5
  102. package/src/auctionSubscriber/auctionSubscriber.ts +0 -86
  103. package/src/auctionSubscriber/auctionSubscriberGrpc.ts +0 -99
  104. package/src/auctionSubscriber/index.ts +0 -9
  105. package/src/auctionSubscriber/types.ts +0 -30
  106. package/src/bankrun/bankrunConnection.ts +0 -630
  107. package/src/blockhashSubscriber/BlockhashSubscriber.ts +0 -160
  108. package/src/blockhashSubscriber/index.ts +0 -6
  109. package/src/blockhashSubscriber/types.ts +0 -13
  110. package/src/clock/clockSubscriber.ts +0 -146
  111. package/src/config.ts +0 -312
  112. package/src/constants/index.ts +0 -9
  113. package/src/constants/numericConstants.ts +0 -194
  114. package/src/constants/perpMarkets.ts +0 -127
  115. package/src/constants/spotMarkets.ts +0 -104
  116. package/src/constants/txConstants.ts +0 -2
  117. package/src/constituentMap/constituentMap.ts +0 -305
  118. package/src/constituentMap/pollingConstituentAccountSubscriber.ts +0 -99
  119. package/src/constituentMap/webSocketConstituentAccountSubscriber.ts +0 -121
  120. package/src/core/VelocityCore.ts +0 -606
  121. package/src/core/index.ts +0 -12
  122. package/src/core/instructions/deposit.ts +0 -64
  123. package/src/core/instructions/fill.ts +0 -51
  124. package/src/core/instructions/funding.ts +0 -33
  125. package/src/core/instructions/liquidation.ts +0 -55
  126. package/src/core/instructions/orders.ts +0 -84
  127. package/src/core/instructions/perpOrders.ts +0 -312
  128. package/src/core/instructions/settlement.ts +0 -40
  129. package/src/core/instructions/trigger.ts +0 -41
  130. package/src/core/instructions/withdraw.ts +0 -65
  131. package/src/core/remainingAccounts.ts +0 -320
  132. package/src/core/signedMsg.ts +0 -109
  133. package/src/decode/customCoder.ts +0 -148
  134. package/src/decode/user.ts +0 -401
  135. package/src/dlob/DLOB.ts +0 -2793
  136. package/src/dlob/DLOBNode.ts +0 -305
  137. package/src/dlob/DLOBSubscriber.ts +0 -269
  138. package/src/dlob/NodeList.ts +0 -244
  139. package/src/dlob/orderBookLevels.ts +0 -695
  140. package/src/dlob/types.ts +0 -37
  141. package/src/events/eventList.ts +0 -114
  142. package/src/events/eventSubscriber.ts +0 -521
  143. package/src/events/eventsServerLogProvider.ts +0 -189
  144. package/src/events/fetchLogs.ts +0 -219
  145. package/src/events/parse.ts +0 -271
  146. package/src/events/pollingLogProvider.ts +0 -113
  147. package/src/events/sort.ts +0 -51
  148. package/src/events/txEventCache.ts +0 -92
  149. package/src/events/types.ts +0 -337
  150. package/src/events/webSocketLogProvider.ts +0 -152
  151. package/src/factory/bigNum.ts +0 -709
  152. package/src/factory/oracleClient.ts +0 -73
  153. package/src/idl/pyth.json +0 -142
  154. package/src/idl/pyth.ts +0 -97
  155. package/src/idl/pyth_solana_receiver.json +0 -628
  156. package/src/idl/token_faucet.json +0 -229
  157. package/src/idl/token_faucet.ts +0 -197
  158. package/src/idl/velocity.json +0 -23974
  159. package/src/idl/velocity.ts +0 -23980
  160. package/src/index.ts +0 -150
  161. package/src/indicative-quotes/indicativeQuotesSender.ts +0 -233
  162. package/src/isomorphic/README.md +0 -19
  163. package/src/isomorphic/anchor.browser.ts +0 -44
  164. package/src/isomorphic/anchor.node.ts +0 -1
  165. package/src/isomorphic/anchor.ts +0 -1
  166. package/src/isomorphic/anchor29.browser.ts +0 -24
  167. package/src/isomorphic/anchor29.node.ts +0 -1
  168. package/src/isomorphic/anchor29.ts +0 -1
  169. package/src/isomorphic/grpc.browser.ts +0 -4
  170. package/src/isomorphic/grpc.node.ts +0 -130
  171. package/src/isomorphic/grpc.ts +0 -1
  172. package/src/jupiter/jupiterClient.ts +0 -502
  173. package/src/keypair.ts +0 -32
  174. package/src/margin/README.md +0 -138
  175. package/src/marginCalculation.ts +0 -407
  176. package/src/marinade/idl/idl.json +0 -1962
  177. package/src/marinade/index.ts +0 -73
  178. package/src/marinade/types.ts +0 -3925
  179. package/src/math/amm.ts +0 -1758
  180. package/src/math/auction.ts +0 -480
  181. package/src/math/bankruptcy.ts +0 -138
  182. package/src/math/builder.ts +0 -130
  183. package/src/math/conversion.ts +0 -45
  184. package/src/math/exchangeStatus.ts +0 -261
  185. package/src/math/funding.ts +0 -498
  186. package/src/math/insurance.ts +0 -171
  187. package/src/math/liquidation.ts +0 -433
  188. package/src/math/margin.ts +0 -327
  189. package/src/math/market.ts +0 -487
  190. package/src/math/oracles.ts +0 -477
  191. package/src/math/orders.ts +0 -500
  192. package/src/math/position.ts +0 -381
  193. package/src/math/repeg.ts +0 -223
  194. package/src/math/spotBalance.ts +0 -996
  195. package/src/math/spotMarket.ts +0 -115
  196. package/src/math/spotPosition.ts +0 -263
  197. package/src/math/state.ts +0 -71
  198. package/src/math/superStake.ts +0 -602
  199. package/src/math/tiers.ts +0 -73
  200. package/src/math/trade.ts +0 -879
  201. package/src/math/utils.ts +0 -183
  202. package/src/memcmp.ts +0 -279
  203. package/src/oracles/oracleClientCache.ts +0 -41
  204. package/src/oracles/oracleId.ts +0 -99
  205. package/src/oracles/prelaunchOracleClient.ts +0 -63
  206. package/src/oracles/pythClient.ts +0 -125
  207. package/src/oracles/pythLazerClient.ts +0 -141
  208. package/src/oracles/quoteAssetOracleClient.ts +0 -43
  209. package/src/oracles/strictOraclePrice.ts +0 -40
  210. package/src/oracles/types.ts +0 -82
  211. package/src/oracles/utils.ts +0 -45
  212. package/src/orderParams.ts +0 -117
  213. package/src/orderSubscriber/OrderSubscriber.ts +0 -378
  214. package/src/orderSubscriber/PollingSubscription.ts +0 -50
  215. package/src/orderSubscriber/WebsocketSubscription.ts +0 -137
  216. package/src/orderSubscriber/grpcSubscription.ts +0 -155
  217. package/src/orderSubscriber/index.ts +0 -7
  218. package/src/orderSubscriber/types.ts +0 -64
  219. package/src/priorityFee/averageOverSlotsStrategy.ts +0 -17
  220. package/src/priorityFee/averageStrategy.ts +0 -13
  221. package/src/priorityFee/ewmaStrategy.ts +0 -51
  222. package/src/priorityFee/heliusPriorityFeeMethod.ts +0 -68
  223. package/src/priorityFee/index.ts +0 -16
  224. package/src/priorityFee/maxOverSlotsStrategy.ts +0 -18
  225. package/src/priorityFee/maxStrategy.ts +0 -8
  226. package/src/priorityFee/priorityFeeSubscriber.ts +0 -328
  227. package/src/priorityFee/priorityFeeSubscriberMap.ts +0 -134
  228. package/src/priorityFee/solanaPriorityFeeMethod.ts +0 -46
  229. package/src/priorityFee/types.ts +0 -82
  230. package/src/priorityFee/velocityPriorityFeeMethod.ts +0 -53
  231. package/src/pyth/constants.ts +0 -9
  232. package/src/pyth/index.ts +0 -15
  233. package/src/pyth/pythLazerSubscriber.ts +0 -365
  234. package/src/pyth/types.ts +0 -4451
  235. package/src/pyth/utils.ts +0 -13
  236. package/src/slot/SlotSubscriber.ts +0 -126
  237. package/src/slot/SlothashSubscriber.ts +0 -163
  238. package/src/swap/UnifiedSwapClient.ts +0 -315
  239. package/src/swift/grpcSignedMsgUserAccountSubscriber.ts +0 -81
  240. package/src/swift/index.ts +0 -10
  241. package/src/swift/signedMsgUserAccountSubscriber.ts +0 -251
  242. package/src/swift/swiftOrderSubscriber.ts +0 -351
  243. package/src/testClient.ts +0 -42
  244. package/src/titan/titanClient.ts +0 -438
  245. package/src/token/index.ts +0 -13
  246. package/src/tokenFaucet.ts +0 -296
  247. package/src/tx/baseTxSender.ts +0 -651
  248. package/src/tx/blockhashFetcher/baseBlockhashFetcher.ts +0 -31
  249. package/src/tx/blockhashFetcher/cachedBlockhashFetcher.ts +0 -105
  250. package/src/tx/blockhashFetcher/types.ts +0 -9
  251. package/src/tx/fastSingleTxSender.ts +0 -200
  252. package/src/tx/forwardOnlyTxSender.ts +0 -193
  253. package/src/tx/priorityFeeCalculator.ts +0 -117
  254. package/src/tx/reportTransactionError.ts +0 -176
  255. package/src/tx/retryTxSender.ts +0 -177
  256. package/src/tx/txHandler.ts +0 -1009
  257. package/src/tx/txParamProcessor.ts +0 -225
  258. package/src/tx/types.ts +0 -117
  259. package/src/tx/utils.ts +0 -133
  260. package/src/tx/whileValidTxSender.ts +0 -377
  261. package/src/types.ts +0 -2575
  262. package/src/user.ts +0 -5316
  263. package/src/userConfig.ts +0 -38
  264. package/src/userMap/PollingSubscription.ts +0 -61
  265. package/src/userMap/WebsocketSubscription.ts +0 -93
  266. package/src/userMap/grpcSubscription.ts +0 -93
  267. package/src/userMap/referrerMap.ts +0 -360
  268. package/src/userMap/revenueShareEscrowMap.ts +0 -342
  269. package/src/userMap/userMap.ts +0 -784
  270. package/src/userMap/userMapConfig.ts +0 -82
  271. package/src/userMap/userStatsMap.ts +0 -393
  272. package/src/userName.ts +0 -37
  273. package/src/userStats.ts +0 -159
  274. package/src/userStatsConfig.ts +0 -35
  275. package/src/util/TransactionConfirmationManager.ts +0 -333
  276. package/src/util/chainClock.ts +0 -65
  277. package/src/util/computeUnits.ts +0 -101
  278. package/src/util/digest.ts +0 -33
  279. package/src/util/ed25519Utils.ts +0 -95
  280. package/src/util/promiseTimeout.ts +0 -23
  281. package/src/velocityClient.ts +0 -14802
  282. package/src/velocityClientConfig.ts +0 -119
  283. package/src/wallet.ts +0 -91
  284. package/tests/VelocityCore/builder_escrow.test.ts +0 -121
  285. package/tests/VelocityCore/decode.test.ts +0 -16
  286. package/tests/VelocityCore/fill_trigger.test.ts +0 -73
  287. package/tests/VelocityCore/instructions.test.ts +0 -46
  288. package/tests/VelocityCore/pdas.test.ts +0 -30
  289. package/tests/VelocityCore/perp_orders.test.ts +0 -205
  290. package/tests/VelocityCore/remainingAccounts.test.ts +0 -72
  291. package/tests/VelocityCore/settlement_liquidation.test.ts +0 -69
  292. package/tests/accounts/customizedCadenceBulkAccountLoader.test.ts +0 -211
  293. package/tests/amm/test.ts +0 -2402
  294. package/tests/auctions/test.ts +0 -81
  295. package/tests/bn/test.ts +0 -355
  296. package/tests/builder/builderFee.test.ts +0 -42
  297. package/tests/ci/verifyConstants.ts +0 -393
  298. package/tests/decode/test.ts +0 -262
  299. package/tests/decode/userAccountBufferStrings.ts +0 -102
  300. package/tests/dlob/helpers.ts +0 -748
  301. package/tests/dlob/test.ts +0 -6969
  302. package/tests/dlob/tickSizeStandardization.ts +0 -545
  303. package/tests/events/parseLogsForCuUsage.ts +0 -139
  304. package/tests/exchangeStatus/test.ts +0 -45
  305. package/tests/insurance/test.ts +0 -40
  306. package/tests/liquidation/test.ts +0 -125
  307. package/tests/oracles/mmOracleGate.test.ts +0 -379
  308. package/tests/oracles/pythPegSnap.test.ts +0 -76
  309. package/tests/sdkParity/enumParity.test.ts +0 -84
  310. package/tests/sdkParity/marginCategoryFill.test.ts +0 -143
  311. package/tests/sdkParity/memcmpOffsets.test.ts +0 -139
  312. package/tests/spot/test.ts +0 -281
  313. package/tests/tx/TransactionConfirmationManager.test.ts +0 -312
  314. package/tests/tx/cachedBlockhashFetcher.test.ts +0 -96
  315. package/tests/tx/priorityFeeCalculator.ts +0 -77
  316. package/tests/tx/priorityFeeStrategy.ts +0 -95
  317. package/tests/user/bankruptcy.ts +0 -165
  318. package/tests/user/feeAndWithdrawLimits.ts +0 -284
  319. package/tests/user/getMarginCalculation.ts +0 -586
  320. package/tests/user/helpers.ts +0 -184
  321. package/tests/user/liquidations.ts +0 -129
  322. package/tests/user/marginCalculations.test.ts +0 -321
  323. package/tests/user/test.ts +0 -833
  324. package/tsconfig.browser.json +0 -18
  325. package/tsconfig.json +0 -36
@@ -1,407 +0,0 @@
1
- import { BN } from './isomorphic/anchor';
2
- import { MARGIN_PRECISION, ZERO } from './constants/numericConstants';
3
- import { getVariant, isVariant, MarginCategory, MarketType } from './types';
4
-
5
- /**
6
- * Which margin threshold a `MarginCalculation` is computing against: `Initial` (opening/increasing
7
- * risk), `Maintenance` (liquidation eligibility), or `Fill` (order-fill-time check, the
8
- * integer-averaged midpoint of Initial and Maintenance). Re-exported from `./types` so the SDK has
9
- * a single `MarginCategory` definition.
10
- */
11
- export type { MarginCategory };
12
-
13
- /** Selects the margin-buffer behavior of a `MarginContext`: `Standard` for ordinary health checks (no buffer), or `Liquidation` to apply the cross/isolated margin buffers used to avoid liquidating a user who is only marginally underwater. */
14
- export type MarginCalculationMode =
15
- | { type: 'Standard' }
16
- | { type: 'Liquidation' };
17
-
18
- /** Identifies a market by type (spot or perp) and index, used as a key into per-market margin state (e.g. isolated margin buffers). Construct via `MarketIdentifier.spot` / `MarketIdentifier.perp`. */
19
- export class MarketIdentifier {
20
- marketType: MarketType;
21
- marketIndex: number;
22
-
23
- private constructor(marketType: MarketType, marketIndex: number) {
24
- this.marketType = marketType;
25
- this.marketIndex = marketIndex;
26
- }
27
-
28
- /** Builds a `MarketIdentifier` for a spot market index. */
29
- static spot(marketIndex: number): MarketIdentifier {
30
- return new MarketIdentifier(MarketType.SPOT, marketIndex);
31
- }
32
-
33
- /** Builds a `MarketIdentifier` for a perp market index. */
34
- static perp(marketIndex: number): MarketIdentifier {
35
- return new MarketIdentifier(MarketType.PERP, marketIndex);
36
- }
37
-
38
- /** True if `other` refers to the same market type and index. */
39
- equals(other: MarketIdentifier | undefined): boolean {
40
- return (
41
- !!other &&
42
- isVariant(this.marketType, getVariant(other.marketType)) &&
43
- this.marketIndex === other.marketIndex
44
- );
45
- }
46
- }
47
-
48
- /**
49
- * Configuration driving a `MarginCalculation` pass: which margin category to compute,
50
- * whether it's a plain health check or a liquidation-margin-freed calculation, and the
51
- * per-market buffers (in `MARGIN_PRECISION`, 1e4, fractional-of-liability-value units)
52
- * applied to cross-margin and isolated-margin requirements/collateral so a user isn't
53
- * flagged liquidatable from a hair's-width shortfall. Mirrors `MarginContext` in
54
- * `programs/velocity/src/state/margin_calculation.rs`.
55
- */
56
- export class MarginContext {
57
- marginType: MarginCategory;
58
- mode: MarginCalculationMode;
59
- strict: boolean;
60
- ignoreInvalidDepositOracles: boolean;
61
- isolatedMarginBuffers: Map<number, BN>;
62
- crossMarginBuffer: BN;
63
-
64
- private constructor(marginType: MarginCategory) {
65
- this.marginType = marginType;
66
- this.mode = { type: 'Standard' };
67
- this.strict = false;
68
- this.ignoreInvalidDepositOracles = false;
69
- this.isolatedMarginBuffers = new Map();
70
- this.crossMarginBuffer = ZERO;
71
- }
72
-
73
- /** Builds a plain `Standard`-mode context (no liquidation buffers) for the given margin category — the usual choice for health/leverage/order-placement checks. */
74
- static standard(marginType: MarginCategory): MarginContext {
75
- return new MarginContext(marginType);
76
- }
77
-
78
- /**
79
- * Builds a `Maintenance`-category, `Liquidation`-mode context with the given buffers.
80
- * Used by liquidation eligibility / margin-freed calculations so a position is only
81
- * eligible once it's underwater by more than the buffer, avoiding flip-flopping right
82
- * at the maintenance threshold.
83
- * @param crossMarginBuffer Extra maintenance-margin cushion applied to the cross-margin
84
- * book, `MARGIN_PRECISION` (1e4) fraction of liability value.
85
- * @param isolatedMarginBuffers Same buffer, per isolated-position market index.
86
- */
87
- static liquidation(
88
- crossMarginBuffer: BN,
89
- isolatedMarginBuffers: Map<number, BN>
90
- ): MarginContext {
91
- const ctx = new MarginContext('Maintenance');
92
- ctx.mode = { type: 'Liquidation' };
93
- ctx.crossMarginBuffer = crossMarginBuffer;
94
- ctx.isolatedMarginBuffers = isolatedMarginBuffers;
95
- return ctx;
96
- }
97
-
98
- /** Sets whether strict oracle pricing (worse of last/twap price) is used for collateral/liability valuation. Returns `this` for chaining. */
99
- strictMode(strict: boolean): this {
100
- this.strict = strict;
101
- return this;
102
- }
103
-
104
- /** Sets whether spot deposits with an invalid oracle are ignored (valued at zero) rather than failing the calculation. Returns `this` for chaining. */
105
- ignoreInvalidDeposits(ignore: boolean): this {
106
- this.ignoreInvalidDepositOracles = ignore;
107
- return this;
108
- }
109
-
110
- /** Sets the cross-margin maintenance buffer (`MARGIN_PRECISION`, 1e4, fraction of liability value). Returns `this` for chaining. */
111
- setCrossMarginBuffer(crossMarginBuffer: BN): this {
112
- this.crossMarginBuffer = crossMarginBuffer;
113
- return this;
114
- }
115
- /** Replaces the whole per-market isolated-margin buffer map. Returns `this` for chaining. */
116
- setIsolatedMarginBuffers(isolatedMarginBuffers: Map<number, BN>): this {
117
- this.isolatedMarginBuffers = isolatedMarginBuffers;
118
- return this;
119
- }
120
- /** Sets the isolated-margin buffer (`MARGIN_PRECISION`, 1e4, fraction of liability value) for a single perp market index. Returns `this` for chaining. */
121
- setIsolatedMarginBuffer(marketIndex: number, isolatedMarginBuffer: BN): this {
122
- this.isolatedMarginBuffers.set(marketIndex, isolatedMarginBuffer);
123
- return this;
124
- }
125
- }
126
-
127
- /**
128
- * Accumulated margin requirement and collateral for a single isolated perp position,
129
- * built up during a `MarginCalculation` pass via `MarginCalculation.addIsolatedMarginCalculation`.
130
- * All BN fields are QUOTE_PRECISION (1e6). Isolated positions have their own dedicated
131
- * collateral pool, so their margin health is tracked independently of the user's
132
- * cross-margin book.
133
- */
134
- export class IsolatedMarginCalculation {
135
- /** Margin required to maintain/open the isolated position, QUOTE_PRECISION (1e6). */
136
- marginRequirement: BN;
137
- /** Isolated collateral: position's deposit value plus unrealized/settled pnl, QUOTE_PRECISION (1e6). */
138
- totalCollateral: BN; // deposit + pnl
139
- /** Signed adjustment to `totalCollateral` from the context's isolated margin buffer (liquidation mode only), QUOTE_PRECISION (1e6). */
140
- totalCollateralBuffer: BN;
141
- /** `marginRequirement` plus the buffered liability-value addition (liquidation mode only), QUOTE_PRECISION (1e6). */
142
- marginRequirementPlusBuffer: BN;
143
-
144
- constructor() {
145
- this.marginRequirement = ZERO;
146
- this.totalCollateral = ZERO;
147
- this.totalCollateralBuffer = ZERO;
148
- this.marginRequirementPlusBuffer = ZERO;
149
- }
150
-
151
- /** `totalCollateral + totalCollateralBuffer`, QUOTE_PRECISION (1e6). */
152
- getTotalCollateralPlusBuffer(): BN {
153
- return this.totalCollateral.add(this.totalCollateralBuffer);
154
- }
155
-
156
- /** True if the isolated position's collateral covers its margin requirement (no buffer applied). */
157
- meetsMarginRequirement(): boolean {
158
- return this.totalCollateral.gte(this.marginRequirement);
159
- }
160
-
161
- /** True if the buffered collateral covers the buffered margin requirement — the check used for liquidation eligibility. */
162
- meetsMarginRequirementWithBuffer(): boolean {
163
- return this.getTotalCollateralPlusBuffer().gte(
164
- this.marginRequirementPlusBuffer
165
- );
166
- }
167
-
168
- /** Buffered margin shortfall (`marginRequirementPlusBuffer - totalCollateralPlusBuffer`, floored at zero), QUOTE_PRECISION (1e6). */
169
- marginShortage(): BN {
170
- const shortage = this.marginRequirementPlusBuffer.sub(
171
- this.getTotalCollateralPlusBuffer()
172
- );
173
- return shortage.isNeg() ? ZERO : shortage;
174
- }
175
- }
176
-
177
- /**
178
- * Accumulator built up by walking a user's spot and perp positions, mirroring
179
- * `MarginCalculation` in `programs/velocity/src/state/margin_calculation.rs`. Tracks the
180
- * cross-margin book's total collateral/margin requirement plus a separate
181
- * `IsolatedMarginCalculation` per isolated perp market, so cross and isolated health are
182
- * evaluated independently — `meetsMarginRequirement`/`meetsMarginRequirementWithBuffer`
183
- * require both the cross book and every isolated position to pass.
184
- *
185
- * `numSpotLiabilities`/`numPerpLiabilities`/`withPerpIsolatedLiability`/
186
- * `withSpotIsolatedLiability` track the on-chain "isolated contract tier" risk-isolation
187
- * rule (`validate_any_isolated_tier_requirements`): a user holding a liability in a market
188
- * whose `ContractTier` is `Isolated` may not simultaneously hold other liabilities (perp or
189
- * non-quote spot) unless in reduce-only mode. Note this `ContractTier::Isolated` market
190
- * classification is unrelated to per-position isolated margin
191
- * (`isolatedPositionScaledBalance`) — a market can be isolated-tier without any position on
192
- * it using isolated margin.
193
- */
194
- export class MarginCalculation {
195
- context: MarginContext;
196
- /** Cross-margin collateral (deposits + perp pnl), QUOTE_PRECISION (1e6). */
197
- totalCollateral: BN;
198
- /** Signed liquidation-buffer adjustment to `totalCollateral`, QUOTE_PRECISION (1e6). Zero outside `Liquidation` mode. */
199
- totalCollateralBuffer: BN;
200
- /** Cross-margin requirement accumulated so far, QUOTE_PRECISION (1e6). */
201
- marginRequirement: BN;
202
- /** `marginRequirement` plus the buffered liability-value addition (liquidation mode only), QUOTE_PRECISION (1e6). */
203
- marginRequirementPlusBuffer: BN;
204
- /** Per-isolated-perp-market margin state, keyed by perp market index. */
205
- isolatedMarginCalculations: Map<number, IsolatedMarginCalculation>;
206
- /** Sum of worst-case perp liability value across all (cross + isolated) perp positions seen so far, QUOTE_PRECISION (1e6). */
207
- totalPerpLiabilityValue: BN;
208
- /** Count of spot positions counted as liabilities (borrows) so far. */
209
- numSpotLiabilities: number;
210
- /** Count of perp positions counted as liabilities (non-flat base, negative quote, or open orders) so far. */
211
- numPerpLiabilities: number;
212
- /** True once any perp liability seen belongs to a `ContractTier::Isolated` market. */
213
- withPerpIsolatedLiability: boolean;
214
- /** True once any spot liability seen is a borrow (or has open orders) in an `AssetTier::Isolated` spot market (isolated-tier borrows are restricted to the quote asset). */
215
- withSpotIsolatedLiability: boolean;
216
-
217
- constructor(context: MarginContext) {
218
- this.context = context;
219
- this.totalCollateral = ZERO;
220
- this.totalCollateralBuffer = ZERO;
221
- this.marginRequirement = ZERO;
222
- this.marginRequirementPlusBuffer = ZERO;
223
- this.isolatedMarginCalculations = new Map();
224
- this.totalPerpLiabilityValue = ZERO;
225
- this.numSpotLiabilities = 0;
226
- this.numPerpLiabilities = 0;
227
- this.withPerpIsolatedLiability = false;
228
- this.withSpotIsolatedLiability = false;
229
- }
230
-
231
- /**
232
- * Adds a signed collateral delta (deposit value or perp pnl, QUOTE_PRECISION 1e6) to
233
- * the cross-margin book. When in `Liquidation` mode with a nonzero `crossMarginBuffer`
234
- * and the delta is negative, also extends `totalCollateralBuffer` by
235
- * `delta * crossMarginBuffer / MARGIN_PRECISION` so a negative-pnl position looks worse
236
- * under the buffered (liquidation-eligibility) check than under the plain one.
237
- * @param delta Signed collateral value to add, QUOTE_PRECISION (1e6).
238
- */
239
- addCrossMarginTotalCollateral(delta: BN): void {
240
- const crossMarginBuffer = this.context.crossMarginBuffer;
241
- this.totalCollateral = this.totalCollateral.add(delta);
242
- if (crossMarginBuffer.gt(ZERO) && delta.isNeg()) {
243
- this.totalCollateralBuffer = this.totalCollateralBuffer.add(
244
- delta.mul(crossMarginBuffer).div(MARGIN_PRECISION)
245
- );
246
- }
247
- }
248
-
249
- /**
250
- * Adds a position's margin requirement to the cross-margin book. When a nonzero
251
- * `crossMarginBuffer` is configured, also accrues `marginRequirementPlusBuffer` with an
252
- * extra `liabilityValue * crossMarginBuffer / MARGIN_PRECISION` on top, inflating the
253
- * buffered requirement used for liquidation eligibility.
254
- * @param marginRequirement Margin required for this position, QUOTE_PRECISION (1e6).
255
- * @param liabilityValue Position's (worst-case) liability value the buffer is scaled from, QUOTE_PRECISION (1e6).
256
- */
257
- addCrossMarginRequirement(marginRequirement: BN, liabilityValue: BN): void {
258
- const crossMarginBuffer = this.context.crossMarginBuffer;
259
- this.marginRequirement = this.marginRequirement.add(marginRequirement);
260
- if (crossMarginBuffer.gt(ZERO)) {
261
- this.marginRequirementPlusBuffer = this.marginRequirementPlusBuffer.add(
262
- marginRequirement.add(
263
- liabilityValue.mul(crossMarginBuffer).div(MARGIN_PRECISION)
264
- )
265
- );
266
- }
267
- }
268
-
269
- /**
270
- * Records (or overwrites) the margin state for one isolated perp position, applying that
271
- * market's isolated margin buffer (from `context.isolatedMarginBuffers`) to the
272
- * buffered requirement, and to the buffered collateral only when `pnl` is negative —
273
- * mirroring `addCrossMarginRequirement`/`addCrossMarginTotalCollateral` but scoped to a
274
- * single isolated market instead of the shared cross-margin book.
275
- * @param marketIndex Perp market index of the isolated position.
276
- * @param depositValue Isolated collateral deposited into the position, QUOTE_PRECISION (1e6).
277
- * @param pnl Position's unrealized/settled pnl, QUOTE_PRECISION (1e6, signed).
278
- * @param liabilityValue Position's (worst-case) liability value the buffer is scaled from, QUOTE_PRECISION (1e6).
279
- * @param marginRequirement Margin required to maintain/open the isolated position, QUOTE_PRECISION (1e6).
280
- */
281
- addIsolatedMarginCalculation(
282
- marketIndex: number,
283
- depositValue: BN,
284
- pnl: BN,
285
- liabilityValue: BN,
286
- marginRequirement: BN
287
- ): void {
288
- const totalCollateral = depositValue.add(pnl);
289
- const isolatedMarginBuffer =
290
- this.context.isolatedMarginBuffers.get(marketIndex) ?? ZERO;
291
-
292
- const totalCollateralBuffer =
293
- isolatedMarginBuffer.gt(ZERO) && pnl.isNeg()
294
- ? pnl.mul(isolatedMarginBuffer).div(MARGIN_PRECISION)
295
- : ZERO;
296
-
297
- const marginRequirementPlusBuffer = isolatedMarginBuffer.gt(ZERO)
298
- ? marginRequirement.add(
299
- liabilityValue.mul(isolatedMarginBuffer).div(MARGIN_PRECISION)
300
- )
301
- : marginRequirement;
302
-
303
- const iso = new IsolatedMarginCalculation();
304
- iso.marginRequirement = marginRequirement;
305
- iso.totalCollateral = totalCollateral;
306
- iso.totalCollateralBuffer = totalCollateralBuffer;
307
- iso.marginRequirementPlusBuffer = marginRequirementPlusBuffer;
308
- this.isolatedMarginCalculations.set(marketIndex, iso);
309
- }
310
-
311
- /** Adds to the running total of worst-case perp liability value across all perp positions seen. @param perpLiabilityValue QUOTE_PRECISION (1e6). */
312
- addPerpLiabilityValue(perpLiabilityValue: BN): void {
313
- this.totalPerpLiabilityValue =
314
- this.totalPerpLiabilityValue.add(perpLiabilityValue);
315
- }
316
-
317
- /** Increments the count of spot positions counted as liabilities (borrows, or zero-balance positions with open orders). Call once per qualifying spot position. */
318
- addSpotLiability(): void {
319
- this.numSpotLiabilities += 1;
320
- }
321
-
322
- /** Increments the count of perp positions counted as liabilities (non-flat base, negative quote, or open orders). Call once per qualifying perp position. */
323
- addPerpLiability(): void {
324
- this.numPerpLiabilities += 1;
325
- }
326
-
327
- /** Latches `withSpotIsolatedLiability` to `true` if `isolated` is true (sticky OR — never reset to false once set). Pass whether the spot liability just added belongs to an `AssetTier::Isolated` market. */
328
- updateWithSpotIsolatedLiability(isolated: boolean): void {
329
- this.withSpotIsolatedLiability = this.withSpotIsolatedLiability || isolated;
330
- }
331
-
332
- /** Latches `withPerpIsolatedLiability` to `true` if `isolated` is true (sticky OR — never reset to false once set). Pass whether the perp liability just added belongs to a `ContractTier::Isolated` market. */
333
- updateWithPerpIsolatedLiability(isolated: boolean): void {
334
- this.withPerpIsolatedLiability = this.withPerpIsolatedLiability || isolated;
335
- }
336
-
337
- /** Total number of liability positions (spot borrows + perp liabilities) counted so far. */
338
- getNumOfLiabilities(): number {
339
- return this.numSpotLiabilities + this.numPerpLiabilities;
340
- }
341
-
342
- /** `totalCollateral + totalCollateralBuffer` for the cross-margin book, QUOTE_PRECISION (1e6). */
343
- getCrossTotalCollateralPlusBuffer(): BN {
344
- return this.totalCollateral.add(this.totalCollateralBuffer);
345
- }
346
-
347
- /** True if the cross-margin book's collateral covers its margin requirement (no buffer applied). */
348
- meetsCrossMarginRequirement(): boolean {
349
- return this.totalCollateral.gte(this.marginRequirement);
350
- }
351
-
352
- /** True if the cross-margin book's buffered collateral covers its buffered margin requirement — the check used for cross-margin liquidation eligibility. */
353
- meetsCrossMarginRequirementWithBuffer(): boolean {
354
- return this.getCrossTotalCollateralPlusBuffer().gte(
355
- this.marginRequirementPlusBuffer
356
- );
357
- }
358
-
359
- /** True only if the cross-margin book AND every tracked isolated position independently meet their (unbuffered) margin requirement. */
360
- meetsMarginRequirement(): boolean {
361
- if (!this.meetsCrossMarginRequirement()) return false;
362
- for (const [, iso] of this.isolatedMarginCalculations) {
363
- if (!iso.meetsMarginRequirement()) return false;
364
- }
365
- return true;
366
- }
367
-
368
- /** True only if the cross-margin book AND every tracked isolated position independently meet their buffered margin requirement — the overall liquidation-eligibility check. */
369
- meetsMarginRequirementWithBuffer(): boolean {
370
- if (!this.meetsCrossMarginRequirementWithBuffer()) return false;
371
- for (const [, iso] of this.isolatedMarginCalculations) {
372
- if (!iso.meetsMarginRequirementWithBuffer()) return false;
373
- }
374
- return true;
375
- }
376
-
377
- /** Cross-margin collateral in excess of its margin requirement, floored at zero, QUOTE_PRECISION (1e6). */
378
- getCrossFreeCollateral(): BN {
379
- const free = this.totalCollateral.sub(this.marginRequirement);
380
- return free.isNeg() ? ZERO : free;
381
- }
382
-
383
- /**
384
- * Free (unbuffered) collateral for one isolated perp position, floored at zero, QUOTE_PRECISION (1e6).
385
- * @param marketIndex Perp market index of the isolated position.
386
- * @throws if no isolated margin calculation was recorded for `marketIndex` (call `addIsolatedMarginCalculation` first).
387
- */
388
- getIsolatedFreeCollateral(marketIndex: number): BN {
389
- const iso = this.isolatedMarginCalculations.get(marketIndex);
390
- if (!iso)
391
- throw new Error('InvalidMarginCalculation: missing isolated calc');
392
- const free = iso.totalCollateral.sub(iso.marginRequirement);
393
- return free.isNeg() ? ZERO : free;
394
- }
395
-
396
- /** Returns the recorded `IsolatedMarginCalculation` for `marketIndex`, or `undefined` if none was recorded (the user has no isolated position in that market). */
397
- getIsolatedMarginCalculation(
398
- marketIndex: number
399
- ): IsolatedMarginCalculation | undefined {
400
- return this.isolatedMarginCalculations.get(marketIndex);
401
- }
402
-
403
- /** True if an isolated margin calculation has been recorded for `marketIndex`. */
404
- hasIsolatedMarginCalculation(marketIndex: number): boolean {
405
- return this.isolatedMarginCalculations.has(marketIndex);
406
- }
407
- }