fix(perps): tpsl builder fee readiness - #9997
Merged
Merged
Conversation
Avoid failing the first TP/SL update when the WebSocket reconnects during builder fee approval lookup. Co-authored-by: Cursor <cursoragent@cursor.com>
Record the cold-start TP/SL reliability fix in the unreleased changelog. Co-authored-by: Cursor <cursoragent@cursor.com>
geositta
marked this pull request as ready for review
August 28, 2026 04:37
Associate the unreleased changelog entry with its pull request so automated changelog checks can verify it. Co-authored-by: Cursor <cursoragent@cursor.com>
abretonc7s
previously approved these changes
Aug 28, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to a conflict with the base branch
Aug 28, 2026
…readiness # Conflicts: # packages/perps-controller/CHANGELOG.md
abretonc7s
enabled auto-merge
August 28, 2026 08:51
michalconsensys
approved these changes
Aug 28, 2026
pull Bot
pushed a commit
to Reality2byte/core
that referenced
this pull request
Aug 28, 2026
## Explanation Releases `@metamask/perps-controller` **13.1.0 → 14.0.0**. The monorepo version goes **1216.0.0 → 1217.0.0**. No other package is being published. Perps-controller has no in-monorepo dependents that need a workspace range bump. The bump is **major**. Adding a required method on the public `PerpsProvider` type is a breaking type change: - **Added (breaking):** `PerpsController.previewPositionModify` and required `PerpsProvider.previewPositionModify` so clients can read an isolated-margin post-trade projection without placing an order ([MetaMask#9968](MetaMask#9968)). Consumers that **implement** `PerpsProvider` must add the method. In-repo providers (`HyperLiquidProvider`, `MYXProvider`, `AggregatedPerpsProvider`) already implement it. Mobile and Extension consume the controller; they do not implement `PerpsProvider`, so they can upgrade without a source change. Client wiring to *call* the API is follow-up (pro-mode increase/decrease UX). - **Fixed:** Transient HyperLiquid WebSocket disconnects no longer fail the first TP/SL update; builder-fee approval is checked over HTTP ([MetaMask#9997](MetaMask#9997)). - **Fixed:** `updatePositionTPSL` no longer reports `TPSL_UPDATE_FAILED` when HyperLiquid accepts a trigger with `waitingForTrigger`; accepted triggers without response order IDs are reconciled before mixed-failure cleanup ([MetaMask#9995](MetaMask#9995)). ## Changelog Moved Unreleased entries in `packages/perps-controller/CHANGELOG.md` under `[14.0.0]`. Breaking entry is prefixed with `**BREAKING:**` and includes adaptation notes. ## References - Source PRs: [MetaMask#9968](MetaMask#9968), [MetaMask#9997](MetaMask#9997), [MetaMask#9995](MetaMask#9995) - No draft Mobile/Extension PRs: neither client implements `PerpsProvider`. Preview-build upgrade PRs are not required to keep those clients compiling. ## Checklist - [x] I've updated the test suite for new or updated code as appropriate - [x] I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate - [x] I've communicated my changes to consumers by [updating changelogs for packages I've changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md) - [ ] I've introduced [breaking changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md) in this PR and have prepared draft pull requests for clients and consumer packages to resolve them — **N/A for clients:** they do not implement `PerpsProvider`. In-repo implementors were updated in [MetaMask#9968](MetaMask#9968). ## Release review - [x] No packages with version bumps that should not be published (`@metamask/perps-controller` only) - [x] New version string matches impact (major 14.0.0 for required `PerpsProvider` method) - [x] Changelog entries are consumer-facing, categorized, and link to the introducing PRs - [x] Breaking change is prefixed with `**BREAKING:**` and describes how to adapt - [x] No Unreleased leftover entries for this package - [ ] Recheck `main` for commits merged while this PR is open and update changelogs if they touch perps-controller <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > No runtime or type changes in the diff; risk is limited to consumers upgrading to 14.0.0 and implementing the new required `PerpsProvider` method if they are custom providers. > > **Overview** > **Release 1217.0.0** cuts a new publish of **`@metamask/perps-controller` only** (13.1.0 → **14.0.0**); the root monorepo version moves 1216.0.0 → 1217.0.0. > > The diff is versioning and changelog housekeeping: Unreleased notes are filed under **`[14.0.0]`**, compare links are updated, and a minor punctuation fix is applied on a 13.1.0 entry. The **14.0.0** notes describe what ships with this tag—chiefly the **breaking** required `PerpsProvider.previewPositionModify` / `PerpsController.previewPositionModify` API ([MetaMask#9968](MetaMask#9968)), plus HyperLiquid TP/SL fixes ([MetaMask#9997](MetaMask#9997), [MetaMask#9995](https://github.com/MetaMask/core/pull/9995))—already merged on `main`, not introduced in this PR’s file changes. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 95c2e07. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
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
The first TP/SL edit after Mobile reload could fail before cancellation or placement because the builder-fee approval lookup sent the one-off
maxBuilderFeerequest over a reconnecting WebSocket. HyperLiquid rejected it withWebSocketRequestError, whichupdatePositionTPSLsurfaced asTPSL_UPDATE_FAILED; a later retry succeeded after reconnection.This routes builder-fee approval reads through the existing HTTP
InfoClient, which is designed for request/response operations and remains available during WebSocket churn.maxBuilderFeewas not a subscription, so this does not remove live updates or change existing approval-cache semantics. Genuine approval failures still block replacement before existing protection is cancelled.Adds regression coverage with distinct WebSocket and HTTP clients and updates the perps-controller changelog. No dependencies or other packages are changed.
Validation:
@metamask/perps-controllertest suite+50/-50TP/SL edit succeeded after reloadReferences
Checklist
Note
Low Risk
Narrow transport change for a read-only approval lookup on an existing HTTP code path; regression test covers the TP/SL cold-start scenario.
Overview
Fixes a case where the first position TP/SL update after app reload could fail with
TPSL_UPDATE_FAILEDbecause the builder-fee approval check (maxBuilderFee) went over a reconnecting HyperLiquid WebSocket and threwWebSocketRequestError.#checkBuilderFeeApprovalinHyperLiquidProvidernow requests the info client withuseHttp: true, so that read uses the HTTPInfoClientpath that stays usable during socket churn. Approval caching and real approval/signing behavior are unchanged; only the lookup transport changes.Adds a regression test that simulates a failing WebSocket
maxBuilderFeeand asserts cold-startupdatePositionTPSLsucceeds via HTTP, plus an Unreleased changelog entry.Reviewed by Cursor Bugbot for commit 3e2cffb. Bugbot is set up for automated code reviews on this repo. Configure here.