Skip to content

refactor: use route from props for type derivation (SwitchAccountType…#26484

Merged
asalsys merged 5 commits into
mainfrom
refactor/route-props-confirmations
Mar 2, 2026
Merged

refactor: use route from props for type derivation (SwitchAccountType…#26484
asalsys merged 5 commits into
mainfrom
refactor/route-props-confirmations

Conversation

@asalsys

@asalsys asalsys commented Feb 24, 2026

Copy link
Copy Markdown
Contributor

Description

Reason for the change:
The SwitchAccountTypeModal component was using the useRoute() hook internally to access route parameters. This approach has several drawbacks:

  • Tightly couples the component to the navigation context
  • Makes type derivation less explicit (required unsafe type assertion: (route?.params as { address: Hex })?.address)
  • Reduces testability as tests needed to mock the useRoute hook globally
  • No graceful handling when address parameter is missing

Improvement/Solution:

  • Refactored SwitchAccountTypeModal to receive route as a prop instead of calling useRoute() internally
  • Added proper TypeScript interfaces: SwitchAccountTypeModalRouteParams, SwitchAccountTypeModalParamList, and SwitchAccountTypeModalProps
  • Added fallback UI with "No account selected" message when no address is available from route params
  • Added missing key prop to AccountNetworkRow component in the map function (fixes React key warning)
  • Significantly expanded test coverage:
    • Organized tests into logical describe blocks (rendering, route params handling, navigation, hook integration)
    • Added tests for empty network list, multiple networks, loading state
    • Added tests for address matching/non-matching scenarios
    • Added test for hook integration to verify correct address is passed

Changelog

CHANGELOG entry: null

Related issues

Fixes: N/A (internal refactoring)

Manual testing steps

Feature: Switch Account Type Modal (EIP-7702)

  Scenario: User opens switch account type modal with valid address
    Given the user has an account upgraded to a smart account on a supported network
    And the user is viewing account details

    When user taps on "Switch account type"
    Then user should see the Switch Account Type modal
    And user should see their account name
    And user should see the list of networks where the account is upgraded
    And each network row should show "Smart account" status

  Scenario: User switches back to regular account
    Given the user is viewing the Switch Account Type modal
    And the account is currently a smart account on Sepolia

    When user taps "Switch back" on the Sepolia row
    Then the account should be downgraded to a regular account on Sepolia

  Scenario: User navigates back from modal
    Given the user is viewing the Switch Account Type modal

    When user taps the back button
    Then the modal should close
    And user should return to the previous screen

  Scenario: Modal shows loading state while fetching network data
    Given the network data is still being fetched

    When user opens the Switch Account Type modal
    Then user should see a loading spinner
    And the network list should not be visible

Screenshots/Recordings

Before

N/A - No visual changes (except for new fallback state)

After

N/A - No visual changes (except for new fallback state when no address is available)

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.

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

@metamaskbot metamaskbot added the team-mobile-platform Mobile Platform team label Feb 24, 2026
@asalsys asalsys self-assigned this Feb 24, 2026
@metamaskbot metamaskbot added the INVALID-PR-TEMPLATE PR's body doesn't match template label Feb 24, 2026
@asalsys asalsys removed the INVALID-PR-TEMPLATE PR's body doesn't match template label Feb 24, 2026
@asalsys asalsys added the skip-sonar-cloud Only used for bypassing sonar cloud when failures are not relevant to the changes. label Feb 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

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

E2E Test Selection:
The PR modifies the SwitchAccountTypeModal component which is part of the EIP-7702 (account abstraction) confirmations flow. The changes include:

  1. TypeScript improvements: Added proper interfaces for route params and props
  2. Route handling refactor: Changed from useRoute() hook to receiving route as a prop directly
  3. Fallback UI: Added handling for when no address is available (displays "No account selected")
  4. React key fix: Added proper key prop to network list items
  5. Test expansion: Significantly improved test coverage with better organization

The modal is registered in App.tsx as ConfirmationSwitchAccountType and is used for switching account types (smart accounts via EIP-7702). It's part of the confirmations system and relates to account management.

Selected tags:

  • SmokeConfirmations: The modal is in the confirmations components directory and is part of the EIP-7702 account abstraction feature which involves transaction confirmations
  • SmokeAccounts: The modal deals with account type switching and account management functionality

The changes are primarily code quality improvements (TypeScript, tests, React key warning fix) and don't modify core business logic, making this a low-risk change.

Performance Test Selection:
The changes are TypeScript improvements, test expansions, and a fallback UI addition. There are no changes that would impact rendering performance, data loading, or app responsiveness. The modal is a simple bottom sheet with minimal UI elements, and the changes don't affect any performance-critical paths.

View GitHub Actions results

@asalsys asalsys marked this pull request as ready for review February 25, 2026 15:48
@asalsys asalsys requested a review from a team as a code owner February 25, 2026 15:48
@asalsys asalsys enabled auto-merge February 25, 2026 15:51

@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 2 potential issues.

const { network7702List, pending } = useEIP7702Networks(address);
const address: Hex | undefined =
route?.params?.address ?? (selectedAccountAddress as Hex | undefined);
const { network7702List, pending } = useEIP7702Networks(address ?? '');

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.

Empty string to hook may crash via error boundary

Medium Severity

When address is undefined, useEIP7702Networks(address ?? '') passes an empty string to the hook. The hook calls isAtomicBatchSupported({ address: '' as Hex, ... }) via useAsyncResultOrThrow, which re-throws any async error during the render phase. If the API rejects the invalid empty-string address, the thrown error propagates to the error boundary, crashing the component tree — the if (!address) fallback UI on line 62 won't survive the subsequent re-render.

Additional Locations (1)

Fix in Cursor Fix in Web

});

describe('rendering', () => {
it('displays account info and network details correctly', () => {

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.

Test names use subjective outcome words

Low Severity

Two test names use subjective outcome words prohibited by the unit testing guidelines. 'displays account info and network details correctly' uses "correctly" and 'passes correct address to useEIP7702Networks hook' uses "correct". The naming convention requires indicating the actual expected result instead of using vague qualifiers like "correctly" or "correct".

Additional Locations (1)

Fix in Cursor Fix in Web

Triggered by project rule: Unit Testing Guidelines

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

Changes look good to me 👍

@asalsys asalsys added this pull request to the merge queue Mar 2, 2026
Merged via the queue into main with commit 847a6cb Mar 2, 2026
110 checks passed
@asalsys asalsys deleted the refactor/route-props-confirmations branch March 2, 2026 05:20
@github-actions github-actions Bot locked and limited conversation to collaborators Mar 2, 2026
@metamaskbot metamaskbot added the release-7.69.0 Issue or pull request that will be included in release 7.69.0 label Mar 2, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-7.69.0 Issue or pull request that will be included in release 7.69.0 size-M skip-sonar-cloud Only used for bypassing sonar cloud when failures are not relevant to the changes. team-mobile-platform Mobile Platform team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants