Skip to content

fix(MUSD-672): resolve Money Hub UX and UI inconsistencies cp-7.74.0#29049

Merged
Kureev merged 24 commits into
mainfrom
kureev/MUSD-672
Apr 20, 2026
Merged

fix(MUSD-672): resolve Money Hub UX and UI inconsistencies cp-7.74.0#29049
Kureev merged 24 commits into
mainfrom
kureev/MUSD-672

Conversation

@Kureev

@Kureev Kureev commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

Description

There are several UX and UI inconsistencies across the Money Hub that reduce conversion confidence, time-to-first-transaction, and overall clarity in the mUSD journey. This PR resolves them:

  1. Education screen from home "Money" entry-point — First-time users clicking the "Money" section header now see the education screen before entering the Money Hub, consistent with other entry-points.
  2. Tooltip "Learn more" keeps tooltip open — The "Your bonus" tooltip no longer dismisses when "Learn more" opens an external URL. Added dismissOnButtonPress support to TooltipModal.
  3. Empty state "Buy" pre-selects mUSD — Pressing "Buy" from the Money Hub empty state now pre-selects mUSD via RampIntent asset ID.
  4. Education screen preserves entry context — The education screen now honors returnTo and navigationOverride params, routing back to the correct Money Hub context instead of defaulting to Quick Convert.
  5. Dedicated Money Hub loading skeleton — Replaced the generic token list skeleton with a layout-matched CashTokensFullViewSkeleton.
  6. Pull-to-refresh in Money Hub — Added useCashTokensRefresh hook that orchestrates parallel refresh of EVM token data and Merkl bonus rewards.

Changelog

CHANGELOG entry: Fixed Money Hub UX inconsistencies including education gate on home entry, tooltip persistence, Buy pre-selection, education context routing, dedicated loading skeleton, and pull-to-refresh

Related issues

Fixes: MUSD-672

Manual testing steps

Feature: Education gate on home screen Money entry

  Scenario: First-time user taps Money section header
    Given the user has not seen the mUSD education screen

    When the user taps the "Money" section header on the home screen
    Then the education screen is displayed
    And after completing education, the user lands on the Money Hub

  Scenario: Returning user taps Money section header
    Given the user has already seen the mUSD education screen

    When the user taps the "Money" section header on the home screen
    Then the user goes directly to the Money Hub

Feature: Tooltip persistence on external navigation

  Scenario: User taps Learn More in bonus tooltip
    Given the "Your bonus" tooltip is displayed

    When the user taps the "Learn more" button
    Then an external URL opens in the browser
    And the tooltip remains visible when returning to the app

Feature: Buy flow pre-selection from Money Hub

  Scenario: User taps Buy from Money Hub empty state
    Given the user has no mUSD or convertible stablecoins

    When the user taps the "Buy" button in the Money Hub empty state
    Then the buy flow opens with mUSD pre-selected

Feature: Education screen context preservation

  Scenario: User triggers education from Money Hub pencil icon
    Given the user has not seen the education screen

    When the user taps the pencil icon in "Convert your stablecoins" section
    Then the education screen is shown
    And the primary button returns the user to the Money Hub conversion context
    And the user is NOT redirected to Quick Convert

Feature: Dedicated Money Hub skeleton

  Scenario: Money Hub is loading
    Given the user navigates to the Money Hub

    When data is loading
    Then a layout-matched skeleton is displayed matching the Money Hub structure

Feature: Money Hub pull-to-refresh

  Scenario: User pulls to refresh Money Hub
    Given the user is on the Money Hub screen

    When the user pulls down to refresh
    Then token balances and Merkl bonus data are refreshed
    And a refresh indicator is shown during loading

Screenshots/Recordings

Before

N/A — behavioral changes, no visual design changes

After

N/A — behavioral changes, no visual design changes

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 navigation flow into Money Hub, adds new refresh orchestration, and alters tooltip dismissal behavior; regressions could affect user routing and refresh UX but do not touch security-critical logic.

