Skip to content

Conversation

@sophieqgu
Copy link
Contributor

@sophieqgu sophieqgu commented Oct 13, 2025

Description

https://consensyssoftware.atlassian.net/browse/RWDS-268
Allow user to go through onboarding tour and opt-in rewards

Open in GitHub Codespaces

Changelog

CHANGELOG entry: Add onboarding tour for user new to Rewards

Related issues

Fixes:

Manual testing steps

  1. Go to this page...

Screenshots/Recordings

Before

After

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

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.

  • Rewards UI/Onboarding:
    • Add guided onboarding modal (OnboardingModal) with steps 1–4, progress indicator, referral code input/validation, legal text, and error surfaces (RewardsErrorBanner, RewardsErrorToast).
    • Update RewardsPointsBalance to show sign-up badge and trigger onboarding; add clickable RewardsBadge.
    • Integrate onboarding modal into Home; remove legacy RewardsProvider usage.
  • State & Hooks:
    • Introduce Redux slice ui/ducks/rewards (state, actions, selectors) for onboarding, geo metadata, candidate subscription ID, season status, and error toasts.
    • New hooks: useOptIn, useLinkAccountGroup, useGeoRewardsMetadata, useCandidateSubscriptionId (reworked), useSeasonStatus (reworked), useValidateReferralCode; remove useRewardsEnabled.
  • Background/API & Controllers:
    • Expose rewards methods via metamask-controller (opt-in, referral validation, geo metadata, opt-in status/linking).
    • RewardsController: change optIn(accounts, referralCode?), add multi-account/linking flow, rename getGeoRewardsMetadatagetRewardsGeoMetadata, adopt shared RewardsGeoMetadata/opt-in DTOs.
  • Data Service & Constants:
    • Default Rewards API to PRD; centralize rewards error messages; adjust tests and endpoints.
  • Localization & Policies:
    • Add comprehensive rewards/onboarding strings (en/en_GB).
    • Update LavaMoat policies for UI usage.
  • Misc/Config:
    • Wire rewards actions in ui/store/actions.ts; update circular-deps allowlist; remove old rewards context/exports; adjust consumers (e.g., coin-overview).
  • Tests:
    • Extensive unit/e2e tests for controllers, services, hooks, components, and reducers.

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

@github-actions
Copy link
Contributor

github-actions bot commented Oct 13, 2025

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.

@sophieqgu sophieqgu force-pushed the rewards-onboarding-tour branch from f89d470 to df11653 Compare October 14, 2025 03:28
@sophieqgu sophieqgu force-pushed the rewards-onboarding-tour branch from df11653 to 20104de Compare October 31, 2025 18:57
@metamaskbot
Copy link
Collaborator

Builds ready [20104de]
📊 Page Load Benchmark Results

Current Commit: 20104de | Date: 10/31/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.05s (±40ms) 🟡 | historical mean value: 1.04s ⬆️ (historical data)
  • domContentLoaded-> current mean value: 728ms (±37ms) 🟢 | historical mean value: 724ms ⬆️ (historical data)
  • firstContentfulPaint-> current mean value: 87ms (±98ms) 🟢 | historical mean value: 77ms ⬆️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.05s 40ms 1.02s 1.34s 1.07s 1.34s
domContentLoaded 728ms 37ms 704ms 994ms 748ms 994ms
firstPaint 87ms 98ms 64ms 1.06s 88ms 1.06s
firstContentfulPaint 87ms 98ms 64ms 1.06s 88ms 1.06s
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 95 Bytes (0%)
  • ui: 427.8 KiB (6.03%)
  • common: 4.13 KiB (0.05%)

@sophieqgu sophieqgu force-pushed the rewards-onboarding-tour branch from 20104de to cccd4b3 Compare November 4, 2025 17:57
@sophieqgu sophieqgu changed the base branch from main to feat/rwds-613-points-estimate November 4, 2025 17:58
@metamaskbot
Copy link
Collaborator

Builds ready [cccd4b3]
📊 Page Load Benchmark Results

Current Commit: cccd4b3 | Date: 11/4/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.03s (±38ms) 🟡 | historical mean value: 1.04s ⬇️ (historical data)
  • domContentLoaded-> current mean value: 721ms (±36ms) 🟢 | historical mean value: 723ms ⬇️ (historical data)
  • firstContentfulPaint-> current mean value: 77ms (±12ms) 🟢 | historical mean value: 77ms ⬇️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.03s 38ms 1.01s 1.33s 1.07s 1.33s
domContentLoaded 721ms 36ms 703ms 998ms 749ms 998ms
firstPaint 77ms 12ms 56ms 184ms 92ms 184ms
firstContentfulPaint 77ms 12ms 56ms 184ms 92ms 184ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 2.43 KiB (0.05%)
  • ui: 451.16 KiB (6.36%)
  • common: 5.9 KiB (0.07%)

@metamaskbot
Copy link
Collaborator

Builds ready [dc9443f]
📊 Page Load Benchmark Results

Current Commit: dc9443f | Date: 11/4/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.03s (±36ms) 🟡 | historical mean value: 1.04s ⬇️ (historical data)
  • domContentLoaded-> current mean value: 717ms (±35ms) 🟢 | historical mean value: 727ms ⬇️ (historical data)
  • firstContentfulPaint-> current mean value: 75ms (±11ms) 🟢 | historical mean value: 77ms ⬇️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.03s 36ms 1.01s 1.30s 1.05s 1.30s
domContentLoaded 717ms 35ms 701ms 976ms 739ms 976ms
firstPaint 75ms 11ms 60ms 164ms 88ms 164ms
firstContentfulPaint 75ms 11ms 60ms 164ms 88ms 164ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms

@metamaskbot
Copy link
Collaborator

Builds ready [9898734]
📊 Page Load Benchmark Results

Current Commit: 9898734 | Date: 11/5/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.03s (±39ms) 🟡 | historical mean value: 1.04s ⬇️ (historical data)
  • domContentLoaded-> current mean value: 719ms (±36ms) 🟢 | historical mean value: 722ms ⬇️ (historical data)
  • firstContentfulPaint-> current mean value: 77ms (±13ms) 🟢 | historical mean value: 77ms ⬇️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.03s 39ms 1.01s 1.33s 1.07s 1.33s
domContentLoaded 719ms 36ms 696ms 996ms 739ms 996ms
firstPaint 77ms 13ms 60ms 192ms 84ms 192ms
firstContentfulPaint 77ms 13ms 60ms 192ms 84ms 192ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms

@sophieqgu sophieqgu force-pushed the rewards-onboarding-tour branch from 9898734 to 7a0e026 Compare November 5, 2025 19:37
@sophieqgu sophieqgu changed the base branch from feat/rwds-613-points-estimate to main November 6, 2025 05:17
@sophieqgu sophieqgu force-pushed the rewards-onboarding-tour branch 2 times, most recently from c62eaba to 592615b Compare November 6, 2025 17:43
@metamaskbot
Copy link
Collaborator

Builds ready [592615b]
📊 Page Load Benchmark Results

Current Commit: 592615b | Date: 11/6/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 981ms (±39ms) 🟢 | historical mean value: 1.05s ⬇️ (historical data)
  • domContentLoaded-> current mean value: 680ms (±35ms) 🟢 | historical mean value: 736ms ⬇️ (historical data)
  • firstContentfulPaint-> current mean value: 75ms (±11ms) 🟢 | historical mean value: 78ms ⬇️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 981ms 39ms 956ms 1.27s 1.01s 1.27s
domContentLoaded 680ms 35ms 658ms 935ms 701ms 935ms
firstPaint 75ms 11ms 60ms 168ms 92ms 168ms
firstContentfulPaint 75ms 11ms 60ms 168ms 92ms 168ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 573 Bytes (0.01%)
  • ui: 436.96 KiB (5.97%)
  • common: 4.68 KiB (0.05%)

@sophieqgu sophieqgu force-pushed the rewards-onboarding-tour branch from 3a425b4 to ad566cc Compare November 6, 2025 20:16
@sophieqgu sophieqgu added the team-rewards Rewards team label Nov 6, 2025
@sophieqgu sophieqgu changed the title Rewards onboarding tour feat: rewards onboarding tour Nov 6, 2025
@sophieqgu sophieqgu marked this pull request as ready for review November 6, 2025 20:19
@sophieqgu sophieqgu requested review from a team as code owners November 6, 2025 20:19
@metamaskbot
Copy link
Collaborator

Builds ready [ad566cc]
📊 Page Load Benchmark Results

Current Commit: ad566cc | Date: 11/6/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.04s (±45ms) 🟡 | historical mean value: 1.05s ⬇️ (historical data)
  • domContentLoaded-> current mean value: 729ms (±43ms) 🟢 | historical mean value: 730ms ⬇️ (historical data)
  • firstContentfulPaint-> current mean value: 78ms (±14ms) 🟢 | historical mean value: 77ms ⬆️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.04s 45ms 1.02s 1.42s 1.06s 1.42s
domContentLoaded 729ms 43ms 708ms 1.09s 743ms 1.09s
firstPaint 78ms 14ms 64ms 208ms 88ms 208ms
firstContentfulPaint 78ms 14ms 64ms 208ms 88ms 208ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 573 Bytes (0.01%)
  • ui: 438.43 KiB (5.99%)
  • common: 4.68 KiB (0.05%)

@sophieqgu sophieqgu requested review from a team, HowardBraham and dbrans as code owners November 6, 2025 22:49
@sophieqgu sophieqgu force-pushed the rewards-onboarding-tour branch from 317bfc3 to ddf406d Compare November 6, 2025 22:50
@metamaskbot
Copy link
Collaborator

metamaskbot commented Nov 6, 2025

✨ Files requiring CODEOWNER review ✨

🧩 @MetaMask/extension-devs (4 files, +28 -0)
  • 📁 lavamoat/
    • 📁 browserify/
      • 📁 beta/
        • 📄 policy.json +7 -0
      • 📁 experimental/
        • 📄 policy.json +7 -0
      • 📁 flask/
        • 📄 policy.json +7 -0
      • 📁 main/
        • 📄 policy.json +7 -0

🔒 @MetaMask/extension-security-team (1 files, +4 -97)
  • 📁 development/
    • 📄 circular-deps.jsonc +4 -97

📜 @MetaMask/policy-reviewers (4 files, +28 -0)
  • 📁 lavamoat/
    • 📁 browserify/
      • 📁 beta/
        • 📄 policy.json +7 -0
      • 📁 experimental/
        • 📄 policy.json +7 -0
      • 📁 flask/
        • 📄 policy.json +7 -0
      • 📁 main/
        • 📄 policy.json +7 -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)
  • 📁 lavamoat/
    • 📁 browserify/
      • 📁 beta/
        • 📄 policy.json +7 -0
      • 📁 experimental/
        • 📄 policy.json +7 -0
      • 📁 flask/
        • 📄 policy.json +7 -0
      • 📁 main/
        • 📄 policy.json +7 -0

👨‍🔧 @dbrans (1 files, +4 -97)
  • 📁 development/
    • 📄 circular-deps.jsonc +4 -97

👨‍🔧 @HowardBraham (1 files, +4 -97)
  • 📁 development/
    • 📄 circular-deps.jsonc +4 -97

@metamaskbot
Copy link
Collaborator

Builds ready [ddf406d]
📊 Page Load Benchmark Results

Current Commit: ddf406d | Date: 11/6/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.06s (±46ms) 🟡 | historical mean value: 1.05s ⬆️ (historical data)
  • domContentLoaded-> current mean value: 743ms (±42ms) 🟢 | historical mean value: 729ms ⬆️ (historical data)
  • firstContentfulPaint-> current mean value: 81ms (±14ms) 🟢 | historical mean value: 77ms ⬆️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.06s 46ms 1.03s 1.43s 1.10s 1.43s
domContentLoaded 743ms 42ms 717ms 1.09s 772ms 1.09s
firstPaint 81ms 14ms 64ms 212ms 88ms 212ms
firstContentfulPaint 81ms 14ms 64ms 212ms 88ms 212ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 573 Bytes (0.01%)
  • ui: 438.43 KiB (5.99%)
  • common: 4.68 KiB (0.05%)

Copy link
Contributor

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?

Copy link
Contributor Author

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?

Copy link
Contributor

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.

Copy link
Contributor Author

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;

Copy link

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.

Fix in Cursor Fix in Web

dispatch(setCandidateSubscriptionId(subscriptionId));
}

setOptinLoading(false);
Copy link

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.

Fix in Cursor Fix in Web

@metamaskbot
Copy link
Collaborator

Builds ready [4e3b980]
UI Startup Metrics (1148 ± 87 ms)
PlatformBuildTypePageMetricMean (ms)Min (ms)Max (ms)Std Dev (ms)P 75 (ms)P 95 (ms)
ChromeBrowserifyStandard HomeuiStartup114899513738712081312
load97684611327510371109
domContentLoaded96983711247510311100
domInteractive221478141863
firstPaint756157113134510111091
backgroundConnect1901762379192208
firstReactRender24164662640
getState2074792539
initialActions006101
loadScripts78663093475847920
setupStore1072431117
numNetworkReqs1367520672
BrowserifyPower User HomeuiStartup17021510269431019622694
load1057904164721313091647
domContentLoaded1050898163321112991633
domInteractive42151284190128
firstPaint66817016924589551692
backgroundConnect24322130820253308
firstReactRender31265373353
getState17615123223191232
initialActions001001
loadScripts824684137220310661372
setupStore12102741127
numNetworkReqs1217026571182265
WebpackStandard HomeuiStartup88072713081039011137
load642581103384636878
domContentLoaded633575101480626861
domInteractive181280121550
firstPaint225591018238206862
backgroundConnect271368133658
firstReactRender311784113646
getState1366371518
initialActions001001
loadScripts630572100377624848
setupStore1363551524
numNetworkReqs1367519871
WebpackPower User HomeuiStartup1048893158422312821584
load651579926101732926
domContentLoaded63656989393711893
domInteractive34131033483103
firstPaint25764776208343776
backgroundConnect571019267140192
firstReactRender27253012830
getState1389316223153162
initialActions001011
loadScripts63256788390700883
setupStore1462792627
numNetworkReqs1116422854164228
FirefoxBrowserifyStandard HomeuiStartup15571319205713716151858
load1302114015819213531513
domContentLoaded1302113915819213521512
domInteractive1123341660115239
firstPaint------
backgroundConnect48261202055101
firstReactRender28225462942
getState148145161230
initialActions001001
loadScripts1273112215449013211480
setupStore178198231436
numNetworkReqs1266516860
BrowserifyPower User HomeuiStartup22211814326145127653261
load14031173199627715261996
domContentLoaded14031173199627715261996
domInteractive19475636174322636
firstPaint------
backgroundConnect10832460111150460
firstReactRender51331061758106
getState1319818628162186
initialActions101111
loadScripts13631151189825214711898
setupStore30686275586
numNetworkReqs1327131972199319
WebpackStandard HomeuiStartup16031381223914516071993
load13651204177010913861663
domContentLoaded13641204177010913851663
domInteractive993052762100182
firstPaint------
backgroundConnect47232112552112
firstReactRender342494153379
getState1285481120
initialActions001011
loadScripts13361187174310213521579
setupStore187246281365
numNetworkReqs1366817766
WebpackPower User HomeuiStartup23521936317936027843179
load15261268178316016851783
domContentLoaded15261268178316016851783
domInteractive15039435128257435
firstPaint------
backgroundConnect1093335290148352
firstReactRender43315774757
getState1518532068169320
initialActions106116
loadScripts14821248175216316541752
setupStore4461494866149
numNetworkReqs1536333379208333
📊 Page Load Benchmark Results

Current Commit: 4e3b980 | Date: 11/12/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.02s (±51ms) 🟡 | historical mean value: 1.04s ⬇️ (historical data)
  • domContentLoaded-> current mean value: 714ms (±48ms) 🟢 | historical mean value: 726ms ⬇️ (historical data)
  • firstContentfulPaint-> current mean value: 74ms (±12ms) 🟢 | historical mean value: 79ms ⬇️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.02s 51ms 1000ms 1.30s 1.08s 1.30s
domContentLoaded 714ms 48ms 692ms 990ms 753ms 990ms
firstPaint 74ms 12ms 60ms 180ms 80ms 180ms
firstContentfulPaint 74ms 12ms 60ms 180ms 80ms 180ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 176 Bytes (0%)
  • ui: 435.6 KiB (5.91%)
  • common: 5.69 KiB (0.07%)

Copy link
Contributor

@MajorLift MajorLift left a 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/.

jbblanc
jbblanc previously approved these changes Nov 13, 2025
@metamaskbot
Copy link
Collaborator

Builds ready [9b73231]
UI Startup Metrics (1173 ± 98 ms)
PlatformBuildTypePageMetricMean (ms)Min (ms)Max (ms)Std Dev (ms)P 75 (ms)P 95 (ms)
ChromeBrowserifyStandard HomeuiStartup1173101516589812181349
load100086714418810561163
domContentLoaded99386214378710421156
domInteractive211477141866
firstPaint68086120338210001097
backgroundConnect1931782248197212
firstReactRender21164552333
getState20861102442
initialActions001001
loadScripts807682125486855958
setupStore1051921113
numNetworkReqs1367719670
BrowserifyPower User HomeuiStartup17341507230127120192301
load1068902158822413121588
domContentLoaded1061896157822313061578
domInteractive34141013279101
firstPaint72417116234689461623
backgroundConnect23522328015245280
firstReactRender39354733947
getState17915223824203238
initialActions001011
loadScripts834674134421710781344
setupStore1081211112
numNetworkReqs1407336994241369
WebpackStandard HomeuiStartup744629111777748939
load54249986262539706
domContentLoaded53549384859531686
domInteractive1711109131343
firstPaint21352738204179683
backgroundConnect251172122749
firstReactRender25163563033
getState1052831115
initialActions001001
loadScripts53249084058529679
setupStore1052731214
numNetworkReqs1467520873
WebpackPower User HomeuiStartup1153947174029113821740
load69759010851557951085
domContentLoaded676580990137752990
domInteractive35141193572119
firstPaint47169993301616993
backgroundConnect51101865654186
firstReactRender41374834348
getState1439516824157168
initialActions001001
loadScripts672578979134742979
setupStore1362782627
numNetworkReqs1126922558165225
FirefoxBrowserifyStandard HomeuiStartup14871319192712215391796
load1257112815059013111439
domContentLoaded1257112615049013111439
domInteractive1103530651113243
firstPaint------
backgroundConnect4326102165284
firstReactRender25205052539
getState1173841118
initialActions002001
loadScripts1232111014798612851419
setupStore165223291233
numNetworkReqs1266315858
BrowserifyPower User HomeuiStartup21171886270327724282703
load13791152185723215791857
domContentLoaded13781151185623215791856
domInteractive19980575179384575
firstPaint------
backgroundConnect803023156124231
firstReactRender57447176271
getState1216618427124184
initialActions001011
loadScripts13441134180922315411809
setupStore25676224576
numNetworkReqs1346622358178223
WebpackStandard HomeuiStartup16231431215214916541988
load13831202172311614291646
domContentLoaded13831201172211614281646
domInteractive983330044105173
firstPaint------
backgroundConnect49252132851111
firstReactRender342495163377
getState157176231244
initialActions001001
loadScripts13531183168210614011578
setupStore147108151248
numNetworkReqs1366918765
WebpackPower User HomeuiStartup22411869276130026562761
load14701230176218316571762
domContentLoaded14701230176118316571761
domInteractive16039516146300516
firstPaint------
backgroundConnect902727177154271
firstReactRender69411112175111
getState1468626153190261
initialActions105115
loadScripts14311214171518316351715
setupStore2761794317179
numNetworkReqs1315826073222260
📊 Page Load Benchmark Results

Current Commit: 9b73231 | Date: 11/13/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.04s (±41ms) 🟡 | historical mean value: 1.03s ⬆️ (historical data)
  • domContentLoaded-> current mean value: 721ms (±38ms) 🟢 | historical mean value: 718ms ⬆️ (historical data)
  • firstContentfulPaint-> current mean value: 76ms (±11ms) 🟢 | historical mean value: 78ms ⬇️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.04s 41ms 1.01s 1.34s 1.09s 1.34s
domContentLoaded 721ms 38ms 696ms 1.00s 768ms 1.00s
firstPaint 76ms 11ms 56ms 164ms 84ms 164ms
firstContentfulPaint 76ms 11ms 56ms 164ms 84ms 164ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 176 Bytes (0%)
  • ui: 435.58 KiB (5.9%)
  • common: 5.7 KiB (0.07%)

Copy link
Contributor

@HowardBraham HowardBraham left a 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

@sophieqgu
Copy link
Contributor Author

Working on breaking up this PR into smaller ones

@sophieqgu sophieqgu marked this pull request as draft November 14, 2025 17:50
github-merge-queue bot pushed a commit that referenced this pull request Nov 17, 2025
<!--
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?
-->

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](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 -->
github-merge-queue bot pushed a commit that referenced this pull request Nov 17, 2025
<!--
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?
-->

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](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 -->
@sophieqgu sophieqgu mentioned this pull request Nov 17, 2025
7 tasks
github-merge-queue bot pushed a commit that referenced this pull request Nov 17, 2025
<!--
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?
-->

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](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 -->
github-merge-queue bot pushed a commit that referenced this pull request Nov 18, 2025
<!--
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?
-->

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](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>
github-merge-queue bot pushed a commit that referenced this pull request Nov 18, 2025
<!--
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?
-->

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](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 -->
github-merge-queue bot pushed a commit that referenced this pull request Nov 18, 2025
<!--
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?
-->

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](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 -->
@sophieqgu sophieqgu closed this Nov 19, 2025
@github-actions github-actions bot locked and limited conversation to collaborators Nov 19, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants