@velocity-exchange/sdk 0.4.0 → 0.6.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 (323) hide show
  1. package/README.md +3 -3
  2. package/lib/browser/adminClient.d.ts +35 -0
  3. package/lib/browser/adminClient.js +65 -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 +146 -3
  9. package/lib/browser/idl/velocity.json +147 -4
  10. package/lib/browser/orderSubscriber/OrderSubscriber.js +3 -0
  11. package/lib/browser/pyth/pythLazerSubscriber.js +37 -27
  12. package/lib/browser/types.d.ts +4 -0
  13. package/lib/browser/user.d.ts +15 -0
  14. package/lib/browser/user.js +37 -1
  15. package/lib/browser/velocityClient.d.ts +46 -10
  16. package/lib/browser/velocityClient.js +107 -35
  17. package/lib/node/adminClient.d.ts +35 -0
  18. package/lib/node/adminClient.d.ts.map +1 -1
  19. package/lib/node/adminClient.js +65 -0
  20. package/lib/node/config.d.ts.map +1 -1
  21. package/lib/node/config.js +6 -7
  22. package/lib/node/constants/numericConstants.d.ts +1 -1
  23. package/lib/node/constants/numericConstants.d.ts.map +1 -1
  24. package/lib/node/constants/numericConstants.js +1 -1
  25. package/lib/node/decode/user.d.ts.map +1 -1
  26. package/lib/node/decode/user.js +5 -1
  27. package/lib/node/idl/velocity.d.ts +146 -3
  28. package/lib/node/idl/velocity.d.ts.map +1 -1
  29. package/lib/node/idl/velocity.json +147 -4
  30. package/lib/node/orderSubscriber/OrderSubscriber.d.ts.map +1 -1
  31. package/lib/node/orderSubscriber/OrderSubscriber.js +3 -0
  32. package/lib/node/pyth/pythLazerSubscriber.d.ts.map +1 -1
  33. package/lib/node/pyth/pythLazerSubscriber.js +37 -27
  34. package/lib/node/types.d.ts +4 -0
  35. package/lib/node/types.d.ts.map +1 -1
  36. package/lib/node/user.d.ts +15 -0
  37. package/lib/node/user.d.ts.map +1 -1
  38. package/lib/node/user.js +37 -1
  39. package/lib/node/velocityClient.d.ts +46 -10
  40. package/lib/node/velocityClient.d.ts.map +1 -1
  41. package/lib/node/velocityClient.js +107 -35
  42. package/package.json +7 -3
  43. package/.prettierignore +0 -1
  44. package/CHANGELOG.md +0 -132
  45. package/build-browser.js +0 -58
  46. package/bunfig.toml +0 -3
  47. package/esbuild-shims.js +0 -12
  48. package/scripts/deposit-isolated-positions.ts +0 -110
  49. package/scripts/find-flagged-users.ts +0 -213
  50. package/scripts/grpc-client-test-comparison.ts +0 -372
  51. package/scripts/grpc-multiuser-client-test-comparison.ts +0 -158
  52. package/scripts/postbuild.js +0 -95
  53. package/scripts/single-grpc-client-test.ts +0 -284
  54. package/scripts/withdraw-isolated-positions.ts +0 -174
  55. package/src/accounts/README_WebSocketAccountSubscriberV2.md +0 -95
  56. package/src/accounts/README_WebSocketProgramAccountSubscriberV2.md +0 -135
  57. package/src/accounts/basicUserAccountSubscriber.ts +0 -79
  58. package/src/accounts/basicUserStatsAccountSubscriber.ts +0 -87
  59. package/src/accounts/bulkAccountLoader.ts +0 -358
  60. package/src/accounts/bulkUserStatsSubscription.ts +0 -40
  61. package/src/accounts/bulkUserSubscription.ts +0 -39
  62. package/src/accounts/customizedCadenceBulkAccountLoader.ts +0 -250
  63. package/src/accounts/fetch.ts +0 -200
  64. package/src/accounts/grpcAccountSubscriber.ts +0 -225
  65. package/src/accounts/grpcInsuranceFundStakeAccountSubscriber.ts +0 -73
  66. package/src/accounts/grpcMultiAccountSubscriber.ts +0 -566
  67. package/src/accounts/grpcMultiUserAccountSubscriber.ts +0 -328
  68. package/src/accounts/grpcProgramAccountSubscriber.ts +0 -264
  69. package/src/accounts/grpcUserAccountSubscriber.ts +0 -63
  70. package/src/accounts/grpcUserStatsAccountSubscriber.ts +0 -65
  71. package/src/accounts/grpcVelocityClientAccountSubscriber.ts +0 -257
  72. package/src/accounts/grpcVelocityClientAccountSubscriberV2.ts +0 -941
  73. package/src/accounts/laserProgramAccountSubscriber.ts +0 -266
  74. package/src/accounts/oneShotUserAccountSubscriber.ts +0 -88
  75. package/src/accounts/oneShotUserStatsAccountSubscriber.ts +0 -94
  76. package/src/accounts/pollingInsuranceFundStakeAccountSubscriber.ts +0 -223
  77. package/src/accounts/pollingOracleAccountSubscriber.ts +0 -151
  78. package/src/accounts/pollingTokenAccountSubscriber.ts +0 -147
  79. package/src/accounts/pollingUserAccountSubscriber.ts +0 -198
  80. package/src/accounts/pollingUserStatsAccountSubscriber.ts +0 -180
  81. package/src/accounts/pollingVelocityClientAccountSubscriber.ts +0 -774
  82. package/src/accounts/testBulkAccountLoader.ts +0 -59
  83. package/src/accounts/types.ts +0 -428
  84. package/src/accounts/utils.ts +0 -90
  85. package/src/accounts/webSocketAccountSubscriber.ts +0 -304
  86. package/src/accounts/webSocketAccountSubscriberV2.ts +0 -536
  87. package/src/accounts/webSocketInsuranceFundStakeAccountSubscriber.ts +0 -171
  88. package/src/accounts/webSocketProgramAccountSubscriber.ts +0 -244
  89. package/src/accounts/webSocketProgramAccountSubscriberV2.ts +0 -1048
  90. package/src/accounts/webSocketProgramAccountsSubscriberV2.ts +0 -1042
  91. package/src/accounts/webSocketUserAccountSubscriber.ts +0 -139
  92. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +0 -131
  93. package/src/accounts/webSocketVelocityClientAccountSubscriber.ts +0 -865
  94. package/src/accounts/webSocketVelocityClientAccountSubscriberV2.ts +0 -897
  95. package/src/accounts/websocketProgramUserAccountSubscriber.ts +0 -127
  96. package/src/addresses/marketAddresses.ts +0 -28
  97. package/src/addresses/pda.ts +0 -620
  98. package/src/adminClient.ts +0 -8136
  99. package/src/assert/assert.ts +0 -5
  100. package/src/auctionSubscriber/auctionSubscriber.ts +0 -86
  101. package/src/auctionSubscriber/auctionSubscriberGrpc.ts +0 -99
  102. package/src/auctionSubscriber/index.ts +0 -9
  103. package/src/auctionSubscriber/types.ts +0 -30
  104. package/src/bankrun/bankrunConnection.ts +0 -630
  105. package/src/blockhashSubscriber/BlockhashSubscriber.ts +0 -160
  106. package/src/blockhashSubscriber/index.ts +0 -6
  107. package/src/blockhashSubscriber/types.ts +0 -13
  108. package/src/clock/clockSubscriber.ts +0 -146
  109. package/src/config.ts +0 -312
  110. package/src/constants/index.ts +0 -9
  111. package/src/constants/numericConstants.ts +0 -194
  112. package/src/constants/perpMarkets.ts +0 -127
  113. package/src/constants/spotMarkets.ts +0 -104
  114. package/src/constants/txConstants.ts +0 -2
  115. package/src/constituentMap/constituentMap.ts +0 -305
  116. package/src/constituentMap/pollingConstituentAccountSubscriber.ts +0 -99
  117. package/src/constituentMap/webSocketConstituentAccountSubscriber.ts +0 -121
  118. package/src/core/VelocityCore.ts +0 -606
  119. package/src/core/index.ts +0 -12
  120. package/src/core/instructions/deposit.ts +0 -64
  121. package/src/core/instructions/fill.ts +0 -51
  122. package/src/core/instructions/funding.ts +0 -33
  123. package/src/core/instructions/liquidation.ts +0 -55
  124. package/src/core/instructions/orders.ts +0 -84
  125. package/src/core/instructions/perpOrders.ts +0 -312
  126. package/src/core/instructions/settlement.ts +0 -40
  127. package/src/core/instructions/trigger.ts +0 -41
  128. package/src/core/instructions/withdraw.ts +0 -65
  129. package/src/core/remainingAccounts.ts +0 -320
  130. package/src/core/signedMsg.ts +0 -109
  131. package/src/decode/customCoder.ts +0 -148
  132. package/src/decode/user.ts +0 -401
  133. package/src/dlob/DLOB.ts +0 -2793
  134. package/src/dlob/DLOBNode.ts +0 -305
  135. package/src/dlob/DLOBSubscriber.ts +0 -269
  136. package/src/dlob/NodeList.ts +0 -244
  137. package/src/dlob/orderBookLevels.ts +0 -695
  138. package/src/dlob/types.ts +0 -37
  139. package/src/events/eventList.ts +0 -114
  140. package/src/events/eventSubscriber.ts +0 -521
  141. package/src/events/eventsServerLogProvider.ts +0 -189
  142. package/src/events/fetchLogs.ts +0 -219
  143. package/src/events/parse.ts +0 -271
  144. package/src/events/pollingLogProvider.ts +0 -113
  145. package/src/events/sort.ts +0 -51
  146. package/src/events/txEventCache.ts +0 -92
  147. package/src/events/types.ts +0 -337
  148. package/src/events/webSocketLogProvider.ts +0 -152
  149. package/src/factory/bigNum.ts +0 -709
  150. package/src/factory/oracleClient.ts +0 -73
  151. package/src/idl/pyth.json +0 -142
  152. package/src/idl/pyth.ts +0 -97
  153. package/src/idl/pyth_solana_receiver.json +0 -628
  154. package/src/idl/token_faucet.json +0 -229
  155. package/src/idl/token_faucet.ts +0 -197
  156. package/src/idl/velocity.json +0 -23974
  157. package/src/idl/velocity.ts +0 -23980
  158. package/src/index.ts +0 -150
  159. package/src/indicative-quotes/indicativeQuotesSender.ts +0 -233
  160. package/src/isomorphic/README.md +0 -19
  161. package/src/isomorphic/anchor.browser.ts +0 -44
  162. package/src/isomorphic/anchor.node.ts +0 -1
  163. package/src/isomorphic/anchor.ts +0 -1
  164. package/src/isomorphic/anchor29.browser.ts +0 -24
  165. package/src/isomorphic/anchor29.node.ts +0 -1
  166. package/src/isomorphic/anchor29.ts +0 -1
  167. package/src/isomorphic/grpc.browser.ts +0 -4
  168. package/src/isomorphic/grpc.node.ts +0 -130
  169. package/src/isomorphic/grpc.ts +0 -1
  170. package/src/jupiter/jupiterClient.ts +0 -502
  171. package/src/keypair.ts +0 -32
  172. package/src/margin/README.md +0 -138
  173. package/src/marginCalculation.ts +0 -407
  174. package/src/marinade/idl/idl.json +0 -1962
  175. package/src/marinade/index.ts +0 -73
  176. package/src/marinade/types.ts +0 -3925
  177. package/src/math/amm.ts +0 -1758
  178. package/src/math/auction.ts +0 -480
  179. package/src/math/bankruptcy.ts +0 -138
  180. package/src/math/builder.ts +0 -130
  181. package/src/math/conversion.ts +0 -45
  182. package/src/math/exchangeStatus.ts +0 -261
  183. package/src/math/funding.ts +0 -498
  184. package/src/math/insurance.ts +0 -171
  185. package/src/math/liquidation.ts +0 -433
  186. package/src/math/margin.ts +0 -327
  187. package/src/math/market.ts +0 -487
  188. package/src/math/oracles.ts +0 -477
  189. package/src/math/orders.ts +0 -500
  190. package/src/math/position.ts +0 -381
  191. package/src/math/repeg.ts +0 -223
  192. package/src/math/spotBalance.ts +0 -996
  193. package/src/math/spotMarket.ts +0 -115
  194. package/src/math/spotPosition.ts +0 -263
  195. package/src/math/state.ts +0 -71
  196. package/src/math/superStake.ts +0 -602
  197. package/src/math/tiers.ts +0 -73
  198. package/src/math/trade.ts +0 -879
  199. package/src/math/utils.ts +0 -183
  200. package/src/memcmp.ts +0 -279
  201. package/src/oracles/oracleClientCache.ts +0 -41
  202. package/src/oracles/oracleId.ts +0 -99
  203. package/src/oracles/prelaunchOracleClient.ts +0 -63
  204. package/src/oracles/pythClient.ts +0 -125
  205. package/src/oracles/pythLazerClient.ts +0 -141
  206. package/src/oracles/quoteAssetOracleClient.ts +0 -43
  207. package/src/oracles/strictOraclePrice.ts +0 -40
  208. package/src/oracles/types.ts +0 -82
  209. package/src/oracles/utils.ts +0 -45
  210. package/src/orderParams.ts +0 -117
  211. package/src/orderSubscriber/OrderSubscriber.ts +0 -378
  212. package/src/orderSubscriber/PollingSubscription.ts +0 -50
  213. package/src/orderSubscriber/WebsocketSubscription.ts +0 -137
  214. package/src/orderSubscriber/grpcSubscription.ts +0 -155
  215. package/src/orderSubscriber/index.ts +0 -7
  216. package/src/orderSubscriber/types.ts +0 -64
  217. package/src/priorityFee/averageOverSlotsStrategy.ts +0 -17
  218. package/src/priorityFee/averageStrategy.ts +0 -13
  219. package/src/priorityFee/ewmaStrategy.ts +0 -51
  220. package/src/priorityFee/heliusPriorityFeeMethod.ts +0 -68
  221. package/src/priorityFee/index.ts +0 -16
  222. package/src/priorityFee/maxOverSlotsStrategy.ts +0 -18
  223. package/src/priorityFee/maxStrategy.ts +0 -8
  224. package/src/priorityFee/priorityFeeSubscriber.ts +0 -328
  225. package/src/priorityFee/priorityFeeSubscriberMap.ts +0 -134
  226. package/src/priorityFee/solanaPriorityFeeMethod.ts +0 -46
  227. package/src/priorityFee/types.ts +0 -82
  228. package/src/priorityFee/velocityPriorityFeeMethod.ts +0 -53
  229. package/src/pyth/constants.ts +0 -9
  230. package/src/pyth/index.ts +0 -15
  231. package/src/pyth/pythLazerSubscriber.ts +0 -365
  232. package/src/pyth/types.ts +0 -4451
  233. package/src/pyth/utils.ts +0 -13
  234. package/src/slot/SlotSubscriber.ts +0 -126
  235. package/src/slot/SlothashSubscriber.ts +0 -163
  236. package/src/swap/UnifiedSwapClient.ts +0 -315
  237. package/src/swift/grpcSignedMsgUserAccountSubscriber.ts +0 -81
  238. package/src/swift/index.ts +0 -10
  239. package/src/swift/signedMsgUserAccountSubscriber.ts +0 -251
  240. package/src/swift/swiftOrderSubscriber.ts +0 -351
  241. package/src/testClient.ts +0 -42
  242. package/src/titan/titanClient.ts +0 -438
  243. package/src/token/index.ts +0 -13
  244. package/src/tokenFaucet.ts +0 -296
  245. package/src/tx/baseTxSender.ts +0 -651
  246. package/src/tx/blockhashFetcher/baseBlockhashFetcher.ts +0 -31
  247. package/src/tx/blockhashFetcher/cachedBlockhashFetcher.ts +0 -105
  248. package/src/tx/blockhashFetcher/types.ts +0 -9
  249. package/src/tx/fastSingleTxSender.ts +0 -200
  250. package/src/tx/forwardOnlyTxSender.ts +0 -193
  251. package/src/tx/priorityFeeCalculator.ts +0 -117
  252. package/src/tx/reportTransactionError.ts +0 -176
  253. package/src/tx/retryTxSender.ts +0 -177
  254. package/src/tx/txHandler.ts +0 -1009
  255. package/src/tx/txParamProcessor.ts +0 -225
  256. package/src/tx/types.ts +0 -117
  257. package/src/tx/utils.ts +0 -133
  258. package/src/tx/whileValidTxSender.ts +0 -377
  259. package/src/types.ts +0 -2575
  260. package/src/user.ts +0 -5316
  261. package/src/userConfig.ts +0 -38
  262. package/src/userMap/PollingSubscription.ts +0 -61
  263. package/src/userMap/WebsocketSubscription.ts +0 -93
  264. package/src/userMap/grpcSubscription.ts +0 -93
  265. package/src/userMap/referrerMap.ts +0 -360
  266. package/src/userMap/revenueShareEscrowMap.ts +0 -342
  267. package/src/userMap/userMap.ts +0 -784
  268. package/src/userMap/userMapConfig.ts +0 -82
  269. package/src/userMap/userStatsMap.ts +0 -393
  270. package/src/userName.ts +0 -37
  271. package/src/userStats.ts +0 -159
  272. package/src/userStatsConfig.ts +0 -35
  273. package/src/util/TransactionConfirmationManager.ts +0 -333
  274. package/src/util/chainClock.ts +0 -65
  275. package/src/util/computeUnits.ts +0 -101
  276. package/src/util/digest.ts +0 -33
  277. package/src/util/ed25519Utils.ts +0 -95
  278. package/src/util/promiseTimeout.ts +0 -23
  279. package/src/velocityClient.ts +0 -14802
  280. package/src/velocityClientConfig.ts +0 -119
  281. package/src/wallet.ts +0 -91
  282. package/tests/VelocityCore/builder_escrow.test.ts +0 -121
  283. package/tests/VelocityCore/decode.test.ts +0 -16
  284. package/tests/VelocityCore/fill_trigger.test.ts +0 -73
  285. package/tests/VelocityCore/instructions.test.ts +0 -46
  286. package/tests/VelocityCore/pdas.test.ts +0 -30
  287. package/tests/VelocityCore/perp_orders.test.ts +0 -205
  288. package/tests/VelocityCore/remainingAccounts.test.ts +0 -72
  289. package/tests/VelocityCore/settlement_liquidation.test.ts +0 -69
  290. package/tests/accounts/customizedCadenceBulkAccountLoader.test.ts +0 -211
  291. package/tests/amm/test.ts +0 -2402
  292. package/tests/auctions/test.ts +0 -81
  293. package/tests/bn/test.ts +0 -355
  294. package/tests/builder/builderFee.test.ts +0 -42
  295. package/tests/ci/verifyConstants.ts +0 -393
  296. package/tests/decode/test.ts +0 -262
  297. package/tests/decode/userAccountBufferStrings.ts +0 -102
  298. package/tests/dlob/helpers.ts +0 -748
  299. package/tests/dlob/test.ts +0 -6969
  300. package/tests/dlob/tickSizeStandardization.ts +0 -545
  301. package/tests/events/parseLogsForCuUsage.ts +0 -139
  302. package/tests/exchangeStatus/test.ts +0 -45
  303. package/tests/insurance/test.ts +0 -40
  304. package/tests/liquidation/test.ts +0 -125
  305. package/tests/oracles/mmOracleGate.test.ts +0 -379
  306. package/tests/oracles/pythPegSnap.test.ts +0 -76
  307. package/tests/sdkParity/enumParity.test.ts +0 -84
  308. package/tests/sdkParity/marginCategoryFill.test.ts +0 -143
  309. package/tests/sdkParity/memcmpOffsets.test.ts +0 -139
  310. package/tests/spot/test.ts +0 -281
  311. package/tests/tx/TransactionConfirmationManager.test.ts +0 -312
  312. package/tests/tx/cachedBlockhashFetcher.test.ts +0 -96
  313. package/tests/tx/priorityFeeCalculator.ts +0 -77
  314. package/tests/tx/priorityFeeStrategy.ts +0 -95
  315. package/tests/user/bankruptcy.ts +0 -165
  316. package/tests/user/feeAndWithdrawLimits.ts +0 -284
  317. package/tests/user/getMarginCalculation.ts +0 -586
  318. package/tests/user/helpers.ts +0 -184
  319. package/tests/user/liquidations.ts +0 -129
  320. package/tests/user/marginCalculations.test.ts +0 -321
  321. package/tests/user/test.ts +0 -833
  322. package/tsconfig.browser.json +0 -18
  323. package/tsconfig.json +0 -36
@@ -1,602 +0,0 @@
1
- import {
2
- AddressLookupTableAccount,
3
- LAMPORTS_PER_SOL,
4
- PublicKey,
5
- TransactionInstruction,
6
- } from '@solana/web3.js';
7
- import { JupiterClient, QuoteResponse } from '../jupiter/jupiterClient';
8
- import { VelocityClient } from '../velocityClient';
9
- import { getMarinadeFinanceProgram, getMarinadeMSolPrice } from '../marinade';
10
- import { BN } from '../isomorphic/anchor';
11
- import { User } from '../user';
12
- import { DepositRecord, isVariant } from '../types';
13
- import { LAMPORTS_PRECISION, ZERO } from '../constants/numericConstants';
14
- import fetch from 'node-fetch';
15
- import { checkSameDate } from './utils';
16
-
17
- /** Response shape of SolBlaze's `bsol/stats` endpoint (bSOL conversion ratio + APY breakdown). */
18
- export type BSOL_STATS_API_RESPONSE = {
19
- success: boolean;
20
- stats?: {
21
- conversion: {
22
- bsol_to_sol: number;
23
- sol_to_bsol: number;
24
- };
25
- apy: {
26
- base: number;
27
- blze: number;
28
- total: number;
29
- lending: number;
30
- liquidity: number;
31
- };
32
- };
33
- };
34
-
35
- /** Response shape of SolBlaze's Velocity-specific lending emissions endpoint. */
36
- export type BSOL_EMISSIONS_API_RESPONSE = {
37
- success: boolean;
38
- emissions?: {
39
- lend: number;
40
- };
41
- };
42
-
43
- /**
44
- * Fetches bSOL conversion/APY stats from SolBlaze's public API.
45
- *
46
- * @return {Promise<Response>} The raw `fetch` response; caller must check `.status` and parse
47
- * JSON as `BSOL_STATS_API_RESPONSE`
48
- */
49
- export async function fetchBSolMetrics() {
50
- return await fetch('https://stake.solblaze.org/api/v1/stats');
51
- }
52
-
53
- /**
54
- * Fetches bSOL lending-emissions data specific to Velocity from SolBlaze's public API.
55
- *
56
- * @return {Promise<Response>} The raw `fetch` response; caller must check `.status` and parse
57
- * JSON as `BSOL_EMISSIONS_API_RESPONSE`
58
- */
59
- export async function fetchBSolVelocityEmissions() {
60
- return await fetch('https://stake.solblaze.org/api/v1/velocity_emissions');
61
- }
62
-
63
- /**
64
- * Dispatches to the correct "super-stake" (deposit SOL, swap to an LST, deposit the LST as
65
- * leveraged collateral) instruction builder for a given LST spot market, routing by the SDK's
66
- * hardcoded market-index constants: `2` (mSOL) uses Marinade-or-Jupiter (`findBestMSolSuperStakeIxs`),
67
- * `6` (JitoSOL) and `8` (a generic LST, e.g. bSOL) both use Jupiter-only routing.
68
- *
69
- * @param {object} params
70
- * @param {number} params.marketIndex - The LST spot market index; must be `2`, `6`, or `8`
71
- * @param {BN} params.amount - SOL amount to stake, `LAMPORTS_PRECISION` (1e9)
72
- * @param {JupiterClient} params.jupiterClient - Jupiter aggregator client for swap routing
73
- * @param {VelocityClient} params.velocityClient - Velocity client (for market accounts + instruction building)
74
- * @param {PublicKey} [params.userAccountPublicKey] - The target sub-account; defaults to the
75
- * client's active sub-account if omitted
76
- * @param {number} [params.price] - Pre-fetched mSOL/SOL price (market index 2 only); fetched from
77
- * Marinade if omitted
78
- * @param {boolean} [params.forceMarinade] - Force the direct Marinade stake path over a Jupiter
79
- * swap even if Jupiter would be cheaper (market index 2 only)
80
- * @param {boolean} [params.onlyDirectRoutes] - Restrict Jupiter routing to direct swaps only
81
- * @param {QuoteResponse} [params.jupiterQuote] - A pre-fetched Jupiter quote to reuse instead of
82
- * fetching a fresh one
83
- * @return {Promise<{ ixs: TransactionInstruction[]; lookupTables: AddressLookupTableAccount[];
84
- * method: 'jupiter' | 'marinade'; price?: number }>} The instructions to submit, any address
85
- * lookup tables they require, which routing method was chosen, and (market index 2 only) the
86
- * price used for the routing decision
87
- * @throws {Error} If `marketIndex` is not one of the supported LST markets
88
- */
89
- export async function findBestSuperStakeIxs({
90
- marketIndex,
91
- amount,
92
- jupiterClient,
93
- velocityClient,
94
- userAccountPublicKey,
95
- price,
96
- forceMarinade,
97
- onlyDirectRoutes,
98
- jupiterQuote,
99
- }: {
100
- marketIndex: number;
101
- amount: BN;
102
- jupiterClient: JupiterClient;
103
- velocityClient: VelocityClient;
104
- price?: number;
105
- userAccountPublicKey?: PublicKey;
106
- forceMarinade?: boolean;
107
- onlyDirectRoutes?: boolean;
108
- jupiterQuote?: QuoteResponse;
109
- }): Promise<{
110
- ixs: TransactionInstruction[];
111
- lookupTables: AddressLookupTableAccount[];
112
- method: 'jupiter' | 'marinade';
113
- price?: number;
114
- }> {
115
- if (marketIndex === 2) {
116
- return findBestMSolSuperStakeIxs({
117
- amount,
118
- jupiterClient,
119
- velocityClient,
120
- userAccountPublicKey,
121
- price,
122
- forceMarinade,
123
- onlyDirectRoutes,
124
- jupiterQuote,
125
- });
126
- } else if (marketIndex === 6) {
127
- return findBestJitoSolSuperStakeIxs({
128
- amount,
129
- jupiterClient,
130
- velocityClient,
131
- userAccountPublicKey,
132
- onlyDirectRoutes,
133
- jupiterQuote,
134
- });
135
- } else if (marketIndex === 8) {
136
- return findBestLstSuperStakeIxs({
137
- amount,
138
- lstMint: velocityClient.getSpotMarketAccountOrThrow(8).mint,
139
- lstMarketIndex: 8,
140
- jupiterClient,
141
- velocityClient,
142
- userAccountPublicKey,
143
- onlyDirectRoutes,
144
- jupiterQuote,
145
- });
146
- } else {
147
- throw new Error(`Unsupported superstake market index: ${marketIndex}`);
148
- }
149
- }
150
-
151
- /**
152
- * Chooses between staking SOL directly with Marinade (mint mSOL 1:1 at the protocol rate) or
153
- * swapping SOL for mSOL via Jupiter, whichever is cheaper for the user, then returns the
154
- * resulting deposit instructions. Marinade is chosen when its price is lower than (i.e. gives
155
- * more mSOL per SOL than) the best Jupiter quote, when `forceMarinade` is set, or when a Jupiter
156
- * quote couldn't be obtained.
157
- *
158
- * @param {object} params
159
- * @param {BN} params.amount - SOL amount to stake, `LAMPORTS_PRECISION` (1e9)
160
- * @param {JupiterClient} params.jupiterClient - Jupiter aggregator client
161
- * @param {VelocityClient} params.velocityClient - Velocity client
162
- * @param {number} [params.price] - Pre-fetched mSOL/SOL Marinade rate; fetched live if omitted
163
- * @param {PublicKey} [params.userAccountPublicKey] - The target sub-account
164
- * @param {boolean} [params.forceMarinade] - Force the Marinade path regardless of Jupiter pricing
165
- * @param {boolean} [params.onlyDirectRoutes] - Restrict Jupiter routing to direct swaps only
166
- * @param {QuoteResponse} [params.jupiterQuote] - A pre-fetched Jupiter quote to reuse
167
- * @return {Promise<{ ixs: TransactionInstruction[]; lookupTables: AddressLookupTableAccount[];
168
- * method: 'jupiter' | 'marinade'; price: number }>} The chosen route's instructions, required
169
- * lookup tables, the method used, and the mSOL/SOL price used for the decision
170
- */
171
- export async function findBestMSolSuperStakeIxs({
172
- amount,
173
- jupiterClient,
174
- velocityClient,
175
- userAccountPublicKey,
176
- price,
177
- forceMarinade,
178
- onlyDirectRoutes,
179
- jupiterQuote,
180
- }: {
181
- amount: BN;
182
- jupiterClient: JupiterClient;
183
- velocityClient: VelocityClient;
184
- price?: number;
185
- userAccountPublicKey?: PublicKey;
186
- forceMarinade?: boolean;
187
- onlyDirectRoutes?: boolean;
188
- jupiterQuote?: QuoteResponse;
189
- }): Promise<{
190
- ixs: TransactionInstruction[];
191
- lookupTables: AddressLookupTableAccount[];
192
- method: 'jupiter' | 'marinade';
193
- price: number;
194
- }> {
195
- if (!price) {
196
- const marinadeProgram = getMarinadeFinanceProgram(velocityClient.provider);
197
- price = await getMarinadeMSolPrice(marinadeProgram);
198
- }
199
-
200
- const solSpotMarketAccount = velocityClient.getSpotMarketAccountOrThrow(1);
201
- const mSolSpotMarketAccount = velocityClient.getSpotMarketAccountOrThrow(2);
202
-
203
- let jupiterPrice: number | undefined;
204
- let quote = jupiterQuote;
205
- if (!jupiterQuote) {
206
- try {
207
- const fetchedQuote = await jupiterClient.getQuote({
208
- inputMint: solSpotMarketAccount.mint,
209
- outputMint: mSolSpotMarketAccount.mint,
210
- amount,
211
- slippageBps: 1000,
212
- onlyDirectRoutes,
213
- });
214
-
215
- jupiterPrice = +fetchedQuote.outAmount / +fetchedQuote.inAmount;
216
-
217
- quote = fetchedQuote;
218
- } catch (e) {
219
- console.error('Error getting jupiter price', e);
220
- }
221
- }
222
-
223
- if (!jupiterPrice || price <= jupiterPrice || forceMarinade) {
224
- const ixs = await velocityClient.getStakeForMSOLIx({
225
- amount,
226
- userAccountPublicKey,
227
- });
228
- return {
229
- method: 'marinade',
230
- ixs,
231
- lookupTables: [],
232
- price: price,
233
- };
234
- } else {
235
- const { ixs, lookupTables } = await velocityClient.getJupiterSwapIxV6({
236
- inMarketIndex: 1,
237
- outMarketIndex: 2,
238
- jupiterClient,
239
- amount,
240
- userAccountPublicKey,
241
- onlyDirectRoutes,
242
- quote,
243
- });
244
- return {
245
- method: 'jupiter',
246
- ixs,
247
- lookupTables,
248
- price: jupiterPrice,
249
- };
250
- }
251
- }
252
-
253
- /**
254
- * Builds instructions to super-stake into JitoSOL (spot market index `6`) by swapping SOL for
255
- * JitoSOL via Jupiter. Thin wrapper around `findBestLstSuperStakeIxs`.
256
- *
257
- * @param {object} params
258
- * @param {BN} params.amount - SOL amount to stake, `LAMPORTS_PRECISION` (1e9)
259
- * @param {JupiterClient} params.jupiterClient - Jupiter aggregator client
260
- * @param {VelocityClient} params.velocityClient - Velocity client
261
- * @param {PublicKey} [params.userAccountPublicKey] - The target sub-account
262
- * @param {boolean} [params.onlyDirectRoutes] - Restrict Jupiter routing to direct swaps only
263
- * @param {QuoteResponse} [params.jupiterQuote] - A pre-fetched Jupiter quote to reuse
264
- * @return {Promise<{ ixs: TransactionInstruction[]; lookupTables: AddressLookupTableAccount[];
265
- * method: 'jupiter' | 'marinade'; price?: number }>} Always resolves with `method: 'jupiter'`
266
- */
267
- export async function findBestJitoSolSuperStakeIxs({
268
- amount,
269
- jupiterClient,
270
- velocityClient,
271
- userAccountPublicKey,
272
- onlyDirectRoutes,
273
- jupiterQuote,
274
- }: {
275
- amount: BN;
276
- jupiterClient: JupiterClient;
277
- velocityClient: VelocityClient;
278
- userAccountPublicKey?: PublicKey;
279
- onlyDirectRoutes?: boolean;
280
- jupiterQuote?: QuoteResponse;
281
- }): Promise<{
282
- ixs: TransactionInstruction[];
283
- lookupTables: AddressLookupTableAccount[];
284
- method: 'jupiter' | 'marinade';
285
- price?: number;
286
- }> {
287
- return await findBestLstSuperStakeIxs({
288
- amount,
289
- jupiterClient,
290
- velocityClient,
291
- userAccountPublicKey,
292
- onlyDirectRoutes,
293
- lstMint: velocityClient.getSpotMarketAccountOrThrow(6).mint,
294
- lstMarketIndex: 6,
295
- jupiterQuote,
296
- });
297
- }
298
-
299
- /**
300
- * Builds instructions to super-stake into an arbitrary LST via a Jupiter swap from SOL. Unlike
301
- * `findBestMSolSuperStakeIxs`, this does not compare against a direct-stake rate with the LST's
302
- * own protocol — it always routes through Jupiter.
303
- *
304
- * @param {object} params
305
- * @param {BN} params.amount - SOL amount to stake, `LAMPORTS_PRECISION` (1e9)
306
- * @param {PublicKey} params.lstMint - The target LST's mint (unused directly here; kept for
307
- * caller symmetry with `lstMarketIndex`)
308
- * @param {number} params.lstMarketIndex - The target LST's spot market index
309
- * @param {JupiterClient} params.jupiterClient - Jupiter aggregator client
310
- * @param {VelocityClient} params.velocityClient - Velocity client
311
- * @param {PublicKey} [params.userAccountPublicKey] - The target sub-account
312
- * @param {boolean} [params.onlyDirectRoutes] - Restrict Jupiter routing to direct swaps only
313
- * @param {QuoteResponse} [params.jupiterQuote] - A pre-fetched Jupiter quote to reuse
314
- * @return {Promise<{ ixs: TransactionInstruction[]; lookupTables: AddressLookupTableAccount[];
315
- * method: 'jupiter' | 'marinade' }>} Always resolves with `method: 'jupiter'`
316
- */
317
- export async function findBestLstSuperStakeIxs({
318
- amount,
319
- jupiterClient,
320
- velocityClient,
321
- userAccountPublicKey,
322
- onlyDirectRoutes,
323
- lstMarketIndex,
324
- jupiterQuote,
325
- }: {
326
- amount: BN;
327
- lstMint: PublicKey;
328
- lstMarketIndex: number;
329
- jupiterClient: JupiterClient;
330
- velocityClient: VelocityClient;
331
- userAccountPublicKey?: PublicKey;
332
- onlyDirectRoutes?: boolean;
333
- jupiterQuote?: QuoteResponse;
334
- }): Promise<{
335
- ixs: TransactionInstruction[];
336
- lookupTables: AddressLookupTableAccount[];
337
- method: 'jupiter' | 'marinade';
338
- }> {
339
- const { ixs, lookupTables } = await velocityClient.getJupiterSwapIxV6({
340
- inMarketIndex: 1,
341
- outMarketIndex: lstMarketIndex,
342
- jupiterClient,
343
- amount,
344
- userAccountPublicKey,
345
- onlyDirectRoutes,
346
- quote: jupiterQuote,
347
- });
348
- return {
349
- method: 'jupiter',
350
- ixs,
351
- lookupTables,
352
- // price: jupiterPrice,
353
- };
354
- }
355
-
356
- /** Response shape of Jito's `stake_pool_stats` endpoint: daily TVL, jitoSOL supply, and APY series. */
357
- export type JITO_SOL_METRICS_ENDPOINT_RESPONSE = {
358
- tvl: {
359
- // TVL in SOL, BN
360
- data: number;
361
- date: string;
362
- }[];
363
- supply: {
364
- // jitoSOL supply
365
- data: number;
366
- date: string;
367
- }[];
368
- apy: {
369
- data: number;
370
- date: string;
371
- }[];
372
- };
373
-
374
- /**
375
- * Removes hours, minutes, seconds from a date, and returns the ISO string value (with milliseconds trimmed from the output (required by Jito API))
376
- * @param inDate
377
- * @returns
378
- */
379
- const getNormalizedDateString = (inDate: Date) => {
380
- const date = new Date(inDate.getTime());
381
- date.setUTCHours(0, 0, 0, 0);
382
- return date.toISOString().slice(0, 19) + 'Z';
383
- };
384
-
385
- const get30DAgo = () => {
386
- const date = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);
387
- return date;
388
- };
389
-
390
- /**
391
- * Fetches daily jitoSOL TVL/supply/APY stats for the trailing 30 days from Jito's public API.
392
- *
393
- * @return {Promise<JITO_SOL_METRICS_ENDPOINT_RESPONSE>} The parsed JSON response
394
- */
395
- export async function fetchJitoSolMetrics() {
396
- const res = await fetch(
397
- 'https://kobe.mainnet.jito.network/api/v1/stake_pool_stats',
398
- {
399
- headers: {
400
- 'Content-Type': 'application/json',
401
- },
402
- body: JSON.stringify({
403
- bucket_type: 'Daily',
404
- range_filter: {
405
- start: getNormalizedDateString(get30DAgo()),
406
- end: getNormalizedDateString(new Date()),
407
- },
408
- sort_by: {
409
- order: 'Asc',
410
- field: 'BlockTime',
411
- },
412
- }),
413
- method: 'POST',
414
- }
415
- );
416
-
417
- const data: JITO_SOL_METRICS_ENDPOINT_RESPONSE = await res.json();
418
-
419
- return data;
420
- }
421
-
422
- const getJitoSolHistoricalPriceMap = async (timestamps: number[]) => {
423
- try {
424
- const data = await fetchJitoSolMetrics();
425
- const jitoSolHistoricalPriceMap = new Map<number, number>();
426
- const jitoSolHistoricalPriceInSol = [];
427
-
428
- for (let i = 0; i < data.supply.length; i++) {
429
- const priceInSol = data.tvl[i].data / 10 ** 9 / data.supply[i].data;
430
- jitoSolHistoricalPriceInSol.push({
431
- price: priceInSol,
432
- ts: data.tvl[i].date,
433
- });
434
- }
435
-
436
- for (const timestamp of timestamps) {
437
- const date = new Date(timestamp * 1000);
438
- const dateString = date.toISOString();
439
-
440
- const price = jitoSolHistoricalPriceInSol.find((p) =>
441
- checkSameDate(p.ts, dateString)
442
- );
443
-
444
- if (price) {
445
- jitoSolHistoricalPriceMap.set(timestamp, price.price);
446
- }
447
- }
448
-
449
- return jitoSolHistoricalPriceMap;
450
- } catch (err) {
451
- console.error(err);
452
- return undefined;
453
- }
454
- };
455
-
456
- /**
457
- * Estimates net SOL earned (or lost) from super-staking a given LST market over the user's full
458
- * deposit history, by converting every historical SOL and LST deposit/withdrawal record to a SOL
459
- * value at the LST/SOL ratio effective at that record's timestamp, then adding back the current
460
- * SOL-value of the user's present SOL and LST balances. Requires third-party price history APIs
461
- * per LST (Marinade for mSOL, Jito's stake pool stats for JitoSOL, SolBlaze's current-only rate
462
- * for bSOL — bSOL therefore uses one flat ratio for all historical records, not a true history).
463
- *
464
- * @param {object} params
465
- * @param {number} params.marketIndex - The LST spot market index (`2` mSOL, `6` JitoSOL, `8` bSOL)
466
- * @param {User} params.user - The user account to read current SOL/LST balances from
467
- * @param {DepositRecord[]} params.depositRecords - The user's historical deposit/withdraw records
468
- * across the SOL market (index `1`) and the LST market
469
- * @return {Promise<BN>} Estimated net SOL earned, `LAMPORTS_PRECISION` (1e9); can be negative
470
- * @throws {Error} If an LST/SOL ratio can't be resolved for a record's timestamp (or for "now")
471
- */
472
- export async function calculateSolEarned({
473
- marketIndex,
474
- user,
475
- depositRecords,
476
- }: {
477
- marketIndex: number;
478
- user: User;
479
- depositRecords: DepositRecord[];
480
- }): Promise<BN> {
481
- const now = Date.now() / 1000;
482
- const timestamps: number[] = [
483
- now,
484
- ...depositRecords
485
- .filter((r) => r.marketIndex === marketIndex)
486
- .map((r) => r.ts.toNumber()),
487
- ];
488
-
489
- let lstRatios = new Map<number, number>();
490
-
491
- const getMsolPrice = async (timestamp: number) => {
492
- const date = new Date(timestamp * 1000); // Convert Unix timestamp to milliseconds
493
- const swaggerApiDateTime = date.toISOString(); // Format date as swagger API date-time
494
- const url = `https://api.marinade.finance/msol/price_sol?time=${swaggerApiDateTime}`;
495
- const response = await fetch(url);
496
- if (response.status === 200) {
497
- const data = await response.json();
498
- lstRatios.set(timestamp, data);
499
- }
500
- };
501
-
502
- const getBSolPrice = async (timestamps: number[]) => {
503
- // Currently there's only one bSOL price, no timestamped data
504
- // So just use the same price for every timestamp for now
505
- const response = await fetchBSolMetrics();
506
- if (response.status === 200) {
507
- const data = (await response.json()) as BSOL_STATS_API_RESPONSE;
508
- const bSolRatio = data?.stats?.conversion?.bsol_to_sol;
509
- if (bSolRatio) {
510
- timestamps.forEach((timestamp) => lstRatios.set(timestamp, bSolRatio));
511
- }
512
- }
513
- };
514
-
515
- // This block kind of assumes the record are all from the same market
516
- // Otherwise the following code that checks the record.marketIndex would break
517
- if (marketIndex === 2) {
518
- await Promise.all(timestamps.map(getMsolPrice));
519
- } else if (marketIndex === 6) {
520
- const jitoSolRatios = await getJitoSolHistoricalPriceMap(timestamps);
521
- if (jitoSolRatios) {
522
- lstRatios = jitoSolRatios;
523
- }
524
- } else if (marketIndex === 8) {
525
- await getBSolPrice(timestamps);
526
- }
527
-
528
- let solEarned = ZERO;
529
- for (const record of depositRecords) {
530
- if (record.marketIndex === 1) {
531
- if (isVariant(record.direction, 'deposit')) {
532
- solEarned = solEarned.sub(record.amount);
533
- } else {
534
- solEarned = solEarned.add(record.amount);
535
- }
536
- } else if (
537
- record.marketIndex === 2 ||
538
- record.marketIndex === 6 ||
539
- record.marketIndex === 8
540
- ) {
541
- const lstRatio = lstRatios.get(record.ts.toNumber());
542
- if (lstRatio === undefined) {
543
- throw new Error(
544
- `Missing LST/SOL ratio for deposit record at timestamp ${record.ts.toNumber()}`
545
- );
546
- }
547
- const lstRatioBN = new BN(lstRatio * LAMPORTS_PER_SOL);
548
-
549
- const solAmount = record.amount.mul(lstRatioBN).div(LAMPORTS_PRECISION);
550
- if (isVariant(record.direction, 'deposit')) {
551
- solEarned = solEarned.sub(solAmount);
552
- } else {
553
- solEarned = solEarned.add(solAmount);
554
- }
555
- }
556
- }
557
-
558
- const currentLstTokenAmount = await user.getTokenAmount(marketIndex);
559
- const currentLstRatio = lstRatios.get(now);
560
- if (currentLstRatio === undefined) {
561
- throw new Error(`Missing current LST/SOL ratio for timestamp ${now}`);
562
- }
563
- const currentLstRatioBN = new BN(currentLstRatio * LAMPORTS_PER_SOL);
564
-
565
- solEarned = solEarned.add(
566
- currentLstTokenAmount.mul(currentLstRatioBN).div(LAMPORTS_PRECISION)
567
- );
568
-
569
- const currentSOLTokenAmount = await user.getTokenAmount(1);
570
- solEarned = solEarned.add(currentSOLTokenAmount);
571
-
572
- return solEarned;
573
- }
574
-
575
- /**
576
- * Estimates the LST/SOL price at which a super-staked (leveraged LST-collateral, SOL-borrow)
577
- * position would hit maintenance margin and become liquidatable: the price where
578
- * `lstMaintenanceAssetWeight * lstDepositAmount * price === solMaintenanceLiabilityWeight * solBorrowAmount`.
579
- * All inputs are plain (unscaled) numbers, not `BN` — weights are expected as fractions (e.g.
580
- * `0.8` for 80%, i.e. already divided by `SPOT_MARKET_WEIGHT_PRECISION`), and this is a
581
- * float-precision estimate for UI display, not a program-exact calculation.
582
- *
583
- * @param {number} lstDepositAmount - LST collateral amount, in whole LST tokens
584
- * @param {number} lstMaintenanceAssetWeight - The LST market's maintenance asset weight, as a fraction
585
- * @param {number} solBorrowAmount - SOL borrow amount, in whole SOL
586
- * @param {number} solMaintenanceLiabilityWeight - The SOL market's maintenance liability weight, as a fraction
587
- * @param {number} lstPriceRatio - Current LST/SOL price ratio
588
- * @return {number} Estimated liquidation LST/SOL price
589
- */
590
- export function calculateEstimatedSuperStakeLiquidationPrice(
591
- lstDepositAmount: number,
592
- lstMaintenanceAssetWeight: number,
593
- solBorrowAmount: number,
594
- solMaintenanceLiabilityWeight: number,
595
- lstPriceRatio: number
596
- ): number {
597
- const liquidationDivergence =
598
- (solMaintenanceLiabilityWeight * solBorrowAmount) /
599
- (lstMaintenanceAssetWeight * lstDepositAmount * lstPriceRatio);
600
- const liquidationPrice = lstPriceRatio * liquidationDivergence;
601
- return liquidationPrice;
602
- }
package/src/math/tiers.ts DELETED
@@ -1,73 +0,0 @@
1
- import { isVariant, PerpMarketAccount, SpotMarketAccount } from '../types';
2
-
3
- /**
4
- * Maps a perp market's `contractTier` to an ordinal safety rank, lower is safer. Matches the
5
- * declaration order of the Rust `ContractTier` enum (which derives `Ord` from declaration order,
6
- * used by `ContractTier::is_as_safe_as_contract`'s `self <= other`).
7
- *
8
- * @param {PerpMarketAccount} perpMarket - The perp market account
9
- * @return {number} `0` (A, safest) through `5` (Isolated, riskiest); `4` = HighlySpeculative
10
- */
11
- export function getPerpMarketTierNumber(perpMarket: PerpMarketAccount): number {
12
- if (isVariant(perpMarket.contractTier, 'a')) {
13
- return 0;
14
- } else if (isVariant(perpMarket.contractTier, 'b')) {
15
- return 1;
16
- } else if (isVariant(perpMarket.contractTier, 'c')) {
17
- return 2;
18
- } else if (isVariant(perpMarket.contractTier, 'speculative')) {
19
- return 3;
20
- } else if (isVariant(perpMarket.contractTier, 'highlySpeculative')) {
21
- return 4;
22
- } else {
23
- return 5;
24
- }
25
- }
26
-
27
- /**
28
- * Maps a spot market's `assetTier` to an ordinal safety rank, lower is safer. Matches the
29
- * declaration order of the Rust `AssetTier` enum, used by `ContractTier::is_as_safe_as_asset`.
30
- *
31
- * @param {SpotMarketAccount} spotMarket - The spot market account
32
- * @return {number} `0` (Collateral, safest) through `4` (Unlisted, riskiest); `5` is unreachable
33
- * (falls through only if `assetTier` matches none of the known variants)
34
- */
35
- export function getSpotMarketTierNumber(spotMarket: SpotMarketAccount): number {
36
- if (isVariant(spotMarket.assetTier, 'collateral')) {
37
- return 0;
38
- } else if (isVariant(spotMarket.assetTier, 'protected')) {
39
- return 1;
40
- } else if (isVariant(spotMarket.assetTier, 'cross')) {
41
- return 2;
42
- } else if (isVariant(spotMarket.assetTier, 'isolated')) {
43
- return 3;
44
- } else if (isVariant(spotMarket.assetTier, 'unlisted')) {
45
- return 4;
46
- } else {
47
- return 5;
48
- }
49
- }
50
-
51
- /**
52
- * True if a perp market's tier is at least as safe as both a reference perp tier and a reference
53
- * spot tier, mirroring `ContractTier::is_as_safe_as`. Used to gate cross-margining: a position in
54
- * a market riskier than the account's other collateral/positions can force isolated margin.
55
- * A perp tier is "as safe as" a spot tier if the spot tier is Unlisted (anything beats Unlisted);
56
- * otherwise, if the spot tier is Cross or Isolated, the perp tier must be C-or-safer (tiers 0-2).
57
- *
58
- * @param {number} perpTier - This market's tier number, from `getPerpMarketTierNumber`
59
- * @param {number} otherPerpTier - The reference perp tier number to compare against
60
- * @param {number} otherSpotTier - The reference spot tier number to compare against, from
61
- * `getSpotMarketTierNumber`
62
- * @return {boolean} Whether `perpTier` is as safe as both references
63
- */
64
- export function perpTierIsAsSafeAs(
65
- perpTier: number,
66
- otherPerpTier: number,
67
- otherSpotTier: number
68
- ): boolean {
69
- const asSafeAsPerp = perpTier <= otherPerpTier;
70
- const asSafeAsSpot =
71
- otherSpotTier === 4 || (otherSpotTier >= 2 && perpTier <= 2);
72
- return asSafeAsSpot && asSafeAsPerp;
73
- }