fix: in the position card, when user has multiple TP (or SL) orders, Then display TP (or SL) orders count instead of the position TP (or SL) priceof - #9912
Merged
Conversation
A partial (quantity-scoped) take profit cannot be position-bound, so it is placed as a standalone reduce-only trigger. The scalar summary fields takeProfitPrice/stopLossPrice were only ever scanned from position-bound triggers, so a position whose only take profit was partial reported takeProfitCount: 1 with no price, and clients rendering the scalar showed none. Add resolvePositionTriggerSummaryPrice and use it wherever the summary is assembled — REST getPositions, getUserDataSnapshot, and the WebSocket merge — so a lone trigger reports its own price whatever its grouping. Two or more triggers keep the scanned value, since clients render the count instead.
abretonc7s
marked this pull request as ready for review
August 19, 2026 16:38
The Unreleased entries carried placeholder #0000 links, which the Check changelog workflow rejects: it requires each entry to link to the current PR.
geositta
approved these changes
Aug 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Explanation
A partial (quantity-scoped) take profit cannot be position-bound — a position-bound
trigger always closes the whole position — so
updatePositionTPSLplaces it withgrouping: 'na'as a standalone reduce-only trigger. The scalar summary fieldsPosition.takeProfitPrice/stopLossPricewere only ever scanned fromposition-bound triggers, so a position whose only take profit was partial reported
takeProfitCount: 1with no price at all. Clients that render the scalar — themobile position card among them — showed nothing where a price belongs.
This adds
resolvePositionTriggerSummaryPriceto@metamask/perps-controller/utilsand uses it wherever a position's TP/SL summary is assembled: when a direction has
exactly one trigger order, that order's price is the summary price, partial or not.
Two or more triggers keep the previously scanned value, because no single price
describes them and clients render
takeProfitCountinstead; zero triggers keep ittoo, since it still carries the TP/SL of a pending order on the market, which the
trigger arrays deliberately exclude.
The same summary is computed at three independent sites — the REST
getPositionspath,
getUserDataSnapshot, and the WebSocket merge inHyperLiquidSubscriptionService. All three now go through the helper, so the price aposition reports no longer depends on whether the WebSocket cache happens to be warm.
Note for clients: a partial take profit now surfaces on the scalar. A TP/SL editor
that prefills from
takeProfitPriceshould key offtakeProfitOrders/takeProfitCountinstead, so a partial trigger is not silently offered up forreplacement by a whole-position one.
Proved end to end against HyperLiquid testnet: one real partial take profit attached
through the controller's signing path, read back through
PerpsController.getUserDataSnapshot()—takeProfitPricewasnullbefore thechange and carries the trigger's price after, with a whole-position replacement
asserted in the same run to cover the pre-existing path.
References
Checklist
Note
Cursor Bugbot is generating a summary for commit ec70743. Configure here.