Skip to content

chore(runway): cherry-pick feat(perps): force unified account#29673

Merged
chloeYue merged 1 commit into
release/7.75.1from
cherry-pick-7-75-1-cc44460
May 4, 2026
Merged

chore(runway): cherry-pick feat(perps): force unified account#29673
chloeYue merged 1 commit into
release/7.75.1from
cherry-pick-7-75-1-cc44460

Conversation

@runway-github

@runway-github runway-github Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor

Description

HyperLiquid is deprecating DEX Abstraction mode (~May 9). This PR forces
every Perps user onto Unified Account mode on app open and fixes the
withdraw + balance-display flows that were broken in the target state.

1. Forced migration to Unified Account

Migration paths by current abstraction mode:

  • default / disabled → silently migrated via agentSetAbstraction({ abstraction: 'u' }) — no signing prompt
  • dexAbstraction → one-time EIP-712 prompt via userSetAbstraction({ user, abstraction: 'unifiedAccount' }) — agent-key path is blocked by
    HL for this transition
  • unifiedAccount → no-op, cached immediately

Key details:

  • Replaces deprecated agentEnableDexAbstraction / userDexAbstraction
    with agentSetAbstraction / userSetAbstraction / userAbstraction
  • Runs on perps section open (#ensureReady()) so users are set up
    before trading
  • TradingReadinessCache prevents repeated prompts (critical for
    hardware/QR wallets); KEYRING_LOCKED skips the cache so it retries on
    unlock
  • In-flight deduplication blocks concurrent signing attempts across
    provider instances
  • Segment analytics: Perp Account Setup event tracks mode distribution
  • outcome (already_enabled / migration_required / success /
    failed)

2. Withdraw + balance display fix (folded in from #29537)

In Unified mode, USDC collateral lives in the spot clearinghouse, so
clearinghouseState.withdrawable is $0 — pre-fix the withdraw screen
showed $0 max with the button disabled, and the confirm-flow alert
blocked submission.

  • accountUtils.addSpotBalanceToAccountState folds free spot USDC into
    availableToTradeBalance for Unified / Portfolio Margin;
    dexAbstraction / Standard keep spot separate (fold gated on resolved
    abstraction mode)
  • HyperLiquidSubscriptionService.invalidateUserAbstractionCache(addr)
    evicts stale pre-migration mode and re-aggregates immediately. Called by
    HyperLiquidProvider after both successful migration paths so the
    WS-driven aggregator doesn't serve a $0 balance for ~60s after migration
    completes.
  • Withdraw screen, withdraw validation, confirm-flow
    insufficient-balance alert, and percentage buttons all read
    availableToTradeBalance ?? availableBalance — fallback keeps Standard
    / legacy callers correct.

Changelog

CHANGELOG entry: Fixed Hyperliquid withdraw showing $0 and being blocked
for users on Unified Account mode.

Related issues

Fixes: TAT-3112 (Unified Account migration), withdrawal break tracked in
TAT-3047

Manual testing steps

Feature: Unified Account migration + withdraw

  Scenario: First-time migration (default/disabled mode)
    Given the user has never used Perps
    When they open the Perps section
    Then migration runs silently (no prompt)
    And HIP-3 markets are visible

  Scenario: dexAbstraction → unifiedAccount migration
    Given the user has DEX Abstraction enabled
    When they open the Perps section
    Then a one-time EIP-712 signing prompt appears
    When they sign
    Then HIP-3 markets are visible and trades succeed
    And reopening Perps does not prompt again

  Scenario: Unified Account user withdraws spot-funded balance
    Given the user is in Unified Mode with $0 perps withdrawable and >$0 spot USDC
    When they open the Withdraw screen
    Then "Available Perps balance" shows the unified value (perps + free spot USDC)
    And Max enables and submission proceeds via withdraw3
    And spot USDC drops by amount + fee

Live validation evidence

Validated on dev1 mainnet (0x8dc6…9003) in the exact bug-class state:

  • HL mode: unifiedAccount / perps withdrawable: $0 / spot USDC free:
    $26.41
  • App: availableBalance = $0 / availableToTradeBalance = $26.41
  • Withdraw screen renders "Available Perps balance: $26.41" + Max
    enabled (pre-fix would show $0 / disabled)

Screenshots/Recordings

Before

After

Pre-merge author checklist

Performance checks (if applicable)

  • I've tested on Android
  • I've tested with a power user scenario
  • I've instrumented key operations with Sentry traces for production
    performance metrics

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the
    app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described
    in the ticket it closes and includes the necessary testing evidence such
    as recordings and or screenshots.

Note

High Risk
High risk because it changes Perps account-mode migration/signing flow
(including hardware-wallet behavior) and alters withdraw/payment balance
calculations that gate user funds and transaction validation.

Overview
Forces Perps users onto HyperLiquid Unified Account by replacing
deprecated DEX-abstraction checks/calls with userAbstraction +
agentSetAbstraction/userSetAbstraction, adding global
in-flight/cached gating, retry semantics, and new Perp Account Setup
analytics.

Updates withdraw, confirmation, and pay-with flows to prefer
availableToTradeBalance ?? availableBalance, and changes spot→perps
folding to be mode-gated (fail-closed when abstraction mode is
unknown) so Unified/Portfolio Margin users see spendable USDC while
Standard/dexAbstraction users don’t over-report withdrawable funds.

Renames cache-clearing APIs from DEX abstraction to Unified Account,
adds hardware-wallet detection to defer user-sign prompts on browse, and
expands tests/docs to cover unified-mode folding, migration paths, and
race conditions in spot/account aggregation.

Reviewed by Cursor Bugbot for commit
e5495f9. Bugbot is set up for automated
code reviews on this repo. Configure
here.


Co-authored-by: geositta matthew.denton@consensys.net
Co-authored-by: Nick Gambino nicholas.gambino@consensys.net
Co-authored-by: Arthur Breton arthur.breton@consensys.net
Co-authored-by: abretonc7s 107169956+abretonc7s@users.noreply.github.com cc44460

@runway-github runway-github Bot requested review from a team as code owners May 4, 2026 16:41
@github-actions

github-actions Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbotv2 metamaskbotv2 Bot added the team-bots Bot team (for MetaMask Bot, Runway Bot, etc.) label May 4, 2026
@github-actions

github-actions Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

⏭️ Smart E2E selection skipped - PR targets a release branch (release/*)

All E2E tests pre-selected.

View GitHub Actions results

@gambinish

Copy link
Copy Markdown
Member

Please don't merge yet. Verifying one last thing

@gambinish gambinish added DO-NOT-MERGE Pull requests that should not be merged and removed DO-NOT-MERGE Pull requests that should not be merged labels May 4, 2026
@gambinish

Copy link
Copy Markdown
Member

Okay, all good. Feel free to merge when ready

@sonarqubecloud

sonarqubecloud Bot commented May 4, 2026

Copy link
Copy Markdown

@github-actions

github-actions Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor

E2E Fixture Validation — Schema is up to date
12 value mismatches detected (expected — fixture represents an existing user).
View details

@chloeYue chloeYue merged commit b166faf into release/7.75.1 May 4, 2026
219 of 224 checks passed
@chloeYue chloeYue deleted the cherry-pick-7-75-1-cc44460 branch May 4, 2026 18:43
@github-actions github-actions Bot locked and limited conversation to collaborators May 4, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

size-XL team-bots Bot team (for MetaMask Bot, Runway Bot, etc.)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants