@velocity-exchange/sdk 0.3.0 → 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.
- package/CHANGELOG.md +51 -0
- package/lib/browser/accounts/basicUserAccountSubscriber.d.ts +18 -0
- package/lib/browser/accounts/basicUserAccountSubscriber.js +18 -0
- package/lib/browser/accounts/basicUserStatsAccountSubscriber.d.ts +18 -0
- package/lib/browser/accounts/basicUserStatsAccountSubscriber.js +18 -0
- package/lib/browser/accounts/bulkAccountLoader.d.ts +52 -0
- package/lib/browser/accounts/bulkAccountLoader.js +51 -0
- package/lib/browser/accounts/bulkUserStatsSubscription.d.ts +9 -2
- package/lib/browser/accounts/bulkUserStatsSubscription.js +9 -2
- package/lib/browser/accounts/bulkUserSubscription.d.ts +8 -2
- package/lib/browser/accounts/bulkUserSubscription.js +8 -2
- package/lib/browser/accounts/customizedCadenceBulkAccountLoader.d.ts +37 -0
- package/lib/browser/accounts/customizedCadenceBulkAccountLoader.js +37 -0
- package/lib/browser/accounts/fetch.d.ts +59 -2
- package/lib/browser/accounts/fetch.js +57 -2
- package/lib/browser/accounts/grpcAccountSubscriber.d.ts +30 -0
- package/lib/browser/accounts/grpcAccountSubscriber.js +30 -0
- package/lib/browser/accounts/grpcInsuranceFundStakeAccountSubscriber.d.ts +16 -0
- package/lib/browser/accounts/grpcInsuranceFundStakeAccountSubscriber.js +16 -0
- package/lib/browser/accounts/grpcMultiAccountSubscriber.d.ts +60 -1
- package/lib/browser/accounts/grpcMultiAccountSubscriber.js +118 -37
- package/lib/browser/accounts/grpcMultiUserAccountSubscriber.d.ts +32 -0
- package/lib/browser/accounts/grpcMultiUserAccountSubscriber.js +40 -12
- package/lib/browser/accounts/grpcProgramAccountSubscriber.d.ts +33 -0
- package/lib/browser/accounts/grpcProgramAccountSubscriber.js +33 -0
- package/lib/browser/accounts/grpcUserAccountSubscriber.d.ts +15 -0
- package/lib/browser/accounts/grpcUserAccountSubscriber.js +15 -0
- package/lib/browser/accounts/grpcUserStatsAccountSubscriber.d.ts +15 -0
- package/lib/browser/accounts/grpcUserStatsAccountSubscriber.js +15 -0
- package/lib/browser/accounts/grpcVelocityClientAccountSubscriber.d.ts +41 -0
- package/lib/browser/accounts/grpcVelocityClientAccountSubscriber.js +41 -0
- package/lib/browser/accounts/grpcVelocityClientAccountSubscriberV2.d.ts +116 -0
- package/lib/browser/accounts/grpcVelocityClientAccountSubscriberV2.js +152 -1
- package/lib/browser/accounts/laserProgramAccountSubscriber.d.ts +34 -0
- package/lib/browser/accounts/laserProgramAccountSubscriber.js +34 -0
- package/lib/browser/accounts/oneShotUserAccountSubscriber.d.ts +19 -0
- package/lib/browser/accounts/oneShotUserAccountSubscriber.js +19 -0
- package/lib/browser/accounts/oneShotUserStatsAccountSubscriber.d.ts +19 -0
- package/lib/browser/accounts/oneShotUserStatsAccountSubscriber.js +19 -0
- package/lib/browser/accounts/pollingInsuranceFundStakeAccountSubscriber.d.ts +31 -0
- package/lib/browser/accounts/pollingInsuranceFundStakeAccountSubscriber.js +31 -0
- package/lib/browser/accounts/pollingOracleAccountSubscriber.d.ts +19 -0
- package/lib/browser/accounts/pollingOracleAccountSubscriber.js +21 -2
- package/lib/browser/accounts/pollingTokenAccountSubscriber.d.ts +22 -0
- package/lib/browser/accounts/pollingTokenAccountSubscriber.js +22 -0
- package/lib/browser/accounts/pollingUserAccountSubscriber.d.ts +32 -0
- package/lib/browser/accounts/pollingUserAccountSubscriber.js +32 -0
- package/lib/browser/accounts/pollingUserStatsAccountSubscriber.d.ts +22 -0
- package/lib/browser/accounts/pollingUserStatsAccountSubscriber.js +22 -0
- package/lib/browser/accounts/pollingVelocityClientAccountSubscriber.d.ts +83 -0
- package/lib/browser/accounts/pollingVelocityClientAccountSubscriber.js +84 -1
- package/lib/browser/accounts/testBulkAccountLoader.d.ts +8 -0
- package/lib/browser/accounts/testBulkAccountLoader.js +8 -0
- package/lib/browser/accounts/types.d.ts +149 -0
- package/lib/browser/accounts/types.js +13 -0
- package/lib/browser/accounts/utils.d.ts +18 -0
- package/lib/browser/accounts/utils.js +32 -16
- package/lib/browser/accounts/webSocketAccountSubscriber.d.ts +41 -0
- package/lib/browser/accounts/webSocketAccountSubscriber.js +41 -0
- package/lib/browser/accounts/webSocketAccountSubscriberV2.d.ts +31 -0
- package/lib/browser/accounts/webSocketAccountSubscriberV2.js +31 -23
- package/lib/browser/accounts/webSocketInsuranceFundStakeAccountSubscriber.d.ts +27 -0
- package/lib/browser/accounts/webSocketInsuranceFundStakeAccountSubscriber.js +27 -0
- package/lib/browser/accounts/webSocketProgramAccountSubscriber.d.ts +36 -0
- package/lib/browser/accounts/webSocketProgramAccountSubscriber.js +36 -0
- package/lib/browser/accounts/webSocketProgramAccountSubscriberV2.d.ts +21 -0
- package/lib/browser/accounts/webSocketProgramAccountSubscriberV2.js +25 -0
- package/lib/browser/accounts/webSocketProgramAccountsSubscriberV2.d.ts +21 -0
- package/lib/browser/accounts/webSocketProgramAccountsSubscriberV2.js +21 -0
- package/lib/browser/accounts/webSocketUserAccountSubscriber.d.ts +26 -0
- package/lib/browser/accounts/webSocketUserAccountSubscriber.js +26 -0
- package/lib/browser/accounts/webSocketUserStatsAccountSubsriber.d.ts +20 -0
- package/lib/browser/accounts/webSocketUserStatsAccountSubsriber.js +20 -0
- package/lib/browser/accounts/webSocketVelocityClientAccountSubscriber.d.ts +121 -0
- package/lib/browser/accounts/webSocketVelocityClientAccountSubscriber.js +123 -2
- package/lib/browser/accounts/webSocketVelocityClientAccountSubscriberV2.d.ts +96 -0
- package/lib/browser/accounts/webSocketVelocityClientAccountSubscriberV2.js +108 -0
- package/lib/browser/accounts/websocketProgramUserAccountSubscriber.d.ts +28 -0
- package/lib/browser/accounts/websocketProgramUserAccountSubscriber.js +33 -0
- package/lib/browser/addresses/marketAddresses.d.ts +10 -0
- package/lib/browser/addresses/marketAddresses.js +10 -0
- package/lib/browser/addresses/pda.d.ts +214 -2
- package/lib/browser/addresses/pda.js +217 -5
- package/lib/browser/adminClient.d.ts +2136 -4
- package/lib/browser/adminClient.js +2150 -4
- package/lib/browser/auctionSubscriber/auctionSubscriber.d.ts +15 -0
- package/lib/browser/auctionSubscriber/auctionSubscriber.js +15 -0
- package/lib/browser/auctionSubscriber/auctionSubscriberGrpc.d.ts +19 -0
- package/lib/browser/auctionSubscriber/auctionSubscriberGrpc.js +19 -0
- package/lib/browser/auctionSubscriber/index.d.ts +6 -0
- package/lib/browser/auctionSubscriber/index.js +6 -0
- package/lib/browser/auctionSubscriber/types.d.ts +7 -0
- package/lib/browser/blockhashSubscriber/BlockhashSubscriber.d.ts +33 -0
- package/lib/browser/blockhashSubscriber/BlockhashSubscriber.js +33 -0
- package/lib/browser/blockhashSubscriber/index.d.ts +5 -0
- package/lib/browser/blockhashSubscriber/index.js +5 -0
- package/lib/browser/blockhashSubscriber/types.d.ts +5 -0
- package/lib/browser/clock/clockSubscriber.d.ts +24 -0
- package/lib/browser/clock/clockSubscriber.js +22 -0
- package/lib/browser/config.d.ts +58 -4
- package/lib/browser/config.js +88 -21
- package/lib/browser/constants/numericConstants.d.ts +67 -0
- package/lib/browser/constants/numericConstants.js +68 -1
- package/lib/browser/constants/perpMarkets.d.ts +10 -0
- package/lib/browser/constants/perpMarkets.js +40 -908
- package/lib/browser/constants/spotMarkets.d.ts +13 -0
- package/lib/browser/constants/spotMarkets.js +16 -742
- package/lib/browser/constants/txConstants.d.ts +1 -0
- package/lib/browser/constants/txConstants.js +1 -0
- package/lib/browser/core/VelocityCore.d.ts +285 -8
- package/lib/browser/core/VelocityCore.js +281 -8
- package/lib/browser/core/instructions/deposit.d.ts +22 -0
- package/lib/browser/core/instructions/deposit.js +22 -0
- package/lib/browser/core/instructions/fill.d.ts +17 -0
- package/lib/browser/core/instructions/fill.js +17 -0
- package/lib/browser/core/instructions/funding.d.ts +12 -0
- package/lib/browser/core/instructions/funding.js +12 -0
- package/lib/browser/core/instructions/liquidation.d.ts +18 -0
- package/lib/browser/core/instructions/liquidation.js +18 -0
- package/lib/browser/core/instructions/orders.d.ts +28 -0
- package/lib/browser/core/instructions/orders.js +28 -0
- package/lib/browser/core/instructions/perpOrders.d.ts +106 -0
- package/lib/browser/core/instructions/perpOrders.js +106 -0
- package/lib/browser/core/instructions/settlement.d.ts +14 -0
- package/lib/browser/core/instructions/settlement.js +14 -0
- package/lib/browser/core/instructions/trigger.d.ts +15 -0
- package/lib/browser/core/instructions/trigger.js +15 -0
- package/lib/browser/core/instructions/withdraw.d.ts +21 -0
- package/lib/browser/core/instructions/withdraw.js +21 -0
- package/lib/browser/core/remainingAccounts.d.ts +47 -3
- package/lib/browser/core/remainingAccounts.js +20 -0
- package/lib/browser/core/signedMsg.d.ts +38 -0
- package/lib/browser/core/signedMsg.js +33 -0
- package/lib/browser/decode/customCoder.d.ts +39 -3
- package/lib/browser/decode/customCoder.js +45 -3
- package/lib/browser/decode/user.d.ts +22 -0
- package/lib/browser/decode/user.js +22 -0
- package/lib/browser/dlob/DLOB.d.ts +502 -53
- package/lib/browser/dlob/DLOB.js +540 -98
- package/lib/browser/dlob/DLOBNode.d.ts +86 -4
- package/lib/browser/dlob/DLOBNode.js +37 -4
- package/lib/browser/dlob/DLOBSubscriber.d.ts +39 -12
- package/lib/browser/dlob/DLOBSubscriber.js +42 -12
- package/lib/browser/dlob/NodeList.d.ts +69 -0
- package/lib/browser/dlob/NodeList.js +66 -0
- package/lib/browser/dlob/orderBookLevels.d.ts +106 -13
- package/lib/browser/dlob/orderBookLevels.js +84 -14
- package/lib/browser/dlob/types.d.ts +15 -0
- package/lib/browser/events/eventList.d.ts +14 -0
- package/lib/browser/events/eventList.js +14 -0
- package/lib/browser/events/eventSubscriber.d.ts +87 -10
- package/lib/browser/events/eventSubscriber.js +93 -8
- package/lib/browser/events/eventsServerLogProvider.d.ts +22 -0
- package/lib/browser/events/eventsServerLogProvider.js +27 -0
- package/lib/browser/events/fetchLogs.d.ts +31 -0
- package/lib/browser/events/fetchLogs.js +46 -1
- package/lib/browser/events/parse.d.ts +23 -0
- package/lib/browser/events/parse.js +23 -0
- package/lib/browser/events/pollingLogProvider.d.ts +24 -0
- package/lib/browser/events/pollingLogProvider.js +24 -0
- package/lib/browser/events/sort.d.ts +11 -0
- package/lib/browser/events/sort.js +12 -0
- package/lib/browser/events/txEventCache.d.ts +13 -3
- package/lib/browser/events/txEventCache.js +19 -7
- package/lib/browser/events/types.d.ts +118 -2
- package/lib/browser/events/types.js +11 -0
- package/lib/browser/events/webSocketLogProvider.d.ts +23 -0
- package/lib/browser/events/webSocketLogProvider.js +28 -0
- package/lib/browser/factory/oracleClient.js +2 -2
- package/lib/browser/idl/velocity.d.ts +4 -4
- package/lib/browser/idl/velocity.json +4 -4
- package/lib/browser/keypair.d.ts +8 -0
- package/lib/browser/keypair.js +8 -0
- package/lib/browser/marginCalculation.d.ts +134 -2
- package/lib/browser/marginCalculation.js +121 -0
- package/lib/browser/math/amm.d.ts +348 -29
- package/lib/browser/math/amm.js +310 -32
- package/lib/browser/math/auction.d.ts +95 -19
- package/lib/browser/math/auction.js +118 -28
- package/lib/browser/math/bankruptcy.d.ts +46 -0
- package/lib/browser/math/bankruptcy.js +89 -1
- package/lib/browser/math/builder.d.ts +64 -8
- package/lib/browser/math/builder.js +71 -9
- package/lib/browser/math/conversion.d.ts +21 -0
- package/lib/browser/math/conversion.js +21 -0
- package/lib/browser/math/exchangeStatus.d.ts +91 -0
- package/lib/browser/math/exchangeStatus.js +106 -3
- package/lib/browser/math/funding.d.ts +57 -20
- package/lib/browser/math/funding.js +63 -23
- package/lib/browser/math/insurance.d.ts +62 -0
- package/lib/browser/math/insurance.js +62 -0
- package/lib/browser/math/liquidation.d.ts +127 -11
- package/lib/browser/math/liquidation.js +182 -19
- package/lib/browser/math/margin.d.ts +79 -13
- package/lib/browser/math/margin.js +80 -14
- package/lib/browser/math/market.d.ts +135 -15
- package/lib/browser/math/market.js +145 -17
- package/lib/browser/math/oracles.d.ts +113 -0
- package/lib/browser/math/oracles.js +118 -1
- package/lib/browser/math/orders.d.ts +115 -10
- package/lib/browser/math/orders.js +130 -19
- package/lib/browser/math/position.d.ts +80 -33
- package/lib/browser/math/position.js +80 -33
- package/lib/browser/math/repeg.d.ts +48 -10
- package/lib/browser/math/repeg.js +48 -10
- package/lib/browser/math/spotBalance.d.ts +200 -5
- package/lib/browser/math/spotBalance.js +239 -10
- package/lib/browser/math/spotMarket.d.ts +36 -3
- package/lib/browser/math/spotMarket.js +36 -3
- package/lib/browser/math/spotPosition.d.ts +72 -0
- package/lib/browser/math/spotPosition.js +62 -0
- package/lib/browser/math/state.d.ts +31 -0
- package/lib/browser/math/state.js +31 -0
- package/lib/browser/math/superStake.d.ts +126 -2
- package/lib/browser/math/superStake.js +123 -3
- package/lib/browser/math/tiers.d.ts +29 -0
- package/lib/browser/math/tiers.js +29 -0
- package/lib/browser/math/trade.d.ts +102 -51
- package/lib/browser/math/trade.js +101 -55
- package/lib/browser/math/utils.d.ts +71 -9
- package/lib/browser/math/utils.js +71 -9
- package/lib/browser/memcmp.d.ts +94 -0
- package/lib/browser/memcmp.js +103 -2
- package/lib/browser/oracles/oracleClientCache.d.ts +16 -0
- package/lib/browser/oracles/oracleClientCache.js +16 -0
- package/lib/browser/oracles/oracleId.d.ts +31 -0
- package/lib/browser/oracles/oracleId.js +39 -8
- package/lib/browser/oracles/prelaunchOracleClient.d.ts +20 -0
- package/lib/browser/oracles/prelaunchOracleClient.js +20 -0
- package/lib/browser/oracles/pythClient.d.ts +31 -0
- package/lib/browser/oracles/pythClient.js +32 -1
- package/lib/browser/oracles/pythLazerClient.d.ts +34 -0
- package/lib/browser/oracles/pythLazerClient.js +35 -1
- package/lib/browser/oracles/quoteAssetOracleClient.d.ts +18 -0
- package/lib/browser/oracles/quoteAssetOracleClient.js +18 -0
- package/lib/browser/oracles/strictOraclePrice.d.ts +21 -0
- package/lib/browser/oracles/strictOraclePrice.js +21 -0
- package/lib/browser/oracles/types.d.ts +45 -0
- package/lib/browser/oracles/utils.d.ts +20 -0
- package/lib/browser/oracles/utils.js +20 -0
- package/lib/browser/orderParams.d.ts +42 -4
- package/lib/browser/orderParams.js +42 -4
- package/lib/browser/orderSubscriber/OrderSubscriber.d.ts +56 -0
- package/lib/browser/orderSubscriber/OrderSubscriber.js +56 -0
- package/lib/browser/orderSubscriber/PollingSubscription.d.ts +11 -0
- package/lib/browser/orderSubscriber/PollingSubscription.js +11 -0
- package/lib/browser/orderSubscriber/WebsocketSubscription.d.ts +18 -0
- package/lib/browser/orderSubscriber/WebsocketSubscription.js +18 -0
- package/lib/browser/orderSubscriber/grpcSubscription.d.ts +16 -0
- package/lib/browser/orderSubscriber/grpcSubscription.js +16 -0
- package/lib/browser/orderSubscriber/types.d.ts +9 -0
- package/lib/browser/priorityFee/averageOverSlotsStrategy.d.ts +1 -0
- package/lib/browser/priorityFee/averageOverSlotsStrategy.js +1 -0
- package/lib/browser/priorityFee/averageStrategy.d.ts +1 -0
- package/lib/browser/priorityFee/averageStrategy.js +1 -0
- package/lib/browser/priorityFee/ewmaStrategy.d.ts +10 -0
- package/lib/browser/priorityFee/ewmaStrategy.js +10 -0
- package/lib/browser/priorityFee/heliusPriorityFeeMethod.d.ts +13 -0
- package/lib/browser/priorityFee/heliusPriorityFeeMethod.js +9 -2
- package/lib/browser/priorityFee/maxOverSlotsStrategy.d.ts +1 -0
- package/lib/browser/priorityFee/maxOverSlotsStrategy.js +1 -0
- package/lib/browser/priorityFee/maxStrategy.d.ts +1 -0
- package/lib/browser/priorityFee/maxStrategy.js +1 -0
- package/lib/browser/priorityFee/priorityFeeSubscriber.d.ts +39 -0
- package/lib/browser/priorityFee/priorityFeeSubscriber.js +39 -0
- package/lib/browser/priorityFee/priorityFeeSubscriberMap.d.ts +20 -1
- package/lib/browser/priorityFee/priorityFeeSubscriberMap.js +21 -2
- package/lib/browser/priorityFee/solanaPriorityFeeMethod.d.ts +12 -0
- package/lib/browser/priorityFee/solanaPriorityFeeMethod.js +10 -0
- package/lib/browser/priorityFee/types.d.ts +32 -0
- package/lib/browser/priorityFee/types.js +5 -0
- package/lib/browser/priorityFee/velocityPriorityFeeMethod.d.ts +11 -0
- package/lib/browser/priorityFee/velocityPriorityFeeMethod.js +8 -0
- package/lib/browser/slot/SlotSubscriber.d.ts +18 -0
- package/lib/browser/slot/SlotSubscriber.js +16 -0
- package/lib/browser/slot/SlothashSubscriber.d.ts +26 -0
- package/lib/browser/slot/SlothashSubscriber.js +25 -1
- package/lib/browser/tx/baseTxSender.d.ts +163 -0
- package/lib/browser/tx/baseTxSender.js +174 -6
- package/lib/browser/tx/blockhashFetcher/baseBlockhashFetcher.d.ts +12 -0
- package/lib/browser/tx/blockhashFetcher/baseBlockhashFetcher.js +12 -0
- package/lib/browser/tx/blockhashFetcher/cachedBlockhashFetcher.d.ts +15 -0
- package/lib/browser/tx/blockhashFetcher/cachedBlockhashFetcher.js +15 -0
- package/lib/browser/tx/blockhashFetcher/types.d.ts +4 -0
- package/lib/browser/tx/fastSingleTxSender.d.ts +47 -0
- package/lib/browser/tx/fastSingleTxSender.js +48 -1
- package/lib/browser/tx/forwardOnlyTxSender.d.ts +48 -0
- package/lib/browser/tx/forwardOnlyTxSender.js +48 -0
- package/lib/browser/tx/reportTransactionError.d.ts +18 -6
- package/lib/browser/tx/reportTransactionError.js +18 -6
- package/lib/browser/tx/retryTxSender.d.ts +40 -0
- package/lib/browser/tx/retryTxSender.js +39 -0
- package/lib/browser/tx/txHandler.d.ts +146 -35
- package/lib/browser/tx/txHandler.js +132 -32
- package/lib/browser/tx/txParamProcessor.d.ts +47 -0
- package/lib/browser/tx/txParamProcessor.js +47 -0
- package/lib/browser/tx/types.d.ts +46 -0
- package/lib/browser/tx/types.js +5 -0
- package/lib/browser/tx/utils.d.ts +26 -0
- package/lib/browser/tx/utils.js +26 -0
- package/lib/browser/tx/whileValidTxSender.d.ts +82 -0
- package/lib/browser/tx/whileValidTxSender.js +81 -0
- package/lib/browser/types.d.ts +781 -13
- package/lib/browser/types.js +126 -9
- package/lib/browser/user.d.ts +645 -84
- package/lib/browser/user.js +779 -96
- package/lib/browser/userMap/PollingSubscription.d.ts +10 -0
- package/lib/browser/userMap/PollingSubscription.js +14 -2
- package/lib/browser/userMap/WebsocketSubscription.d.ts +9 -0
- package/lib/browser/userMap/WebsocketSubscription.js +9 -0
- package/lib/browser/userMap/grpcSubscription.d.ts +8 -0
- package/lib/browser/userMap/grpcSubscription.js +8 -0
- package/lib/browser/userMap/referrerMap.d.ts +72 -2
- package/lib/browser/userMap/referrerMap.js +84 -2
- package/lib/browser/userMap/revenueShareEscrowMap.d.ts +37 -10
- package/lib/browser/userMap/revenueShareEscrowMap.js +38 -11
- package/lib/browser/userMap/userMap.d.ts +81 -3
- package/lib/browser/userMap/userMap.js +81 -4
- package/lib/browser/userMap/userMapConfig.d.ts +23 -0
- package/lib/browser/userMap/userStatsMap.d.ts +22 -0
- package/lib/browser/userMap/userStatsMap.js +22 -0
- package/lib/browser/userName.d.ts +16 -0
- package/lib/browser/userName.js +16 -0
- package/lib/browser/userStats.d.ts +28 -1
- package/lib/browser/userStats.js +28 -1
- package/lib/browser/util/TransactionConfirmationManager.d.ts +33 -0
- package/lib/browser/util/TransactionConfirmationManager.js +33 -0
- package/lib/browser/util/chainClock.d.ts +24 -0
- package/lib/browser/util/chainClock.js +20 -0
- package/lib/browser/util/computeUnits.d.ts +32 -0
- package/lib/browser/util/computeUnits.js +32 -0
- package/lib/browser/util/digest.d.ts +17 -0
- package/lib/browser/util/digest.js +17 -0
- package/lib/browser/util/ed25519Utils.d.ts +12 -2
- package/lib/browser/util/ed25519Utils.js +12 -2
- package/lib/browser/util/promiseTimeout.d.ts +9 -0
- package/lib/browser/util/promiseTimeout.js +9 -0
- package/lib/browser/velocityClient.d.ts +3322 -215
- package/lib/browser/velocityClient.js +3412 -245
- package/lib/browser/wallet.d.ts +37 -0
- package/lib/browser/wallet.js +37 -0
- package/lib/node/accounts/basicUserAccountSubscriber.d.ts +18 -0
- package/lib/node/accounts/basicUserAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/basicUserAccountSubscriber.js +18 -0
- package/lib/node/accounts/basicUserStatsAccountSubscriber.d.ts +18 -0
- package/lib/node/accounts/basicUserStatsAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/basicUserStatsAccountSubscriber.js +18 -0
- package/lib/node/accounts/bulkAccountLoader.d.ts +52 -0
- package/lib/node/accounts/bulkAccountLoader.d.ts.map +1 -1
- package/lib/node/accounts/bulkAccountLoader.js +51 -0
- package/lib/node/accounts/bulkUserStatsSubscription.d.ts +9 -2
- package/lib/node/accounts/bulkUserStatsSubscription.d.ts.map +1 -1
- package/lib/node/accounts/bulkUserStatsSubscription.js +9 -2
- package/lib/node/accounts/bulkUserSubscription.d.ts +8 -2
- package/lib/node/accounts/bulkUserSubscription.d.ts.map +1 -1
- package/lib/node/accounts/bulkUserSubscription.js +8 -2
- package/lib/node/accounts/customizedCadenceBulkAccountLoader.d.ts +37 -0
- package/lib/node/accounts/customizedCadenceBulkAccountLoader.d.ts.map +1 -1
- package/lib/node/accounts/customizedCadenceBulkAccountLoader.js +37 -0
- package/lib/node/accounts/fetch.d.ts +59 -2
- package/lib/node/accounts/fetch.d.ts.map +1 -1
- package/lib/node/accounts/fetch.js +57 -2
- package/lib/node/accounts/grpcAccountSubscriber.d.ts +30 -0
- package/lib/node/accounts/grpcAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/grpcAccountSubscriber.js +30 -0
- package/lib/node/accounts/grpcInsuranceFundStakeAccountSubscriber.d.ts +16 -0
- package/lib/node/accounts/grpcInsuranceFundStakeAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/grpcInsuranceFundStakeAccountSubscriber.js +16 -0
- package/lib/node/accounts/grpcMultiAccountSubscriber.d.ts +60 -1
- package/lib/node/accounts/grpcMultiAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/grpcMultiAccountSubscriber.js +118 -37
- package/lib/node/accounts/grpcMultiUserAccountSubscriber.d.ts +32 -0
- package/lib/node/accounts/grpcMultiUserAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/grpcMultiUserAccountSubscriber.js +40 -12
- package/lib/node/accounts/grpcProgramAccountSubscriber.d.ts +33 -0
- package/lib/node/accounts/grpcProgramAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/grpcProgramAccountSubscriber.js +33 -0
- package/lib/node/accounts/grpcUserAccountSubscriber.d.ts +15 -0
- package/lib/node/accounts/grpcUserAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/grpcUserAccountSubscriber.js +15 -0
- package/lib/node/accounts/grpcUserStatsAccountSubscriber.d.ts +15 -0
- package/lib/node/accounts/grpcUserStatsAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/grpcUserStatsAccountSubscriber.js +15 -0
- package/lib/node/accounts/grpcVelocityClientAccountSubscriber.d.ts +41 -0
- package/lib/node/accounts/grpcVelocityClientAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/grpcVelocityClientAccountSubscriber.js +41 -0
- package/lib/node/accounts/grpcVelocityClientAccountSubscriberV2.d.ts +116 -0
- package/lib/node/accounts/grpcVelocityClientAccountSubscriberV2.d.ts.map +1 -1
- package/lib/node/accounts/grpcVelocityClientAccountSubscriberV2.js +152 -1
- package/lib/node/accounts/laserProgramAccountSubscriber.d.ts +34 -0
- package/lib/node/accounts/laserProgramAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/laserProgramAccountSubscriber.js +34 -0
- package/lib/node/accounts/oneShotUserAccountSubscriber.d.ts +19 -0
- package/lib/node/accounts/oneShotUserAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/oneShotUserAccountSubscriber.js +19 -0
- package/lib/node/accounts/oneShotUserStatsAccountSubscriber.d.ts +19 -0
- package/lib/node/accounts/oneShotUserStatsAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/oneShotUserStatsAccountSubscriber.js +19 -0
- package/lib/node/accounts/pollingInsuranceFundStakeAccountSubscriber.d.ts +31 -0
- package/lib/node/accounts/pollingInsuranceFundStakeAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/pollingInsuranceFundStakeAccountSubscriber.js +31 -0
- package/lib/node/accounts/pollingOracleAccountSubscriber.d.ts +19 -0
- package/lib/node/accounts/pollingOracleAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/pollingOracleAccountSubscriber.js +21 -2
- package/lib/node/accounts/pollingTokenAccountSubscriber.d.ts +22 -0
- package/lib/node/accounts/pollingTokenAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/pollingTokenAccountSubscriber.js +22 -0
- package/lib/node/accounts/pollingUserAccountSubscriber.d.ts +32 -0
- package/lib/node/accounts/pollingUserAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/pollingUserAccountSubscriber.js +32 -0
- package/lib/node/accounts/pollingUserStatsAccountSubscriber.d.ts +22 -0
- package/lib/node/accounts/pollingUserStatsAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/pollingUserStatsAccountSubscriber.js +22 -0
- package/lib/node/accounts/pollingVelocityClientAccountSubscriber.d.ts +83 -0
- package/lib/node/accounts/pollingVelocityClientAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/pollingVelocityClientAccountSubscriber.js +84 -1
- package/lib/node/accounts/testBulkAccountLoader.d.ts +8 -0
- package/lib/node/accounts/testBulkAccountLoader.d.ts.map +1 -1
- package/lib/node/accounts/testBulkAccountLoader.js +8 -0
- package/lib/node/accounts/types.d.ts +149 -0
- package/lib/node/accounts/types.d.ts.map +1 -1
- package/lib/node/accounts/types.js +13 -0
- package/lib/node/accounts/utils.d.ts +18 -0
- package/lib/node/accounts/utils.d.ts.map +1 -1
- package/lib/node/accounts/utils.js +32 -16
- package/lib/node/accounts/webSocketAccountSubscriber.d.ts +41 -0
- package/lib/node/accounts/webSocketAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/webSocketAccountSubscriber.js +41 -0
- package/lib/node/accounts/webSocketAccountSubscriberV2.d.ts +31 -0
- package/lib/node/accounts/webSocketAccountSubscriberV2.d.ts.map +1 -1
- package/lib/node/accounts/webSocketAccountSubscriberV2.js +31 -23
- package/lib/node/accounts/webSocketInsuranceFundStakeAccountSubscriber.d.ts +27 -0
- package/lib/node/accounts/webSocketInsuranceFundStakeAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/webSocketInsuranceFundStakeAccountSubscriber.js +27 -0
- package/lib/node/accounts/webSocketProgramAccountSubscriber.d.ts +36 -0
- package/lib/node/accounts/webSocketProgramAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/webSocketProgramAccountSubscriber.js +36 -0
- package/lib/node/accounts/webSocketProgramAccountSubscriberV2.d.ts +21 -0
- package/lib/node/accounts/webSocketProgramAccountSubscriberV2.d.ts.map +1 -1
- package/lib/node/accounts/webSocketProgramAccountSubscriberV2.js +25 -0
- package/lib/node/accounts/webSocketProgramAccountsSubscriberV2.d.ts +21 -0
- package/lib/node/accounts/webSocketProgramAccountsSubscriberV2.d.ts.map +1 -1
- package/lib/node/accounts/webSocketProgramAccountsSubscriberV2.js +21 -0
- package/lib/node/accounts/webSocketUserAccountSubscriber.d.ts +26 -0
- package/lib/node/accounts/webSocketUserAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/webSocketUserAccountSubscriber.js +26 -0
- package/lib/node/accounts/webSocketUserStatsAccountSubsriber.d.ts +20 -0
- package/lib/node/accounts/webSocketUserStatsAccountSubsriber.d.ts.map +1 -1
- package/lib/node/accounts/webSocketUserStatsAccountSubsriber.js +20 -0
- package/lib/node/accounts/webSocketVelocityClientAccountSubscriber.d.ts +121 -0
- package/lib/node/accounts/webSocketVelocityClientAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/webSocketVelocityClientAccountSubscriber.js +123 -2
- package/lib/node/accounts/webSocketVelocityClientAccountSubscriberV2.d.ts +96 -0
- package/lib/node/accounts/webSocketVelocityClientAccountSubscriberV2.d.ts.map +1 -1
- package/lib/node/accounts/webSocketVelocityClientAccountSubscriberV2.js +108 -0
- package/lib/node/accounts/websocketProgramUserAccountSubscriber.d.ts +28 -0
- package/lib/node/accounts/websocketProgramUserAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/websocketProgramUserAccountSubscriber.js +33 -0
- package/lib/node/addresses/marketAddresses.d.ts +10 -0
- package/lib/node/addresses/marketAddresses.d.ts.map +1 -1
- package/lib/node/addresses/marketAddresses.js +10 -0
- package/lib/node/addresses/pda.d.ts +214 -2
- package/lib/node/addresses/pda.d.ts.map +1 -1
- package/lib/node/addresses/pda.js +217 -5
- package/lib/node/adminClient.d.ts +2136 -4
- package/lib/node/adminClient.d.ts.map +1 -1
- package/lib/node/adminClient.js +2150 -4
- package/lib/node/auctionSubscriber/auctionSubscriber.d.ts +15 -0
- package/lib/node/auctionSubscriber/auctionSubscriber.d.ts.map +1 -1
- package/lib/node/auctionSubscriber/auctionSubscriber.js +15 -0
- package/lib/node/auctionSubscriber/auctionSubscriberGrpc.d.ts +19 -0
- package/lib/node/auctionSubscriber/auctionSubscriberGrpc.d.ts.map +1 -1
- package/lib/node/auctionSubscriber/auctionSubscriberGrpc.js +19 -0
- package/lib/node/auctionSubscriber/index.d.ts +6 -0
- package/lib/node/auctionSubscriber/index.d.ts.map +1 -1
- package/lib/node/auctionSubscriber/index.js +6 -0
- package/lib/node/auctionSubscriber/types.d.ts +7 -0
- package/lib/node/auctionSubscriber/types.d.ts.map +1 -1
- package/lib/node/blockhashSubscriber/BlockhashSubscriber.d.ts +33 -0
- package/lib/node/blockhashSubscriber/BlockhashSubscriber.d.ts.map +1 -1
- package/lib/node/blockhashSubscriber/BlockhashSubscriber.js +33 -0
- package/lib/node/blockhashSubscriber/index.d.ts +5 -0
- package/lib/node/blockhashSubscriber/index.d.ts.map +1 -1
- package/lib/node/blockhashSubscriber/index.js +5 -0
- package/lib/node/blockhashSubscriber/types.d.ts +5 -0
- package/lib/node/blockhashSubscriber/types.d.ts.map +1 -1
- package/lib/node/clock/clockSubscriber.d.ts +24 -0
- package/lib/node/clock/clockSubscriber.d.ts.map +1 -1
- package/lib/node/clock/clockSubscriber.js +22 -0
- package/lib/node/config.d.ts +58 -4
- package/lib/node/config.d.ts.map +1 -1
- package/lib/node/config.js +88 -21
- package/lib/node/constants/numericConstants.d.ts +67 -0
- package/lib/node/constants/numericConstants.d.ts.map +1 -1
- package/lib/node/constants/numericConstants.js +68 -1
- package/lib/node/constants/perpMarkets.d.ts +10 -0
- package/lib/node/constants/perpMarkets.d.ts.map +1 -1
- package/lib/node/constants/perpMarkets.js +40 -908
- package/lib/node/constants/spotMarkets.d.ts +13 -0
- package/lib/node/constants/spotMarkets.d.ts.map +1 -1
- package/lib/node/constants/spotMarkets.js +16 -742
- package/lib/node/constants/txConstants.d.ts +1 -0
- package/lib/node/constants/txConstants.d.ts.map +1 -1
- package/lib/node/constants/txConstants.js +1 -0
- package/lib/node/core/VelocityCore.d.ts +285 -8
- package/lib/node/core/VelocityCore.d.ts.map +1 -1
- package/lib/node/core/VelocityCore.js +281 -8
- package/lib/node/core/instructions/deposit.d.ts +22 -0
- package/lib/node/core/instructions/deposit.d.ts.map +1 -1
- package/lib/node/core/instructions/deposit.js +22 -0
- package/lib/node/core/instructions/fill.d.ts +17 -0
- package/lib/node/core/instructions/fill.d.ts.map +1 -1
- package/lib/node/core/instructions/fill.js +17 -0
- package/lib/node/core/instructions/funding.d.ts +12 -0
- package/lib/node/core/instructions/funding.d.ts.map +1 -1
- package/lib/node/core/instructions/funding.js +12 -0
- package/lib/node/core/instructions/liquidation.d.ts +18 -0
- package/lib/node/core/instructions/liquidation.d.ts.map +1 -1
- package/lib/node/core/instructions/liquidation.js +18 -0
- package/lib/node/core/instructions/orders.d.ts +28 -0
- package/lib/node/core/instructions/orders.d.ts.map +1 -1
- package/lib/node/core/instructions/orders.js +28 -0
- package/lib/node/core/instructions/perpOrders.d.ts +106 -0
- package/lib/node/core/instructions/perpOrders.d.ts.map +1 -1
- package/lib/node/core/instructions/perpOrders.js +106 -0
- package/lib/node/core/instructions/settlement.d.ts +14 -0
- package/lib/node/core/instructions/settlement.d.ts.map +1 -1
- package/lib/node/core/instructions/settlement.js +14 -0
- package/lib/node/core/instructions/trigger.d.ts +15 -0
- package/lib/node/core/instructions/trigger.d.ts.map +1 -1
- package/lib/node/core/instructions/trigger.js +15 -0
- package/lib/node/core/instructions/withdraw.d.ts +21 -0
- package/lib/node/core/instructions/withdraw.d.ts.map +1 -1
- package/lib/node/core/instructions/withdraw.js +21 -0
- package/lib/node/core/remainingAccounts.d.ts +47 -3
- package/lib/node/core/remainingAccounts.d.ts.map +1 -1
- package/lib/node/core/remainingAccounts.js +20 -0
- package/lib/node/core/signedMsg.d.ts +38 -0
- package/lib/node/core/signedMsg.d.ts.map +1 -1
- package/lib/node/core/signedMsg.js +33 -0
- package/lib/node/decode/customCoder.d.ts +39 -3
- package/lib/node/decode/customCoder.d.ts.map +1 -1
- package/lib/node/decode/customCoder.js +45 -3
- package/lib/node/decode/user.d.ts +22 -0
- package/lib/node/decode/user.d.ts.map +1 -1
- package/lib/node/decode/user.js +22 -0
- package/lib/node/dlob/DLOB.d.ts +502 -53
- package/lib/node/dlob/DLOB.d.ts.map +1 -1
- package/lib/node/dlob/DLOB.js +540 -98
- package/lib/node/dlob/DLOBNode.d.ts +86 -4
- package/lib/node/dlob/DLOBNode.d.ts.map +1 -1
- package/lib/node/dlob/DLOBNode.js +37 -4
- package/lib/node/dlob/DLOBSubscriber.d.ts +39 -12
- package/lib/node/dlob/DLOBSubscriber.d.ts.map +1 -1
- package/lib/node/dlob/DLOBSubscriber.js +42 -12
- package/lib/node/dlob/NodeList.d.ts +69 -0
- package/lib/node/dlob/NodeList.d.ts.map +1 -1
- package/lib/node/dlob/NodeList.js +66 -0
- package/lib/node/dlob/orderBookLevels.d.ts +106 -13
- package/lib/node/dlob/orderBookLevels.d.ts.map +1 -1
- package/lib/node/dlob/orderBookLevels.js +84 -14
- package/lib/node/dlob/types.d.ts +15 -0
- package/lib/node/dlob/types.d.ts.map +1 -1
- package/lib/node/events/eventList.d.ts +14 -0
- package/lib/node/events/eventList.d.ts.map +1 -1
- package/lib/node/events/eventList.js +14 -0
- package/lib/node/events/eventSubscriber.d.ts +87 -10
- package/lib/node/events/eventSubscriber.d.ts.map +1 -1
- package/lib/node/events/eventSubscriber.js +93 -8
- package/lib/node/events/eventsServerLogProvider.d.ts +22 -0
- package/lib/node/events/eventsServerLogProvider.d.ts.map +1 -1
- package/lib/node/events/eventsServerLogProvider.js +27 -0
- package/lib/node/events/fetchLogs.d.ts +31 -0
- package/lib/node/events/fetchLogs.d.ts.map +1 -1
- package/lib/node/events/fetchLogs.js +46 -1
- package/lib/node/events/parse.d.ts +23 -0
- package/lib/node/events/parse.d.ts.map +1 -1
- package/lib/node/events/parse.js +23 -0
- package/lib/node/events/pollingLogProvider.d.ts +24 -0
- package/lib/node/events/pollingLogProvider.d.ts.map +1 -1
- package/lib/node/events/pollingLogProvider.js +24 -0
- package/lib/node/events/sort.d.ts +11 -0
- package/lib/node/events/sort.d.ts.map +1 -1
- package/lib/node/events/sort.js +12 -0
- package/lib/node/events/txEventCache.d.ts +13 -3
- package/lib/node/events/txEventCache.d.ts.map +1 -1
- package/lib/node/events/txEventCache.js +19 -7
- package/lib/node/events/types.d.ts +118 -2
- package/lib/node/events/types.d.ts.map +1 -1
- package/lib/node/events/types.js +11 -0
- package/lib/node/events/webSocketLogProvider.d.ts +23 -0
- package/lib/node/events/webSocketLogProvider.d.ts.map +1 -1
- package/lib/node/events/webSocketLogProvider.js +28 -0
- package/lib/node/factory/oracleClient.js +2 -2
- package/lib/node/idl/velocity.d.ts +4 -4
- package/lib/node/idl/velocity.d.ts.map +1 -1
- package/lib/node/idl/velocity.json +4 -4
- package/lib/node/keypair.d.ts +8 -0
- package/lib/node/keypair.d.ts.map +1 -1
- package/lib/node/keypair.js +8 -0
- package/lib/node/marginCalculation.d.ts +134 -2
- package/lib/node/marginCalculation.d.ts.map +1 -1
- package/lib/node/marginCalculation.js +121 -0
- package/lib/node/math/amm.d.ts +348 -29
- package/lib/node/math/amm.d.ts.map +1 -1
- package/lib/node/math/amm.js +310 -32
- package/lib/node/math/auction.d.ts +95 -19
- package/lib/node/math/auction.d.ts.map +1 -1
- package/lib/node/math/auction.js +118 -28
- package/lib/node/math/bankruptcy.d.ts +46 -0
- package/lib/node/math/bankruptcy.d.ts.map +1 -1
- package/lib/node/math/bankruptcy.js +89 -1
- package/lib/node/math/builder.d.ts +64 -8
- package/lib/node/math/builder.d.ts.map +1 -1
- package/lib/node/math/builder.js +71 -9
- package/lib/node/math/conversion.d.ts +21 -0
- package/lib/node/math/conversion.d.ts.map +1 -1
- package/lib/node/math/conversion.js +21 -0
- package/lib/node/math/exchangeStatus.d.ts +91 -0
- package/lib/node/math/exchangeStatus.d.ts.map +1 -1
- package/lib/node/math/exchangeStatus.js +106 -3
- package/lib/node/math/funding.d.ts +57 -20
- package/lib/node/math/funding.d.ts.map +1 -1
- package/lib/node/math/funding.js +63 -23
- package/lib/node/math/insurance.d.ts +62 -0
- package/lib/node/math/insurance.d.ts.map +1 -1
- package/lib/node/math/insurance.js +62 -0
- package/lib/node/math/liquidation.d.ts +127 -11
- package/lib/node/math/liquidation.d.ts.map +1 -1
- package/lib/node/math/liquidation.js +182 -19
- package/lib/node/math/margin.d.ts +79 -13
- package/lib/node/math/margin.d.ts.map +1 -1
- package/lib/node/math/margin.js +80 -14
- package/lib/node/math/market.d.ts +135 -15
- package/lib/node/math/market.d.ts.map +1 -1
- package/lib/node/math/market.js +145 -17
- package/lib/node/math/oracles.d.ts +113 -0
- package/lib/node/math/oracles.d.ts.map +1 -1
- package/lib/node/math/oracles.js +118 -1
- package/lib/node/math/orders.d.ts +115 -10
- package/lib/node/math/orders.d.ts.map +1 -1
- package/lib/node/math/orders.js +130 -19
- package/lib/node/math/position.d.ts +80 -33
- package/lib/node/math/position.d.ts.map +1 -1
- package/lib/node/math/position.js +80 -33
- package/lib/node/math/repeg.d.ts +48 -10
- package/lib/node/math/repeg.d.ts.map +1 -1
- package/lib/node/math/repeg.js +48 -10
- package/lib/node/math/spotBalance.d.ts +200 -5
- package/lib/node/math/spotBalance.d.ts.map +1 -1
- package/lib/node/math/spotBalance.js +239 -10
- package/lib/node/math/spotMarket.d.ts +36 -3
- package/lib/node/math/spotMarket.d.ts.map +1 -1
- package/lib/node/math/spotMarket.js +36 -3
- package/lib/node/math/spotPosition.d.ts +72 -0
- package/lib/node/math/spotPosition.d.ts.map +1 -1
- package/lib/node/math/spotPosition.js +62 -0
- package/lib/node/math/state.d.ts +31 -0
- package/lib/node/math/state.d.ts.map +1 -1
- package/lib/node/math/state.js +31 -0
- package/lib/node/math/superStake.d.ts +126 -2
- package/lib/node/math/superStake.d.ts.map +1 -1
- package/lib/node/math/superStake.js +123 -3
- package/lib/node/math/tiers.d.ts +29 -0
- package/lib/node/math/tiers.d.ts.map +1 -1
- package/lib/node/math/tiers.js +29 -0
- package/lib/node/math/trade.d.ts +102 -51
- package/lib/node/math/trade.d.ts.map +1 -1
- package/lib/node/math/trade.js +101 -55
- package/lib/node/math/utils.d.ts +71 -9
- package/lib/node/math/utils.d.ts.map +1 -1
- package/lib/node/math/utils.js +71 -9
- package/lib/node/memcmp.d.ts +94 -0
- package/lib/node/memcmp.d.ts.map +1 -1
- package/lib/node/memcmp.js +103 -2
- package/lib/node/oracles/oracleClientCache.d.ts +16 -0
- package/lib/node/oracles/oracleClientCache.d.ts.map +1 -1
- package/lib/node/oracles/oracleClientCache.js +16 -0
- package/lib/node/oracles/oracleId.d.ts +31 -0
- package/lib/node/oracles/oracleId.d.ts.map +1 -1
- package/lib/node/oracles/oracleId.js +39 -8
- package/lib/node/oracles/prelaunchOracleClient.d.ts +20 -0
- package/lib/node/oracles/prelaunchOracleClient.d.ts.map +1 -1
- package/lib/node/oracles/prelaunchOracleClient.js +20 -0
- package/lib/node/oracles/pythClient.d.ts +31 -0
- package/lib/node/oracles/pythClient.d.ts.map +1 -1
- package/lib/node/oracles/pythClient.js +32 -1
- package/lib/node/oracles/pythLazerClient.d.ts +34 -0
- package/lib/node/oracles/pythLazerClient.d.ts.map +1 -1
- package/lib/node/oracles/pythLazerClient.js +35 -1
- package/lib/node/oracles/quoteAssetOracleClient.d.ts +18 -0
- package/lib/node/oracles/quoteAssetOracleClient.d.ts.map +1 -1
- package/lib/node/oracles/quoteAssetOracleClient.js +18 -0
- package/lib/node/oracles/strictOraclePrice.d.ts +21 -0
- package/lib/node/oracles/strictOraclePrice.d.ts.map +1 -1
- package/lib/node/oracles/strictOraclePrice.js +21 -0
- package/lib/node/oracles/types.d.ts +45 -0
- package/lib/node/oracles/types.d.ts.map +1 -1
- package/lib/node/oracles/utils.d.ts +20 -0
- package/lib/node/oracles/utils.d.ts.map +1 -1
- package/lib/node/oracles/utils.js +20 -0
- package/lib/node/orderParams.d.ts +42 -4
- package/lib/node/orderParams.d.ts.map +1 -1
- package/lib/node/orderParams.js +42 -4
- package/lib/node/orderSubscriber/OrderSubscriber.d.ts +56 -0
- package/lib/node/orderSubscriber/OrderSubscriber.d.ts.map +1 -1
- package/lib/node/orderSubscriber/OrderSubscriber.js +56 -0
- package/lib/node/orderSubscriber/PollingSubscription.d.ts +11 -0
- package/lib/node/orderSubscriber/PollingSubscription.d.ts.map +1 -1
- package/lib/node/orderSubscriber/PollingSubscription.js +11 -0
- package/lib/node/orderSubscriber/WebsocketSubscription.d.ts +18 -0
- package/lib/node/orderSubscriber/WebsocketSubscription.d.ts.map +1 -1
- package/lib/node/orderSubscriber/WebsocketSubscription.js +18 -0
- package/lib/node/orderSubscriber/grpcSubscription.d.ts +16 -0
- package/lib/node/orderSubscriber/grpcSubscription.d.ts.map +1 -1
- package/lib/node/orderSubscriber/grpcSubscription.js +16 -0
- package/lib/node/orderSubscriber/types.d.ts +9 -0
- package/lib/node/orderSubscriber/types.d.ts.map +1 -1
- package/lib/node/priorityFee/averageOverSlotsStrategy.d.ts +1 -0
- package/lib/node/priorityFee/averageOverSlotsStrategy.d.ts.map +1 -1
- package/lib/node/priorityFee/averageOverSlotsStrategy.js +1 -0
- package/lib/node/priorityFee/averageStrategy.d.ts +1 -0
- package/lib/node/priorityFee/averageStrategy.d.ts.map +1 -1
- package/lib/node/priorityFee/averageStrategy.js +1 -0
- package/lib/node/priorityFee/ewmaStrategy.d.ts +10 -0
- package/lib/node/priorityFee/ewmaStrategy.d.ts.map +1 -1
- package/lib/node/priorityFee/ewmaStrategy.js +10 -0
- package/lib/node/priorityFee/heliusPriorityFeeMethod.d.ts +13 -0
- package/lib/node/priorityFee/heliusPriorityFeeMethod.d.ts.map +1 -1
- package/lib/node/priorityFee/heliusPriorityFeeMethod.js +9 -2
- package/lib/node/priorityFee/maxOverSlotsStrategy.d.ts +1 -0
- package/lib/node/priorityFee/maxOverSlotsStrategy.d.ts.map +1 -1
- package/lib/node/priorityFee/maxOverSlotsStrategy.js +1 -0
- package/lib/node/priorityFee/maxStrategy.d.ts +1 -0
- package/lib/node/priorityFee/maxStrategy.d.ts.map +1 -1
- package/lib/node/priorityFee/maxStrategy.js +1 -0
- package/lib/node/priorityFee/priorityFeeSubscriber.d.ts +39 -0
- package/lib/node/priorityFee/priorityFeeSubscriber.d.ts.map +1 -1
- package/lib/node/priorityFee/priorityFeeSubscriber.js +39 -0
- package/lib/node/priorityFee/priorityFeeSubscriberMap.d.ts +20 -1
- package/lib/node/priorityFee/priorityFeeSubscriberMap.d.ts.map +1 -1
- package/lib/node/priorityFee/priorityFeeSubscriberMap.js +21 -2
- package/lib/node/priorityFee/solanaPriorityFeeMethod.d.ts +12 -0
- package/lib/node/priorityFee/solanaPriorityFeeMethod.d.ts.map +1 -1
- package/lib/node/priorityFee/solanaPriorityFeeMethod.js +10 -0
- package/lib/node/priorityFee/types.d.ts +32 -0
- package/lib/node/priorityFee/types.d.ts.map +1 -1
- package/lib/node/priorityFee/types.js +5 -0
- package/lib/node/priorityFee/velocityPriorityFeeMethod.d.ts +11 -0
- package/lib/node/priorityFee/velocityPriorityFeeMethod.d.ts.map +1 -1
- package/lib/node/priorityFee/velocityPriorityFeeMethod.js +8 -0
- package/lib/node/slot/SlotSubscriber.d.ts +18 -0
- package/lib/node/slot/SlotSubscriber.d.ts.map +1 -1
- package/lib/node/slot/SlotSubscriber.js +16 -0
- package/lib/node/slot/SlothashSubscriber.d.ts +26 -0
- package/lib/node/slot/SlothashSubscriber.d.ts.map +1 -1
- package/lib/node/slot/SlothashSubscriber.js +25 -1
- package/lib/node/tx/baseTxSender.d.ts +163 -0
- package/lib/node/tx/baseTxSender.d.ts.map +1 -1
- package/lib/node/tx/baseTxSender.js +174 -6
- package/lib/node/tx/blockhashFetcher/baseBlockhashFetcher.d.ts +12 -0
- package/lib/node/tx/blockhashFetcher/baseBlockhashFetcher.d.ts.map +1 -1
- package/lib/node/tx/blockhashFetcher/baseBlockhashFetcher.js +12 -0
- package/lib/node/tx/blockhashFetcher/cachedBlockhashFetcher.d.ts +15 -0
- package/lib/node/tx/blockhashFetcher/cachedBlockhashFetcher.d.ts.map +1 -1
- package/lib/node/tx/blockhashFetcher/cachedBlockhashFetcher.js +15 -0
- package/lib/node/tx/blockhashFetcher/types.d.ts +4 -0
- package/lib/node/tx/blockhashFetcher/types.d.ts.map +1 -1
- package/lib/node/tx/fastSingleTxSender.d.ts +47 -0
- package/lib/node/tx/fastSingleTxSender.d.ts.map +1 -1
- package/lib/node/tx/fastSingleTxSender.js +48 -1
- package/lib/node/tx/forwardOnlyTxSender.d.ts +48 -0
- package/lib/node/tx/forwardOnlyTxSender.d.ts.map +1 -1
- package/lib/node/tx/forwardOnlyTxSender.js +48 -0
- package/lib/node/tx/reportTransactionError.d.ts +18 -6
- package/lib/node/tx/reportTransactionError.d.ts.map +1 -1
- package/lib/node/tx/reportTransactionError.js +18 -6
- package/lib/node/tx/retryTxSender.d.ts +40 -0
- package/lib/node/tx/retryTxSender.d.ts.map +1 -1
- package/lib/node/tx/retryTxSender.js +39 -0
- package/lib/node/tx/txHandler.d.ts +146 -35
- package/lib/node/tx/txHandler.d.ts.map +1 -1
- package/lib/node/tx/txHandler.js +132 -32
- package/lib/node/tx/txParamProcessor.d.ts +47 -0
- package/lib/node/tx/txParamProcessor.d.ts.map +1 -1
- package/lib/node/tx/txParamProcessor.js +47 -0
- package/lib/node/tx/types.d.ts +46 -0
- package/lib/node/tx/types.d.ts.map +1 -1
- package/lib/node/tx/types.js +5 -0
- package/lib/node/tx/utils.d.ts +26 -0
- package/lib/node/tx/utils.d.ts.map +1 -1
- package/lib/node/tx/utils.js +26 -0
- package/lib/node/tx/whileValidTxSender.d.ts +82 -0
- package/lib/node/tx/whileValidTxSender.d.ts.map +1 -1
- package/lib/node/tx/whileValidTxSender.js +81 -0
- package/lib/node/types.d.ts +781 -13
- package/lib/node/types.d.ts.map +1 -1
- package/lib/node/types.js +126 -9
- package/lib/node/user.d.ts +645 -84
- package/lib/node/user.d.ts.map +1 -1
- package/lib/node/user.js +779 -96
- package/lib/node/userMap/PollingSubscription.d.ts +10 -0
- package/lib/node/userMap/PollingSubscription.d.ts.map +1 -1
- package/lib/node/userMap/PollingSubscription.js +14 -2
- package/lib/node/userMap/WebsocketSubscription.d.ts +9 -0
- package/lib/node/userMap/WebsocketSubscription.d.ts.map +1 -1
- package/lib/node/userMap/WebsocketSubscription.js +9 -0
- package/lib/node/userMap/grpcSubscription.d.ts +8 -0
- package/lib/node/userMap/grpcSubscription.d.ts.map +1 -1
- package/lib/node/userMap/grpcSubscription.js +8 -0
- package/lib/node/userMap/referrerMap.d.ts +72 -2
- package/lib/node/userMap/referrerMap.d.ts.map +1 -1
- package/lib/node/userMap/referrerMap.js +84 -2
- package/lib/node/userMap/revenueShareEscrowMap.d.ts +37 -10
- package/lib/node/userMap/revenueShareEscrowMap.d.ts.map +1 -1
- package/lib/node/userMap/revenueShareEscrowMap.js +38 -11
- package/lib/node/userMap/userMap.d.ts +81 -3
- package/lib/node/userMap/userMap.d.ts.map +1 -1
- package/lib/node/userMap/userMap.js +81 -4
- package/lib/node/userMap/userMapConfig.d.ts +23 -0
- package/lib/node/userMap/userMapConfig.d.ts.map +1 -1
- package/lib/node/userMap/userStatsMap.d.ts +22 -0
- package/lib/node/userMap/userStatsMap.d.ts.map +1 -1
- package/lib/node/userMap/userStatsMap.js +22 -0
- package/lib/node/userName.d.ts +16 -0
- package/lib/node/userName.d.ts.map +1 -1
- package/lib/node/userName.js +16 -0
- package/lib/node/userStats.d.ts +28 -1
- package/lib/node/userStats.d.ts.map +1 -1
- package/lib/node/userStats.js +28 -1
- package/lib/node/util/TransactionConfirmationManager.d.ts +33 -0
- package/lib/node/util/TransactionConfirmationManager.d.ts.map +1 -1
- package/lib/node/util/TransactionConfirmationManager.js +33 -0
- package/lib/node/util/chainClock.d.ts +24 -0
- package/lib/node/util/chainClock.d.ts.map +1 -1
- package/lib/node/util/chainClock.js +20 -0
- package/lib/node/util/computeUnits.d.ts +32 -0
- package/lib/node/util/computeUnits.d.ts.map +1 -1
- package/lib/node/util/computeUnits.js +32 -0
- package/lib/node/util/digest.d.ts +17 -0
- package/lib/node/util/digest.d.ts.map +1 -1
- package/lib/node/util/digest.js +17 -0
- package/lib/node/util/ed25519Utils.d.ts +12 -2
- package/lib/node/util/ed25519Utils.d.ts.map +1 -1
- package/lib/node/util/ed25519Utils.js +12 -2
- package/lib/node/util/promiseTimeout.d.ts +9 -0
- package/lib/node/util/promiseTimeout.d.ts.map +1 -1
- package/lib/node/util/promiseTimeout.js +9 -0
- package/lib/node/velocityClient.d.ts +3322 -215
- package/lib/node/velocityClient.d.ts.map +1 -1
- package/lib/node/velocityClient.js +3412 -245
- package/lib/node/wallet.d.ts +37 -0
- package/lib/node/wallet.d.ts.map +1 -1
- package/lib/node/wallet.js +37 -0
- package/package.json +2 -1
- package/src/accounts/basicUserAccountSubscriber.ts +18 -0
- package/src/accounts/basicUserStatsAccountSubscriber.ts +18 -0
- package/src/accounts/bulkAccountLoader.ts +52 -0
- package/src/accounts/bulkUserStatsSubscription.ts +9 -2
- package/src/accounts/bulkUserSubscription.ts +8 -2
- package/src/accounts/customizedCadenceBulkAccountLoader.ts +37 -0
- package/src/accounts/fetch.ts +59 -2
- package/src/accounts/grpcAccountSubscriber.ts +30 -0
- package/src/accounts/grpcInsuranceFundStakeAccountSubscriber.ts +16 -0
- package/src/accounts/grpcMultiAccountSubscriber.ts +121 -38
- package/src/accounts/grpcMultiUserAccountSubscriber.ts +49 -11
- package/src/accounts/grpcProgramAccountSubscriber.ts +33 -0
- package/src/accounts/grpcUserAccountSubscriber.ts +15 -0
- package/src/accounts/grpcUserStatsAccountSubscriber.ts +15 -0
- package/src/accounts/grpcVelocityClientAccountSubscriber.ts +41 -0
- package/src/accounts/grpcVelocityClientAccountSubscriberV2.ts +160 -1
- package/src/accounts/laserProgramAccountSubscriber.ts +34 -0
- package/src/accounts/oneShotUserAccountSubscriber.ts +19 -0
- package/src/accounts/oneShotUserStatsAccountSubscriber.ts +19 -0
- package/src/accounts/pollingInsuranceFundStakeAccountSubscriber.ts +31 -0
- package/src/accounts/pollingOracleAccountSubscriber.ts +21 -2
- package/src/accounts/pollingTokenAccountSubscriber.ts +22 -0
- package/src/accounts/pollingUserAccountSubscriber.ts +32 -0
- package/src/accounts/pollingUserStatsAccountSubscriber.ts +22 -0
- package/src/accounts/pollingVelocityClientAccountSubscriber.ts +84 -1
- package/src/accounts/testBulkAccountLoader.ts +8 -0
- package/src/accounts/types.ts +149 -0
- package/src/accounts/utils.ts +42 -24
- package/src/accounts/webSocketAccountSubscriber.ts +41 -0
- package/src/accounts/webSocketAccountSubscriberV2.ts +31 -23
- package/src/accounts/webSocketInsuranceFundStakeAccountSubscriber.ts +27 -0
- package/src/accounts/webSocketProgramAccountSubscriber.ts +36 -0
- package/src/accounts/webSocketProgramAccountSubscriberV2.ts +26 -0
- package/src/accounts/webSocketProgramAccountsSubscriberV2.ts +21 -0
- package/src/accounts/webSocketUserAccountSubscriber.ts +26 -0
- package/src/accounts/webSocketUserStatsAccountSubsriber.ts +20 -0
- package/src/accounts/webSocketVelocityClientAccountSubscriber.ts +127 -2
- package/src/accounts/webSocketVelocityClientAccountSubscriberV2.ts +110 -0
- package/src/accounts/websocketProgramUserAccountSubscriber.ts +33 -0
- package/src/addresses/marketAddresses.ts +10 -0
- package/src/addresses/pda.ts +228 -12
- package/src/adminClient.ts +2156 -4
- package/src/auctionSubscriber/auctionSubscriber.ts +15 -0
- package/src/auctionSubscriber/auctionSubscriberGrpc.ts +19 -0
- package/src/auctionSubscriber/index.ts +6 -0
- package/src/auctionSubscriber/types.ts +7 -0
- package/src/blockhashSubscriber/BlockhashSubscriber.ts +33 -0
- package/src/blockhashSubscriber/index.ts +5 -0
- package/src/blockhashSubscriber/types.ts +5 -4
- package/src/clock/clockSubscriber.ts +24 -0
- package/src/config.ts +109 -22
- package/src/constants/numericConstants.ts +70 -0
- package/src/constants/perpMarkets.ts +45 -960
- package/src/constants/spotMarkets.ts +23 -793
- package/src/constants/txConstants.ts +1 -0
- package/src/core/VelocityCore.ts +286 -8
- package/src/core/instructions/deposit.ts +22 -0
- package/src/core/instructions/fill.ts +17 -0
- package/src/core/instructions/funding.ts +12 -0
- package/src/core/instructions/liquidation.ts +18 -0
- package/src/core/instructions/orders.ts +28 -0
- package/src/core/instructions/perpOrders.ts +106 -0
- package/src/core/instructions/settlement.ts +14 -0
- package/src/core/instructions/trigger.ts +15 -0
- package/src/core/instructions/withdraw.ts +21 -0
- package/src/core/remainingAccounts.ts +47 -3
- package/src/core/signedMsg.ts +38 -0
- package/src/decode/customCoder.ts +46 -3
- package/src/decode/user.ts +22 -0
- package/src/dlob/DLOB.ts +668 -97
- package/src/dlob/DLOBNode.ts +98 -6
- package/src/dlob/DLOBSubscriber.ts +49 -12
- package/src/dlob/NodeList.ts +69 -0
- package/src/dlob/orderBookLevels.ts +108 -14
- package/src/dlob/types.ts +15 -0
- package/src/events/eventList.ts +14 -0
- package/src/events/eventSubscriber.ts +100 -19
- package/src/events/eventsServerLogProvider.ts +28 -0
- package/src/events/fetchLogs.ts +52 -2
- package/src/events/parse.ts +23 -0
- package/src/events/pollingLogProvider.ts +24 -0
- package/src/events/sort.ts +12 -0
- package/src/events/txEventCache.ts +19 -7
- package/src/events/types.ts +131 -11
- package/src/events/webSocketLogProvider.ts +29 -0
- package/src/factory/oracleClient.ts +2 -2
- package/src/idl/velocity.json +4 -4
- package/src/idl/velocity.ts +4 -4
- package/src/keypair.ts +8 -0
- package/src/marginCalculation.ts +153 -2
- package/src/math/amm.ts +371 -36
- package/src/math/auction.ts +139 -30
- package/src/math/bankruptcy.ts +104 -1
- package/src/math/builder.ts +74 -8
- package/src/math/conversion.ts +21 -0
- package/src/math/exchangeStatus.ts +117 -2
- package/src/math/funding.ts +63 -23
- package/src/math/insurance.ts +62 -0
- package/src/math/liquidation.ts +227 -17
- package/src/math/margin.ts +80 -14
- package/src/math/market.ts +148 -17
- package/src/math/oracles.ts +124 -0
- package/src/math/orders.ts +141 -19
- package/src/math/position.ts +80 -33
- package/src/math/repeg.ts +48 -10
- package/src/math/spotBalance.ts +252 -12
- package/src/math/spotMarket.ts +36 -3
- package/src/math/spotPosition.ts +72 -0
- package/src/math/state.ts +31 -0
- package/src/math/superStake.ts +126 -3
- package/src/math/tiers.ts +29 -0
- package/src/math/trade.ts +125 -55
- package/src/math/utils.ts +71 -9
- package/src/memcmp.ts +104 -2
- package/src/oracles/oracleClientCache.ts +16 -0
- package/src/oracles/oracleId.ts +39 -6
- package/src/oracles/prelaunchOracleClient.ts +20 -0
- package/src/oracles/pythClient.ts +32 -1
- package/src/oracles/pythLazerClient.ts +35 -1
- package/src/oracles/quoteAssetOracleClient.ts +18 -0
- package/src/oracles/strictOraclePrice.ts +21 -0
- package/src/oracles/types.ts +45 -0
- package/src/oracles/utils.ts +20 -0
- package/src/orderParams.ts +42 -4
- package/src/orderSubscriber/OrderSubscriber.ts +56 -0
- package/src/orderSubscriber/PollingSubscription.ts +11 -0
- package/src/orderSubscriber/WebsocketSubscription.ts +18 -0
- package/src/orderSubscriber/grpcSubscription.ts +16 -0
- package/src/orderSubscriber/types.ts +9 -0
- package/src/priorityFee/averageOverSlotsStrategy.ts +1 -0
- package/src/priorityFee/averageStrategy.ts +1 -0
- package/src/priorityFee/ewmaStrategy.ts +10 -0
- package/src/priorityFee/heliusPriorityFeeMethod.ts +13 -2
- package/src/priorityFee/maxOverSlotsStrategy.ts +1 -0
- package/src/priorityFee/maxStrategy.ts +1 -0
- package/src/priorityFee/priorityFeeSubscriber.ts +39 -0
- package/src/priorityFee/priorityFeeSubscriberMap.ts +21 -2
- package/src/priorityFee/solanaPriorityFeeMethod.ts +12 -0
- package/src/priorityFee/types.ts +33 -15
- package/src/priorityFee/velocityPriorityFeeMethod.ts +11 -0
- package/src/slot/SlotSubscriber.ts +18 -0
- package/src/slot/SlothashSubscriber.ts +27 -1
- package/src/tx/baseTxSender.ts +185 -5
- package/src/tx/blockhashFetcher/baseBlockhashFetcher.ts +12 -0
- package/src/tx/blockhashFetcher/cachedBlockhashFetcher.ts +15 -0
- package/src/tx/blockhashFetcher/types.ts +4 -0
- package/src/tx/fastSingleTxSender.ts +58 -4
- package/src/tx/forwardOnlyTxSender.ts +48 -0
- package/src/tx/reportTransactionError.ts +18 -6
- package/src/tx/retryTxSender.ts +40 -0
- package/src/tx/txHandler.ts +146 -35
- package/src/tx/txParamProcessor.ts +47 -0
- package/src/tx/types.ts +46 -0
- package/src/tx/utils.ts +26 -0
- package/src/tx/whileValidTxSender.ts +82 -0
- package/src/types.ts +777 -24
- package/src/user.ts +869 -110
- package/src/userMap/PollingSubscription.ts +16 -2
- package/src/userMap/WebsocketSubscription.ts +9 -0
- package/src/userMap/grpcSubscription.ts +8 -0
- package/src/userMap/referrerMap.ts +92 -3
- package/src/userMap/revenueShareEscrowMap.ts +38 -11
- package/src/userMap/userMap.ts +82 -4
- package/src/userMap/userMapConfig.ts +23 -10
- package/src/userMap/userStatsMap.ts +22 -0
- package/src/userName.ts +16 -0
- package/src/userStats.ts +28 -1
- package/src/util/TransactionConfirmationManager.ts +33 -0
- package/src/util/chainClock.ts +24 -0
- package/src/util/computeUnits.ts +32 -0
- package/src/util/digest.ts +17 -0
- package/src/util/ed25519Utils.ts +12 -2
- package/src/util/promiseTimeout.ts +9 -0
- package/src/velocityClient.ts +3439 -249
- package/src/wallet.ts +37 -0
- package/tests/VelocityCore/builder_escrow.test.ts +121 -0
- package/tests/amm/test.ts +102 -0
- package/tests/builder/builderFee.test.ts +42 -0
- package/tests/dlob/tickSizeStandardization.ts +545 -0
- package/tests/exchangeStatus/test.ts +45 -0
- package/tests/liquidation/test.ts +125 -0
- package/tests/oracles/mmOracleGate.test.ts +379 -0
- package/tests/oracles/pythPegSnap.test.ts +76 -0
- package/tests/sdkParity/enumParity.test.ts +84 -0
- package/tests/sdkParity/marginCategoryFill.test.ts +143 -0
- package/tests/sdkParity/memcmpOffsets.test.ts +139 -0
- package/tests/spot/test.ts +55 -0
- package/tests/user/bankruptcy.ts +165 -0
- package/tests/user/feeAndWithdrawLimits.ts +284 -0
- package/tests/user/getMarginCalculation.ts +226 -1
- package/tests/user/test.ts +8 -4
package/lib/node/user.js
CHANGED
|
@@ -16,6 +16,7 @@ const spotBalance_1 = require("./math/spotBalance");
|
|
|
16
16
|
const trade_1 = require("./math/trade");
|
|
17
17
|
const types_2 = require("./types");
|
|
18
18
|
const orders_1 = require("./math/orders");
|
|
19
|
+
const builder_1 = require("./math/builder");
|
|
19
20
|
const websocketProgramUserAccountSubscriber_1 = require("./accounts/websocketProgramUserAccountSubscriber");
|
|
20
21
|
const spotBalance_2 = require("./math/spotBalance");
|
|
21
22
|
const margin_2 = require("./math/margin");
|
|
@@ -27,13 +28,35 @@ const tiers_1 = require("./math/tiers");
|
|
|
27
28
|
const strictOraclePrice_1 = require("./oracles/strictOraclePrice");
|
|
28
29
|
const grpcUserAccountSubscriber_1 = require("./accounts/grpcUserAccountSubscriber");
|
|
29
30
|
const marginCalculation_1 = require("./marginCalculation");
|
|
31
|
+
/**
|
|
32
|
+
* Ports `get_proportion_u128` (math/helpers.rs) for the referee fee discount
|
|
33
|
+
* calculation. The Rust version routes large operands through a wider U192
|
|
34
|
+
* type purely to avoid u128 overflow; BN has no such ceiling, so that branch
|
|
35
|
+
* is elided here since it produces the same numeric result.
|
|
36
|
+
*/
|
|
37
|
+
function getProportion128(value, numerator, denominator) {
|
|
38
|
+
if (numerator.eq(denominator)) {
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
if (numerator.gt(denominator.div(numericConstants_1.TWO)) && denominator.gt(numerator)) {
|
|
42
|
+
// ceiling division, mirroring standardize_value_with_remainder_i128
|
|
43
|
+
const scaled = value.mul(denominator.sub(numerator));
|
|
44
|
+
const remainder = scaled.mod(denominator);
|
|
45
|
+
const floorDiv = scaled.div(denominator);
|
|
46
|
+
const ceilDiv = remainder.isZero() ? floorDiv : floorDiv.add(numericConstants_1.ONE);
|
|
47
|
+
return value.sub(ceilDiv);
|
|
48
|
+
}
|
|
49
|
+
return value.mul(numerator).div(denominator);
|
|
50
|
+
}
|
|
30
51
|
class User {
|
|
52
|
+
/** True only when both `subscribe()` has completed and the underlying `accountSubscriber` itself reports subscribed. */
|
|
31
53
|
get isSubscribed() {
|
|
32
54
|
return this._isSubscribed && this.accountSubscriber.isSubscribed;
|
|
33
55
|
}
|
|
34
56
|
set isSubscribed(val) {
|
|
35
57
|
this._isSubscribed = val;
|
|
36
58
|
}
|
|
59
|
+
/** 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. */
|
|
37
60
|
constructor(config) {
|
|
38
61
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
39
62
|
this._isSubscribed = false;
|
|
@@ -74,19 +97,22 @@ class User {
|
|
|
74
97
|
this.eventEmitter = this.accountSubscriber.eventEmitter;
|
|
75
98
|
}
|
|
76
99
|
/**
|
|
77
|
-
*
|
|
78
|
-
*
|
|
100
|
+
* Subscribes to this `User` account (websocket/polling/gRPC/custom per
|
|
101
|
+
* `UserConfig.accountSubscription`) and awaits the initial account fetch.
|
|
102
|
+
* Must resolve before any `get*`/margin/PnL accessor is called — those
|
|
103
|
+
* throw `NotSubscribedError` until this has completed.
|
|
104
|
+
* @param userAccount Optional pre-fetched account to seed the subscriber with, skipping the initial RPC fetch.
|
|
105
|
+
* @returns True once the underlying subscriber reports subscribed.
|
|
79
106
|
*/
|
|
80
107
|
async subscribe(userAccount) {
|
|
81
108
|
this.isSubscribed = await this.accountSubscriber.subscribe(userAccount);
|
|
82
109
|
return this.isSubscribed;
|
|
83
110
|
}
|
|
84
|
-
/**
|
|
85
|
-
* Forces the accountSubscriber to fetch account updates from rpc
|
|
86
|
-
*/
|
|
111
|
+
/** Forces the account subscriber to re-fetch the `User` account from RPC (bypassing any push/poll cadence). */
|
|
87
112
|
async fetchAccounts() {
|
|
88
113
|
await this.accountSubscriber.fetch();
|
|
89
114
|
}
|
|
115
|
+
/** Removes all event listeners and tears down the account subscription. */
|
|
90
116
|
async unsubscribe() {
|
|
91
117
|
this.eventEmitter.removeAllListeners();
|
|
92
118
|
await this.accountSubscriber.unsubscribe();
|
|
@@ -96,7 +122,7 @@ class User {
|
|
|
96
122
|
* Returns the cached user account.
|
|
97
123
|
*
|
|
98
124
|
* - **Throws** `NotSubscribedError` if the subscriber has not been subscribed
|
|
99
|
-
* yet — reading the account before
|
|
125
|
+
* yet — reading the account before `subscribe()` resolves is a
|
|
100
126
|
* programming error, not a missing-account condition.
|
|
101
127
|
* - Returns `undefined` when subscribed but no account was found on chain.
|
|
102
128
|
* Because `subscribe()` awaits the initial fetch, an `undefined` here means
|
|
@@ -108,13 +134,14 @@ class User {
|
|
|
108
134
|
return (_a = this.accountSubscriber.getUserAccountAndSlot()) === null || _a === void 0 ? void 0 : _a.data;
|
|
109
135
|
}
|
|
110
136
|
/**
|
|
111
|
-
* Like
|
|
137
|
+
* Like `getUserAccount` but throws instead of returning `undefined`
|
|
112
138
|
* when the account was not found. Use at call sites that structurally
|
|
113
139
|
* require the account to exist. (Still propagates `NotSubscribedError` when
|
|
114
140
|
* called before subscribing.)
|
|
115
141
|
*
|
|
116
|
-
* Delegates to
|
|
142
|
+
* Delegates to `getUserAccount` (rather than the subscriber directly)
|
|
117
143
|
* so callers that override `getUserAccount` see the override here too.
|
|
144
|
+
* @returns The current `UserAccount`.
|
|
118
145
|
*/
|
|
119
146
|
getUserAccountOrThrow() {
|
|
120
147
|
const userAccount = this.getUserAccount();
|
|
@@ -123,16 +150,27 @@ class User {
|
|
|
123
150
|
}
|
|
124
151
|
return userAccount;
|
|
125
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* Bypasses the cached subscriber state and force-fetches the `User` account
|
|
155
|
+
* directly from the RPC (via `fetchAccounts`), then returns the freshly
|
|
156
|
+
* cached value. Useful right after sending a transaction, when the
|
|
157
|
+
* websocket/polling subscriber may not yet have observed the update.
|
|
158
|
+
* @returns The freshly fetched `UserAccount`, or `undefined` if the account does not exist on chain.
|
|
159
|
+
*/
|
|
126
160
|
async forceGetUserAccount() {
|
|
127
161
|
await this.fetchAccounts();
|
|
128
162
|
const account = this.accountSubscriber.getUserAccountAndSlot();
|
|
129
163
|
return account === null || account === void 0 ? void 0 : account.data;
|
|
130
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* Returns the cached user account together with the slot at which it was
|
|
167
|
+
* last observed. Same `undefined`/`NotSubscribedError` contract as `getUserAccount`.
|
|
168
|
+
*/
|
|
131
169
|
getUserAccountAndSlot() {
|
|
132
170
|
return this.accountSubscriber.getUserAccountAndSlot();
|
|
133
171
|
}
|
|
134
172
|
/**
|
|
135
|
-
* Like
|
|
173
|
+
* Like `getUserAccountAndSlot` but throws instead of returning
|
|
136
174
|
* `undefined` when the account was not found. Use at call sites that
|
|
137
175
|
* structurally require the account to exist. (Still propagates
|
|
138
176
|
* `NotSubscribedError` when called before subscribing.)
|
|
@@ -140,6 +178,16 @@ class User {
|
|
|
140
178
|
getUserAccountAndSlotOrThrow() {
|
|
141
179
|
return (0, utils_1.assertDataAndSlot)(this.accountSubscriber.getUserAccountAndSlot(), `User account not found: ${this.getUserAccountPublicKey().toString()}`);
|
|
142
180
|
}
|
|
181
|
+
/**
|
|
182
|
+
* Finds the perp position for `marketIndex` on an explicit `userAccount`
|
|
183
|
+
* snapshot rather than the cached account. Only matches "active" positions
|
|
184
|
+
* (see `getActivePerpPositionsForUserAccount`) — a market the user has never
|
|
185
|
+
* touched (or has fully closed and settled) returns `undefined` even though
|
|
186
|
+
* the on-chain array always has a fixed-size slot for every market.
|
|
187
|
+
* @param userAccount Account snapshot to search (does not have to be the subscribed account).
|
|
188
|
+
* @param marketIndex Perp market index to look up.
|
|
189
|
+
* @returns The matching `PerpPosition`, or `undefined` if the user has no active position in that market.
|
|
190
|
+
*/
|
|
143
191
|
getPerpPositionForUserAccount(userAccount, marketIndex) {
|
|
144
192
|
return this.getActivePerpPositionsForUserAccount(userAccount).find((position) => position.marketIndex === marketIndex);
|
|
145
193
|
}
|
|
@@ -152,11 +200,21 @@ class User {
|
|
|
152
200
|
const userAccount = this.getUserAccountOrThrow();
|
|
153
201
|
return this.getPerpPositionForUserAccount(userAccount, marketIndex);
|
|
154
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* Like `getPerpPosition`, but returns a zeroed-out placeholder position
|
|
205
|
+
* (see `getEmptyPosition`) instead of `undefined` when the user has no
|
|
206
|
+
* active position in `marketIndex`. Convenient for math helpers that need a
|
|
207
|
+
* `PerpPosition` shape unconditionally (e.g. buying-power/leverage calcs).
|
|
208
|
+
*/
|
|
155
209
|
getPerpPositionOrEmpty(marketIndex) {
|
|
156
210
|
var _a;
|
|
157
211
|
const userAccount = this.getUserAccountOrThrow();
|
|
158
212
|
return ((_a = this.getPerpPositionForUserAccount(userAccount, marketIndex)) !== null && _a !== void 0 ? _a : this.getEmptyPosition(marketIndex));
|
|
159
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Like `getPerpPosition`, but throws instead of returning `undefined` when
|
|
216
|
+
* the user has no active position in `marketIndex`.
|
|
217
|
+
*/
|
|
160
218
|
getPerpPositionOrThrow(marketIndex) {
|
|
161
219
|
const position = this.getPerpPosition(marketIndex);
|
|
162
220
|
if (!position) {
|
|
@@ -164,6 +222,10 @@ class User {
|
|
|
164
222
|
}
|
|
165
223
|
return position;
|
|
166
224
|
}
|
|
225
|
+
/**
|
|
226
|
+
* Like `getPerpPosition`, but also returns the slot at which the underlying
|
|
227
|
+
* `UserAccount` was observed.
|
|
228
|
+
*/
|
|
167
229
|
getPerpPositionAndSlot(marketIndex) {
|
|
168
230
|
const userAccount = this.getUserAccountAndSlotOrThrow();
|
|
169
231
|
const perpPosition = this.getPerpPositionForUserAccount(userAccount.data, marketIndex);
|
|
@@ -172,6 +234,14 @@ class User {
|
|
|
172
234
|
slot: userAccount.slot,
|
|
173
235
|
};
|
|
174
236
|
}
|
|
237
|
+
/**
|
|
238
|
+
* Finds the spot position for `marketIndex` on an explicit `userAccount`
|
|
239
|
+
* snapshot. Unlike `getPerpPositionForUserAccount`, this does not filter to
|
|
240
|
+
* "active" positions first — it returns whatever fixed-size slot entry
|
|
241
|
+
* exists for that market index, even if the position is empty/available.
|
|
242
|
+
* @param userAccount Account snapshot to search (does not have to be the subscribed account).
|
|
243
|
+
* @param marketIndex Spot market index to look up.
|
|
244
|
+
*/
|
|
175
245
|
getSpotPositionForUserAccount(userAccount, marketIndex) {
|
|
176
246
|
return userAccount.spotPositions.find((position) => position.marketIndex === marketIndex);
|
|
177
247
|
}
|
|
@@ -184,6 +254,10 @@ class User {
|
|
|
184
254
|
const userAccount = this.getUserAccountOrThrow();
|
|
185
255
|
return this.getSpotPositionForUserAccount(userAccount, marketIndex);
|
|
186
256
|
}
|
|
257
|
+
/**
|
|
258
|
+
* Like `getSpotPosition`, but also returns the slot at which the underlying
|
|
259
|
+
* `UserAccount` was observed.
|
|
260
|
+
*/
|
|
187
261
|
getSpotPositionAndSlot(marketIndex) {
|
|
188
262
|
const userAccount = this.getUserAccountAndSlotOrThrow();
|
|
189
263
|
const spotPosition = this.getSpotPositionForUserAccount(userAccount.data, marketIndex);
|
|
@@ -192,6 +266,7 @@ class User {
|
|
|
192
266
|
slot: userAccount.slot,
|
|
193
267
|
};
|
|
194
268
|
}
|
|
269
|
+
/** Returns a zeroed-out (no deposit/borrow) placeholder `SpotPosition` for `marketIndex`. */
|
|
195
270
|
getEmptySpotPosition(marketIndex) {
|
|
196
271
|
return {
|
|
197
272
|
marketIndex,
|
|
@@ -208,6 +283,7 @@ class User {
|
|
|
208
283
|
* Positive if it is a deposit, negative if it is a borrow.
|
|
209
284
|
*
|
|
210
285
|
* @param marketIndex
|
|
286
|
+
* @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.
|
|
211
287
|
*/
|
|
212
288
|
getTokenAmount(marketIndex) {
|
|
213
289
|
const spotPosition = this.getSpotPosition(marketIndex);
|
|
@@ -217,6 +293,7 @@ class User {
|
|
|
217
293
|
const spotMarket = this.velocityClient.getSpotMarketAccountOrThrow(marketIndex);
|
|
218
294
|
return (0, spotBalance_1.getSignedTokenAmount)((0, spotBalance_2.getTokenAmount)(spotPosition.scaledBalance, spotMarket, spotPosition.balanceType), spotPosition.balanceType);
|
|
219
295
|
}
|
|
296
|
+
/** Returns a zeroed-out placeholder `PerpPosition` for `marketIndex` (no size, no orders, cross margin). */
|
|
220
297
|
getEmptyPosition(marketIndex) {
|
|
221
298
|
return {
|
|
222
299
|
baseAssetAmount: numericConstants_1.ZERO,
|
|
@@ -235,9 +312,18 @@ class User {
|
|
|
235
312
|
positionFlag: 0,
|
|
236
313
|
};
|
|
237
314
|
}
|
|
315
|
+
/** Returns true if `position` has no size and no open orders (a market slot that can be treated as unused). */
|
|
238
316
|
isPositionEmpty(position) {
|
|
239
317
|
return position.baseAssetAmount.eq(numericConstants_1.ZERO) && position.openOrders === 0;
|
|
240
318
|
}
|
|
319
|
+
/**
|
|
320
|
+
* Returns the isolated-margin quote deposit backing a given perp position,
|
|
321
|
+
* i.e. `PerpPosition.isolatedPositionScaledBalance` converted to a token
|
|
322
|
+
* amount. This is the collateral segregated to that single isolated
|
|
323
|
+
* position, separate from the user's cross-margin free collateral.
|
|
324
|
+
* @param perpMarketIndex
|
|
325
|
+
* @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.
|
|
326
|
+
*/
|
|
241
327
|
getIsolatePerpPositionTokenAmount(perpMarketIndex) {
|
|
242
328
|
var _a;
|
|
243
329
|
const perpPosition = this.getPerpPosition(perpMarketIndex);
|
|
@@ -253,6 +339,7 @@ class User {
|
|
|
253
339
|
}
|
|
254
340
|
/**
|
|
255
341
|
* Returns the total USD value of deposits across all isolated perp positions.
|
|
342
|
+
* @returns Precision QUOTE_PRECISION (1e6).
|
|
256
343
|
*/
|
|
257
344
|
getTotalIsolatedPositionDeposits() {
|
|
258
345
|
return this.getActivePerpPositions().reduce((total, perpPosition) => {
|
|
@@ -268,21 +355,25 @@ class User {
|
|
|
268
355
|
return total.add((0, spotBalance_1.getStrictTokenValue)(tokenAmount, quoteSpotMarket.decimals, strictOracle));
|
|
269
356
|
}, numericConstants_1.ZERO);
|
|
270
357
|
}
|
|
358
|
+
/** Returns a shallow copy of `position`. Mutating the clone does not affect the cached account. */
|
|
271
359
|
getClonedPosition(position) {
|
|
272
360
|
const clonedPosition = Object.assign({}, position);
|
|
273
361
|
return clonedPosition;
|
|
274
362
|
}
|
|
363
|
+
/** Finds an order by its program-assigned `orderId` on an explicit `userAccount` snapshot. */
|
|
275
364
|
getOrderForUserAccount(userAccount, orderId) {
|
|
276
365
|
return userAccount.orders.find((order) => order.orderId === orderId);
|
|
277
366
|
}
|
|
278
367
|
/**
|
|
368
|
+
* Finds an order in the cached `UserAccount` by its program-assigned `orderId`.
|
|
279
369
|
* @param orderId
|
|
280
|
-
* @returns Order
|
|
370
|
+
* @returns The matching `Order`, or `undefined` if no order with that id exists.
|
|
281
371
|
*/
|
|
282
372
|
getOrder(orderId) {
|
|
283
373
|
const userAccount = this.getUserAccountOrThrow();
|
|
284
374
|
return this.getOrderForUserAccount(userAccount, orderId);
|
|
285
375
|
}
|
|
376
|
+
/** Like `getOrder`, but also returns the slot at which the underlying `UserAccount` was observed. */
|
|
286
377
|
getOrderAndSlot(orderId) {
|
|
287
378
|
const userAccount = this.getUserAccountAndSlotOrThrow();
|
|
288
379
|
const order = this.getOrderForUserAccount(userAccount.data, orderId);
|
|
@@ -291,17 +382,25 @@ class User {
|
|
|
291
382
|
slot: userAccount.slot,
|
|
292
383
|
};
|
|
293
384
|
}
|
|
385
|
+
/**
|
|
386
|
+
* Finds an order by its caller-assigned `userOrderId` (a client-chosen tag,
|
|
387
|
+
* distinct from the program-assigned `orderId`) on an explicit `userAccount`
|
|
388
|
+
* snapshot.
|
|
389
|
+
*/
|
|
294
390
|
getOrderByUserIdForUserAccount(userAccount, userOrderId) {
|
|
295
391
|
return userAccount.orders.find((order) => order.userOrderId === userOrderId);
|
|
296
392
|
}
|
|
297
393
|
/**
|
|
394
|
+
* Finds an order in the cached `UserAccount` by its caller-assigned
|
|
395
|
+
* `userOrderId` (a client-chosen tag, distinct from the program-assigned `orderId`).
|
|
298
396
|
* @param userOrderId
|
|
299
|
-
* @returns Order
|
|
397
|
+
* @returns The matching `Order`, or `undefined` if no order with that tag exists.
|
|
300
398
|
*/
|
|
301
399
|
getOrderByUserOrderId(userOrderId) {
|
|
302
400
|
const userAccount = this.getUserAccountOrThrow();
|
|
303
401
|
return this.getOrderByUserIdForUserAccount(userAccount, userOrderId);
|
|
304
402
|
}
|
|
403
|
+
/** Like `getOrderByUserOrderId`, but also returns the slot at which the underlying `UserAccount` was observed. */
|
|
305
404
|
getOrderByUserOrderIdAndSlot(userOrderId) {
|
|
306
405
|
const userAccount = this.getUserAccountAndSlotOrThrow();
|
|
307
406
|
const order = this.getOrderByUserIdForUserAccount(userAccount.data, userOrderId);
|
|
@@ -310,14 +409,21 @@ class User {
|
|
|
310
409
|
slot: userAccount.slot,
|
|
311
410
|
};
|
|
312
411
|
}
|
|
412
|
+
/**
|
|
413
|
+
* Filters an explicit `userAccount` snapshot's orders down to those with
|
|
414
|
+
* `OrderStatus.Open`.
|
|
415
|
+
* @returns `undefined` if `userAccount` is `undefined` (i.e. no account loaded), otherwise the array of open orders (possibly empty).
|
|
416
|
+
*/
|
|
313
417
|
getOpenOrdersForUserAccount(userAccount) {
|
|
314
418
|
return userAccount === null || userAccount === void 0 ? void 0 : userAccount.orders.filter((order) => (0, types_1.isVariant)(order.status, 'open'));
|
|
315
419
|
}
|
|
420
|
+
/** Returns all of the user's orders with `OrderStatus.Open`. Empty array (not `undefined`) if there are none or no account is loaded. */
|
|
316
421
|
getOpenOrders() {
|
|
317
422
|
var _a;
|
|
318
423
|
const userAccount = this.getUserAccount();
|
|
319
424
|
return (_a = this.getOpenOrdersForUserAccount(userAccount)) !== null && _a !== void 0 ? _a : [];
|
|
320
425
|
}
|
|
426
|
+
/** Like `getOpenOrders`, but also returns the slot at which the underlying `UserAccount` was observed. */
|
|
321
427
|
getOpenOrdersAndSlot() {
|
|
322
428
|
var _a;
|
|
323
429
|
const userAccount = this.getUserAccountAndSlotOrThrow();
|
|
@@ -327,17 +433,19 @@ class User {
|
|
|
327
433
|
slot: userAccount.slot,
|
|
328
434
|
};
|
|
329
435
|
}
|
|
436
|
+
/** Returns this `User`'s account address (does not require the account to be subscribed or to exist on chain). */
|
|
330
437
|
getUserAccountPublicKey() {
|
|
331
438
|
return this.userAccountPublicKey;
|
|
332
439
|
}
|
|
440
|
+
/** Checks directly via RPC (bypassing the subscriber cache) whether the `User` account exists on chain. */
|
|
333
441
|
async exists() {
|
|
334
442
|
const userAccountRPCResponse = await this.velocityClient.connection.getParsedAccountInfo(this.userAccountPublicKey);
|
|
335
443
|
return userAccountRPCResponse.value !== null;
|
|
336
444
|
}
|
|
337
445
|
/**
|
|
338
|
-
*
|
|
339
|
-
* @
|
|
340
|
-
* @returns
|
|
446
|
+
* Returns the position's total resting open-order bid/ask size in a perp market.
|
|
447
|
+
* @param marketIndex
|
|
448
|
+
* @returns Tuple of `[openBids, openAsks]`, both `BASE_PRECISION` (1e9). Throws (via `getPerpPositionOrThrow`) if the user has no active position in `marketIndex`.
|
|
341
449
|
*/
|
|
342
450
|
getPerpBidAsks(marketIndex) {
|
|
343
451
|
const position = this.getPerpPositionOrThrow(marketIndex);
|
|
@@ -347,7 +455,17 @@ class User {
|
|
|
347
455
|
}
|
|
348
456
|
/**
|
|
349
457
|
* calculates Buying Power = free collateral / initial margin ratio
|
|
350
|
-
*
|
|
458
|
+
*
|
|
459
|
+
* For `positionType: 'isolated'`, the buying power is capped by the
|
|
460
|
+
* lesser of (a) the user's cross free collateral and (b) the free quote
|
|
461
|
+
* asset value in the perp's quote spot market — mirroring that an isolated
|
|
462
|
+
* position can only draw down as much quote collateral as is actually
|
|
463
|
+
* available to isolate into it.
|
|
464
|
+
* @param marketIndex Perp market to size buying power for.
|
|
465
|
+
* @param collateralBuffer Amount (QUOTE_PRECISION) subtracted from free collateral before sizing, e.g. to reserve for fees. Defaults to zero.
|
|
466
|
+
* @param maxMarginRatio Optional override for the max margin ratio component (see `resolveMaxMarginRatio`); defaults to the position's/user's configured ratio.
|
|
467
|
+
* @param positionType Whether to size for a cross or isolated-margin position. Defaults to `'cross'`.
|
|
468
|
+
* @returns Precision QUOTE_PRECISION (1e6).
|
|
351
469
|
*/
|
|
352
470
|
getPerpBuyingPower(marketIndex, collateralBuffer = numericConstants_1.ZERO, maxMarginRatio = undefined, positionType = 'cross') {
|
|
353
471
|
const perpPosition = this.getPerpPositionOrEmpty(marketIndex);
|
|
@@ -375,6 +493,17 @@ class User {
|
|
|
375
493
|
// userAccount.maxMarginRatio unchanged — the expected semantic.
|
|
376
494
|
return Math.max(perpMarketMaxMarginRatio !== null && perpMarketMaxMarginRatio !== void 0 ? perpMarketMaxMarginRatio : 0, this.getUserAccountOrThrow().maxMarginRatio);
|
|
377
495
|
}
|
|
496
|
+
/**
|
|
497
|
+
* Converts a free-collateral amount directly into buying power for a perp
|
|
498
|
+
* market, given the (hypothetical) resulting base position size — used
|
|
499
|
+
* internally so the margin ratio (which can vary with position size via the
|
|
500
|
+
* IMF factor) reflects the post-trade size rather than the current size.
|
|
501
|
+
* @param marketIndex
|
|
502
|
+
* @param freeCollateral QUOTE_PRECISION (1e6).
|
|
503
|
+
* @param baseAssetAmount Base size, BASE_PRECISION (1e9), used only to select the applicable margin ratio.
|
|
504
|
+
* @param perpMarketMaxMarginRatio Optional max-margin-ratio override, see `resolveMaxMarginRatio`.
|
|
505
|
+
* @returns Precision QUOTE_PRECISION (1e6).
|
|
506
|
+
*/
|
|
378
507
|
getPerpBuyingPowerFromFreeCollateralAndBaseAssetAmount(marketIndex, freeCollateral, baseAssetAmount, perpMarketMaxMarginRatio = undefined) {
|
|
379
508
|
const maxMarginRatio = this.resolveMaxMarginRatio(perpMarketMaxMarginRatio);
|
|
380
509
|
const marginRatio = (0, market_1.calculateMarketMarginRatio)(this.velocityClient.getPerpMarketAccountOrThrow(marketIndex), baseAssetAmount, 'Initial', maxMarginRatio);
|
|
@@ -382,7 +511,15 @@ class User {
|
|
|
382
511
|
}
|
|
383
512
|
/**
|
|
384
513
|
* calculates Free Collateral = Total collateral - margin requirement
|
|
385
|
-
*
|
|
514
|
+
*
|
|
515
|
+
* When `perpMarketIndex` is provided, returns the free collateral scoped to
|
|
516
|
+
* that market's isolated margin bucket (the isolated quote deposit plus its
|
|
517
|
+
* unrealized PnL, minus its own margin requirement) rather than the user's
|
|
518
|
+
* cross-margin free collateral. If the user has no isolated position open in
|
|
519
|
+
* that market, returns `ZERO` rather than throwing.
|
|
520
|
+
* @param marginCategory `'Initial'` or `'Maintenance'`. Defaults to `'Initial'`; `'Initial'` also enables strict (TWAP-bounded) oracle pricing.
|
|
521
|
+
* @param perpMarketIndex Optional isolated perp market to scope the calculation to; omit for cross margin.
|
|
522
|
+
* @returns Precision QUOTE_PRECISION (1e6). Can be negative (deficit).
|
|
386
523
|
*/
|
|
387
524
|
getFreeCollateral(marginCategory = 'Initial', perpMarketIndex) {
|
|
388
525
|
const calc = this.getMarginCalculation(marginCategory, {
|
|
@@ -432,19 +569,35 @@ class User {
|
|
|
432
569
|
return marginCalc.marginRequirement;
|
|
433
570
|
}
|
|
434
571
|
/**
|
|
435
|
-
*
|
|
572
|
+
* Initial margin requirement — the collateral needed to open/maintain a
|
|
573
|
+
* position at initial (as opposed to maintenance) margin ratios, using
|
|
574
|
+
* strict (TWAP-bounded) oracle pricing. This is what gates new orders and
|
|
575
|
+
* increases in leverage.
|
|
576
|
+
* @param perpMarketIndex Optional isolated perp market to scope to; omit for the cross-margin requirement.
|
|
577
|
+
* @returns The initial margin requirement in USDC. : QUOTE_PRECISION (1e6)
|
|
436
578
|
*/
|
|
437
579
|
getInitialMarginRequirement(perpMarketIndex) {
|
|
438
580
|
return this.getMarginRequirement('Initial', undefined, true, undefined, perpMarketIndex);
|
|
439
581
|
}
|
|
440
582
|
/**
|
|
441
|
-
*
|
|
583
|
+
* Maintenance margin requirement — the minimum collateral below which the
|
|
584
|
+
* position becomes eligible for liquidation. Uses non-strict oracle pricing
|
|
585
|
+
* and includes open orders' worst-case impact by default.
|
|
586
|
+
* @param liquidationBuffer Optional buffer (MARGIN_PRECISION, 1e4) added to the margin ratio, mirroring the state account's `liquidationMarginBufferRatio`.
|
|
587
|
+
* @param perpMarketIndex Optional isolated perp market to scope to; omit for the cross-margin requirement.
|
|
588
|
+
* @returns The maintenance margin requirement in USDC. : QUOTE_PRECISION (1e6)
|
|
442
589
|
*/
|
|
443
590
|
getMaintenanceMarginRequirement(liquidationBuffer, perpMarketIndex) {
|
|
444
591
|
return this.getMarginRequirement('Maintenance', liquidationBuffer, false, // strict default
|
|
445
592
|
true, // includeOpenOrders default
|
|
446
593
|
perpMarketIndex);
|
|
447
594
|
}
|
|
595
|
+
/**
|
|
596
|
+
* Filters an explicit `userAccount` snapshot's fixed-size perp position
|
|
597
|
+
* array down to slots that are actually "active": nonzero base or quote
|
|
598
|
+
* amount, an outstanding open order count, or a nonzero isolated-margin
|
|
599
|
+
* quote deposit (a position can be flat but still isolated-funded).
|
|
600
|
+
*/
|
|
448
601
|
getActivePerpPositionsForUserAccount(userAccount) {
|
|
449
602
|
return userAccount.perpPositions.filter((pos) => {
|
|
450
603
|
var _a;
|
|
@@ -454,10 +607,12 @@ class User {
|
|
|
454
607
|
((_a = pos.isolatedPositionScaledBalance) === null || _a === void 0 ? void 0 : _a.gt(numericConstants_1.ZERO));
|
|
455
608
|
});
|
|
456
609
|
}
|
|
610
|
+
/** Returns the cached account's active perp positions. See `getActivePerpPositionsForUserAccount` for the activity criteria. */
|
|
457
611
|
getActivePerpPositions() {
|
|
458
612
|
const userAccount = this.getUserAccountOrThrow();
|
|
459
613
|
return this.getActivePerpPositionsForUserAccount(userAccount);
|
|
460
614
|
}
|
|
615
|
+
/** Like `getActivePerpPositions`, but also returns the slot at which the underlying `UserAccount` was observed. */
|
|
461
616
|
getActivePerpPositionsAndSlot() {
|
|
462
617
|
const userAccount = this.getUserAccountAndSlotOrThrow();
|
|
463
618
|
const positions = this.getActivePerpPositionsForUserAccount(userAccount.data);
|
|
@@ -466,13 +621,16 @@ class User {
|
|
|
466
621
|
slot: userAccount.slot,
|
|
467
622
|
};
|
|
468
623
|
}
|
|
624
|
+
/** Filters an explicit `userAccount` snapshot's spot positions to those that are not `isSpotPositionAvailable` (i.e. have a nonzero balance, orders, or cumulative deposits). */
|
|
469
625
|
getActiveSpotPositionsForUserAccount(userAccount) {
|
|
470
626
|
return userAccount.spotPositions.filter((pos) => !(0, spotPosition_1.isSpotPositionAvailable)(pos));
|
|
471
627
|
}
|
|
628
|
+
/** Returns the cached account's active spot positions. See `getActiveSpotPositionsForUserAccount` for the activity criteria. */
|
|
472
629
|
getActiveSpotPositions() {
|
|
473
630
|
const userAccount = this.getUserAccountOrThrow();
|
|
474
631
|
return this.getActiveSpotPositionsForUserAccount(userAccount);
|
|
475
632
|
}
|
|
633
|
+
/** Like `getActiveSpotPositions`, but also returns the slot at which the underlying `UserAccount` was observed. */
|
|
476
634
|
getActiveSpotPositionsAndSlot() {
|
|
477
635
|
const userAccount = this.getUserAccountAndSlotOrThrow();
|
|
478
636
|
const positions = this.getActiveSpotPositionsForUserAccount(userAccount.data);
|
|
@@ -482,8 +640,25 @@ class User {
|
|
|
482
640
|
};
|
|
483
641
|
}
|
|
484
642
|
/**
|
|
485
|
-
*
|
|
486
|
-
*
|
|
643
|
+
* Calculates unrealized position price PnL, summed across all active perp
|
|
644
|
+
* positions (or a single one if `marketIndex` is given).
|
|
645
|
+
*
|
|
646
|
+
* When `withWeightMarginCategory` is supplied, the PnL is asset-weighted
|
|
647
|
+
* for margin purposes: profitable positions are scaled down by
|
|
648
|
+
* `calculateUnrealizedAssetWeight` (an unrealized gain is a less-trusted
|
|
649
|
+
* asset than settled collateral), and — for `'Initial'` margin specifically
|
|
650
|
+
* — the *per-position* weighted gain is additionally capped at
|
|
651
|
+
* `MAX_POSITIVE_UPNL_FOR_INITIAL_MARGIN` (**$100**, QUOTE_PRECISION), a
|
|
652
|
+
* safety guard against a single dangerously-configured or manipulated
|
|
653
|
+
* market inflating buying power. Losses are never capped, and a
|
|
654
|
+
* `liquidationBuffer` (if provided) further inflates negative PnL to
|
|
655
|
+
* mirror the on-chain liquidation-buffer treatment.
|
|
656
|
+
* @param withFunding If true, includes unsettled funding in each position's PnL.
|
|
657
|
+
* @param marketIndex Optional single perp market to scope to; omit to sum across all active positions.
|
|
658
|
+
* @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.
|
|
659
|
+
* @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.
|
|
660
|
+
* @param liquidationBuffer Optional buffer (MARGIN_PRECISION, 1e4) that further penalizes negative PnL; only applied when `withWeightMarginCategory` is set.
|
|
661
|
+
* @returns : Precision QUOTE_PRECISION (1e6)
|
|
487
662
|
*/
|
|
488
663
|
getUnrealizedPNL(withFunding, marketIndex, withWeightMarginCategory, strict = false, liquidationBuffer) {
|
|
489
664
|
return this.getActivePerpPositions()
|
|
@@ -513,6 +688,10 @@ class User {
|
|
|
513
688
|
.mul((0, market_1.calculateUnrealizedAssetWeight)(market, quoteSpotMarket, positionUnrealizedPnl, withWeightMarginCategory, oraclePriceData))
|
|
514
689
|
.div(new anchor_1.BN(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION));
|
|
515
690
|
}
|
|
691
|
+
if (withWeightMarginCategory === 'Initial') {
|
|
692
|
+
// safety guard for dangerously configured perp market
|
|
693
|
+
positionUnrealizedPnl = anchor_1.BN.min(positionUnrealizedPnl, numericConstants_1.MAX_POSITIVE_UPNL_FOR_INITIAL_MARGIN);
|
|
694
|
+
}
|
|
516
695
|
if (liquidationBuffer && positionUnrealizedPnl.lt(numericConstants_1.ZERO)) {
|
|
517
696
|
positionUnrealizedPnl = positionUnrealizedPnl.add(positionUnrealizedPnl.mul(liquidationBuffer).div(numericConstants_1.MARGIN_PRECISION));
|
|
518
697
|
}
|
|
@@ -521,8 +700,11 @@ class User {
|
|
|
521
700
|
}, numericConstants_1.ZERO);
|
|
522
701
|
}
|
|
523
702
|
/**
|
|
524
|
-
*
|
|
525
|
-
*
|
|
703
|
+
* Calculates unrealized funding payment PnL — the funding accrued since
|
|
704
|
+
* each position's `lastCumulativeFundingRate` was last settled, not yet
|
|
705
|
+
* reflected in `quoteAssetAmount`.
|
|
706
|
+
* @param marketIndex Optional single perp market to scope to; omit to sum across all positions.
|
|
707
|
+
* @returns : Precision QUOTE_PRECISION (1e6)
|
|
526
708
|
*/
|
|
527
709
|
getUnrealizedFundingPNL(marketIndex) {
|
|
528
710
|
return this.getUserAccountOrThrow()
|
|
@@ -532,6 +714,20 @@ class User {
|
|
|
532
714
|
return pnl.add((0, position_1.calculateUnsettledFundingPnl)(market, perpPosition));
|
|
533
715
|
}, numericConstants_1.ZERO);
|
|
534
716
|
}
|
|
717
|
+
/**
|
|
718
|
+
* Computes the combined weighted asset value and weighted liability value
|
|
719
|
+
* across the user's spot positions (worst-case, including open-order
|
|
720
|
+
* exposure by default), plus the net quote balance. This is the core spot
|
|
721
|
+
* side of the margin system that `getTotalCollateral`/`getMarginRequirement`
|
|
722
|
+
* build on.
|
|
723
|
+
* @param marketIndex Optional single spot market to scope to; omit to sum across all spot markets.
|
|
724
|
+
* @param marginCategory `'Initial'` or `'Maintenance'` asset/liability weights; omit for unweighted (100%) values.
|
|
725
|
+
* @param liquidationBuffer Optional buffer (MARGIN_PRECISION, 1e4) added to the liability weight side.
|
|
726
|
+
* @param includeOpenOrders If false, ignores open bids/asks and only counts the current balance (faster, less conservative).
|
|
727
|
+
* @param strict Use the worse of live oracle price vs 5-minute TWAP. Defaults to false.
|
|
728
|
+
* @param now Unix timestamp (seconds) used for TWAP staleness when `strict` is set; defaults to current time.
|
|
729
|
+
* @returns `{ totalAssetValue, totalLiabilityValue }`, both QUOTE_PRECISION (1e6) and non-negative.
|
|
730
|
+
*/
|
|
535
731
|
getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, liquidationBuffer, includeOpenOrders, strict = false, now) {
|
|
536
732
|
now = now || new anchor_1.BN(new Date().getTime() / 1000);
|
|
537
733
|
let netQuoteValue = numericConstants_1.ZERO;
|
|
@@ -616,24 +812,35 @@ class User {
|
|
|
616
812
|
}
|
|
617
813
|
return { totalAssetValue, totalLiabilityValue };
|
|
618
814
|
}
|
|
815
|
+
/** Convenience wrapper around `getSpotMarketAssetAndLiabilityValue` returning only `totalLiabilityValue`. See that method for parameter semantics. Returns QUOTE_PRECISION (1e6). */
|
|
619
816
|
getSpotMarketLiabilityValue(marketIndex, marginCategory, liquidationBuffer, includeOpenOrders, strict = false, now) {
|
|
620
817
|
const { totalLiabilityValue } = this.getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, liquidationBuffer, includeOpenOrders, strict, now);
|
|
621
818
|
return totalLiabilityValue;
|
|
622
819
|
}
|
|
820
|
+
/** Thin wrapper around the `math/spotBalance` `getSpotLiabilityValue` helper that supplies the user's `maxMarginRatio`. Returns QUOTE_PRECISION (1e6), negative. */
|
|
623
821
|
getSpotLiabilityValue(tokenAmount, strictOraclePrice, spotMarketAccount, marginCategory, liquidationBuffer) {
|
|
624
822
|
return (0, spotBalance_2.getSpotLiabilityValue)(tokenAmount, strictOraclePrice, spotMarketAccount, this.getUserAccountOrThrow().maxMarginRatio, marginCategory, liquidationBuffer);
|
|
625
823
|
}
|
|
824
|
+
/** Convenience wrapper around `getSpotMarketAssetAndLiabilityValue` returning only `totalAssetValue`. See that method for parameter semantics. Returns QUOTE_PRECISION (1e6), non-negative. */
|
|
626
825
|
getSpotMarketAssetValue(marketIndex, marginCategory, includeOpenOrders, strict = false, now) {
|
|
627
826
|
const { totalAssetValue } = this.getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, undefined, includeOpenOrders, strict, now);
|
|
628
827
|
return totalAssetValue;
|
|
629
828
|
}
|
|
829
|
+
/** Thin wrapper around the `math/spotBalance` `getSpotAssetValue` helper that supplies the user's `maxMarginRatio`. Returns QUOTE_PRECISION (1e6), non-negative. */
|
|
630
830
|
getSpotAssetValue(tokenAmount, strictOraclePrice, spotMarketAccount, marginCategory) {
|
|
631
831
|
return (0, spotBalance_2.getSpotAssetValue)(tokenAmount, strictOraclePrice, spotMarketAccount, this.getUserAccountOrThrow().maxMarginRatio, marginCategory);
|
|
632
832
|
}
|
|
833
|
+
/** Net spot value (`totalAssetValue - totalLiabilityValue`) for a single spot market. See `getSpotMarketAssetAndLiabilityValue` for parameter semantics. Returns QUOTE_PRECISION (1e6), can be negative. */
|
|
633
834
|
getSpotPositionValue(marketIndex, marginCategory, includeOpenOrders, strict = false, now) {
|
|
634
835
|
const { totalAssetValue, totalLiabilityValue } = this.getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, undefined, includeOpenOrders, strict, now);
|
|
635
836
|
return totalAssetValue.sub(totalLiabilityValue);
|
|
636
837
|
}
|
|
838
|
+
/**
|
|
839
|
+
* Net spot value (`totalAssetValue - totalLiabilityValue`) across all spot
|
|
840
|
+
* markets combined.
|
|
841
|
+
* @param withWeightMarginCategory Optional `'Initial'`/`'Maintenance'` weighting; omit for unweighted values.
|
|
842
|
+
* @returns Precision QUOTE_PRECISION (1e6), can be negative.
|
|
843
|
+
*/
|
|
637
844
|
getNetSpotMarketValue(withWeightMarginCategory) {
|
|
638
845
|
const { totalAssetValue, totalLiabilityValue } = this.getSpotMarketAssetAndLiabilityValue(undefined, withWeightMarginCategory);
|
|
639
846
|
return totalAssetValue.sub(totalLiabilityValue);
|
|
@@ -642,6 +849,24 @@ class User {
|
|
|
642
849
|
* calculates TotalCollateral: collateral + unrealized pnl
|
|
643
850
|
* @returns : Precision QUOTE_PRECISION
|
|
644
851
|
*/
|
|
852
|
+
/**
|
|
853
|
+
* Calculates Total Collateral: net spot collateral value plus weighted
|
|
854
|
+
* unrealized perp PnL (see `getUnrealizedPNL`'s `$100`-per-position cap
|
|
855
|
+
* under `'Initial'` margin). This is the numerator side of the margin
|
|
856
|
+
* system; `getFreeCollateral`/`getMarginRequirement` are derived from it.
|
|
857
|
+
*
|
|
858
|
+
* When `perpMarketIndex` is provided, returns the isolated total collateral
|
|
859
|
+
* for that market's isolated position bucket instead of the cross-margin
|
|
860
|
+
* total — and **throws** if the user has no isolated margin calculation for
|
|
861
|
+
* that market (unlike `getFreeCollateral`, which swallows the same case and
|
|
862
|
+
* returns `ZERO`).
|
|
863
|
+
* @param marginCategory `'Initial'` or `'Maintenance'`. Defaults to `'Initial'`.
|
|
864
|
+
* @param strict Use TWAP-bounded oracle pricing. Defaults to false.
|
|
865
|
+
* @param includeOpenOrders Include open orders' worst-case impact. Defaults to true.
|
|
866
|
+
* @param liquidationBuffer Optional buffer (MARGIN_PRECISION, 1e4); selects the buffered collateral variant when non-zero.
|
|
867
|
+
* @param perpMarketIndex Optional isolated perp market to scope to.
|
|
868
|
+
* @returns Precision QUOTE_PRECISION (1e6).
|
|
869
|
+
*/
|
|
645
870
|
getTotalCollateral(marginCategory = 'Initial', strict = false, includeOpenOrders = true, liquidationBuffer, perpMarketIndex) {
|
|
646
871
|
const liquidationBufferMap = (() => {
|
|
647
872
|
if (liquidationBuffer && perpMarketIndex !== undefined) {
|
|
@@ -673,6 +898,15 @@ class User {
|
|
|
673
898
|
}
|
|
674
899
|
return marginCalc.totalCollateral;
|
|
675
900
|
}
|
|
901
|
+
/**
|
|
902
|
+
* Builds the liquidation-buffer map to pass into margin calculations while
|
|
903
|
+
* a liquidation is in progress: `'cross'` is set to the state account's
|
|
904
|
+
* `liquidationMarginBufferRatio` if cross margin is being liquidated, and
|
|
905
|
+
* each isolated perp position currently flagged `BeingLiquidated` or
|
|
906
|
+
* `Bankruptcy` gets the same buffer under its market index. Positions not
|
|
907
|
+
* currently being liquidated are omitted (no buffer applied).
|
|
908
|
+
* @returns Map from `'cross'` or a perp market index to the buffer amount (MARGIN_PRECISION, 1e4).
|
|
909
|
+
*/
|
|
676
910
|
getLiquidationBuffer() {
|
|
677
911
|
const liquidationBufferMap = new Map();
|
|
678
912
|
if (this.isBeingLiquidated()) {
|
|
@@ -687,8 +921,19 @@ class User {
|
|
|
687
921
|
return liquidationBufferMap;
|
|
688
922
|
}
|
|
689
923
|
/**
|
|
690
|
-
*
|
|
691
|
-
*
|
|
924
|
+
* Calculates a user's health score by comparing total collateral against
|
|
925
|
+
* the maintenance margin requirement: `100 * (1 - maintenanceMarginReq / totalCollateral)`,
|
|
926
|
+
* clamped to `[0, 100]` and rounded to the nearest integer. `100` means no
|
|
927
|
+
* maintenance requirement (or a requirement of zero with non-negative
|
|
928
|
+
* collateral); `0` means at or past the maintenance threshold (liquidatable)
|
|
929
|
+
* or that collateral is non-positive.
|
|
930
|
+
*
|
|
931
|
+
* Short-circuits to `0` if the relevant scope is already flagged as being
|
|
932
|
+
* liquidated: cross margin via `isCrossMarginBeingLiquidated` (when
|
|
933
|
+
* `perpMarketIndex` is omitted), or the specific isolated position via
|
|
934
|
+
* `isIsolatedPositionBeingLiquidated` (when `perpMarketIndex` is given).
|
|
935
|
+
* @param perpMarketIndex Optional isolated perp market to scope health to; omit for the cross-margin account's health.
|
|
936
|
+
* @returns Health, an integer in `[0, 100]`.
|
|
692
937
|
*/
|
|
693
938
|
getHealth(perpMarketIndex) {
|
|
694
939
|
if (this.isCrossMarginBeingLiquidated() && !perpMarketIndex) {
|
|
@@ -725,6 +970,15 @@ class User {
|
|
|
725
970
|
}
|
|
726
971
|
return health;
|
|
727
972
|
}
|
|
973
|
+
/**
|
|
974
|
+
* Computes a single perp position's margin-weighted liability value: worst-case
|
|
975
|
+
* (or current, if `includeOpenOrders` is false) base amount, valued at the
|
|
976
|
+
* oracle price (or `expiryPrice` if the market is in settlement, which also
|
|
977
|
+
* zeroes the margin ratio), scaled by the applicable margin ratio for
|
|
978
|
+
* `marginCategory`. Underlies `getPerpMarketLiabilityValue`,
|
|
979
|
+
* `getTotalPerpPositionLiability`, and the leverage/liquidation-price math.
|
|
980
|
+
* @returns Precision QUOTE_PRECISION (1e6); unweighted (raw notional, no margin ratio applied) if `marginCategory` is omitted.
|
|
981
|
+
*/
|
|
728
982
|
calculateWeightedPerpPositionLiability(perpPosition, marginCategory, liquidationBuffer, includeOpenOrders, strict = false) {
|
|
729
983
|
const market = this.velocityClient.getPerpMarketAccountOrThrow(perpPosition.marketIndex);
|
|
730
984
|
let valuationPrice = this.getOracleDataForPerpMarket(market.marketIndex).price;
|
|
@@ -772,16 +1026,28 @@ class User {
|
|
|
772
1026
|
return liabilityValue;
|
|
773
1027
|
}
|
|
774
1028
|
/**
|
|
775
|
-
*
|
|
776
|
-
*
|
|
1029
|
+
* Margin-weighted liability value of a single perp position. Thin wrapper
|
|
1030
|
+
* around `calculateWeightedPerpPositionLiability` for the position in
|
|
1031
|
+
* `marketIndex`; see that method for the worst-case/margin-ratio semantics.
|
|
1032
|
+
* @param marketIndex
|
|
1033
|
+
* @param marginCategory `'Initial'`/`'Maintenance'` margin ratio to apply; omit for the raw unweighted notional.
|
|
1034
|
+
* @param liquidationBuffer Optional buffer (MARGIN_PRECISION, 1e4) added to the margin ratio.
|
|
1035
|
+
* @param includeOpenOrders If true (recommended for margin checks), uses the worst-case base amount including open bids/asks.
|
|
1036
|
+
* @param strict Use TWAP-bounded quote pricing. Defaults to false.
|
|
1037
|
+
* @returns Precision QUOTE_PRECISION (1e6). Throws (via `getPerpPositionOrThrow`) if the user has no active position in `marketIndex`.
|
|
777
1038
|
*/
|
|
778
1039
|
getPerpMarketLiabilityValue(marketIndex, marginCategory, liquidationBuffer, includeOpenOrders, strict = false) {
|
|
779
1040
|
const perpPosition = this.getPerpPositionOrThrow(marketIndex);
|
|
780
1041
|
return this.calculateWeightedPerpPositionLiability(perpPosition, marginCategory, liquidationBuffer, includeOpenOrders, strict);
|
|
781
1042
|
}
|
|
782
1043
|
/**
|
|
783
|
-
*
|
|
784
|
-
*
|
|
1044
|
+
* Sums `calculateWeightedPerpPositionLiability` across every active perp
|
|
1045
|
+
* position — the perp side of the margin requirement (see `getMarginRequirement`).
|
|
1046
|
+
* @param marginCategory `'Initial'`/`'Maintenance'` margin ratio to apply; omit for the raw unweighted notional.
|
|
1047
|
+
* @param liquidationBuffer Optional buffer (MARGIN_PRECISION, 1e4) added to the margin ratio.
|
|
1048
|
+
* @param includeOpenOrders If true, uses each position's worst-case base amount including open bids/asks.
|
|
1049
|
+
* @param strict Use TWAP-bounded quote pricing. Defaults to false.
|
|
1050
|
+
* @returns Precision QUOTE_PRECISION (1e6).
|
|
785
1051
|
*/
|
|
786
1052
|
getTotalPerpPositionLiability(marginCategory, liquidationBuffer, includeOpenOrders, strict = false) {
|
|
787
1053
|
return this.getActivePerpPositions().reduce((totalPerpValue, perpPosition) => {
|
|
@@ -790,8 +1056,14 @@ class User {
|
|
|
790
1056
|
}, numericConstants_1.ZERO);
|
|
791
1057
|
}
|
|
792
1058
|
/**
|
|
793
|
-
*
|
|
794
|
-
*
|
|
1059
|
+
* Values a perp position's base-asset notional at a caller-supplied oracle
|
|
1060
|
+
* price rather than looking one up internally — useful for pricing against
|
|
1061
|
+
* a simulated/custom price. Returns `ZERO` (via `getPerpPositionOrEmpty`) if
|
|
1062
|
+
* the user has no position in `marketIndex`.
|
|
1063
|
+
* @param marketIndex
|
|
1064
|
+
* @param oraclePriceData Price to value the position at, PRICE_PRECISION (1e6). Caller-supplied so callers can pass a custom/simulated price.
|
|
1065
|
+
* @param includeOpenOrders If true, uses the worst-case base amount (including open bids/asks) instead of the current position size. Defaults to false.
|
|
1066
|
+
* @returns Precision QUOTE_PRECISION (1e6).
|
|
795
1067
|
*/
|
|
796
1068
|
getPerpPositionValue(marketIndex, oraclePriceData, includeOpenOrders = false) {
|
|
797
1069
|
const userPosition = this.getPerpPositionOrEmpty(marketIndex);
|
|
@@ -799,8 +1071,13 @@ class User {
|
|
|
799
1071
|
return (0, margin_2.calculateBaseAssetValueWithOracle)(market, userPosition, oraclePriceData, includeOpenOrders);
|
|
800
1072
|
}
|
|
801
1073
|
/**
|
|
802
|
-
*
|
|
803
|
-
*
|
|
1074
|
+
* Unweighted (no margin ratio applied) perp liability notional at a
|
|
1075
|
+
* caller-supplied oracle price. Returns `ZERO` (via `getPerpPositionOrEmpty`)
|
|
1076
|
+
* if the user has no position in `marketIndex`.
|
|
1077
|
+
* @param marketIndex
|
|
1078
|
+
* @param oraclePriceData Price to value the position at, PRICE_PRECISION (1e6).
|
|
1079
|
+
* @param includeOpenOrders If true, uses the worst-case (including open bids/asks) liability value; otherwise just the current position. Defaults to false.
|
|
1080
|
+
* @returns Precision QUOTE_PRECISION (1e6).
|
|
804
1081
|
*/
|
|
805
1082
|
getPerpLiabilityValue(marketIndex, oraclePriceData, includeOpenOrders = false) {
|
|
806
1083
|
const userPosition = this.getPerpPositionOrEmpty(marketIndex);
|
|
@@ -812,6 +1089,7 @@ class User {
|
|
|
812
1089
|
return (0, margin_1.calculatePerpLiabilityValue)(userPosition.baseAssetAmount, oraclePriceData.price);
|
|
813
1090
|
}
|
|
814
1091
|
}
|
|
1092
|
+
/** Returns `PositionDirection.LONG`/`SHORT` from the sign of `baseAssetAmount`, or `undefined` if the position is flat. */
|
|
815
1093
|
getPositionSide(currentPosition) {
|
|
816
1094
|
if (currentPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
|
|
817
1095
|
return types_2.PositionDirection.LONG;
|
|
@@ -825,7 +1103,10 @@ class User {
|
|
|
825
1103
|
}
|
|
826
1104
|
/**
|
|
827
1105
|
* calculates average exit price (optionally for closing up to 100% of position)
|
|
828
|
-
* @
|
|
1106
|
+
* @param position Position to estimate the close for.
|
|
1107
|
+
* @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.
|
|
1108
|
+
* @param useAMMClose If true, values the close against the AMM's own reserves (`calculateBaseAssetValue`) instead of the oracle-referenced value (`calculateBaseAssetValueWithOracle`). Defaults to false.
|
|
1109
|
+
* @returns Tuple of `[exitPrice, pnl]` — exitPrice is PRICE_PRECISION (1e6), pnl is QUOTE_PRECISION (1e6).
|
|
829
1110
|
*/
|
|
830
1111
|
getPositionEstimatedExitPriceAndPnl(position, amountToClose, useAMMClose = false) {
|
|
831
1112
|
const market = this.velocityClient.getPerpMarketAccountOrThrow(position.marketIndex);
|
|
@@ -865,11 +1146,14 @@ class User {
|
|
|
865
1146
|
}
|
|
866
1147
|
/**
|
|
867
1148
|
* calculates current user leverage which is (total liability size) / (net asset value)
|
|
868
|
-
* @
|
|
1149
|
+
* @param includeOpenOrders If true, sizes the perp liability using worst-case open-order exposure. Defaults to true.
|
|
1150
|
+
* @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.
|
|
1151
|
+
* @returns : Precision TEN_THOUSAND (1e4, i.e. `10000` = 1x leverage). `ZERO` if net asset value is zero.
|
|
869
1152
|
*/
|
|
870
1153
|
getLeverage(includeOpenOrders = true, perpMarketIndex) {
|
|
871
1154
|
return this.calculateLeverageFromComponents(this.getLeverageComponents(includeOpenOrders, undefined, perpMarketIndex));
|
|
872
1155
|
}
|
|
1156
|
+
/** 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. */
|
|
873
1157
|
calculateLeverageFromComponents({ perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue, }) {
|
|
874
1158
|
const totalLiabilityValue = perpLiabilityValue.add(spotLiabilityValue);
|
|
875
1159
|
const totalAssetValue = spotAssetValue.add(perpPnl);
|
|
@@ -879,6 +1163,18 @@ class User {
|
|
|
879
1163
|
}
|
|
880
1164
|
return totalLiabilityValue.mul(numericConstants_1.TEN_THOUSAND).div(netAssetValue);
|
|
881
1165
|
}
|
|
1166
|
+
/**
|
|
1167
|
+
* Gathers the four raw components (`perpLiabilityValue`, `perpPnl`,
|
|
1168
|
+
* `spotAssetValue`, `spotLiabilityValue`, all QUOTE_PRECISION/1e6) that
|
|
1169
|
+
* `calculateLeverageFromComponents` combines into a leverage ratio.
|
|
1170
|
+
*
|
|
1171
|
+
* When `perpMarketIndex` is given, scopes to a single isolated position:
|
|
1172
|
+
* `spotAssetValue` becomes that position's isolated quote deposit and
|
|
1173
|
+
* `spotLiabilityValue` is `ZERO` (isolated positions carry no spot
|
|
1174
|
+
* liability of their own). Otherwise sums across the whole account, and
|
|
1175
|
+
* folds in `getTotalIsolatedPositionDeposits` as additional spot asset
|
|
1176
|
+
* value when `marginCategory` is unweighted.
|
|
1177
|
+
*/
|
|
882
1178
|
getLeverageComponents(includeOpenOrders = true, marginCategory = undefined, perpMarketIndex) {
|
|
883
1179
|
var _a;
|
|
884
1180
|
if (perpMarketIndex) {
|
|
@@ -912,6 +1208,13 @@ class User {
|
|
|
912
1208
|
spotLiabilityValue,
|
|
913
1209
|
};
|
|
914
1210
|
}
|
|
1211
|
+
/**
|
|
1212
|
+
* Returns true if the user's deposit position in `spotMarketAccount` is
|
|
1213
|
+
* non-empty but worth less than `DUST_POSITION_SIZE` (QUOTE_PRECISION) —
|
|
1214
|
+
* i.e. too small to be economically worth withdrawing/settling. Only
|
|
1215
|
+
* evaluates deposits (returns false for borrows or an empty position).
|
|
1216
|
+
* @throws If the user has no spot position slot for the market (should not happen for a valid `SpotMarketAccount`).
|
|
1217
|
+
*/
|
|
915
1218
|
isDustDepositPosition(spotMarketAccount) {
|
|
916
1219
|
const marketIndex = spotMarketAccount.marketIndex;
|
|
917
1220
|
const spotPosition = this.getSpotPosition(spotMarketAccount.marketIndex);
|
|
@@ -933,6 +1236,7 @@ class User {
|
|
|
933
1236
|
}
|
|
934
1237
|
return false;
|
|
935
1238
|
}
|
|
1239
|
+
/** Returns every spot market where the user holds a dust-sized deposit; see `isDustDepositPosition`. */
|
|
936
1240
|
getSpotMarketAccountsWithDustPosition() {
|
|
937
1241
|
const spotMarketAccounts = this.velocityClient.getSpotMarketAccounts();
|
|
938
1242
|
const dustPositionAccounts = [];
|
|
@@ -944,9 +1248,22 @@ class User {
|
|
|
944
1248
|
}
|
|
945
1249
|
return dustPositionAccounts;
|
|
946
1250
|
}
|
|
1251
|
+
/**
|
|
1252
|
+
* Sum of the user's total perp position liability (worst-case, open orders
|
|
1253
|
+
* included) and total spot liability value (worst-case, open orders included).
|
|
1254
|
+
* @param marginCategory Optional `'Initial'`/`'Maintenance'` weighting; omit for unweighted values.
|
|
1255
|
+
* @returns Precision QUOTE_PRECISION (1e6), non-negative.
|
|
1256
|
+
*/
|
|
947
1257
|
getTotalLiabilityValue(marginCategory) {
|
|
948
1258
|
return this.getTotalPerpPositionLiability(marginCategory, undefined, true).add(this.getSpotMarketLiabilityValue(undefined, marginCategory, undefined, true));
|
|
949
1259
|
}
|
|
1260
|
+
/**
|
|
1261
|
+
* Sum of the user's total spot asset value and total unrealized perp PnL
|
|
1262
|
+
* (with funding). When `marginCategory` is omitted (unweighted), also
|
|
1263
|
+
* includes `getTotalIsolatedPositionDeposits`.
|
|
1264
|
+
* @param marginCategory Optional `'Initial'`/`'Maintenance'` weighting; omit for unweighted values.
|
|
1265
|
+
* @returns Precision QUOTE_PRECISION (1e6), non-negative.
|
|
1266
|
+
*/
|
|
950
1267
|
getTotalAssetValue(marginCategory) {
|
|
951
1268
|
const value = this.getSpotMarketAssetValue(undefined, marginCategory, true).add(this.getUnrealizedPNL(true, undefined, marginCategory));
|
|
952
1269
|
if (marginCategory === undefined) {
|
|
@@ -954,6 +1271,11 @@ class User {
|
|
|
954
1271
|
}
|
|
955
1272
|
return value;
|
|
956
1273
|
}
|
|
1274
|
+
/**
|
|
1275
|
+
* Unweighted net USD value of the account: net spot market value, plus
|
|
1276
|
+
* unrealized (funding-inclusive) perp PnL, plus isolated position deposits.
|
|
1277
|
+
* @returns Precision QUOTE_PRECISION (1e6), can be negative.
|
|
1278
|
+
*/
|
|
957
1279
|
getNetUsdValue() {
|
|
958
1280
|
const netSpotValue = this.getNetSpotMarketValue();
|
|
959
1281
|
const unrealizedPnl = this.getUnrealizedPNL(true, undefined, undefined);
|
|
@@ -961,9 +1283,11 @@ class User {
|
|
|
961
1283
|
return netSpotValue.add(unrealizedPnl).add(isolatedDeposits);
|
|
962
1284
|
}
|
|
963
1285
|
/**
|
|
964
|
-
* Calculates the all
|
|
965
|
-
*
|
|
966
|
-
*
|
|
1286
|
+
* Calculates the all-time P&L of the user: current net USD value
|
|
1287
|
+
* (`getNetUsdValue`), plus lifetime total withdraws, minus lifetime total
|
|
1288
|
+
* deposits. Equivalent to "everything the account is worth now, plus
|
|
1289
|
+
* everything ever taken out, minus everything ever put in".
|
|
1290
|
+
* @returns Precision QUOTE_PRECISION (1e6), can be negative.
|
|
967
1291
|
*/
|
|
968
1292
|
getTotalAllTimePnl() {
|
|
969
1293
|
const netUsdValue = this.getNetUsdValue();
|
|
@@ -975,8 +1299,8 @@ class User {
|
|
|
975
1299
|
/**
|
|
976
1300
|
* calculates max allowable leverage exceeding hitting requirement category
|
|
977
1301
|
* for large sizes where imf factor activates, result is a lower bound
|
|
978
|
-
* @param marginCategory {Initial, Maintenance}
|
|
979
|
-
* @returns : Precision TEN_THOUSAND
|
|
1302
|
+
* @param marginCategory {Initial, Maintenance} — currently unused; the calculation always uses the max-tradeable-size ('Initial') buying power.
|
|
1303
|
+
* @returns : Precision TEN_THOUSAND (1e4, i.e. `10000` = 1x)
|
|
980
1304
|
*/
|
|
981
1305
|
getMaxLeverageForPerp(perpMarketIndex, _marginCategory = 'Initial') {
|
|
982
1306
|
const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } = this.getLeverageComponents();
|
|
@@ -997,8 +1321,8 @@ class User {
|
|
|
997
1321
|
/**
|
|
998
1322
|
* calculates max allowable leverage exceeding hitting requirement category
|
|
999
1323
|
* @param spotMarketIndex
|
|
1000
|
-
* @param direction
|
|
1001
|
-
* @returns : Precision TEN_THOUSAND
|
|
1324
|
+
* @param direction Whether to simulate a long (deposit-increasing) or short (borrow-increasing) trade.
|
|
1325
|
+
* @returns : Precision TEN_THOUSAND (1e4, i.e. `10000` = 1x)
|
|
1002
1326
|
*/
|
|
1003
1327
|
getMaxLeverageForSpot(spotMarketIndex, direction) {
|
|
1004
1328
|
const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } = this.getLeverageComponents();
|
|
@@ -1039,7 +1363,7 @@ class User {
|
|
|
1039
1363
|
}
|
|
1040
1364
|
/**
|
|
1041
1365
|
* calculates margin ratio: 1 / leverage
|
|
1042
|
-
* @returns : Precision TEN_THOUSAND
|
|
1366
|
+
* @returns : Precision TEN_THOUSAND (1e4, i.e. `10000` = 100% margin ratio / 1x leverage). Returns `BN_MAX` if the account has no liabilities.
|
|
1043
1367
|
*/
|
|
1044
1368
|
getMarginRatio() {
|
|
1045
1369
|
const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } = this.getLeverageComponents();
|
|
@@ -1051,6 +1375,10 @@ class User {
|
|
|
1051
1375
|
const netAssetValue = totalAssetValue.sub(spotLiabilityValue);
|
|
1052
1376
|
return netAssetValue.mul(numericConstants_1.TEN_THOUSAND).div(totalLiabilityValue);
|
|
1053
1377
|
}
|
|
1378
|
+
/**
|
|
1379
|
+
* @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.
|
|
1380
|
+
* @returns The cross-margin `AccountLiquidatableStatus`, plus `isolatedPositions` mapping each isolated perp market index to its own status.
|
|
1381
|
+
*/
|
|
1054
1382
|
canBeLiquidated() {
|
|
1055
1383
|
// Deprecated signature retained for backward compatibility in type only
|
|
1056
1384
|
// but implementation now delegates to the new Map-based API and returns cross margin status.
|
|
@@ -1073,6 +1401,14 @@ class User {
|
|
|
1073
1401
|
* Map keys:
|
|
1074
1402
|
* - 'cross' for cross margin
|
|
1075
1403
|
* - marketIndex (number) for each isolated perp position
|
|
1404
|
+
*
|
|
1405
|
+
* Each `canBeLiquidated` compares maintenance total collateral against the
|
|
1406
|
+
* maintenance margin requirement for that scope. If `marginCalc` is not
|
|
1407
|
+
* supplied, one is computed under `'Maintenance'` with the account's
|
|
1408
|
+
* current `getLiquidationBuffer()` applied — i.e. this defaults to the same
|
|
1409
|
+
* buffered check the on-chain liquidation instructions use, not a bare
|
|
1410
|
+
* maintenance-margin comparison.
|
|
1411
|
+
* @param marginCalc Optional pre-computed `MarginCalculation` to reuse (avoids recomputing margin across repeated calls).
|
|
1076
1412
|
*/
|
|
1077
1413
|
getLiquidationStatuses(marginCalc) {
|
|
1078
1414
|
// If not provided, use buffer-aware calc for canBeLiquidated checks
|
|
@@ -1103,10 +1439,12 @@ class User {
|
|
|
1103
1439
|
}
|
|
1104
1440
|
return result;
|
|
1105
1441
|
}
|
|
1442
|
+
/** Returns true if cross margin or any isolated perp position is currently flagged as being liquidated or bankrupt. */
|
|
1106
1443
|
isBeingLiquidated() {
|
|
1107
1444
|
return (this.isCrossMarginBeingLiquidated() ||
|
|
1108
1445
|
this.hasIsolatedPositionBeingLiquidated());
|
|
1109
1446
|
}
|
|
1447
|
+
/** Returns true if the account-level `UserStatus` has `BEING_LIQUIDATED` or `BANKRUPT` set (cross margin, not per-isolated-position). */
|
|
1110
1448
|
isCrossMarginBeingLiquidated() {
|
|
1111
1449
|
return ((this.getUserAccountOrThrow().status &
|
|
1112
1450
|
(types_1.UserStatus.BEING_LIQUIDATED | types_1.UserStatus.BANKRUPT)) >
|
|
@@ -1117,11 +1455,13 @@ class User {
|
|
|
1117
1455
|
const calc = marginCalc !== null && marginCalc !== void 0 ? marginCalc : this.getMarginCalculation('Maintenance');
|
|
1118
1456
|
return calc.totalCollateral.lt(calc.marginRequirement);
|
|
1119
1457
|
}
|
|
1458
|
+
/** Returns true if any active perp position has `PositionFlag.BeingLiquidated` or `PositionFlag.Bankruptcy` set. */
|
|
1120
1459
|
hasIsolatedPositionBeingLiquidated() {
|
|
1121
1460
|
return this.getActivePerpPositions().some((position) => (position.positionFlag &
|
|
1122
1461
|
(types_2.PositionFlag.BeingLiquidated | types_2.PositionFlag.Bankruptcy)) >
|
|
1123
1462
|
0);
|
|
1124
1463
|
}
|
|
1464
|
+
/** 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. */
|
|
1125
1465
|
isIsolatedPositionBeingLiquidated(perpMarketIndex) {
|
|
1126
1466
|
var _a;
|
|
1127
1467
|
const position = this.getActivePerpPositions().find((position) => position.marketIndex === perpMarketIndex);
|
|
@@ -1140,18 +1480,21 @@ class User {
|
|
|
1140
1480
|
}
|
|
1141
1481
|
return liquidatableIsolatedPositions;
|
|
1142
1482
|
}
|
|
1483
|
+
/** Returns true if `isolatedMarginCalculation`'s collateral is below its margin requirement (no buffer). */
|
|
1143
1484
|
canIsolatedPositionMarginBeLiquidated(isolatedMarginCalculation) {
|
|
1144
1485
|
return isolatedMarginCalculation.totalCollateral.lt(isolatedMarginCalculation.marginRequirement);
|
|
1145
1486
|
}
|
|
1487
|
+
/** Returns true if the account's `UserStatus` bitmask has `status` set. */
|
|
1146
1488
|
hasStatus(status) {
|
|
1147
1489
|
return (this.getUserAccountOrThrow().status & status) > 0;
|
|
1148
1490
|
}
|
|
1491
|
+
/** Returns true if the account's `UserStatus` has `BANKRUPT` set (equity insufficient to cover liabilities; awaiting bankruptcy resolution). */
|
|
1149
1492
|
isBankrupt() {
|
|
1150
1493
|
return (this.getUserAccountOrThrow().status & types_1.UserStatus.BANKRUPT) > 0;
|
|
1151
1494
|
}
|
|
1152
1495
|
/**
|
|
1153
1496
|
* Checks if any user position cumulative funding differs from respective market cumulative funding
|
|
1154
|
-
* @returns
|
|
1497
|
+
* @returns True if at least one non-flat perp position has stale `lastCumulativeFundingRate` relative to the market's current long/short cumulative funding rate.
|
|
1155
1498
|
*/
|
|
1156
1499
|
needsToSettleFundingPayment() {
|
|
1157
1500
|
for (const userPosition of this.getUserAccountOrThrow().perpPositions) {
|
|
@@ -1168,9 +1511,16 @@ class User {
|
|
|
1168
1511
|
return false;
|
|
1169
1512
|
}
|
|
1170
1513
|
/**
|
|
1171
|
-
* Calculate the liquidation price of a spot position
|
|
1172
|
-
*
|
|
1173
|
-
*
|
|
1514
|
+
* Calculate the liquidation price of a spot position — the oracle price at
|
|
1515
|
+
* which maintenance free collateral would hit zero, extrapolating linearly
|
|
1516
|
+
* from the current free collateral and the position's per-unit-price
|
|
1517
|
+
* sensitivity (`calculateFreeCollateralDeltaForSpot`). If a perp market
|
|
1518
|
+
* shares the same oracle as this spot market, that perp position's
|
|
1519
|
+
* sensitivity is folded in too (scaled for any oracle-source unit
|
|
1520
|
+
* difference), since a single price move affects both simultaneously.
|
|
1521
|
+
* @param marketIndex Spot market to compute the liquidation price for.
|
|
1522
|
+
* @param positionBaseSizeChange Optional simulated change to the position size, in the spot market's own token decimals. Defaults to no change.
|
|
1523
|
+
* @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).
|
|
1174
1524
|
*/
|
|
1175
1525
|
spotLiquidationPrice(marketIndex, positionBaseSizeChange = numericConstants_1.ZERO) {
|
|
1176
1526
|
const currentSpotPosition = this.getSpotPosition(marketIndex);
|
|
@@ -1218,14 +1568,23 @@ class User {
|
|
|
1218
1568
|
return liqPrice;
|
|
1219
1569
|
}
|
|
1220
1570
|
/**
|
|
1221
|
-
* Calculate the liquidation price of a perp position, with optional parameter to calculate the liquidation price after a trade
|
|
1571
|
+
* Calculate the liquidation price of a perp position, with optional parameter to calculate the liquidation price after a trade.
|
|
1572
|
+
*
|
|
1573
|
+
* Like `spotLiquidationPrice`, this extrapolates linearly from current free
|
|
1574
|
+
* collateral (`totalCollateral - marginRequirement`, plus `offsetCollateral`)
|
|
1575
|
+
* and the position's price sensitivity; if a spot market shares the same
|
|
1576
|
+
* oracle, its sensitivity is folded in too. When `marginType === 'Isolated'`,
|
|
1577
|
+
* free collateral and the margin requirement are scoped to that market's
|
|
1578
|
+
* isolated bucket instead of the cross-margin account (and the spot-oracle
|
|
1579
|
+
* cross-contribution above is skipped).
|
|
1222
1580
|
* @param marketIndex
|
|
1223
|
-
* @param positionBaseSizeChange
|
|
1224
|
-
* @param estimatedEntryPrice
|
|
1225
|
-
* @param marginCategory
|
|
1226
|
-
* @param includeOpenOrders
|
|
1227
|
-
* @param offsetCollateral
|
|
1228
|
-
* @
|
|
1581
|
+
* @param positionBaseSizeChange Change in position size to calculate the liquidation price for, standardized to the market's order step size. Precision BASE_PRECISION (1e9).
|
|
1582
|
+
* @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).
|
|
1583
|
+
* @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).
|
|
1584
|
+
* @param includeOpenOrders Include open orders' worst-case exposure when sizing the position. Defaults to false.
|
|
1585
|
+
* @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.
|
|
1586
|
+
* @param marginType `'Isolated'` to scope the calculation to `marketIndex`'s isolated margin bucket; omit/`'Cross'` for the cross-margin account.
|
|
1587
|
+
* @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).
|
|
1229
1588
|
*/
|
|
1230
1589
|
liquidationPrice(marketIndex, positionBaseSizeChange = numericConstants_1.ZERO, estimatedEntryPrice = numericConstants_1.ZERO, marginCategory = 'Maintenance', includeOpenOrders = false, offsetCollateral = numericConstants_1.ZERO, marginType) {
|
|
1231
1590
|
const market = this.velocityClient.getPerpMarketAccountOrThrow(marketIndex);
|
|
@@ -1294,6 +1653,16 @@ class User {
|
|
|
1294
1653
|
}
|
|
1295
1654
|
return liqPrice;
|
|
1296
1655
|
}
|
|
1656
|
+
/**
|
|
1657
|
+
* Helper for `liquidationPrice`: estimates the net change to free collateral
|
|
1658
|
+
* from simultaneously (a) realizing PnL on `positionBaseSizeChange` entered
|
|
1659
|
+
* at `estimatedEntryPrice` (assuming the worst/taker fee tier) versus the
|
|
1660
|
+
* oracle price, and (b) the resulting change in margin requirement from the
|
|
1661
|
+
* new position size. Only component (a) applies under `'Maintenance'`
|
|
1662
|
+
* (matching `liquidationPrice`'s default); under other margin categories
|
|
1663
|
+
* only the margin-requirement delta is applied.
|
|
1664
|
+
* @returns Precision QUOTE_PRECISION (1e6); can be negative.
|
|
1665
|
+
*/
|
|
1297
1666
|
calculateEntriesEffectOnFreeCollateral(market, oraclePrice, perpPosition, positionBaseSizeChange, estimatedEntryPrice, includeOpenOrders, marginCategory = 'Maintenance') {
|
|
1298
1667
|
let freeCollateralChange = numericConstants_1.ZERO;
|
|
1299
1668
|
// update free collateral to account for change in pnl from new position
|
|
@@ -1312,11 +1681,9 @@ class User {
|
|
|
1312
1681
|
else {
|
|
1313
1682
|
freeCollateralChange = newPositionValue.sub(costBasis);
|
|
1314
1683
|
}
|
|
1315
|
-
// assume worst fee tier
|
|
1684
|
+
// assume worst fee tier; ceil-divide to match calculate_taker_fee's safe_div_ceil
|
|
1316
1685
|
const takerFeeTier = this.velocityClient.getStateAccount().perpFeeStructure.feeTiers[0];
|
|
1317
|
-
const takerFee = newPositionValue
|
|
1318
|
-
.muln(takerFeeTier.feeNumerator)
|
|
1319
|
-
.divn(takerFeeTier.feeDenominator);
|
|
1686
|
+
const takerFee = (0, utils_2.divCeil)(newPositionValue.muln(takerFeeTier.feeNumerator), new anchor_1.BN(takerFeeTier.feeDenominator));
|
|
1320
1687
|
freeCollateralChange = freeCollateralChange.sub(takerFee);
|
|
1321
1688
|
}
|
|
1322
1689
|
const calculateMarginRequirement = (perpPosition) => {
|
|
@@ -1341,6 +1708,14 @@ class User {
|
|
|
1341
1708
|
const freeCollateralConsumptionAfter = calculateMarginRequirement(perpPositionAfter);
|
|
1342
1709
|
return freeCollateralChange.sub(freeCollateralConsumptionAfter.sub(freeCollateralConsumptionBefore));
|
|
1343
1710
|
}
|
|
1711
|
+
/**
|
|
1712
|
+
* Helper for `liquidationPrice`: the derivative of free collateral with
|
|
1713
|
+
* respect to the perp market's oracle price, for the proposed post-trade
|
|
1714
|
+
* position (`positionBaseSizeChange` applied to the current, or worst-case
|
|
1715
|
+
* if `includeOpenOrders`, base amount). Used as the linear-extrapolation
|
|
1716
|
+
* slope to solve for the price at which free collateral hits zero.
|
|
1717
|
+
* @returns Precision QUOTE_PRECISION (1e6) per unit of PRICE_PRECISION move, or `undefined` if the proposed position is flat (no defined liquidation price).
|
|
1718
|
+
*/
|
|
1344
1719
|
calculateFreeCollateralDeltaForPerp(market, perpPosition, positionBaseSizeChange, oraclePrice, marginCategory = 'Maintenance', includeOpenOrders = false) {
|
|
1345
1720
|
const baseAssetAmount = includeOpenOrders
|
|
1346
1721
|
? (0, margin_2.calculateWorstCaseBaseAssetAmount)(perpPosition, market, oraclePrice)
|
|
@@ -1375,6 +1750,12 @@ class User {
|
|
|
1375
1750
|
}
|
|
1376
1751
|
return freeCollateralDelta;
|
|
1377
1752
|
}
|
|
1753
|
+
/**
|
|
1754
|
+
* Helper for `spotLiquidationPrice`/`liquidationPrice`: the derivative of
|
|
1755
|
+
* free collateral with respect to the spot market's oracle price, for a
|
|
1756
|
+
* position of `signedTokenAmount` (positive = deposit, negative = borrow).
|
|
1757
|
+
* @returns Precision QUOTE_PRECISION (1e6) per unit of PRICE_PRECISION move.
|
|
1758
|
+
*/
|
|
1378
1759
|
calculateFreeCollateralDeltaForSpot(market, signedTokenAmount, marginCategory = 'Maintenance') {
|
|
1379
1760
|
const tokenPrecision = new anchor_1.BN(Math.pow(10, market.decimals));
|
|
1380
1761
|
if (signedTokenAmount.gt(numericConstants_1.ZERO)) {
|
|
@@ -1397,8 +1778,9 @@ class User {
|
|
|
1397
1778
|
/**
|
|
1398
1779
|
* Calculates the estimated liquidation price for a position after closing a quote amount of the position.
|
|
1399
1780
|
* @param positionMarketIndex
|
|
1400
|
-
* @param closeQuoteAmount
|
|
1401
|
-
* @
|
|
1781
|
+
* @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.
|
|
1782
|
+
* @param estimatedEntryPrice Forwarded to `liquidationPrice` as the entry price for the (negative, i.e. closing) size change. PRICE_PRECISION (1e6). Defaults to zero.
|
|
1783
|
+
* @returns : Precision PRICE_PRECISION (1e6). See `liquidationPrice` for the `-1` sentinel cases.
|
|
1402
1784
|
*/
|
|
1403
1785
|
liquidationPriceAfterClose(positionMarketIndex, closeQuoteAmount, estimatedEntryPrice = numericConstants_1.ZERO) {
|
|
1404
1786
|
const currentPosition = this.getPerpPositionOrEmpty(positionMarketIndex);
|
|
@@ -1411,10 +1793,27 @@ class User {
|
|
|
1411
1793
|
.neg();
|
|
1412
1794
|
return this.liquidationPrice(positionMarketIndex, closeBaseAmount, estimatedEntryPrice);
|
|
1413
1795
|
}
|
|
1796
|
+
/**
|
|
1797
|
+
* 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.
|
|
1798
|
+
* @param baseSize BASE_PRECISION (1e9).
|
|
1799
|
+
* @param estEntryPrice Optional entry price to value the trade at, PRICE_PRECISION (1e6); defaults to the oracle price.
|
|
1800
|
+
* @param perpMarketMaxMarginRatio Optional max-margin-ratio override, see `resolveMaxMarginRatio`.
|
|
1801
|
+
* @returns Precision QUOTE_PRECISION (1e6).
|
|
1802
|
+
*/
|
|
1414
1803
|
getMarginUSDCRequiredForTrade(targetMarketIndex, baseSize, estEntryPrice, perpMarketMaxMarginRatio) {
|
|
1415
1804
|
const maxMarginRatio = this.resolveMaxMarginRatio(perpMarketMaxMarginRatio);
|
|
1416
1805
|
return (0, margin_2.calculateMarginUSDCRequiredForTrade)(this.velocityClient, targetMarketIndex, baseSize, maxMarginRatio, estEntryPrice);
|
|
1417
1806
|
}
|
|
1807
|
+
/**
|
|
1808
|
+
* Converts `getMarginUSDCRequiredForTrade`'s USDC margin requirement into
|
|
1809
|
+
* how much of `collateralIndex`'s token a user would need to deposit to
|
|
1810
|
+
* cover it, accounting for that collateral's scaled initial asset weight
|
|
1811
|
+
* (a lower-weighted asset requires proportionally more deposited).
|
|
1812
|
+
* @param baseSize BASE_PRECISION (1e9).
|
|
1813
|
+
* @param collateralIndex Spot market to size the deposit in.
|
|
1814
|
+
* @param perpMarketMaxMarginRatio Optional max-margin-ratio override, see `resolveMaxMarginRatio`.
|
|
1815
|
+
* @returns Token amount in `collateralIndex`'s own decimals.
|
|
1816
|
+
*/
|
|
1418
1817
|
getCollateralDepositRequiredForTrade(targetMarketIndex, baseSize, collateralIndex, perpMarketMaxMarginRatio) {
|
|
1419
1818
|
const maxMarginRatio = this.resolveMaxMarginRatio(perpMarketMaxMarginRatio);
|
|
1420
1819
|
return (0, margin_2.calculateCollateralDepositRequiredForTrade)(this.velocityClient, targetMarketIndex, baseSize, collateralIndex, maxMarginRatio);
|
|
@@ -1425,7 +1824,9 @@ class User {
|
|
|
1425
1824
|
* - oppositeSideTradeSize: the trade size for closing the opposite direction
|
|
1426
1825
|
* @param targetMarketIndex
|
|
1427
1826
|
* @param tradeSide
|
|
1428
|
-
* @
|
|
1827
|
+
* @param maxMarginRatio Optional max-margin-ratio override, see `resolveMaxMarginRatio`.
|
|
1828
|
+
* @param positionType Whether to size for a cross or isolated-margin position (forwarded to `getPerpBuyingPower`). Defaults to `'cross'`.
|
|
1829
|
+
* @returns { tradeSize: BN, oppositeSideTradeSize: BN} : Precision QUOTE_PRECISION (1e6)
|
|
1429
1830
|
*/
|
|
1430
1831
|
getMaxTradeSizeUSDCForPerp(targetMarketIndex, tradeSide, maxMarginRatio = undefined, positionType = 'cross') {
|
|
1431
1832
|
let tradeSize = numericConstants_1.ZERO;
|
|
@@ -1504,10 +1905,10 @@ class User {
|
|
|
1504
1905
|
* Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
|
|
1505
1906
|
*
|
|
1506
1907
|
* @param targetMarketIndex
|
|
1507
|
-
* @param direction
|
|
1508
|
-
* @param currentQuoteAssetValue
|
|
1509
|
-
* @param currentSpotMarketNetValue
|
|
1510
|
-
* @returns tradeSizeAllowed : Precision QUOTE_PRECISION
|
|
1908
|
+
* @param direction Long (increase deposit / reduce borrow) or short (increase borrow / reduce deposit).
|
|
1909
|
+
* @param currentQuoteAssetValue Ignored — always recomputed internally from `getSpotMarketAssetValue(QUOTE_SPOT_MARKET_INDEX)`.
|
|
1910
|
+
* @param currentSpotMarketNetValue Optional pre-computed net value for `targetMarketIndex` (QUOTE_PRECISION, 1e6); if omitted, computed via `getSpotPositionValue`.
|
|
1911
|
+
* @returns tradeSizeAllowed : Precision QUOTE_PRECISION (1e6)
|
|
1511
1912
|
*/
|
|
1512
1913
|
getMaxTradeSizeUSDCForSpot(targetMarketIndex, direction, currentQuoteAssetValue, currentSpotMarketNetValue) {
|
|
1513
1914
|
const market = this.velocityClient.getSpotMarketAccountOrThrow(targetMarketIndex);
|
|
@@ -1549,8 +1950,9 @@ class User {
|
|
|
1549
1950
|
*
|
|
1550
1951
|
* @param inMarketIndex
|
|
1551
1952
|
* @param outMarketIndex
|
|
1552
|
-
* @param calculateSwap function to
|
|
1553
|
-
* @param iterationLimit
|
|
1953
|
+
* @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.
|
|
1954
|
+
* @param iterationLimit How many binary-search iterations to run before erroring out. Defaults to 1000.
|
|
1955
|
+
* @returns `inAmount`/`outAmount` in each market's own token decimals, and the resulting `leverage` (TEN_THOUSAND, 1e4 precision) after the swap.
|
|
1554
1956
|
*/
|
|
1555
1957
|
getMaxSwapAmount({ inMarketIndex, outMarketIndex, calculateSwap, iterationLimit = 1000, }) {
|
|
1556
1958
|
const inMarket = this.velocityClient.getSpotMarketAccountOrThrow(inMarketIndex);
|
|
@@ -1654,6 +2056,13 @@ class User {
|
|
|
1654
2056
|
});
|
|
1655
2057
|
return { inAmount: inSwap, outAmount: outSwap, leverage };
|
|
1656
2058
|
}
|
|
2059
|
+
/**
|
|
2060
|
+
* Returns a cloned `SpotPosition` with `tokenAmount` (signed, positive =
|
|
2061
|
+
* deposit / negative = borrow) applied on top of the existing balance —
|
|
2062
|
+
* used to simulate the post-trade/post-swap position without mutating the
|
|
2063
|
+
* cached account.
|
|
2064
|
+
* @param tokenAmount Signed delta in `market`'s own token decimals.
|
|
2065
|
+
*/
|
|
1657
2066
|
cloneAndUpdateSpotPosition(position, tokenAmount, market) {
|
|
1658
2067
|
const clonedPosition = Object.assign({}, position);
|
|
1659
2068
|
if (tokenAmount.eq(numericConstants_1.ZERO)) {
|
|
@@ -1680,12 +2089,14 @@ class User {
|
|
|
1680
2089
|
}
|
|
1681
2090
|
return clonedPosition;
|
|
1682
2091
|
}
|
|
2092
|
+
/** Worst-case free-collateral contribution (under `'Initial'` margin) of a single spot position. Returns QUOTE_PRECISION (1e6). */
|
|
1683
2093
|
calculateSpotPositionFreeCollateralContribution(spotPosition, strictOraclePrice) {
|
|
1684
2094
|
const marginCategory = 'Initial';
|
|
1685
2095
|
const spotMarketAccount = this.velocityClient.getSpotMarketAccountOrThrow(spotPosition.marketIndex);
|
|
1686
2096
|
const { freeCollateralContribution } = (0, spotPosition_1.getWorstCaseTokenAmounts)(spotPosition, spotMarketAccount, strictOraclePrice, marginCategory, this.getUserAccountOrThrow().maxMarginRatio);
|
|
1687
2097
|
return freeCollateralContribution;
|
|
1688
2098
|
}
|
|
2099
|
+
/** 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. */
|
|
1689
2100
|
calculateSpotPositionLeverageContribution(spotPosition, strictOraclePrice) {
|
|
1690
2101
|
let totalAssetValue = numericConstants_1.ZERO;
|
|
1691
2102
|
let totalLiabilityValue = numericConstants_1.ZERO;
|
|
@@ -1710,10 +2121,11 @@ class User {
|
|
|
1710
2121
|
}
|
|
1711
2122
|
/**
|
|
1712
2123
|
* Estimates what the user leverage will be after swap
|
|
1713
|
-
* @param inMarketIndex
|
|
1714
|
-
* @param outMarketIndex
|
|
1715
|
-
* @param inAmount
|
|
1716
|
-
* @param outAmount
|
|
2124
|
+
* @param inMarketIndex Market being sold/paid from.
|
|
2125
|
+
* @param outMarketIndex Market being bought/received.
|
|
2126
|
+
* @param inAmount Amount removed from `inMarketIndex`, that market's own token decimals.
|
|
2127
|
+
* @param outAmount Amount added to `outMarketIndex`, that market's own token decimals.
|
|
2128
|
+
* @returns Precision TEN_THOUSAND (1e4, i.e. `10000` = 1x).
|
|
1717
2129
|
*/
|
|
1718
2130
|
accountLeverageAfterSwap({ inMarketIndex, outMarketIndex, inAmount, outAmount, }) {
|
|
1719
2131
|
const inMarket = this.velocityClient.getSpotMarketAccountOrThrow(inMarketIndex);
|
|
@@ -1756,11 +2168,11 @@ class User {
|
|
|
1756
2168
|
/**
|
|
1757
2169
|
* Returns the leverage ratio for the account after adding (or subtracting) the given quote size to the given position
|
|
1758
2170
|
* @param targetMarketIndex
|
|
1759
|
-
* @param
|
|
1760
|
-
* @param tradeQuoteAmount
|
|
1761
|
-
* @param tradeSide
|
|
1762
|
-
* @param includeOpenOrders
|
|
1763
|
-
* @returns leverageRatio : Precision TEN_THOUSAND
|
|
2171
|
+
* @param targetMarketType Whether the trade is on a perp or spot market — the two use different valuation paths.
|
|
2172
|
+
* @param tradeQuoteAmount Quote size of the simulated trade, QUOTE_PRECISION (1e6).
|
|
2173
|
+
* @param tradeSide Direction of the simulated trade.
|
|
2174
|
+
* @param includeOpenOrders Include existing open orders' worst-case impact in both the before/after values. Defaults to true.
|
|
2175
|
+
* @returns leverageRatio : Precision TEN_THOUSAND (1e4, i.e. `10000` = 1x)
|
|
1764
2176
|
*/
|
|
1765
2177
|
accountLeverageRatioAfterTrade(targetMarketIndex, targetMarketType, tradeQuoteAmount, tradeSide, includeOpenOrders = true) {
|
|
1766
2178
|
const tradeIsPerp = (0, types_1.isVariant)(targetMarketType, 'perp');
|
|
@@ -1837,6 +2249,19 @@ class User {
|
|
|
1837
2249
|
.div(netAssetValue);
|
|
1838
2250
|
return newLeverage;
|
|
1839
2251
|
}
|
|
2252
|
+
/**
|
|
2253
|
+
* Looks up the user's fee tier from the state account's fee structure.
|
|
2254
|
+
*
|
|
2255
|
+
* For perp markets, the tier is selected by the user's rolling 30-day
|
|
2256
|
+
* volume (`getUser30dRollingVolumeEstimate`, QUOTE_PRECISION) against fixed
|
|
2257
|
+
* breakpoints — $2M, $10M, $20M, $80M, $200M — picking the lowest-index
|
|
2258
|
+
* tier whose breakpoint the user's volume is still under (tier 5, the
|
|
2259
|
+
* lowest fees, if volume meets or exceeds the top breakpoint). Spot markets
|
|
2260
|
+
* always use tier 0 (no volume-based discount).
|
|
2261
|
+
* @param marketType `MarketType.PERP` or `MarketType.SPOT`.
|
|
2262
|
+
* @param now Optional unix timestamp (seconds) to evaluate the rolling volume window as of; defaults to current time.
|
|
2263
|
+
* @returns The matching `FeeTier` (numerator/denominator fee fractions and referee-discount fractions).
|
|
2264
|
+
*/
|
|
1840
2265
|
getUserFeeTier(marketType, now) {
|
|
1841
2266
|
const state = this.velocityClient.getStateAccount();
|
|
1842
2267
|
if ((0, types_1.isVariant)(marketType, 'perp')) {
|
|
@@ -1863,28 +2288,64 @@ class User {
|
|
|
1863
2288
|
return state.spotFeeStructure.feeTiers[0];
|
|
1864
2289
|
}
|
|
1865
2290
|
/**
|
|
1866
|
-
* Calculates how much perp fee will be taken for a given sized trade
|
|
1867
|
-
*
|
|
1868
|
-
*
|
|
2291
|
+
* Calculates how much perp fee will be taken for a given sized trade.
|
|
2292
|
+
*
|
|
2293
|
+
* When `marketIndex` is provided, delegates to `VelocityClient.getMarketFees`
|
|
2294
|
+
* for that specific market's taker-fee multiplier (which itself applies the
|
|
2295
|
+
* market's `feeAdjustment`, the referee discount, and — when `builderInfo` is
|
|
2296
|
+
* passed — the builder fee). Otherwise uses the volume-based fee tier from
|
|
2297
|
+
* `getUserFeeTier(MarketType.PERP)`; if the user is a referee (determined
|
|
2298
|
+
* from `UserStats.referrerStatus`'s `IsReferred` flag unless `isReferee` is
|
|
2299
|
+
* explicitly passed), the tier's `refereeFeeNumerator`/`refereeFeeDenominator`
|
|
2300
|
+
* proportion is subtracted from the fee as a discount, and — when `builderInfo`
|
|
2301
|
+
* carries a builder code — the builder fee (`quoteAmount * builderFeeTenthBps /
|
|
2302
|
+
* 100_000`) is added on top, mirroring the program's `builder_fee` (`math/fees.rs`).
|
|
2303
|
+
* @param quoteAmount Trade size, QUOTE_PRECISION (1e6).
|
|
2304
|
+
* @param marketIndex Optional perp market to use `VelocityClient.getMarketFees` for instead of the volume-tier fee structure.
|
|
2305
|
+
* @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`).
|
|
2306
|
+
* @param builderInfo Optional builder code; when it carries `builderIdx` + `builderFeeTenthBps`, the builder fee is added on top of the tiered fee.
|
|
2307
|
+
* @returns feeForQuote : Precision QUOTE_PRECISION (1e6)
|
|
1869
2308
|
*/
|
|
1870
|
-
|
|
2309
|
+
calculatePerpTakerFee(quoteAmount, marketIndex, isReferee, builderInfo) {
|
|
1871
2310
|
if (marketIndex !== undefined) {
|
|
1872
|
-
const takerFeeMultiplier = this.velocityClient.getMarketFees(types_2.MarketType.PERP, marketIndex, this).takerFee;
|
|
2311
|
+
const takerFeeMultiplier = this.velocityClient.getMarketFees(types_2.MarketType.PERP, marketIndex, this, builderInfo).takerFee;
|
|
1873
2312
|
const feeAmountNum = bigNum_1.BigNum.from(quoteAmount, numericConstants_1.QUOTE_PRECISION_EXP).toNum() *
|
|
1874
2313
|
takerFeeMultiplier;
|
|
1875
2314
|
return bigNum_1.BigNum.fromPrint(feeAmountNum.toString(), numericConstants_1.QUOTE_PRECISION_EXP).val;
|
|
1876
2315
|
}
|
|
1877
2316
|
else {
|
|
1878
2317
|
const feeTier = this.getUserFeeTier(types_2.MarketType.PERP);
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
.
|
|
2318
|
+
let fee = (0, utils_2.divCeil)(quoteAmount.mul(new anchor_1.BN(feeTier.feeNumerator)), new anchor_1.BN(feeTier.feeDenominator));
|
|
2319
|
+
const isUserReferee = isReferee !== null && isReferee !== void 0 ? isReferee : (this.velocityClient.getUserStatsOrThrow().getAccountOrThrow()
|
|
2320
|
+
.referrerStatus &
|
|
2321
|
+
types_1.ReferrerStatus.IsReferred) >
|
|
2322
|
+
0;
|
|
2323
|
+
if (isUserReferee) {
|
|
2324
|
+
const refereeDiscount = getProportion128(fee, new anchor_1.BN(feeTier.refereeFeeNumerator), new anchor_1.BN(feeTier.refereeFeeDenominator));
|
|
2325
|
+
fee = fee.sub(refereeDiscount);
|
|
2326
|
+
}
|
|
2327
|
+
// Builder fee (M12): charged on top of the tiered fee, on the raw quote
|
|
2328
|
+
// (independent of the referee discount), mirroring `builder_fee` in `math/fees.rs`.
|
|
2329
|
+
if (builderInfo && (0, builder_1.hasBuilderParams)(builderInfo)) {
|
|
2330
|
+
fee = fee.add((0, builder_1.calculateBuilderFee)(quoteAmount, builderInfo.builderFeeTenthBps));
|
|
2331
|
+
}
|
|
2332
|
+
return fee;
|
|
1882
2333
|
}
|
|
1883
2334
|
}
|
|
1884
2335
|
/**
|
|
1885
2336
|
* Calculates a user's max withdrawal amounts for a spot market. If reduceOnly is true,
|
|
1886
|
-
* it will return the max withdrawal amount without opening a liability for the user
|
|
2337
|
+
* it will return the max withdrawal amount without opening a liability for the user.
|
|
2338
|
+
*
|
|
2339
|
+
* Combines three caps: the market-wide withdraw/borrow guard
|
|
2340
|
+
* (`calculateWithdrawLimit`, a rolling-window rate limit on the spot
|
|
2341
|
+
* market), the user's own deposit balance, and how much their free
|
|
2342
|
+
* collateral supports withdrawing/borrowing. If `canBypassWithdrawLimits`
|
|
2343
|
+
* returns `canBypass: true` (see that method), the market-wide withdraw
|
|
2344
|
+
* limit floor is raised to the user's full deposit amount — letting a
|
|
2345
|
+
* small, healthy, always-net-positive depositor withdraw in full even if
|
|
2346
|
+
* the market-wide guard would otherwise throttle them.
|
|
1887
2347
|
* @param marketIndex
|
|
2348
|
+
* @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.
|
|
1888
2349
|
* @returns withdrawalLimit : Precision is the token precision for the chosen SpotMarket
|
|
1889
2350
|
*/
|
|
1890
2351
|
getWithdrawalLimit(marketIndex, reduceOnly) {
|
|
@@ -1941,6 +2402,24 @@ class User {
|
|
|
1941
2402
|
return anchor_1.BN.max(maxBorrowValue, numericConstants_1.ZERO);
|
|
1942
2403
|
}
|
|
1943
2404
|
}
|
|
2405
|
+
/**
|
|
2406
|
+
* Determines whether the user can bypass the spot market's rolling
|
|
2407
|
+
* withdraw-guard limit for `marketIndex`. `canBypass` is true only when
|
|
2408
|
+
* **all** of the following hold:
|
|
2409
|
+
* - The user currently holds a deposit (not a borrow) in the market.
|
|
2410
|
+
* - Their lifetime net deposits (`totalDeposits - totalWithdraws`) are
|
|
2411
|
+
* non-negative — they have never net-withdrawn more than they net-deposited.
|
|
2412
|
+
* - Their `cumulativeDeposits` for the position has never gone negative
|
|
2413
|
+
* (no history of having borrowed and repaid in this market).
|
|
2414
|
+
* - Their current deposit amount is below `maxDepositAmount`, i.e. 10% of
|
|
2415
|
+
* the spot market's `withdrawGuardThreshold`.
|
|
2416
|
+
*
|
|
2417
|
+
* This lets a small, well-behaved depositor withdraw their own funds in
|
|
2418
|
+
* full even while the market-wide withdraw guard is actively throttling
|
|
2419
|
+
* larger movements. Used by `getWithdrawalLimit`.
|
|
2420
|
+
* @param marketIndex
|
|
2421
|
+
* @returns `canBypass`; `netDeposits` (lifetime `totalDeposits - totalWithdraws`, QUOTE_PRECISION, 1e6); `depositAmount` and `maxDepositAmount`, both in the spot market's own token decimals.
|
|
2422
|
+
*/
|
|
1944
2423
|
canBypassWithdrawLimits(marketIndex) {
|
|
1945
2424
|
const spotMarket = this.velocityClient.getSpotMarketAccountOrThrow(marketIndex);
|
|
1946
2425
|
const maxDepositAmount = spotMarket.withdrawGuardThreshold.div(new anchor_1.BN(10));
|
|
@@ -1971,6 +2450,14 @@ class User {
|
|
|
1971
2450
|
netDeposits,
|
|
1972
2451
|
};
|
|
1973
2452
|
}
|
|
2453
|
+
if (position.cumulativeDeposits.lt(numericConstants_1.ZERO)) {
|
|
2454
|
+
return {
|
|
2455
|
+
canBypass: false,
|
|
2456
|
+
maxDepositAmount,
|
|
2457
|
+
depositAmount,
|
|
2458
|
+
netDeposits,
|
|
2459
|
+
};
|
|
2460
|
+
}
|
|
1974
2461
|
return {
|
|
1975
2462
|
canBypass: depositAmount.lt(maxDepositAmount),
|
|
1976
2463
|
maxDepositAmount,
|
|
@@ -1978,6 +2465,15 @@ class User {
|
|
|
1978
2465
|
depositAmount,
|
|
1979
2466
|
};
|
|
1980
2467
|
}
|
|
2468
|
+
/**
|
|
2469
|
+
* Determines whether the user can be marked idle (excluded from userMap
|
|
2470
|
+
* subscriptions by default, and skipped by most keeper crank passes) as of
|
|
2471
|
+
* `slot`. Requires: not already idle; inactive for the required window
|
|
2472
|
+
* since `lastActiveSlot` (1 hour / 9,000 slots if equity is under $1,000,
|
|
2473
|
+
* otherwise 1 week / 1,512,000 slots); not currently being liquidated; and
|
|
2474
|
+
* no open perp positions, borrows, spot open orders, or open orders of any kind.
|
|
2475
|
+
* @param slot Current slot to evaluate inactivity against.
|
|
2476
|
+
*/
|
|
1981
2477
|
canMakeIdle(slot) {
|
|
1982
2478
|
const userAccount = this.getUserAccountOrThrow();
|
|
1983
2479
|
if (userAccount.idle) {
|
|
@@ -2021,6 +2517,20 @@ class User {
|
|
|
2021
2517
|
}
|
|
2022
2518
|
return true;
|
|
2023
2519
|
}
|
|
2520
|
+
/**
|
|
2521
|
+
* Determines whether this `User` (sub)account can be deleted (checked
|
|
2522
|
+
* before sending a delete-user instruction, to give a friendlier error than
|
|
2523
|
+
* an on-chain revert). Returns `canDelete: false` with a `reason` string if
|
|
2524
|
+
* any of the following hold: it's a referrer's sub-account 0 (referrers
|
|
2525
|
+
* cannot delete their primary account); the account is bankrupt or being
|
|
2526
|
+
* liquidated; it has any non-empty perp/spot position or open order; or
|
|
2527
|
+
* (when the state account charges an initialize-user fee) the account is a
|
|
2528
|
+
* "fresh" account — younger than `ACCOUNT_AGE_DELETION_CUTOFF_SECONDS`,
|
|
2529
|
+
* measured from its earliest recorded filler/maker/taker volume timestamp —
|
|
2530
|
+
* that is not currently idle.
|
|
2531
|
+
* @param userStatsAccount Optional pre-fetched `UserStatsAccount`; defaults to `VelocityClient.getUserStatsOrThrow().getAccount()`.
|
|
2532
|
+
* @param now Optional unix timestamp (seconds) to evaluate account age against; defaults to current time.
|
|
2533
|
+
*/
|
|
2024
2534
|
canBeDeleted(userStatsAccount, now) {
|
|
2025
2535
|
const userAccount = this.getUserAccountOrThrow();
|
|
2026
2536
|
const userStatsAccountToUse = userStatsAccount !== null && userStatsAccount !== void 0 ? userStatsAccount : this.velocityClient.getUserStatsOrThrow().getAccount();
|
|
@@ -2071,6 +2581,17 @@ class User {
|
|
|
2071
2581
|
}
|
|
2072
2582
|
return { canDelete: true };
|
|
2073
2583
|
}
|
|
2584
|
+
/**
|
|
2585
|
+
* Returns the numerically-lowest (i.e. safest) contract/asset tier across
|
|
2586
|
+
* the user's active positions — perp tiers from active perp positions,
|
|
2587
|
+
* spot tiers only from spot **borrows** (deposits are skipped, since asset
|
|
2588
|
+
* tier only restricts borrowing exposure). Defaults to `4` (the
|
|
2589
|
+
* second-riskiest tier index) when the user has no positions of that kind —
|
|
2590
|
+
* this is a permissive default intended for callers doing tier-safety
|
|
2591
|
+
* comparisons (see `perpTierIsAsSafeAs` in `math/tiers`), not a claim that
|
|
2592
|
+
* "no position" is itself a risky tier.
|
|
2593
|
+
* @returns Lower `perpTier`/`spotTier` numbers indicate a safer tier; see `math/tiers` (`getPerpMarketTierNumber`/`getSpotMarketTierNumber`) for the numbering.
|
|
2594
|
+
*/
|
|
2074
2595
|
getSafestTiers() {
|
|
2075
2596
|
let safestPerpTier = 4;
|
|
2076
2597
|
let safestSpotTier = 4;
|
|
@@ -2088,6 +2609,21 @@ class User {
|
|
|
2088
2609
|
spotTier: safestSpotTier,
|
|
2089
2610
|
};
|
|
2090
2611
|
}
|
|
2612
|
+
/**
|
|
2613
|
+
* Breaks down a single perp position's contribution to the margin system
|
|
2614
|
+
* as a `HealthComponent`: worst-case base size, its unweighted liability
|
|
2615
|
+
* value, the applicable margin ratio (`weight`), and the resulting
|
|
2616
|
+
* weighted margin requirement (`weightedValue`, which includes the
|
|
2617
|
+
* position's open-order margin add-on). Used to build up
|
|
2618
|
+
* `getHealthComponents`' `perpPositions` array (e.g. for UI breakdowns of
|
|
2619
|
+
* "what's consuming my margin").
|
|
2620
|
+
* @param marginCategory `'Initial'` or `'Maintenance'`.
|
|
2621
|
+
* @param perpPosition Position to evaluate.
|
|
2622
|
+
* @param oraclePriceData Optional oracle price override for the perp market; defaults to the live oracle price.
|
|
2623
|
+
* @param quoteOraclePriceData Optional oracle price override for the quote spot market; defaults to the live oracle price.
|
|
2624
|
+
* @param includeOpenOrders Include worst-case open-order exposure. Defaults to true.
|
|
2625
|
+
* @returns `size` is BASE_PRECISION (1e9); `value`/`weightedValue` are QUOTE_PRECISION (1e6); `weight` is MARGIN_PRECISION (1e4).
|
|
2626
|
+
*/
|
|
2091
2627
|
getPerpPositionHealth({ marginCategory, perpPosition, oraclePriceData, quoteOraclePriceData, includeOpenOrders = true, }) {
|
|
2092
2628
|
const perpMarket = this.velocityClient.getPerpMarketAccountOrThrow(perpPosition.marketIndex);
|
|
2093
2629
|
const _oraclePriceData = oraclePriceData ||
|
|
@@ -2122,6 +2658,18 @@ class User {
|
|
|
2122
2658
|
weightedValue: marginRequirement,
|
|
2123
2659
|
};
|
|
2124
2660
|
}
|
|
2661
|
+
/**
|
|
2662
|
+
* Builds a full breakdown of every component feeding into the user's
|
|
2663
|
+
* margin calculation, for UI/diagnostic display: `deposits` and `borrows`
|
|
2664
|
+
* (one `HealthComponent` per non-quote spot market with a nonzero
|
|
2665
|
+
* worst-case position, plus a synthetic entry for the net quote balance),
|
|
2666
|
+
* `perpPositions` (via `getPerpPositionHealth`, one per active perp
|
|
2667
|
+
* position), and `perpPnl` (each position's weighted unrealized PnL — see
|
|
2668
|
+
* `getUnrealizedPNL` for the `'Initial'`-margin $100 cap that also applies
|
|
2669
|
+
* here).
|
|
2670
|
+
* @param marginCategory `'Initial'` or `'Maintenance'` — determines which asset/liability weights are applied.
|
|
2671
|
+
* @returns `HealthComponents` with `size`/`value`/`weightedValue` in each entry using the same precisions as `getPerpPositionHealth`.
|
|
2672
|
+
*/
|
|
2125
2673
|
getHealthComponents({ marginCategory, }) {
|
|
2126
2674
|
const healthComponents = {
|
|
2127
2675
|
deposits: [],
|
|
@@ -2246,6 +2794,7 @@ class User {
|
|
|
2246
2794
|
}
|
|
2247
2795
|
/**
|
|
2248
2796
|
* Get the active perp and spot positions of the user.
|
|
2797
|
+
* @returns Market indices only (not full position objects); see `getActivePerpPositions`/`getActiveSpotPositions` for the "active" criteria.
|
|
2249
2798
|
*/
|
|
2250
2799
|
getActivePositions() {
|
|
2251
2800
|
const activePerpMarkets = this.getActivePerpPositions().map((position) => position.marketIndex);
|
|
@@ -2259,9 +2808,28 @@ class User {
|
|
|
2259
2808
|
* Compute the full margin calculation for the user's account.
|
|
2260
2809
|
* Prioritize using this function instead of calling getMarginRequirement or getTotalCollateral multiple times.
|
|
2261
2810
|
* Consumers can use this to avoid duplicating work across separate calls.
|
|
2811
|
+
*
|
|
2812
|
+
* Mirrors the on-chain margin accumulation in `math/margin.rs`, splitting
|
|
2813
|
+
* contributions into cross-margin and per-market isolated buckets
|
|
2814
|
+
* (`MarginCalculation.isolatedMarginCalculations`, keyed by perp market
|
|
2815
|
+
* index — see `isPerpPositionIsolated`) and tracking whether the account
|
|
2816
|
+
* holds any isolated-tier liability (`withPerpIsolatedLiability` /
|
|
2817
|
+
* `withSpotIsolatedLiability`, consumed by
|
|
2818
|
+
* `validateAnyIsolatedTierRequirements`). A perp position's isolated
|
|
2819
|
+
* quote-deposit collateral only counts toward that position's own isolated
|
|
2820
|
+
* bucket, never the cross-margin total.
|
|
2821
|
+
*
|
|
2822
|
+
* Also enforces pool-id consistency: every spot/perp position's market must
|
|
2823
|
+
* match the user's `poolId`, **except** a pool-1 user is allowed to hold a
|
|
2824
|
+
* quote-asset deposit (not borrow) even though the quote spot market itself
|
|
2825
|
+
* belongs to pool 0 — throws `InvalidPoolId: ...` otherwise.
|
|
2826
|
+
* @param marginCategory `'Initial'` or `'Maintenance'`. Defaults to `'Initial'`.
|
|
2827
|
+
* @param opts.strict Apply TWAP-bounded (`StrictOraclePrice`) oracle pricing, mirroring the on-chain strict-price gating. Defaults to false.
|
|
2828
|
+
* @param opts.includeOpenOrders Include open orders' worst-case impact. Defaults to true.
|
|
2829
|
+
* @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`.
|
|
2262
2830
|
*/
|
|
2263
2831
|
getMarginCalculation(marginCategory = 'Initial', opts) {
|
|
2264
|
-
var _a, _b, _c, _d, _e, _f, _g, _h
|
|
2832
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
2265
2833
|
const strict = (_a = opts === null || opts === void 0 ? void 0 : opts.strict) !== null && _a !== void 0 ? _a : false;
|
|
2266
2834
|
const liquidationBufferMap = (_b = opts === null || opts === void 0 ? void 0 : opts.liquidationBufferMap) !== null && _b !== void 0 ? _b : new Map();
|
|
2267
2835
|
const includeOpenOrders = (_c = opts === null || opts === void 0 ? void 0 : opts.includeOpenOrders) !== null && _c !== void 0 ? _c : true;
|
|
@@ -2281,12 +2849,29 @@ class User {
|
|
|
2281
2849
|
.setCrossMarginBuffer((_f = (_e = opts === null || opts === void 0 ? void 0 : opts.liquidationBufferMap) === null || _e === void 0 ? void 0 : _e.get('cross')) !== null && _f !== void 0 ? _f : numericConstants_1.ZERO)
|
|
2282
2850
|
.setIsolatedMarginBuffers(isolatedMarginBuffers);
|
|
2283
2851
|
const calc = new marginCalculation_1.MarginCalculation(ctx);
|
|
2852
|
+
const userPoolId = this.getUserAccountOrThrow().poolId;
|
|
2284
2853
|
// SPOT POSITIONS
|
|
2285
2854
|
for (const spotPosition of this.getUserAccountOrThrow().spotPositions) {
|
|
2286
2855
|
if ((0, spotPosition_1.isSpotPositionAvailable)(spotPosition))
|
|
2287
2856
|
continue;
|
|
2288
2857
|
const isQuote = spotPosition.marketIndex === numericConstants_1.QUOTE_SPOT_MARKET_INDEX;
|
|
2858
|
+
const isBorrow = (0, types_1.isVariant)(spotPosition.balanceType, 'borrow');
|
|
2289
2859
|
const spotMarket = this.velocityClient.getSpotMarketAccountOrThrow(spotPosition.marketIndex);
|
|
2860
|
+
// the pool-1/quote-deposit carve-out lets a pool-1 user *hold* a quote
|
|
2861
|
+
// deposit without matching the quote market's own pool id (no
|
|
2862
|
+
// InvalidPoolId throw); every other combination requires an exact pool
|
|
2863
|
+
// match. Note the deposit still contributes ZERO collateral in this case
|
|
2864
|
+
// (skipTokenValue below) — this faithfully mirrors margin.rs:319-321,
|
|
2865
|
+
// which sets token_value = 0 before add_cross_margin_total_collateral.
|
|
2866
|
+
let skipTokenValue = false;
|
|
2867
|
+
if (!(userPoolId === 1 && isQuote && !isBorrow)) {
|
|
2868
|
+
if (userPoolId !== spotMarket.poolId) {
|
|
2869
|
+
throw new Error(`InvalidPoolId: user pool id (${userPoolId}) does not match spot market pool id (${spotMarket.poolId}) for market index ${spotMarket.marketIndex}`);
|
|
2870
|
+
}
|
|
2871
|
+
}
|
|
2872
|
+
else {
|
|
2873
|
+
skipTokenValue = true;
|
|
2874
|
+
}
|
|
2290
2875
|
const oraclePriceData = this.getOracleDataForSpotMarket(spotPosition.marketIndex);
|
|
2291
2876
|
const twap5 = strict
|
|
2292
2877
|
? (0, oracles_1.calculateLiveOracleTwap)(spotMarket.historicalOracleData, oraclePriceData, new anchor_1.BN(Math.floor(Date.now() / 1000)), numericConstants_1.FIVE_MINUTE)
|
|
@@ -2294,15 +2879,20 @@ class User {
|
|
|
2294
2879
|
const strictOracle = new strictOraclePrice_1.StrictOraclePrice(oraclePriceData.price, twap5);
|
|
2295
2880
|
if (isQuote) {
|
|
2296
2881
|
const tokenAmount = (0, spotBalance_1.getSignedTokenAmount)((0, spotBalance_2.getTokenAmount)(spotPosition.scaledBalance, spotMarket, spotPosition.balanceType), spotPosition.balanceType);
|
|
2882
|
+
// mirrors margin.rs's `market_index == 0` block: the quote market uses the
|
|
2883
|
+
// raw strict token value on both sides — no asset/liability weight, and the
|
|
2884
|
+
// cross-margin buffer is applied inside addCrossMarginRequirement (from
|
|
2885
|
+
// context.crossMarginBuffer), not folded into the value here
|
|
2886
|
+
const tokenValue = (0, spotBalance_1.getStrictTokenValue)(tokenAmount, spotMarket.decimals, strictOracle);
|
|
2297
2887
|
if ((0, types_1.isVariant)(spotPosition.balanceType, 'deposit')) {
|
|
2298
2888
|
// add deposit value to total collateral
|
|
2299
|
-
|
|
2300
|
-
calc.addCrossMarginTotalCollateral(weightedTokenValue);
|
|
2889
|
+
calc.addCrossMarginTotalCollateral(skipTokenValue ? numericConstants_1.ZERO : tokenValue);
|
|
2301
2890
|
}
|
|
2302
2891
|
else {
|
|
2303
2892
|
// borrow on quote contributes to margin requirement
|
|
2304
|
-
const tokenValueAbs =
|
|
2893
|
+
const tokenValueAbs = tokenValue.abs();
|
|
2305
2894
|
calc.addCrossMarginRequirement(tokenValueAbs, tokenValueAbs);
|
|
2895
|
+
calc.addSpotLiability();
|
|
2306
2896
|
}
|
|
2307
2897
|
continue;
|
|
2308
2898
|
}
|
|
@@ -2314,6 +2904,7 @@ class User {
|
|
|
2314
2904
|
// open order IM
|
|
2315
2905
|
calc.addCrossMarginRequirement(new anchor_1.BN(spotPosition.openOrders).mul(numericConstants_1.OPEN_ORDER_MARGIN_REQUIREMENT), numericConstants_1.ZERO);
|
|
2316
2906
|
}
|
|
2907
|
+
const isIsolatedSpotTier = (0, types_1.isVariant)(spotMarket.assetTier, 'isolated');
|
|
2317
2908
|
if (worstCaseTokenAmount.gt(numericConstants_1.ZERO)) {
|
|
2318
2909
|
const baseAssetValue = this.getSpotAssetValue(worstCaseTokenAmount, strictOracle, spotMarket, marginCategory);
|
|
2319
2910
|
// asset side increases total collateral (weighted)
|
|
@@ -2323,6 +2914,14 @@ class User {
|
|
|
2323
2914
|
// liability side increases margin requirement (weighted >= abs(token_value))
|
|
2324
2915
|
const getSpotLiabilityValue = this.getSpotLiabilityValue(worstCaseTokenAmount, strictOracle, spotMarket, marginCategory, liquidationBufferMap.get('cross'));
|
|
2325
2916
|
calc.addCrossMarginRequirement(getSpotLiabilityValue.abs(), getSpotLiabilityValue.abs());
|
|
2917
|
+
calc.addSpotLiability();
|
|
2918
|
+
calc.updateWithSpotIsolatedLiability(isIsolatedSpotTier);
|
|
2919
|
+
}
|
|
2920
|
+
else if (spotPosition.openOrders !== 0 ||
|
|
2921
|
+
!spotPosition.openBids.isZero() ||
|
|
2922
|
+
!spotPosition.openAsks.isZero()) {
|
|
2923
|
+
calc.addSpotLiability();
|
|
2924
|
+
calc.updateWithSpotIsolatedLiability(isIsolatedSpotTier);
|
|
2326
2925
|
}
|
|
2327
2926
|
// orders value contributes to collateral or requirement
|
|
2328
2927
|
if (worstCaseOrdersValue.gt(numericConstants_1.ZERO)) {
|
|
@@ -2336,6 +2935,9 @@ class User {
|
|
|
2336
2935
|
// PERP POSITIONS
|
|
2337
2936
|
for (const marketPosition of this.getActivePerpPositions()) {
|
|
2338
2937
|
const market = this.velocityClient.getPerpMarketAccountOrThrow(marketPosition.marketIndex);
|
|
2938
|
+
if (userPoolId !== market.poolId) {
|
|
2939
|
+
throw new Error(`InvalidPoolId: user pool id (${userPoolId}) does not match perp market pool id (${market.poolId}) for market index ${market.marketIndex}`);
|
|
2940
|
+
}
|
|
2339
2941
|
const quoteSpotMarket = this.velocityClient.getSpotMarketAccountOrThrow(market.quoteSpotMarketIndex);
|
|
2340
2942
|
const quoteOraclePriceData = this.getOracleDataForSpotMarket(market.quoteSpotMarketIndex);
|
|
2341
2943
|
const oraclePriceData = this.getMMOracleDataForPerpMarket(market.marketIndex);
|
|
@@ -2348,13 +2950,15 @@ class User {
|
|
|
2348
2950
|
if ((0, types_1.isVariant)(market.status, 'settlement')) {
|
|
2349
2951
|
marginRatio = numericConstants_1.ZERO;
|
|
2350
2952
|
}
|
|
2351
|
-
// convert liability to quote value and apply margin ratio
|
|
2953
|
+
// convert liability to quote value and apply margin ratio; since this is
|
|
2954
|
+
// a liability, use the larger of the twap and current quote price
|
|
2352
2955
|
const quotePrice = strict
|
|
2353
2956
|
? anchor_1.BN.max(quoteOraclePriceData.price, quoteSpotMarket.historicalOracleData.lastOraclePriceTwap5Min)
|
|
2354
2957
|
: quoteOraclePriceData.price;
|
|
2355
|
-
|
|
2958
|
+
const worstCaseLiabilityValueQuote = worstCaseLiabilityValue
|
|
2356
2959
|
.mul(quotePrice)
|
|
2357
|
-
.div(numericConstants_1.PRICE_PRECISION)
|
|
2960
|
+
.div(numericConstants_1.PRICE_PRECISION);
|
|
2961
|
+
let perpMarginRequirement = worstCaseLiabilityValueQuote
|
|
2358
2962
|
.mul(marginRatio)
|
|
2359
2963
|
.div(numericConstants_1.MARGIN_PRECISION);
|
|
2360
2964
|
// add open orders IM
|
|
@@ -2383,33 +2987,112 @@ class User {
|
|
|
2383
2987
|
.div(new anchor_1.BN(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION));
|
|
2384
2988
|
}
|
|
2385
2989
|
}
|
|
2990
|
+
if (marginCategory === 'Initial') {
|
|
2991
|
+
// safety guard for dangerously configured perp market
|
|
2992
|
+
positionUnrealizedPnl = anchor_1.BN.min(positionUnrealizedPnl, numericConstants_1.MAX_POSITIVE_UPNL_FOR_INITIAL_MARGIN);
|
|
2993
|
+
}
|
|
2994
|
+
const hasPerpLiability = !marketPosition.baseAssetAmount.isZero() ||
|
|
2995
|
+
marketPosition.quoteAssetAmount.isNeg() ||
|
|
2996
|
+
marketPosition.openOrders !== 0 ||
|
|
2997
|
+
!marketPosition.openBids.isZero() ||
|
|
2998
|
+
!marketPosition.openAsks.isZero();
|
|
2999
|
+
if (hasPerpLiability) {
|
|
3000
|
+
calc.addPerpLiability();
|
|
3001
|
+
calc.updateWithPerpIsolatedLiability((0, types_1.isVariant)(market.contractTier, 'isolated'));
|
|
3002
|
+
}
|
|
2386
3003
|
// Add perp contribution: isolated vs cross
|
|
2387
3004
|
const isIsolated = this.isPerpPositionIsolated(marketPosition);
|
|
2388
3005
|
if (isIsolated) {
|
|
2389
3006
|
// derive isolated quote deposit value, mirroring on-chain logic
|
|
2390
3007
|
let depositValue = numericConstants_1.ZERO;
|
|
2391
|
-
if ((
|
|
3008
|
+
if ((_g = marketPosition.isolatedPositionScaledBalance) === null || _g === void 0 ? void 0 : _g.gt(numericConstants_1.ZERO)) {
|
|
2392
3009
|
const quoteSpotMarket = this.velocityClient.getSpotMarketAccountOrThrow(market.quoteSpotMarketIndex);
|
|
2393
3010
|
const quoteOraclePriceData = this.getOracleDataForSpotMarket(market.quoteSpotMarketIndex);
|
|
2394
3011
|
const strictQuote = new strictOraclePrice_1.StrictOraclePrice(quoteOraclePriceData.price, strict
|
|
2395
3012
|
? quoteSpotMarket.historicalOracleData.lastOraclePriceTwap5Min
|
|
2396
3013
|
: undefined);
|
|
2397
|
-
const quoteTokenAmount = (0, spotBalance_2.getTokenAmount)((
|
|
3014
|
+
const quoteTokenAmount = (0, spotBalance_2.getTokenAmount)((_h = marketPosition.isolatedPositionScaledBalance) !== null && _h !== void 0 ? _h : numericConstants_1.ZERO, quoteSpotMarket, types_2.SpotBalanceType.DEPOSIT);
|
|
2398
3015
|
depositValue = (0, spotBalance_1.getStrictTokenValue)(quoteTokenAmount, quoteSpotMarket.decimals, strictQuote);
|
|
2399
3016
|
}
|
|
2400
|
-
calc.addIsolatedMarginCalculation(market.marketIndex, depositValue, positionUnrealizedPnl,
|
|
2401
|
-
calc.addPerpLiabilityValue(worstCaseLiabilityValue);
|
|
3017
|
+
calc.addIsolatedMarginCalculation(market.marketIndex, depositValue, positionUnrealizedPnl, worstCaseLiabilityValueQuote, perpMarginRequirement);
|
|
2402
3018
|
}
|
|
2403
3019
|
else {
|
|
2404
3020
|
// cross: add to global requirement and collateral
|
|
2405
|
-
calc.addCrossMarginRequirement(perpMarginRequirement,
|
|
3021
|
+
calc.addCrossMarginRequirement(perpMarginRequirement, worstCaseLiabilityValueQuote);
|
|
2406
3022
|
calc.addCrossMarginTotalCollateral(positionUnrealizedPnl);
|
|
2407
3023
|
}
|
|
3024
|
+
// mirrors margin.rs:616-617 — perp liability value accumulates for every
|
|
3025
|
+
// position regardless of the isolated/cross split, so it must run outside
|
|
3026
|
+
// the branch above (previously only the isolated branch accumulated it,
|
|
3027
|
+
// underreporting totalPerpLiabilityValue for cross positions)
|
|
3028
|
+
calc.addPerpLiabilityValue(worstCaseLiabilityValueQuote);
|
|
2408
3029
|
}
|
|
2409
3030
|
return calc;
|
|
2410
3031
|
}
|
|
3032
|
+
/**
|
|
3033
|
+
* Returns true if `perpPosition` was opened/is held under isolated margin
|
|
3034
|
+
* (`PositionFlag.IsolatedPosition` set) — segregated to its own margin
|
|
3035
|
+
* bucket (see `getMarginCalculation`) rather than sharing cross-margin
|
|
3036
|
+
* collateral with the rest of the account.
|
|
3037
|
+
*/
|
|
2411
3038
|
isPerpPositionIsolated(perpPosition) {
|
|
2412
3039
|
return (perpPosition.positionFlag & types_2.PositionFlag.IsolatedPosition) !== 0;
|
|
2413
3040
|
}
|
|
3041
|
+
/**
|
|
3042
|
+
* Pre-flight check for `IsolatedAssetTierViolation`: mirrors
|
|
3043
|
+
* `validate_any_isolated_tier_requirements` in `math/margin.rs`. A user
|
|
3044
|
+
* holding an isolated-tier perp or spot liability may not simultaneously
|
|
3045
|
+
* carry other liabilities (besides a single usdc borrow, for a perp
|
|
3046
|
+
* isolated liability), unless they are reduce-only.
|
|
3047
|
+
*
|
|
3048
|
+
* Specifically, if `calculation.withPerpIsolatedLiability` is set (an
|
|
3049
|
+
* isolated-*contract-tier* perp liability exists) and the user is not
|
|
3050
|
+
* `UserStatus.REDUCE_ONLY`: more than one perp liability is invalid; margin
|
|
3051
|
+
* trading enabled is invalid; and any spot liability other than a single
|
|
3052
|
+
* USDC borrow is invalid. If `calculation.withSpotIsolatedLiability` is set
|
|
3053
|
+
* (an isolated-*asset-tier* spot liability exists) and not reduce-only: any
|
|
3054
|
+
* perp liability, or more than the one isolated-tier spot liability, is invalid.
|
|
3055
|
+
* @param calculation A `MarginCalculation` from `getMarginCalculation` (any margin category — only the isolated-liability flags and liability counts are read).
|
|
3056
|
+
* @returns `{ valid: true }` if the account satisfies isolated-tier requirements, else `{ valid: false, reason }` with a human-readable reason.
|
|
3057
|
+
*/
|
|
3058
|
+
validateAnyIsolatedTierRequirements(calculation) {
|
|
3059
|
+
const userAccount = this.getUserAccountOrThrow();
|
|
3060
|
+
const isReduceOnly = this.hasStatus(types_1.UserStatus.REDUCE_ONLY);
|
|
3061
|
+
if (calculation.withPerpIsolatedLiability && !isReduceOnly) {
|
|
3062
|
+
if (calculation.numPerpLiabilities > 1) {
|
|
3063
|
+
return {
|
|
3064
|
+
valid: false,
|
|
3065
|
+
reason: 'User attempting to increase perp liabilities above 1 with a isolated tier liability',
|
|
3066
|
+
};
|
|
3067
|
+
}
|
|
3068
|
+
if (userAccount.isMarginTradingEnabled) {
|
|
3069
|
+
return {
|
|
3070
|
+
valid: false,
|
|
3071
|
+
reason: 'User attempting isolated tier liability with margin trading enabled',
|
|
3072
|
+
};
|
|
3073
|
+
}
|
|
3074
|
+
if (calculation.numSpotLiabilities > 0) {
|
|
3075
|
+
const quoteSpotPosition = this.getSpotPosition(numericConstants_1.QUOTE_SPOT_MARKET_INDEX);
|
|
3076
|
+
const quoteIsBorrow = !!quoteSpotPosition &&
|
|
3077
|
+
(0, types_1.isVariant)(quoteSpotPosition.balanceType, 'borrow');
|
|
3078
|
+
if (!(calculation.numSpotLiabilities === 1 && quoteIsBorrow)) {
|
|
3079
|
+
return {
|
|
3080
|
+
valid: false,
|
|
3081
|
+
reason: 'User attempting to increase spot liabilities beyond usdc with a isolated tier liability',
|
|
3082
|
+
};
|
|
3083
|
+
}
|
|
3084
|
+
}
|
|
3085
|
+
}
|
|
3086
|
+
if (calculation.withSpotIsolatedLiability && !isReduceOnly) {
|
|
3087
|
+
if (!(calculation.numPerpLiabilities === 0 &&
|
|
3088
|
+
calculation.numSpotLiabilities === 1)) {
|
|
3089
|
+
return {
|
|
3090
|
+
valid: false,
|
|
3091
|
+
reason: 'User attempting to increase perp liabilities above 0 with a isolated tier liability',
|
|
3092
|
+
};
|
|
3093
|
+
}
|
|
3094
|
+
}
|
|
3095
|
+
return { valid: true };
|
|
3096
|
+
}
|
|
2414
3097
|
}
|
|
2415
3098
|
exports.User = User;
|