Overview
Improves the Money Hub (Cash/mUSD) UX by gating the Home Cash entry behind the mUSD education screen when the user hasn’t seen it yet, using a new shared useCashNavigation path and a new returnTo route param so the education screen can exit to Money Hub without starting conversion.

Updates the education screen to honor caller intent by forwarding navigationOverride into initiateCustomConversion, adding returnTo navigation, and tracking a new redirects_to location (MONEY_HUB) for analytics.

Enhances Money Hub loading/refresh by adding a first-paint CashTokensFullViewSkeleton, a pull-to-refresh hook (useCashTokensRefresh) that refreshes token data plus Merkl rewards via a new refetch surface from useMerklBonusClaim (plumbed up through AssetOverviewClaimBonus), and allowing Tokens/TokenList to accept an external refreshControl and optionally hide the internal skeleton.

Fixes bonus tooltip UX by adding dismissOnButtonPress support to TooltipModal/useTooltipModal and using it from the “Your bonus” tooltip so “Learn more” can open an external URL without dismissing the sheet; Money Hub “Buy” now passes an mUSD assetId to preselect mUSD.

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

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

@Kureev Kureev marked this pull request as ready for review April 20, 2026 15:30
@Kureev Kureev requested review from a team as code owners April 20, 2026 15:30
Comment thread app/components/Views/Homepage/Sections/Cash/MusdAggregatedRow.tsx Outdated
Comment thread app/components/Views/CashTokensFullView/CashTokensFullView.tsx Outdated
Comment thread app/components/Views/CashTokensFullView/CashTokensFullViewSkeleton.test.tsx Outdated
@github-actions github-actions Bot added risk-high Extensive testing required · High bug introduction risk risk-medium Moderate testing recommended · Possible bug introduction risk and removed risk-high Extensive testing required · High bug introduction risk labels Apr 20, 2026
Comment thread app/components/Views/Homepage/Sections/Cash/MusdAggregatedRow.test.tsx Outdated
Comment thread app/components/Views/Homepage/Sections/Cash/CashSection.tsx Outdated
Kureev added 13 commits April 20, 2026 18:09
- Remove duplicate useMerklBonusClaim mount from useCashTokensRefresh
  (was creating a second 60s API polling interval); accept optional
  refetchMerklBonus callback instead
- Extract shared MusdNavigationTarget type into musd.types.ts
- Remove unnecessary as-never casts in education view navigation
- Fix Buy button test missing Money Hub flag
Add tests for handleConvertMaxPress, handleConvertEditPress,
handleConvertPress (including error paths), goToSwaps, goToBuy
in Money Hub mode, and handleLearnMorePress.
…lView

CashTokensFullView already shows its own dedicated skeleton during the
initial load. The Tokens component's internal TokenListSkeleton was also
rendering, causing two skeletons to flash sequentially. Add
hideLoadingSkeleton prop to suppress the internal skeleton when the
parent handles loading state.
@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 20, 2026
@github-actions github-actions Bot added risk-medium Moderate testing recommended · Possible bug introduction risk and removed risk-high Extensive testing required · High bug introduction risk labels Apr 20, 2026
…on gate

- Replace navigation.replace with navigation.navigate in education view
  since returnTo targets a screen outside the Earn stack (replace only
  works within the current navigator).
- Extract shared education-gate logic into useCashNavigation hook,
  eliminating duplication between CashSection and MusdAggregatedRow.
Comment thread app/components/Views/CashTokensFullView/useCashTokensRefresh.ts Outdated
@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 20, 2026
useCashTokensRefresh now accepts a MutableRefObject instead of a
callback parameter. This eliminates the stale-closure risk — the ref
is read at invocation time inside onRefresh, so the callback identity
never participates in the dependency array. Added a test verifying
that a ref populated after hook creation is correctly read on refresh.
@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 20, 2026
submitContinuePressedEvent now checks for returnTo before falling
through to the deeplink/default branches, logging MONEY_HUB as the
destination instead of incorrectly reporting QUICK_CONVERT or
CUSTOM_AMOUNT when the user came through the education gate from the
home section header.
@github-actions github-actions Bot added risk-high Extensive testing required · High bug introduction risk and removed risk-medium Moderate testing recommended · Possible bug introduction risk labels Apr 20, 2026
@Kureev Kureev requested review from Matt561 and salimtb April 20, 2026 17:54
@github-actions github-actions Bot added risk-medium Moderate testing recommended · Possible bug introduction risk and removed risk-high Extensive testing required · High bug introduction risk labels Apr 20, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokeWalletPlatform, SmokeTrade, SmokePerps, SmokeConfirmations, SmokeRamps
  • Selected Performance tags: @PerformanceAssetLoading
  • Risk Level: medium
  • AI Confidence: 82%
click to see 🤖 AI reasoning details

E2E Test Selection:
The changes primarily affect the mUSD/Cash ecosystem and some shared components:

  1. SmokeWalletPlatform (primary): The musd-conversion-happy-path.spec.ts test is tagged with SmokeWalletPlatform and directly tests the mUSD conversion flow. Changes to useCashNavigation (new education gate with returnTo param), EarnMusdConversionEducationView (new navigation logic), CashSection, MusdAggregatedRow, and CashTokensFullView all affect this flow. The education screen now has a three-way navigation branch (Money Hub → education → full view) that must be validated.

  2. SmokeTrade (dependency): useTooltipModal is used by Bridge's ApprovalTooltip component. The new dismissOnButtonPress parameter changes the hook signature. While backward compatible (optional param), the Bridge tooltip behavior could be affected. Also, Tokens component changes (new refreshControl/hideLoadingSkeleton props) affect the token list used in swap/bridge flows.

  3. SmokePerps (dependency): useTooltipModal is used by PerpsOrderView. The tooltip modal behavior change (new dismissOnButtonPress param) could affect Perps tooltip interactions.

  4. SmokeConfirmations (required by SmokeTrade): Per tag description, when selecting SmokeTrade for swap/bridge flows, also select SmokeConfirmations. The mUSD conversion flow also goes through confirmations.

  5. SmokeRamps (related): The CashTokensFullView buy button now passes a specific assetId (mUSD) to goToBuy(), which changes the ramp navigation behavior. This could affect on-ramp flows.

The Tokens component changes (new props) are additive/backward-compatible and shouldn't break existing token list behavior. The TooltipModal change is also backward-compatible (new optional param defaults to true). The main risk is the navigation logic changes in the mUSD/Cash flow.

Performance Test Selection:
The Tokens component changes (new refreshControl and hideLoadingSkeleton props) affect how the token list renders and handles loading states. The CashTokensFullView now has a dedicated skeleton loading state using InteractionManager, which changes the initial render timing. These changes could impact asset loading performance metrics. The @PerformanceAssetLoading tag covers token list rendering and balance fetching which are directly affected by the Tokens component changes.

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 700f157. Configure here.

<Tokens
isFullView
showOnlyMusd
hideLoadingSkeleton

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.

Loading gap between parent skeleton and child content

Medium Severity

When CashTokensFullView dismisses its skeleton after InteractionManager, it mounts Tokens with hideLoadingSkeleton={true}. But Tokens has its own hasInitialLoad state that also waits for a separate InteractionManager tick. During that gap, tokenContent returns null because hideLoadingSkeleton suppresses the internal skeleton while hasInitialLoad is still false. This creates a visible flash of empty content (header + blank area + footer) on every screen load, between the parent skeleton disappearing and the child content appearing.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 700f157. Configure here.

@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

@Kureev Kureev added this pull request to the merge queue Apr 20, 2026
Merged via the queue into main with commit 5c4fccb Apr 20, 2026
106 of 107 checks passed
@Kureev Kureev deleted the kureev/MUSD-672 branch April 20, 2026 19:03
@github-actions github-actions Bot locked and limited conversation to collaborators Apr 20, 2026
@metamaskbotv2 metamaskbotv2 Bot added the release-7.75.0 Issue or pull request that will be included in release 7.75.0 label Apr 20, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-7.75.0 Issue or pull request that will be included in release 7.75.0 risk-medium Moderate testing recommended · Possible bug introduction risk size-XL team-earn

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants