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