Skip to content

fix: ledger ETH app errors#26322

Merged
dawnseeker8 merged 38 commits into
mainfrom
fix/ledger-transaction-not-displayed-after-eth-app-open
Mar 6, 2026
Merged

fix: ledger ETH app errors#26322
dawnseeker8 merged 38 commits into
mainfrom
fix/ledger-transaction-not-displayed-after-eth-app-open

Conversation

@dawnseeker8

@dawnseeker8 dawnseeker8 commented Feb 20, 2026

Copy link
Copy Markdown
Contributor

Description

This PR solve multiple issues related to the ledger ETH app. These are issue #24547, #25631, and #25947

Changelog

CHANGELOG entry: fix Ledger transaction not displayed after opening ETH app.
CHANGELOG entry: fix pagination and unlock accounts uninformative error after opening ETH app

Related issues

Fixes: #24547
Fixes: #25631
Fixes: #25947

Manual testing steps

Steps to reproduce

#24547
Open MM mobile

  1. Add hardware wallet
  2. Connect Ledger Nano X wallet
  3. On Ledger, have the ETH app installed, but don't open it
  4. On MM, initiate Send/Swap transaction
  5. On MM, confirm the transaction
  6. On MM, view the "please open the ETH app" notification
  7. On Ledger, open the ETH app
  8. On MM, notice that the "confirm transaction on your ledger" info
  9. On ledger, The transaction is displayed for review

#25631

  • on Ledger, open the ETH app
  • start with connecting MM to Ledger and get to the Select an Account screen
  • on Ledger, quit the ETH app
  • in MM, select an account and click “Unlock”
  • Notice the error message: Please open the ETH app on your Ledger device - the fix works as expected
  • in Ledger, open the ETH app
  • in MM, select few more Ledger accounts tap Unlock
  • Flow should continue, and everything should work without errors.

#25947

  • on Ledger, open the BTC app
  • start with connecting MM to Ledger and get to the Connect Ledger screen
  • tap Continue and notice the loader
  • on the Ledger device, notice that the BTC app is closed automatically
  • on Ledger, open the ETH app
  • Ledger should open ETH app and continue.

Screenshots/Recordings

Before

Check issues: #24547 #25631 #25947

After

TBC...

Pre-merge author checklist

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

Medium Risk
Refactors Ledger BLE workflow/retry and disconnect handling, which can affect hardware-wallet connection stability and signing flows. Risk is mitigated by substantial new unit coverage across app-switch, error-classification, and retry scenarios.

Overview
Fixes Ledger ETH-app recovery issues by routing account pagination/unlock flows through useLedgerBluetooth.ledgerLogicToRun, ensuring operations resume cleanly after prompting users to open/close the Ethereum app and avoiding stuck loading or misleading disconnect errors.

Refactors useLedgerBluetooth to use a mockable loadBleTransport wrapper (instead of native dynamic import), adds explicit disconnect classification via new ledgerErrors helpers (DISCONNECT_ERROR_NAMES, isDisconnectError), and hardens reconnect/disconnect state handling (including app-switch recursion + restart limits). Tests are significantly expanded for the hook and updated for LedgerBluetoothAdapter transient BLE retry behavior.

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

…24547)

The BLE transport disconnects when the Ledger switches from BOLOS to the
Ethereum app. If the disconnect races ahead of the APDU response, the
`openEthereumAppOnLedger()` promise rejects and the workflow restart
state (`shouldRestartConnection` / `workflowSteps`) is never set,
preventing the disconnect handler from re-entering the signing flow.

Move the restart registration before the APDU calls that trigger the
disconnect and treat `DisconnectedDevice*` errors as expected (non-fatal)
during app-switch so the reconnect handler can resume the workflow.

The same pattern is applied to `closeRunningAppOnLedger()`.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

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.

This update introduces an `isReconnecting` ref to manage late Bluetooth Low Energy (BLE) disconnects during app-switching. The hook now prevents workflow steps from being cleared when a disconnect occurs while processing the app switch. Additionally, the documentation has been updated to reflect this internal mechanism, noting that it cannot be tested due to transport mock limitations.
Comment thread app/components/hooks/Ledger/useLedgerBluetooth.ts
Comment thread app/components/hooks/Ledger/useLedgerBluetooth.ts Outdated
…dling

This commit modifies the `ledgerLogicToRun` function to utilize a ref, allowing for better management of asynchronous operations within the `LedgerSelectAccount` component. The changes ensure that the latest version of `ledgerLogicToRun` is always referenced during execution, enhancing the reliability of ledger operations. Additionally, the test files are updated to reflect this change in behavior.
This commit modifies the `ledgerLogicToRun` function in the `LedgerSelectAccount` tests to accept a transport parameter, enhancing its async handling capabilities. The change ensures that the function can be called with an undefined transport, improving the flexibility of the mock implementation. Corresponding test updates have been made to reflect this change.
@dawnseeker8 dawnseeker8 changed the title fix: resolve Ledger transaction not displayed after opening ETH app (#24547) fix: Resolve issue relative in ledger after opening ETH app (#24547 #25631) Feb 23, 2026
…ive error handling

This commit refactors the `isDisconnectError` function to be re-exported from `ledgerErrors`, enhancing its accessibility across the codebase. The tests for `isDisconnectError` have been updated to ensure comprehensive coverage, including various error scenarios. Additionally, the documentation has been improved to clarify the purpose of the `DISCONNECT_ERROR_NAMES` constant and its usage in error classification.
@dawnseeker8 dawnseeker8 changed the title fix: Resolve issue relative in ledger after opening ETH app (#24547 #25631) fix: Resolve issue relative in ledger after opening ETH app (#24547 #25631 #25947) Feb 23, 2026
dawnseeker8 and others added 3 commits February 23, 2026 12:10
…lity and maintaining existing functionality. Comprehensive tests have been added to ensure proper behavior with the Bluetooth transport.
@github-actions github-actions Bot added size-XL and removed size-M labels Feb 23, 2026
Comment thread app/components/hooks/Ledger/useLedgerBluetooth.ts Outdated
…ror recovery

This commit adds comprehensive tests to the `useLedgerBluetooth` hook, ensuring it properly handles synchronous disconnects during app operations and resets the reconnecting state on errors. The tests cover scenarios for both BOLOS and non-Ethereum app interactions, verifying that the hook maintains expected behavior and error states during these operations.
Comment thread app/components/Views/LedgerSelectAccount/index.tsx
Comment thread app/components/Views/LedgerSelectAccount/index.tsx
Comment thread app/components/hooks/Ledger/useLedgerBluetooth.ts
Comment thread app/components/hooks/Ledger/useLedgerBluetooth.ts Outdated
Comment thread app/components/Views/LedgerSelectAccount/index.tsx
dawnseeker8 and others added 4 commits February 24, 2026 08:21
…ount component

- Enhanced error handling in ledger account fetching functions to ensure error messages are displayed correctly.
- Updated loading modal visibility management to ensure it is consistently shown and hidden during asynchronous operations.
- Refactored pagination logic to streamline account retrieval for next and previous pages, improving code readability and maintainability.
- Introduced functions to classify transport status errors and error messages, improving the handling of various Ledger communication errors.
- Refactored the error handling logic in the `processLedgerWorkflow` function to streamline the management of app opening and closing errors.
- Added retry logic for connection attempts, ensuring better resilience in the Bluetooth communication process with Ledger devices.
Comment thread app/components/Views/LedgerSelectAccount/index.tsx
Comment thread app/components/hooks/Ledger/useLedgerBluetooth.ts
Comment thread app/components/hooks/Ledger/useLedgerBluetooth.ts
@github-actions

github-actions Bot commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

⚠️ E2E Fixture Validation — Structural changes detected

Category Count
New keys 68
Missing keys 11
Type mismatches 0
Value mismatches 6 (informational)

The committed fixture schema is out of date. To update, comment:

@metamaskbot update-mobile-fixture

View full details | Download diff report

Modified the type handling in the LedgerSelectAccount tests and the loadBleTransport hook to use BluetoothInterface for better type safety. This change enhances code clarity and ensures proper type assertions during Bluetooth transport operations.
Replaced the type assertion for `connectLedgerHardware` with the `jest.mocked` utility in the LedgerBluetoothAdapter test suite. This change improves type safety and consistency across the tests, ensuring better maintainability and clarity in the mocking of hardware interactions.
…th hook

Refactored the error classification logic in the useLedgerBluetooth hook for better readability by formatting the conditional statements and return statements. This change enhances code clarity without altering functionality.
@dawnseeker8

Copy link
Copy Markdown
Contributor Author

@metamaskbot update-mobile-fixture

NicolasMassart
NicolasMassart previously approved these changes Mar 6, 2026

@NicolasMassart NicolasMassart left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

despite my multiple requests, I eventually filled the PR Manual testing steps myself, so we can have future easy understanding of the fixed issues and testing without having to dig in the related issue.
Sometimes there's discrepency between issue and PR for many reasons, so PR should be the final source of truth and include all the required data to approve.
Note that when this will land in a release, it will be required to test again and you will have long forgotten the context. Having clear tests steps for you to follow will be crucial.
Thank you for taking this into account for next time.

Comment thread app/components/hooks/Ledger/useLedgerBluetooth.test.ts
@github-project-automation github-project-automation Bot moved this from Needs dev review to Review finalised - Ready to be merged in PR review queue Mar 6, 2026
@dawnseeker8 dawnseeker8 disabled auto-merge March 6, 2026 14:04
@dawnseeker8

Copy link
Copy Markdown
Contributor Author

BLE and app-switch changes look good.

Before merge: finish “Manual testing steps” and “After” screenshots (replace “TBC…” by real content or just mark N/A if it's not manually testable) and address any open Cursor bot comments. Ideally if you could also make suggested changes, that would be cleaner (we really want to avoid eslint exclusions)

The manually tests steps have been mentioned in 3 relative issues.

@dawnseeker8 dawnseeker8 enabled auto-merge March 6, 2026 15:02
@github-actions

github-actions Bot commented Mar 6, 2026

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: None (no tests recommended)
  • Selected Performance tags: None (no tests recommended)
  • Risk Level: medium
  • AI Confidence: 85%
click to see 🤖 AI reasoning details

E2E Test Selection:
The PR focuses entirely on Ledger hardware wallet Bluetooth connectivity improvements:

  1. ledgerErrors.ts: Added DISCONNECT_ERROR_NAMES constant and isDisconnectError() helper for better error classification
  2. LedgerBluetoothAdapter.ts: Refactored to use the new shared disconnect error names
  3. useLedgerBluetooth.ts: Major refactoring of error handling, app switching workflow (BOLOS → Ethereum), and disconnect handler logic with isReconnecting guard
  4. LedgerSelectAccount/index.tsx: Wrapped account operations with ledgerLogicToRun for proper error handling
  5. loadBleTransport.ts: New utility module for BLE transport loading (extracted for testability)

Why no E2E tags are needed:

  • There are no E2E tests for Ledger hardware wallet functionality (requires physical Ledger device)
  • The changes are completely isolated to Ledger-specific code paths
  • The changes don't affect any shared UI components (modals, navigation, confirmations) that other tests depend on
  • SmokeAccounts covers "QR-based hardware wallet accounts" which is a different hardware wallet type (QR-based vs Bluetooth-based Ledger)
  • All changes have comprehensive unit tests covering the new functionality

The changes improve Ledger connection reliability and error handling but don't impact any testable E2E flows.

Performance Test Selection:
The changes are specific to Ledger Bluetooth hardware wallet connectivity and error handling. They don't affect: UI rendering performance, data loading/state management for main wallet flows, account/network list components, critical user flows (login, balance loading, swap, send), or app startup/initialization. The Ledger connection flow is a specialized hardware wallet feature that doesn't impact general app performance metrics.

View GitHub Actions results

@dawnseeker8

Copy link
Copy Markdown
Contributor Author

despite my multiple requests, I eventually filled the PR Manual testing steps myself, so we can have future easy understanding of the fixed issues and testing without having to dig in the related issue. Sometimes there's discrepency between issue and PR for many reasons, so PR should be the final source of truth and include all the required data to approve. Note that when this will land in a release, it will be required to test again and you will have long forgotten the context. Having clear tests steps for you to follow will be crucial. Thank you for taking this into account for next time.

Menaul tests steps have been copied from three issues into this PR for future references.

@sonarqubecloud

sonarqubecloud Bot commented Mar 6, 2026

Copy link
Copy Markdown

@dawnseeker8 dawnseeker8 added this pull request to the merge queue Mar 6, 2026
Merged via the queue into main with commit 29ba999 Mar 6, 2026
67 of 69 checks passed
@dawnseeker8 dawnseeker8 deleted the fix/ledger-transaction-not-displayed-after-eth-app-open branch March 6, 2026 15:50
@github-actions github-actions Bot locked and limited conversation to collaborators Mar 6, 2026
@metamaskbot metamaskbot added the release-7.70.0 Issue or pull request that will be included in release 7.70.0 label Mar 6, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

QA Passed QA testing has been completed and passed release-7.70.0 Issue or pull request that will be included in release 7.70.0 size-XL team-accounts-framework Accounts team

Projects

Archived in project

5 participants