Skip to content

feat(card): migrate authentication to CardController#28414

Merged
Brunonascdev merged 60 commits into
mainfrom
feat/card-migrate-authentication-to-controller
Apr 6, 2026
Merged

feat(card): migrate authentication to CardController#28414
Brunonascdev merged 60 commits into
mainfrom
feat/card-migrate-authentication-to-controller

Conversation

@Brunonascdev

@Brunonascdev Brunonascdev commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

Description

Card: authentication and session state → CardController

This PR migrates Card authentication to CardController so session state is no longer owned by the Redux card slice and coordinated through Card SDK helpers (logout, resetAuthenticatedData, global CardVerification, etc.). Call sites use Engine.context.CardController and selectIsCardAuthenticated (and related selectors in app/selectors/cardController.ts) as the source of truth.

Why: One place for sign-in state, logout, token/session refresh, and cardholder checks avoids duplicated logic between Redux and the SDK and removes the old side-effect verification flow.

What changed (Card-focused):

  • CardAuthentication + useCardAuth
    • Removes useCardProviderAuthentication (hook deleted; large test file removed). The screen uses useCardAuth for the login / OTP flow, with resetToLogin on useCardAuth to reset mutations and step state.
    • CardAuthentication.test.tsx expanded; snapshot updated.
  • CardController
    • Owns isAuthenticated, session/cardholder fields, and logout() / validateAndRefreshSession(); expanded CardController.test.ts, messenger, and types.
  • Selectors (app/selectors/cardController.ts)
    • UI and hooks read selectIsCardAuthenticated, selectCardholderAccounts, selectIsCardholder, selectCardUserLocation, etc., instead of Redux auth fields.
  • Redux card slice
    • Removes auth-related state and actions; slice keeps onboarding-only concerns (e.g. IDs, hasViewedCardButton).
  • Card SDK (sdk/index.tsx)
    • Logout delegates to CardController.logout() instead of provider sdk.logout() + resetAuthenticatedData.
    • Removes CardVerification and the hooks it mounted.
    • fetchUserData updates controller location only when countryOfResidence is set (avoids bad auth/region sync when the API returns null); related fixes for nullable location / effectiveLocation to avoid unnecessary SDK reloads.
  • Removed
    • useCardholderCheck, getCardholder, handleLocalAuthentication, useCardAuthenticationVerification (and tests).
  • Screens / hooks / deeplinks
    • CardHome, CardWelcome, onboarding (SignUp, SetPhoneNumber, PhysicalAddress, etc.), EarnRewardsPreview, push provisioning, and legacy deeplink handlers updated to controller-backed auth; tests adjusted.
  • Onboarding (OnboardingNavigator.tsx)
    • Fixes routing/modal edge cases for auth resume (ACCOUNT vs contactVerificationId, keep-going modal waits for user).
  • Fixtures & tests
    • default-fixture.json; AddToWalletButton mock path fix.

Changelog

CHANGELOG entry: Card authentication and session/cardholder state are sourced from CardController and selectIsCardAuthenticated (and related selectors) instead of the Redux Card slice and Card SDK auth helpers; the global CardVerification flow and legacy auth utilities are removed.

Related issues

Fixes:

Manual testing steps

Feature: Card authentication via CardController

  Scenario: Session and sign-out
    Given I use Card with a provider account
    When I sign in, cold-start the app, or sign out
    Then authenticated state matches CardController and logout clears session as expected

  Scenario: Logout
    When I log out from Card
    Then CardController handles provider logout and local state clears without relying on removed Redux auth actions

  Scenario: Onboarding resume
    Given I am mid-onboarding with a non-ACCOUNT phase
    When I return to the onboarding flow
    Then I am not incorrectly sent to sign-up solely due to missing contact verification id

  Scenario: Keep-going modal
    Given a returning session with an in-progress phase
    When user data finishes loading
    Then the keep-going modal uses the correct step

  Scenario: Entry points still work
    Given Card entry from Earn (e.g. UK banner) or deeplinks
    When I navigate via those paths
    Then behavior matches pre-migration expectations

Screenshots/Recordings

Include Card home after login/logout and any onboarding resume path you exercised while validating auth.

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
Changes the card sign-in/OTP flow to rely on useCardAuth/CardController mutations and resets, affecting login, OTP auto-send/resend, and onboarding redirects. Risk is moderate due to altered authentication control flow and error/loading handling, though covered by expanded tests.

Overview
Refactors CardAuthentication to use the new useCardAuth hook (initiate/submit/stepAction) instead of the removed useCardProviderAuthentication, deriving loading/error/OTP state from React Query mutations and using resetToLogin to return from OTP to email/password.

Updates the login + OTP UX behavior to: initiate auth using the stored location, auto-trigger OTP send when the step becomes otp, auto-submit on 6 digits, support resend with a cooldown timer, and route to either Card Home or onboarding based on submit results.

Reworks and expands CardAuthentication.test.tsx to mock useCardAuth, add OTP-step coverage (auto-send, resend cooldown, auto-submit, back-to-login, onboarding redirect), and updates the snapshot; adds resetToLogin support + test coverage in useCardAuth and deletes useCardProviderAuthentication and its tests.

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

Brunonascdev and others added 30 commits March 20, 2026 12:43
…/metamask-mobile into feat/card-feature-flag-refactor
@Brunonascdev Brunonascdev self-assigned this Apr 6, 2026
@github-actions

github-actions Bot commented Apr 6, 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.

@metamaskbot metamaskbot added the team-card Card Team label Apr 6, 2026
@github-actions github-actions Bot added size-XL risk-medium Moderate testing recommended · Possible bug introduction risk labels Apr 6, 2026
klejeune
klejeune previously approved these changes Apr 6, 2026
@Brunonascdev Brunonascdev requested a review from a team as a code owner April 6, 2026 14:39
@github-actions github-actions Bot added risk-medium Moderate testing recommended · Possible bug introduction risk and removed risk-medium Moderate testing recommended · Possible bug introduction risk labels Apr 6, 2026
@github-actions

github-actions Bot commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

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

E2E Test Selection:
The PR modifies the MetaMask Card authentication flow:

  1. useCardProviderAuthentication.ts deleted - The old authentication hook is completely removed.
  2. useCardAuth.ts updated - A new resetToLogin callback is added that resets the step state and all mutation states (initiate, submit, stepAction) back to the login step.
  3. CardAuthentication.tsx refactored - The component is significantly refactored to use useCardAuth instead of the deleted hook. Key changes include:
    • Derived state replaces local useState for loading/error/OTP step tracking
    • Login flow now uses initiate.mutateAsync + submit.mutateAsync instead of the old login() function
    • OTP handling uses triggerStepAction instead of sendOtpLogin
    • handleBackToLogin now calls resetToLogin() from the hook
    • Error clearing uses mutation .reset() instead of clearError()/clearOtpError()

This is a medium-risk refactor of the Card authentication flow. The core logic is preserved but the implementation is significantly changed, warranting E2E validation of the Card feature.

Per SmokeCard tag description: "When selecting SmokeCard, also select SmokeTrade and SmokeConfirmations (Add Funds uses swaps which require transaction confirmations)."

No other feature areas (accounts, network, identity, etc.) are affected by these changes.

Performance Test Selection:
The changes are a refactor of the Card authentication hook and component. While the component logic changed significantly, these are authentication flow changes (login, OTP) that don't affect rendering performance, list rendering, asset loading, or other performance-sensitive areas. No performance tests are warranted.

View GitHub Actions results

@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 5f48937. Configure here.

@sonarqubecloud

sonarqubecloud Bot commented Apr 6, 2026

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

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

@Brunonascdev Brunonascdev added this pull request to the merge queue Apr 6, 2026
Merged via the queue into main with commit 1e48b30 Apr 6, 2026
85 of 89 checks passed
@Brunonascdev Brunonascdev deleted the feat/card-migrate-authentication-to-controller branch April 6, 2026 15:47
@github-actions github-actions Bot locked and limited conversation to collaborators Apr 6, 2026
@metamaskbot metamaskbot added the release-7.74.0 Issue or pull request that will be included in release 7.74.0 label Apr 6, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-7.74.0 Issue or pull request that will be included in release 7.74.0 risk-medium Moderate testing recommended · Possible bug introduction risk size-XL team-card Card Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants