Skip to content

feat(rewards): add earn rewards preview and mUSD calculator route#27684

Merged
VGR-GIT merged 8 commits into
mainfrom
RWDS-1107-tab-less-rewards-view
Mar 20, 2026
Merged

feat(rewards): add earn rewards preview and mUSD calculator route#27684
VGR-GIT merged 8 commits into
mainfrom
RWDS-1107-tab-less-rewards-view

Conversation

@VGR-GIT

@VGR-GIT VGR-GIT commented Mar 19, 2026

Copy link
Copy Markdown
Contributor

Description

Adds the Earn Rewards section to the Rewards Dashboard and introduces a dedicated mUSD Calculator screen.

Changes

  • EarnRewardsPreview — new dashboard section with two geo-gated earn cards:
    • mUSD card: navigates to MusdCalculatorView; hidden when geo disallows opt-in (e.g. UK)
    • MetaMask Card card: opens card onboarding deeplink; shown only when user's country is supported
    • Shows loading skeletons while geo data resolves; hides entirely when neither card is eligible
  • MusdCalculatorView — new screen wrapping MusdCalculatorTab with standard header; registered as MUSD_CALCULATOR_VIEW route
  • CampaignsPreview — simplified to a single "featured" campaign (priority: active → upcoming → previous) instead of separate active tile + upcoming banner; active campaigns now also sorted by soonest start date
  • selectCardIsLoaded — new selector exported from card redux slice
  • Locale strings and test selectors added for the earn rewards section

Screenshots

  • Showing both earn cards (with alt description for card holder):
image
  • Showing card if not holder:
Screenshot from 2026-03-19 15-33-54
  • Musd calculator page:
image

Checklist

  • Tests added/updated
  • Zero TypeScript errors
  • Lint passes
  • Locale strings added

Changelog

CHANGELOG entry: Added Earn Rewards preview section to the Rewards Dashboard with geo-gated mUSD calculator and MetaMask Card earn cards

🤖 Generated with Claude Code


Note

Medium Risk
Medium risk due to new navigation route and a dashboard section that gates UI/behavior on geo/card state and triggers a deeplink, which could affect user flows if selectors or loading states are incorrect.

Overview
Adds an Earn rewards preview section to the Rewards dashboard, showing geo-gated cards for the mUSD calculator and MetaMask Card (with skeleton loading, cardholder-aware copy, and deeplink navigation).

Introduces a new MusdCalculatorView screen and registers it under the new Routes.MUSD_CALCULATOR_VIEW in both Routes and RewardsNavigator.

Simplifies CampaignsPreview to render a single featured campaign (active → upcoming → previous) and updates useRewardCampaigns to sort active campaigns by soonest startDate, with corresponding test updates and new i18n/test selectors.

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

@VGR-GIT VGR-GIT requested review from a team as code owners March 19, 2026 13:23
@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-rewards Rewards team label Mar 19, 2026
@github-actions github-actions Bot added size-L risk-medium Moderate testing recommended · Possible bug introduction risk labels Mar 19, 2026
@metamaskbot metamaskbot added the INVALID-PR-TEMPLATE PR's body doesn't match template label Mar 19, 2026
Comment thread app/components/UI/Rewards/Views/RewardsDashboard.tsx
@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 Mar 19, 2026

// Card geo check — isCardGeoLoaded flips true when loadCardholderAccounts settles
const isCardGeoLoaded = useSelector(selectCardIsLoaded);
const cardGeoLocation = useSelector(selectCardGeoLocation);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@Brunonascdev I think @Montoya reached out to you about rendering a card earn card here based on geo restriction same as what card is using right now.

Is what is implemented here accurate? Or do we still need a new selector like you suggested?

Image

@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 Mar 19, 2026
VGR-GIT and others added 8 commits March 20, 2026 08:45
- Add EarnRewardsPreview component to dashboard showing geo-gated earn
  cards for mUSD calculator and MetaMask Card onboarding
- Add MusdCalculatorView screen and register MUSD_CALCULATOR_VIEW route
- Simplify CampaignsPreview to single featured campaign (active →
  upcoming → previous) instead of separate active tile + upcoming banner
- Sort active campaigns by soonest start date in useRewardCampaigns
- Export selectCardIsLoaded selector from card redux slice
- Add locale strings and test selectors for earn rewards section

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The new EarnRewardsPreview import pulls in card/index.ts which
transitively imports accounts.ts — that file calls createSelector with
selectAccountTreeControllerState which is undefined at module-eval time
in Jest's jsdom env, crashing the test suite.

Add a module-level jest.mock for EarnRewardsPreview (same pattern as
CampaignsPreview) to break the import chain.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… circular avatar

- Add earn-musd and earn-card PNG/SVG assets extracted from Figma exports
- Replace generic placeholder images with new brand assets
- Card earn card: 12deg rotation + 0.75 scale for visual depth
- mUSD earn card: circular inner avatar with drop shadow using theme color token

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Swap in rewards-musd-earn.png and rewards-card-earn.png from design
- Remove interim SVG/PNG extractions (earn-card, earn-musd)
- Images carry their own background so drop avatarBgClass, rotation, scale and circular avatar wrapper

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds dynamic card subtitle logic — cardholders or authenticated card
users see 'Access your MetaMask Card benefits' instead of the default
CTA. Updates tests with new selector mocks and cardholder subtitle cases.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@VGR-GIT VGR-GIT force-pushed the RWDS-1107-tab-less-rewards-view branch from 9708949 to 11004f7 Compare March 20, 2026 07:47
@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 Mar 20, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

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

E2E Test Selection:
The PR introduces changes across two main areas:

  1. Card Redux Slice (app/core/redux/slices/card/index.ts): Added a new selectCardIsLoaded selector. This is a minor additive change to the card state management. The new selector is consumed by the new EarnRewardsPreview component to determine when card geo data has loaded and whether to show the MetaMask Card earn card. This directly connects to SmokeCard tests.

  2. Rewards Feature (multiple files):

    • New EarnRewardsPreview component added to RewardsDashboard that shows mUSD calculator and MetaMask Card earn options based on geo/card state
    • New MusdCalculatorView screen with its own route (MUSD_CALCULATOR_VIEW)
    • CampaignsPreview refactored to show a single featured campaign (active → upcoming → previous priority) instead of separate active + upcoming banners
    • New route registered in RewardsNavigator
    • New i18n strings and test selectors added
    • useRewardCampaigns hook now sorts active campaigns by start date

Why SmokeCard: The new EarnRewardsPreview component uses selectCardIsLoaded, selectIsCardholder, selectIsAuthenticatedCard, and selectIsUserInSupportedCardCountry from the card Redux slice. It also triggers handleDeeplink({ uri: 'metamask://card-onboarding' }) for the card earn card. This integration of card state into the Rewards dashboard could affect card-related behavior. SmokeCard tests validate card state display and navigation which could be impacted.

Why SmokeWalletPlatform: The Rewards dashboard is part of the Trending tab ecosystem. The RewardsDashboard now includes the new EarnRewardsPreview component and the CampaignsPreview has been refactored. SmokeWalletPlatform covers the Trending discovery tab and wallet platform features including the Rewards area.

No performance tests needed: The changes are UI component additions/modifications with no significant performance-critical paths (no heavy list rendering, no new data fetching infrastructure, no startup/initialization changes).

Performance Test Selection:
The changes are primarily additive UI components (EarnRewardsPreview, MusdCalculatorView) and a minor Redux selector addition. There are no changes to performance-critical paths such as app startup, account/network list rendering, heavy data loading, or core state management infrastructure. The new components use existing selectors and don't introduce new data fetching patterns that would impact render performance.

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.

? strings('rewards.earn_rewards.card_subtitle_cardholder')
: strings('rewards.earn_rewards.card_subtitle');

const isAnyGeoLoading = isGeoLoading || isCardGeoLoading;

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.

Geo-blocked mUSD card flashes before geo check starts

Medium Severity

showMusdCard is derived as optinAllowedForGeo !== false, treating null (initial/undetermined) the same as true (allowed). The rewards Redux initial state has optinAllowedForGeoLoading: false and optinAllowedForGeo: null. When the card slice has already loaded (isCardGeoLoaded = true) but the rewards geo check hasn't started yet (e.g. first time entering Rewards), isAnyGeoLoading evaluates to false while showMusdCard is true. This causes the mUSD card to render for geo-blocked users (e.g. UK) until the geo check dispatches its loading flag and subsequently resolves. The loading guard doesn't cover the "not yet initiated" state because the initial loading flag is false.

Fix in Cursor Fix in Web

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.

Is this true and can we fix it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yeah needs a fix, working on it

@github-actions

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

@sonarqubecloud

Copy link
Copy Markdown

@VGR-GIT VGR-GIT enabled auto-merge March 20, 2026 12:05
@VGR-GIT VGR-GIT added this pull request to the merge queue Mar 20, 2026
Merged via the queue into main with commit e393675 Mar 20, 2026
286 of 291 checks passed
@VGR-GIT VGR-GIT deleted the RWDS-1107-tab-less-rewards-view branch March 20, 2026 13:22
@github-actions github-actions Bot locked and limited conversation to collaborators Mar 20, 2026
@metamaskbot metamaskbot added the release-7.72.0 Issue or pull request that will be included in release 7.72.0 label Mar 20, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

INVALID-PR-TEMPLATE PR's body doesn't match template release-7.72.0 Issue or pull request that will be included in release 7.72.0 risk-medium Moderate testing recommended · Possible bug introduction risk size-L team-rewards Rewards team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants