Skip to content

fix(perps): tpsl builder fee readiness - #9997

Merged
abretonc7s merged 4 commits into
mainfrom
fix/tpsl-builder-fee-readiness
Aug 28, 2026
Merged

fix(perps): tpsl builder fee readiness#9997
abretonc7s merged 4 commits into
mainfrom
fix/tpsl-builder-fee-readiness

Conversation

@geositta

@geositta geositta commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

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 maxBuilderFee request over a reconnecting WebSocket. HyperLiquid rejected it with WebSocketRequestError, which updatePositionTPSL surfaced as TPSL_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. maxBuilderFee was 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:

  • Full @metamask/perps-controller test suite
  • Builder-fee and strategy-order suites
  • Monorepo build
  • Changelog validation and scoped lint/format checks
  • Mobile simulator: first +50/-50 TP/SL edit succeeded after reload

References

  • Discovered while validating #9995

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

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_FAILED because the builder-fee approval check (maxBuilderFee) went over a reconnecting HyperLiquid WebSocket and threw WebSocketRequestError.

#checkBuilderFeeApproval in HyperLiquidProvider now requests the info client with useHttp: true, so that read uses the HTTP InfoClient path 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 maxBuilderFee and asserts cold-start updatePositionTPSL succeeds 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.

geositta and others added 2 commits August 27, 2026 23:31
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
geositta marked this pull request as ready for review August 28, 2026 04:37
@geositta
geositta requested review from a team as code owners August 28, 2026 04:37
@geositta
geositta deployed to default-branch August 28, 2026 04:37 — with GitHub Actions Active
@geositta geositta changed the title Fix/tpsl builder fee readiness fix(perps): tpsl builder fee readiness Aug 28, 2026
Associate the unreleased changelog entry with its pull request so automated changelog checks can verify it.

Co-authored-by: Cursor <cursoragent@cursor.com>
abretonc7s
abretonc7s previously approved these changes Aug 28, 2026
@abretonc7s
abretonc7s added this pull request to the merge queue Aug 28, 2026
@github-merge-queue
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
abretonc7s added this pull request to the merge queue Aug 28, 2026
Merged via the queue into main with commit 0289347 Aug 28, 2026
47 checks passed
@abretonc7s
abretonc7s deleted the fix/tpsl-builder-fee-readiness branch August 28, 2026 08:58
@geositta geositta mentioned this pull request Aug 28, 2026
10 tasks
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 -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants