Skip to content

feat(transaction-pay-controller): add HyperLiquid withdrawal submission via Relay#8314

Merged
dan437 merged 5 commits intomainfrom
perps-withdraw-any-token
Mar 27, 2026
Merged

feat(transaction-pay-controller): add HyperLiquid withdrawal submission via Relay#8314
dan437 merged 5 commits intomainfrom
perps-withdraw-any-token

Conversation

@dan437
Copy link
Copy Markdown
Contributor

@dan437 dan437 commented Mar 26, 2026

Explanation

The quote support for Perps Withdraw was added in #8285. This PR completes the feature by adding the submission flow — the 2-step gasless withdrawal from HyperLiquid via Relay.

When isHyperliquidSource is set on the transaction config, executeSingleQuote now routes to submitHyperliquidWithdraw instead of submitTransactions. This function executes two EIP-712 signing steps:

  1. Authorize — signs a nonce-mapping message and POSTs the signature to Relay's /authorize endpoint, linking the HyperLiquid withdrawal to the Relay order.
  2. Deposit — signs a HyperLiquid sendAsset action and POSTs it to the HyperLiquid exchange API, instructing HL to transfer funds to the Relay solver.

After both steps complete, the existing waitForRelayCompletion polling takes over to track the cross-chain fill on the destination chain.

Key changes

  • New file hyperliquid-withdraw.ts — implements submitHyperliquidWithdraw with the 2-step authorize + deposit flow, EIP-712 domain derivation, and signature r/s/v parsing for the HyperLiquid exchange API format.
  • relay-submit.ts — routes to submitHyperliquidWithdraw when isHyperliquidSource is true; no changes to waitForRelayCompletion or existing submission logic.
  • types.ts — adds KeyringControllerSignTypedMessageAction to AllowedActions (required for silent EIP-712 signing via the keyring controller messenger).
  • constants.ts — adds RELAY_AUTHORIZE_URL and HYPERLIQUID_EXCHANGE_URL endpoints.

References

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

High Risk
Adds a new HyperLiquid withdrawal submission path that performs silent EIP-712 signing and posts signatures to external Relay/HyperLiquid endpoints, plus a breaking messenger permission expansion. Incorrect step parsing/signature construction or permission wiring could cause failed withdrawals or unintended signing behavior.

Overview
Adds a new HyperLiquid withdrawal submission flow for the Relay strategy: when quote.request.isHyperliquidSource is set, relay-submit skips on-chain TransactionController submissions and instead runs a two-step submitHyperliquidWithdraw flow (Relay /authorize EIP-712 signature, then HyperLiquid exchange sendAsset EIP-712 signature + r/s/v POST), before continuing with the existing Relay status polling.

Introduces new endpoints (RELAY_AUTHORIZE_URL, HYPERLIQUID_EXCHANGE_URL), adds comprehensive unit tests for the new withdraw module and the new routing branch, and expands AllowedActions with KeyringControllerSignTypedMessageAction (breaking) so clients must grant KeyringController:signTypedMessage when constructing the controller messenger.

Written by Cursor Bugbot for commit 3240f3d. This will update automatically on new commits. Configure here.

@dan437 dan437 requested a review from a team as a code owner March 26, 2026 13:39
@dan437 dan437 force-pushed the perps-withdraw-any-token branch from f632486 to 8419a95 Compare March 26, 2026 14:04
@dan437 dan437 requested a review from a team as a code owner March 26, 2026 14:15
@dan437 dan437 force-pushed the perps-withdraw-any-token branch from 5ecfe7b to aac2a19 Compare March 27, 2026 12:23
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

dan437 added 5 commits March 27, 2026 13:35
Signed-off-by: dan437 <80175477+dan437@users.noreply.github.com>
Signed-off-by: dan437 <80175477+dan437@users.noreply.github.com>
Signed-off-by: dan437 <80175477+dan437@users.noreply.github.com>
Signed-off-by: dan437 <80175477+dan437@users.noreply.github.com>
@dan437 dan437 force-pushed the perps-withdraw-any-token branch from aac2a19 to 3240f3d Compare March 27, 2026 12:36
@dan437 dan437 enabled auto-merge March 27, 2026 12:48

### Added

- **BREAKING:** Add `KeyringControllerSignTypedMessageAction` to `AllowedActions` for HyperLiquid EIP-712 signing ([#8314](https://github.com/MetaMask/core/pull/8314))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor, this could go under the other new option.

@dan437 dan437 added this pull request to the merge queue Mar 27, 2026
Merged via the queue into main with commit 73192e9 Mar 27, 2026
327 checks passed
@dan437 dan437 deleted the perps-withdraw-any-token branch March 27, 2026 12:58
github-merge-queue bot pushed a commit to MetaMask/metamask-mobile that referenced this pull request Mar 30, 2026
…ig (#28046)

## **Description**

Wires up the confirmation UI and post-quote logic so that
`perpsWithdraw` transactions go through the correct gasless HyperLiquid
withdrawal flow via Relay.

This is the second of two PRs for Perps Withdraw (follows the first one
which added activity/display support).

### Changes

- **Post-quote config** (`useTransactionPayPostQuote`): Sets
`isHyperliquidSource = true` for perps withdrawals, skips `refundTo`
(funds go HyperCore → Relay directly, no Safe proxy involved)
- **Custom amount** (`useTransactionCustomAmount`): Sources available
balance from `PerpsController.state.accountState.availableBalance` for
perps withdrawals
- **Insufficient balance alert** (`useInsufficientBalanceAlert`):
Suppresses the "not enough ETH for gas" alert for `perpsWithdraw` since
the withdrawal is gasless
- **Confirmation UI**: Adds `perpsWithdraw` to
`TRANSACTION_TYPES_DISABLE_ALERT_BANNER`,
`HIDE_FOOTER_BY_DEFAULT_TYPES`, and `GO_BACK_TYPES`
- **Bridge fee row**: Shows withdraw-specific tooltip text and "Provider
fee" label for `perpsWithdraw`
- **Metrics** (`useTransactionPayMetrics`): Includes `perpsWithdraw` in
pay metrics tracking
- **TPC bump**: Bumps `@metamask/transaction-pay-controller` to
`^19.0.0` which includes the HyperLiquid submission logic

### Core dependency

- [feat(transaction-pay-controller): add HyperLiquid withdrawal
submission via Relay](MetaMask/core#8314)

## **Changelog**

CHANGELOG entry: Add Perps Withdraw confirmation flow

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/CONF-1115

## **Manual testing steps**

~~~gherkin
Feature: Perps Withdraw confirmation flow

  Scenario: user withdraws from HyperLiquid Perps to any token
    Given the user has a funded HyperLiquid Perps account
And the user navigates to the Perps Withdraw page via Developer Options

    When user enters a withdrawal amount
    And selects a destination token (e.g. BNB)
    Then the transaction fee is shown with a tooltip
    And no "Insufficient funds" alert is displayed
    And the available Perps balance is shown correctly

    When user confirms the withdrawal
    Then the withdrawal completes successfully
    And the transaction appears in the Activity list as "Perps withdraw"
~~~

## **Screenshots/Recordings**

### **Before**

N/A

### **After**

N/A

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **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.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Adds new `perpsWithdraw` handling across confirmation UI and
Transaction Pay configuration, and bumps
`@metamask/transaction-pay-controller` to a new major version;
regressions could affect withdrawal routing, fee display, or
gasless/sponsored alerting.
> 
> **Overview**
> Enables a dedicated confirmation + payment flow for `perpsWithdraw`
transactions, including **post-quote configuration** that marks
withdrawals as Hyperliquid-sourced and skips `refundTo`.
> 
> Updates confirmation UX/behavior to treat `perpsWithdraw` like other
special flows (hide footer/alert banner by default, adjust back
navigation), **suppresses insufficient-gas alerts** for gasless
withdrawals, and adds a withdraw-specific transaction-fee tooltip
string. Also extends pay metrics (`mm_pay_use_case`) and custom-amount
percentage calculations to use Perps available balance.
> 
> Separately bumps CI iOS bundle-size threshold (53→54) and updates
fixtures/snapshots for new controller state fields; upgrades
`@metamask/transaction-pay-controller` to `^19.0.0` (with associated
lockfile churn).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f9ec71e. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Signed-off-by: dan437 <80175477+dan437@users.noreply.github.com>
github-merge-queue bot pushed a commit to MetaMask/metamask-mobile that referenced this pull request Apr 1, 2026
…ig (#28236)

## **Description**

Wires up the confirmation UI and post-quote logic so that
`perpsWithdraw` transactions go through the correct gasless HyperLiquid
withdrawal flow via Relay.

This is the second of two PRs for Perps Withdraw (follows the first one
which added activity/display support).

### Changes

- **Post-quote config** (`useTransactionPayPostQuote`): Sets
`isHyperliquidSource = true` for perps withdrawals, skips `refundTo`
(funds go HyperCore → Relay directly, no Safe proxy involved)
- **Custom amount** (`useTransactionCustomAmount`): Sources available
balance from `PerpsController.state.accountState.availableBalance` for
perps withdrawals
- **Insufficient balance alert** (`useInsufficientBalanceAlert`):
Suppresses the "not enough ETH for gas" alert for `perpsWithdraw` since
the withdrawal is gasless
- **Confirmation UI**: Adds `perpsWithdraw` to
`TRANSACTION_TYPES_DISABLE_ALERT_BANNER`,
`HIDE_FOOTER_BY_DEFAULT_TYPES`, and `GO_BACK_TYPES`
- **Bridge fee row**: Shows withdraw-specific tooltip text and "Provider
fee" label for `perpsWithdraw`
- **Metrics** (`useTransactionPayMetrics`): Includes `perpsWithdraw` in
pay metrics tracking

### Core dependency

- [feat(transaction-pay-controller): add HyperLiquid withdrawal
submission via Relay](MetaMask/core#8314)

## **Changelog**

CHANGELOG entry: Add Perps Withdraw confirmation flow

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/CONF-1115

## **Manual testing steps**

~~~gherkin
Feature: Perps Withdraw confirmation flow

  Scenario: user withdraws from HyperLiquid Perps to any token
    Given the user has a funded HyperLiquid Perps account
And the user navigates to the Perps Withdraw page via Developer Options

    When user enters a withdrawal amount
    And selects a destination token (e.g. BNB)
    Then the transaction fee is shown with a tooltip
    And no "Insufficient funds" alert is displayed
    And the available Perps balance is shown correctly

    When user confirms the withdrawal
    Then the withdrawal completes successfully
    And the transaction appears in the Activity list as "Perps withdraw"
~~~

## **Screenshots/Recordings**

### **Before**

N/A

### **After**

N/A

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **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.



<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Adds new `perpsWithdraw` handling across confirmation UI and
Transaction Pay post-quote configuration; mistakes could misroute
withdrawals or misconfigure bridge/refund behavior. Changes are scoped
to the confirmations/pay flow and include tests and copy updates.
> 
> **Overview**
> Enables the confirmations flow to properly support **Perps
withdrawals** (`TransactionType.perpsWithdraw`) across UI behavior, fee
display, and Transaction Pay configuration.
> 
> Perps withdrawals are now treated as *gasless/Hyperliquid-sourced* in
`useTransactionPayPostQuote` (sets `isPostQuote` and
`isHyperliquidSource`, and skips `refundTo`), suppress the insufficient
native-balance alert, and use
`PerpsController.state.accountState.availableBalance` for custom-amount
percentage calculations.
> 
> Confirmation presentation is adjusted for `perpsWithdraw` (hide alert
banner/footer by default and include it in go-back handling), and the
transaction-fee tooltip/copy is extended with a new `perps_withdraw`
localized message; related unit tests were updated/added.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
8fdd9cb. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=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.

2 participants