Skip to content

feat(hw): QR wallet connection ui wiring#29086

Merged
montelaidev merged 27 commits into
mainfrom
feat/mul-1507-split-4-connection-ui
Apr 24, 2026
Merged

feat(hw): QR wallet connection ui wiring#29086
montelaidev merged 27 commits into
mainfrom
feat/mul-1507-split-4-connection-ui

Conversation

@montelaidev

@montelaidev montelaidev commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

Description

This PR is split 4 of the QR hardware context merger with the hardware wallet context. It adds a useQRSigningState hook and QRSigningContext to manage pending scan requests from Redux, track request completion, and provide cancellation via the QR keyring scanner. The useDeviceConnectionFlow hook is extended to skip device discovery for QR wallets and resolve readiness directly so the caller can transition straight to awaiting-confirmation. Finally, AwaitingConfirmationContent is expanded to render wallet-type-specific content (Ledger vs QR), including QR scanning instructions, animated connection tips, and a reject button wired to the signing rejection callback.

Changelog

CHANGELOG entry: Merges QR Signing Context with Hardware Wallet Context

Related issues

Related: https://consensyssoftware.atlassian.net/browse/MUL-1741?atlOrigin=eyJpIjoiMDdkOGRkYmYwMTdlNDRhMWEwMjNjMzM2ZGZmZDg5NDIiLCJwIjoiaiJ9

Manual testing steps

Feature: QR hardware wallet context and Hardware wallet context merger. 
  Scenario: User signs a transaction with a Ledger hardware wallet (regression)
    Given the user has a Ledger hardware wallet account imported
    And the user is on the transaction confirmation screen
    When the user initiates the transaction
    Then the awaiting-confirmation bottom sheet appears with Ledger-specific content
    And the existing Bluetooth connection and device discovery flow runs as before
    And the transaction is signed successfully

  Scenario: User signs a message with a Ledger hardware wallet (regression)
    Given the user has a Ledger hardware wallet account imported
    And a dApp requests a message signature
    When the user approves the signature request
    Then the awaiting-confirmation bottom sheet appears with Ledger-specific content
    And the message is signed successfully

  Scenario: User signs a transaction with a QR hardware wallet
    Given the user has a QR hardware wallet account imported
    And the user is on the transaction confirmation screen
    When the user initiates the transaction
    Then the device connection flow skips Bluetooth scanning and device discovery
    And the awaiting-confirmation bottom sheet appears with QR-specific instructions
    And QR connection tips are displayed (camera ready, align QR code, good lighting)
    And the user can scan the QR code to sign the transaction

  Scenario: User signs a message with a QR hardware wallet
    Given the user has a QR hardware wallet account imported
    And a dApp requests a message signature
    When the user approves the signature request
    Then the awaiting-confirmation bottom sheet appears with QR-specific instructions
    And the user can scan the QR code to sign the message

  Scenario: User rejects a QR signing request
    Given the user has a QR hardware wallet account imported
    And the awaiting-confirmation bottom sheet is showing for a signing request
    When the user taps the reject button
    Then the pending QR scan request is cancelled
    And the transaction or message is rejected

  Scenario: QR wallet connection flow resolves without intermediate connected modal
    Given the user has a QR hardware wallet account imported
    When the provider calls ensureDeviceReady for the QR wallet
    Then the flow does not show an intermediate connected/success modal
    And the readiness promise resolves directly
    And the UI transitions straight to awaiting-confirmation

Screenshots/Recordings

Before

After

Pre-merge author checklist

Performance checks (if applicable)

  • I've tested on Android
    • Ideally on a mid-range device; emulator is acceptable
  • I've tested with a power user scenario
    • Use these power-user SRPs to import wallets with many accounts and tokens
  • I've instrumented key operations with Sentry traces for production performance metrics

For performance guidelines and tooling, see the Performance Guide.

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
Touches core hardware-wallet connection/readiness flow and adds QR-specific signing UX, which could regress non-QR device connection states or error/retry behavior if edge cases are missed.

Overview
Adds QR hardware-wallet signing support end-to-end by introducing QRSigningContext/useQRSigningState (Redux-backed) and wrapping HardwareWalletProvider children + bottom sheet with this context.

Updates the connection flow to support QR wallets: derives an effective wallet type from a pending-operation address, prefers a pendingOperationWalletTypeRef before React renders catch up, skips device discovery when requiresDeviceDiscovery is false, and for HardwareWalletType.Qr resolves readiness directly (avoiding the intermediate "Ready/success" modal).

Expands AwaitingConfirmationContent with a QR-specific UI (animated QR, scanner modal, cancel/reject wiring, mismatched-request-id handling with analytics) while keeping the existing Ledger/Lattice spinner view. Tests are significantly extended/updated to cover pending wallet-type derivation, QR scan success/error paths, and updated retry/close semantics after signing errors.

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

Add normalizeReplacementGasFeeParams gas utility, getDeviceIdForAddress
helper, QR connection tips, widen setTargetWalletType type, and refactor
LedgerTransactionModal to use normalizeReplacementGasFeeParams.
Add QRSigningContext for QR hardware wallet signing state, useQRSigningState
hook for managing QR scan request lifecycle, and export from index files.
Add shared utility that runs hardware wallet operations behind the
standard readiness + awaiting-confirmation flow. Includes foundation
helpers (getDeviceIdForAddress, normalizeReplacementGasFeeParams) as
prerequisites.
- useDeviceConnectionFlow: skip device discovery for QR wallets, walletType-aware
  ready handling
- HardwareWalletProvider: integrate QRSigningContext, bug fixes for reject ref
  cleanup and double close
- AwaitingConfirmationContent: full QR signing UI with QR code display, scanner,
  error handling, and scan result verification
@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.

@metamaskbotv2 metamaskbotv2 Bot added the team-accounts-framework Accounts team label Apr 21, 2026
…ress

The provider now auto-derives the wallet type from the pending operation
address, so callers only need to supply the address — not the wallet type.
This removes the need for executeHardwareWalletOperation to compute and
forward the wallet type explicitly.
…ationAddress

LedgerSelectAccount uses setTargetWalletType for the Add Hardware Wallet
flow, so it must remain in the context interface unchanged.
Add pendingOperationAddress state to the provider. The effective wallet
type is now derived from targetWalletType OR the pending operation address
OR the selected account, keeping setTargetWalletType unchanged for
Add Hardware Wallet flows.
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.95973% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.26%. Comparing base (64f79bb) to head (c799df0).
⚠️ Report is 34 commits behind head on main.

Files with missing lines Patch % Lines
app/core/HardwareWallet/HardwareWalletProvider.tsx 84.21% 2 Missing and 1 partial ⚠️
...ttomSheet/contents/AwaitingConfirmationContent.tsx 96.07% 0 Missing and 2 partials ⚠️
.../core/HardwareWallet/contexts/QRSigningContext.tsx 71.42% 1 Missing and 1 partial ⚠️
...e/HardwareWallet/executeHardwareWalletOperation.ts 96.00% 0 Missing and 1 partial ⚠️
...re/HardwareWallet/hooks/useDeviceConnectionFlow.ts 94.44% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #29086      +/-   ##
==========================================
+ Coverage   82.19%   82.26%   +0.07%     
==========================================
  Files        5069     5097      +28     
  Lines      133674   134430     +756     
  Branches    29969    30171     +202     
==========================================
+ Hits       109870   110594     +724     
- Misses      16334    16340       +6     
- Partials     7470     7496      +26     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@montelaidev montelaidev marked this pull request as ready for review April 23, 2026 07:07
@github-actions github-actions Bot added the risk:high AI analysis: high risk label Apr 23, 2026
Comment thread app/core/HardwareWallet/HardwareWalletProvider.tsx
Comment thread app/core/HardwareWallet/executeHardwareWalletOperation.ts
Ensure the awaiting confirmation QR test injects `setRequestCompleted` through `QRSigningContext` so the assertion covers the real completion path instead of an unused prop.

Made-with: Cursor
Read the signing wallet type from shared hardware wallet refs so ensureDeviceReady can select the correct adapter before React finishes re-rendering. Add regression coverage for the pending operation wallet type flow and the provider wallet type update.

