-
Notifications
You must be signed in to change notification settings - Fork 5.4k
feat: rewards onboarding tour #36827
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
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. |
f89d470 to
df11653
Compare
df11653 to
20104de
Compare
Builds ready [20104de]
📊 Page Load Benchmark ResultsCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
20104de to
cccd4b3
Compare
Builds ready [cccd4b3]
📊 Page Load Benchmark ResultsCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
Builds ready [dc9443f]
📊 Page Load Benchmark ResultsCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
|
Builds ready [9898734]
📊 Page Load Benchmark ResultsCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
|
9898734 to
7a0e026
Compare
c62eaba to
592615b
Compare
Builds ready [592615b]
📊 Page Load Benchmark ResultsCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
3a425b4 to
ad566cc
Compare
Builds ready [ad566cc]
📊 Page Load Benchmark ResultsCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
317bfc3 to
ddf406d
Compare
✨ Files requiring CODEOWNER review ✨🧩 @MetaMask/extension-devs (4 files, +28 -0)
🔒 @MetaMask/extension-security-team (1 files, +4 -97)
📜 @MetaMask/policy-reviewers (4 files, +28 -0)
Tip Follow the policy review process outlined in the LavaMoat Policy Review Process doc before expecting an approval from Policy Reviewers. 🔗 @MetaMask/supply-chain (4 files, +28 -0)
👨🔧 @dbrans (1 files, +4 -97)
👨🔧 @HowardBraham (1 files, +4 -97)
|
Builds ready [ddf406d]
📊 Page Load Benchmark ResultsCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR somehow adds 3,295 lines of circular dependencies. How did that even happen?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now seem to reduce to around 341 lines..is this in the normal range?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hah no our policy is actually you can't add ANY new circular dependencies, you can only keep the same or remove. We're trying to get to zero slowly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Going down now 🥹
| sideEffectAccountGroupIdToLink && sideEffectAccounts.length > 0 | ||
| ? activeGroupAccounts | ||
| : sideEffectAccounts; | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Inverted Logic Prevents Account Linking
The logic for determining accountsToLinkAfterOptIn is inverted. When sideEffectAccountGroupIdToLink exists and has accounts, those accounts are used for opt-in, but then activeGroupAccounts are set to be linked afterward. However, when there are no side effect accounts, activeGroupAccounts are used for opt-in, but then sideEffectAccounts (which is empty) are set to be linked afterward. This means the second branch will never link any accounts because sideEffectAccounts is empty when the condition is false.
| dispatch(setCandidateSubscriptionId(subscriptionId)); | ||
| } | ||
|
|
||
| setOptinLoading(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Reliable Loading State Clearing
The setOptinLoading(false) call is outside the try-catch block, which means if any unexpected error occurs after the catch block (lines 172-175), the loading state won't be reset. This should be in a finally block to ensure the loading state is always cleared, even if setCandidateSubscriptionId or other operations throw.
Builds ready [4e3b980]
UI Startup Metrics (1148 ± 87 ms)
📊 Page Load Benchmark ResultsCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
MajorLift
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Policy changes look ok. Will add approval for @MetaMask/policy-reviewers after more reviewers have looked at changes under ui/.
Builds ready [9b73231]
UI Startup Metrics (1173 ± 98 ms)
📊 Page Load Benchmark ResultsCurrent Commit: 📄 Localhost MetaMask Test DappSamples: 100 Summary
📈 Detailed Results
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
HowardBraham
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approving on behalf of circular dependency reduction
|
Working on breaking up this PR into smaller ones |
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** https://consensyssoftware.atlassian.net/browse/RWDS-268 Part 2 of #36827 pertaining to metametrics changes <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> [](https://codespaces.new/MetaMask/metamask-extension/pull/37873?quickstart=1) ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** 1. Go to this page... 2. 3. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] 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. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Expose a MetaMetrics traits update API and add rewards-specific traits, events, and category constants. > > - **MetaMetrics**: > - Expose `updateMetaMetricsTraits` via `getApi()` in `app/scripts/metamask-controller.js` (binds to `metaMetricsController.updateTraits`). > - Extend rewards-related tracking in `shared/constants/metametrics.ts`: > - Add user traits: `has_rewards_opted_in`, `rewards_referred`, `rewards_referral_code_used` and corresponding `MetaMetricsUserTrait` enums. > - Add event names for rewards flows: `REWARDS_OPT_IN_*` and `REWARDS_ACCOUNT_LINKING_*`. > - Add `Rewards` to `MetaMetricsEventCategory`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 9773647. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** https://consensyssoftware.atlassian.net/browse/RWDS-268 Part 1 of #36827 pertaining to rewards controller and data services changes <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> [](https://codespaces.new/MetaMask/metamask-extension/pull/37871?quickstart=1) ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** 1. Go to this page... 2. 3. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] 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. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Refactors Rewards opt-in to accept provided accounts, renames/fixes geo metadata API, moves shared DTOs, defaults Rewards API base URL to PRD, and surfaces new rewards methods via MetaMaskController. > > - **Rewards Controller**: > - Refactor `optIn` to `optIn(accounts, referralCode?)`; iterates provided accounts, links remaining on success, throws if all fail. > - Rename `getGeoRewardsMetadata` → `getRewardsGeoMetadata`; cache behavior preserved. > - Register updated handlers (`getRewardsGeoMetadata`, `linkAccountsToSubscriptionCandidate`, etc.) and expose new utilities (`getCandidateSubscriptionId`, `isOptInSupported`, `getOptInStatus`). > - Internal opt-in flow simplified; consistent state updates and token storage. > - **Shared Types**: > - Move `RewardsGeoMetadata`, `OptInStatusInputDto`, `OptInStatusDto`, `OptOutDto` to `shared/types/rewards` and update imports; remove duplicates from controller types. > - **Rewards Data Service**: > - Default API base URL to `PRD` (including non-prod) and update tests/URLs. > - Add `REWARDS_ERROR_MESSAGES`; use as default messages for `AuthorizationFailedError` and `SeasonNotFoundError`. > - Minor response handling tweaks and new endpoints wired (`getSeasonMetadata`, `getDiscoverSeasons`). > - **MetaMask Controller (UI API)**: > - Expose rewards APIs: `validateRewardsReferralCode`, `getRewardsGeoMetadata`, `rewardsOptIn`, `rewardsIsOptInSupported`, `rewardsGetOptInStatus`, `rewardsLinkAccountsToSubscriptionCandidate`. > - Misc fixes: rename `subscriptionService` → `SubscriptionService`; update Shield subscription metrics capture; add `updateMetaMetricsTraits`. > - **Tests**: > - Update and expand unit tests for new opt-in signature/behavior, geo method rename, PRD URLs, and new data service endpoints. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit fc7f860. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** https://consensyssoftware.atlassian.net/browse/RWDS-268 Part 3 of #36827 pertaining to ui state and selectors <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> [](https://codespaces.new/MetaMask/metamask-extension/pull/37875?quickstart=1) ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** 1. Go to this page... 2. 3. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] 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. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Introduces a new `rewards` UI state slice with selectors and background-thunk actions, integrates it into the root reducer, and adds comprehensive tests plus minor config updates. > > - **State (Redux)**: > - Add `ui/ducks/rewards/` slice (`index.ts`) defining onboarding, geo, subscription/season status, feature flag, and error toast state with actions (e.g., `setOnboardingModalOpen`, `setRewardsGeoMetadata`, `setSeasonStatus`). > - Integrate reducer in `ui/ducks/index.js` as `rewards`. > - **Selectors**: > - Add `ui/ducks/rewards/selectors.ts` (e.g., `selectRewardsEnabled` with version-gated flag support, and basic state selectors). > - **Async actions (background thunks)**: > - Extend `ui/store/actions.ts` with rewards-related thunks: `validateRewardsReferralCode`, `getRewardsGeoMetadata`, `rewardsOptIn`, `rewardsIsOptInSupported`, `rewardsGetOptInStatus`, `rewardsLinkAccountsToSubscriptionCandidate`, `getRewardsSeasonStatus`, `getRewardsSeasonMetadata`, `estimateRewardsPoints`. > - Add `updateMetaMetricsTraits` helper. > - **Tests**: > - Add unit tests for rewards reducer/actions (`ui/ducks/rewards/index.test.ts`), selectors (`ui/ducks/rewards/selectors.test.ts`), and store actions (`ui/store/actions.test.js`). > - **Configs/fixtures**: > - Update E2E UI state snapshot to include `rewards`. > - Tweak circular deps tracking and `.madgerc` allowed globs. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit bd27c29. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** https://consensyssoftware.atlassian.net/browse/RWDS-268 Part 4 of #36827 removes rewards context and uses redux <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> [](https://codespaces.new/MetaMask/metamask-extension/pull/37912?quickstart=1) ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** 1. Go to this page... 2. 3. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] 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. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Migrates Rewards from React context to Redux, updating components/hooks, adding onboarding and error messaging, and removing the RewardsProvider. > > - **Rewards architecture (Redux migration)**: > - Replace `useRewardsContext` and `RewardsProvider` with Redux selectors/actions across app. > - Remove `ui/contexts/rewards` and related exports; delete `ui/components/app/rewards/index.ts`. > - **UI/Components**: > - `RewardsPointsBalance`: now uses Redux selectors; adds sign-up badge (click opens onboarding), improved loading/error states, locale-aware formatting, and GTM onboarding flag via `REWARDS_GTM_MODAL_SHOWN`. > - `RewardsBadge`: new `onClick` prop and cursor styling. > - `coin-overview.tsx` and `global-menu.tsx`: use `selectRewardsEnabled` and render rewards accordingly. > - **Hooks**: > - `useCandidateSubscriptionId` and `useSeasonStatus`: rewritten to dispatch Redux (`setCandidateSubscriptionId`, `setSeasonStatus*`), handle pending/retry/error sentinels, and auth errors; add tests. > - `useRewards`: now reads `selectRewardsEnabled` from Redux (no context); retains debounced estimation; tests updated. > - **Utils & i18n**: > - Add `utils/constants.ts` (`REWARDS_GTM_MODAL_SHOWN`). > - New `handleRewardsErrorMessage` with unit tests. > - Add i18n strings for rewards error messages and "Sign up for Rewards" in `en` and `en_GB` locales. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit eae380b. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: VGR <VanGulckRik@gmail.com>
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** https://consensyssoftware.atlassian.net/browse/RWDS-268 Part 5 of #36827 introduces new rewards hooks <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> [](https://codespaces.new/MetaMask/metamask-extension/pull/37917?quickstart=1) ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** 1. Go to this page... 2. 3. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] 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. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Introduces four rewards-related React hooks with Redux/metrics integration and comprehensive tests. > > - **Hooks (rewards)**: > - `ui/hooks/rewards/useGeoRewardsMetadata`: > - Fetches `RewardsGeoMetadata` on mount (conditional via `enabled`), manages loading/error/reset, dedupes concurrent fetches. > - `ui/hooks/rewards/useLinkAccountGroup`: > - Links eligible accounts in an `AccountGroupId` to a subscription candidate; checks support/status, emits MetaMetrics started/completed/failed events, returns per-address results with loading/error state. > - `ui/hooks/rewards/useOptIn`: > - Orchestrates opt-in (with optional referral), selects accounts (side-effect vs active group), links additional accounts post opt-in, tracks metrics, updates user traits, sets candidate subscription ID, handles errors. > - `ui/hooks/rewards/useValidateReferralCode`: > - Debounced referral code validation (`validateRewardsReferralCode`), exposes `setReferralCode`/`validateCode`, and `isValid`/`isValidating`/unknown-error state. > - **Tests**: > - Adds thorough unit tests for all hooks covering success, loading, error, dedupe, metrics, and edge cases. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit b8c2ba8. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** https://consensyssoftware.atlassian.net/browse/RWDS-268 Part 6 of #36827 introduces new rewards onboarding components <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> [](https://codespaces.new/MetaMask/metamask-extension/pull/37919?quickstart=1) ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** 1. Go to this page... 2. 3. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] 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. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Implements the Rewards onboarding flow (modal with steps, error toast/banner, referral opt‑in) with full tests and new locale strings. > > - **UI/Flow**: > - Add `Rewards` onboarding modal `ui/components/app/rewards/onboarding/OnboardingModal.tsx` with steps `OnboardingIntroStep`, `OnboardingStep1`, `OnboardingStep2`, `OnboardingStep3`, `OnboardingStep4` and `ProgressIndicator`. > - New error surfaces: `RewardsErrorBanner` and `RewardsErrorToast`. > - **Logic**: > - Intro step handles geo eligibility, hardware wallet checks, and candidate subscription ID states (`pending/retry/error`) with retry actions; advances through steps; persists modal‑shown flag. > - Step 4 supports referral code validation UI and opt‑in action; legal links via constants in `onboarding/constants.ts`. > - **i18n**: > - Add/enhance Rewards onboarding and error strings in `app/_locales/en/messages.json` and `app/_locales/en_GB/messages.json`. > - **Tests**: > - Comprehensive tests for modal, steps 1–4, error banner/toast, and progress indicator. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 978bad2. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
Description
https://consensyssoftware.atlassian.net/browse/RWDS-268
Allow user to go through onboarding tour and opt-in rewards
Changelog
CHANGELOG entry: Add onboarding tour for user new to Rewards
Related issues
Fixes:
Manual testing steps
Screenshots/Recordings
Before
After
Pre-merge author checklist
Pre-merge reviewer checklist
Note
Implements the full Rewards onboarding flow (modal steps, referral, geo checks, opt-in and account linking) with new Redux state/hooks, updated controllers/actions/services, UI integrations, and comprehensive tests.
OnboardingModal) with steps 1–4, progress indicator, referral code input/validation, legal text, and error surfaces (RewardsErrorBanner,RewardsErrorToast).RewardsPointsBalanceto show sign-up badge and trigger onboarding; add clickableRewardsBadge.RewardsProviderusage.ui/ducks/rewards(state, actions, selectors) for onboarding, geo metadata, candidate subscription ID, season status, and error toasts.useOptIn,useLinkAccountGroup,useGeoRewardsMetadata,useCandidateSubscriptionId(reworked),useSeasonStatus(reworked),useValidateReferralCode; removeuseRewardsEnabled.metamask-controller(opt-in, referral validation, geo metadata, opt-in status/linking).RewardsController: changeoptIn(accounts, referralCode?), add multi-account/linking flow, renamegetGeoRewardsMetadata→getRewardsGeoMetadata, adopt sharedRewardsGeoMetadata/opt-in DTOs.ui/store/actions.ts; update circular-deps allowlist; remove old rewards context/exports; adjust consumers (e.g.,coin-overview).Written by Cursor Bugbot for commit 9b73231. This will update automatically on new commits. Configure here.