Made-with: Cursor
Comment thread app/core/HardwareWallet/HardwareWalletProvider.tsx Outdated
@montelaidev montelaidev force-pushed the feat/mul-1507-split-4-connection-ui branch from 1032ef1 to f63f233 Compare April 23, 2026 10:15
@github-actions

Copy link
Copy Markdown
Contributor

AI PR Analysis

🚫 Merge safe: false | 🟠 Risk: high

Merge decision: AI analysis did not complete — manual review required before merging.

AI analysis did not complete. Manual review recommended.

View run

Comment thread app/core/HardwareWallet/hooks/useDeviceConnectionFlow.ts
Comment thread app/core/HardwareWallet/hooks/useDeviceConnectionFlow.test.ts Outdated
Comment thread app/core/HardwareWallet/hooks/useDeviceConnectionFlow.test.ts
Comment thread app/core/HardwareWallet/hooks/useDeviceConnectionFlow.test.ts
Comment thread app/core/HardwareWallet/hooks/useDeviceConnectionFlow.test.ts Outdated

@cursor cursor Bot 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.

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.

Reviewed by Cursor Bugbot for commit 4e5a5f6. Configure here.

@ccharly ccharly 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.

LGTM (not tested)

@montelaidev montelaidev enabled auto-merge April 24, 2026 13:44
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

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

E2E Test Selection:
The changes are focused on the Hardware Wallet subsystem, specifically:

  1. QR Hardware Wallet Signing Flow: AwaitingConfirmationContent.tsx now renders a full QR signing UI (animated QR code, scanner modal, error handling) for QR wallet type. This is a significant new feature path in the confirmation flow.

  2. Connection Flow Refactoring: useDeviceConnectionFlow.ts adds QR-specific handling to skip the intermediate "connected/success" modal, adds lastDeviceIdRef for stable device ID tracking, and supports wallets without device discovery.

  3. State Management: useHardwareWalletStateManager.ts adds pendingOperationWalletTypeRef to properly track wallet type during signing operations.

  4. Provider Refactoring: HardwareWalletProvider.tsx now wraps children with QRSigningContext.Provider, changes how pending operation wallet type is tracked, and improves cancel/close flow handling.

Why SmokeAccounts: The tag description explicitly covers "adding QR-based hardware wallet accounts" - this is the most directly relevant E2E coverage for hardware wallet changes.

Why SmokeConfirmations: The AwaitingConfirmationContent.tsx changes directly affect the confirmation/signing UI for QR hardware wallets. Transaction signing flows are covered by SmokeConfirmations.

Risk factors:

  • HardwareWalletProvider wraps the entire app root, so any regression could affect all users
  • The QR signing flow is a new code path that hasn't been tested before
  • Cancel/close flow handling changes could affect existing Ledger hardware wallet flows too
  • No dedicated hardware wallet E2E tests were found in the test suite

Confidence is 72 because: while the changes are clearly scoped to hardware wallet functionality, there are no dedicated hardware wallet E2E tests found. The selected tags (SmokeAccounts, SmokeConfirmations) provide the closest coverage but may not directly exercise the QR hardware wallet paths.

Performance Test Selection:
The changes are focused on hardware wallet connection flow logic and QR signing UI. There are no changes to list rendering, data loading, app startup, or other performance-sensitive paths. The QR signing flow is a specialized user interaction that doesn't impact general app performance metrics.

View GitHub Actions results

@gantunesr gantunesr left a comment

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.

lgtm. Did not test

@sonarqubecloud

Copy link
Copy Markdown

@github-actions

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

@montelaidev montelaidev added this pull request to the merge queue Apr 24, 2026
Merged via the queue into main with commit 4ec2544 Apr 24, 2026
115 of 116 checks passed
@montelaidev montelaidev deleted the feat/mul-1507-split-4-connection-ui branch April 24, 2026 14:55
@github-actions github-actions Bot locked and limited conversation to collaborators Apr 24, 2026
@metamaskbotv2 metamaskbotv2 Bot added the release-7.76.0 Issue or pull request that will be included in release 7.76.0 label Apr 24, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-7.76.0 Issue or pull request that will be included in release 7.76.0 risk:high AI analysis: high risk size-XL team-accounts-framework Accounts team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants