Commit 47741a3
feat: add CashTokensFullView and integrate into MainNavigator (MetaMask#27123)
<!--
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**
1. **What is the reason for the change?**
The redesigned homepage needs a dedicated **Cash** section as the first
section, surfacing mUSD (MetaMask USD) and guiding users to convert
stablecoins and claim bonuses.
2. **What is the improvement/solution?**
- **Cash section (homepage):** When mUSD conversion is enabled and user
is geo-eligible, the first section is **"mUSD"**. It shows aggregated
mUSD balance (Linea + Ethereum), annualized bonus copy (e.g. "Get 3%
annualized bonus…" with the percentage in green), and a "Claim bonus"
CTA on the row when a bonus is claimable. Tapping the section header
navigates to the Cash token list. When the user has no mUSD, the section
shows a **Get mUSD** empty state: the same annualized copy, a tappable
mUSD token row that navigates to Token Details (Mainnet mUSD, same
destination as trending tokens), and a "Get mUSD" button that routes to
the Buy flow (when mUSD is buyable) or the Convert flow (when the user
has convertible stablecoins e.g. USDC).
- **Cash token list screen:** New full-view screen
(`CashTokensFullView`) that shows only mUSD positions across supported
networks (Ethereum Mainnet, Linea). When the user has no mUSD, the
screen renders the same Get mUSD empty state (handled by
`CashTokensFullView` via `useMusdBalance`); when the user has mUSD, it
renders `Tokens` with `showOnlyMusd`. Same network filter as the main
token list; no add-token or sort. No mUSD-specific empty-state logic
inside `Tokens`.
- **mUSD isolation:** mUSD is removed from the main Tokens section and
from the generic full token list; it appears only in the Cash section
and Cash full view.
- **Implementation details:** `Tokens` supports a `showOnlyMusd` prop
(filter list to mUSD, hide add/sort in control bar);
`TokenListControlBar` supports `showAddToken` and `hideSort`. Empty
state component `CashGetMusdEmptyState` is used on the homepage (in
`CashSection`) and in `CashTokensFullView`; token row uses
`NavigationService` to navigate to Token Details. New route
`CASH_TOKENS_FULL_VIEW` and screen registration. Uses design-system
components. Cash section does not expose a refresh ref (no-op removed).
## **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: Added a Cash section on the homepage that shows
aggregated mUSD balance, annualized bonus copy for stablecoin holders,
and a dedicated Cash token list view with network filter.
## **Related issues**
Fixes: https://consensyssoftware.atlassian.net/browse/TMCU-527
## **Manual testing steps**
```gherkin
Feature: Homepage Cash section and Cash token list
Scenario: User with mUSD conversion enabled and geo-eligible sees Cash section first
Given the user has mUSD conversion feature enabled and is in an eligible region
When the user opens the redesigned homepage
Then the Cash section appears as the first section with title "Cash"
And if the user has convertible stablecoins, the annualized bonus copy is shown (e.g. "Get 3% annualized bonus...")
And if the user has mUSD balance, the aggregated mUSD row is shown with balance and optional "Claim bonus"
Scenario: User navigates to Cash token list from section header
Given the user is on the homepage with Cash section visible
When the user taps the Cash section header (or the ">" affordance)
Then the app navigates to the Cash token list screen
And the screen shows only mUSD positions (per network) or the cash empty state when none
And the network filter is visible and works; add-token and sort buttons are not shown
Scenario: User with network filter applied sees mUSD when opening Cash list
Given the user has a network filter applied (e.g. single network) and has mUSD on that network
When the user opens the Cash token list from the homepage
Then mUSD positions for the enabled network(s) are shown
And the user can change the network filter from the control bar
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
https://github.com/user-attachments/assets/ed532349-cfcc-4495-9b38-6e97fbaec30f
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/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-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **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.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Adds new navigation routes and conditional token filtering (including
excluding mUSD from main lists) gated by feature flags/geo eligibility,
which could affect token visibility and analytics. Also changes fiat
formatting to use `currencyDisplay: 'narrowSymbol'`, which may alter
currency rendering across the app.
>
> **Overview**
> Introduces a new **Cash (mUSD)** surface: a `CashSection` is added as
the first homepage section when mUSD conversion is enabled and
geo-eligible, showing either an aggregated mUSD row (with optional
*Claim bonus*) or a *Get mUSD* empty state that deep-links to mUSD
details and routes users into buy/convert flows with new
`home_cash_section` analytics location.
>
> Adds a dedicated `CashTokensFullView` route/screen and extends
`Tokens`/`TokenListControlBar` to support an mUSD-only list
(`showOnlyMusd`) that hides add-token/sort and uses cash-specific empty
state messaging; when the Cash section is rendered, mUSD is filtered out
of the main tokens lists (including popular tokens) to avoid
duplication.
>
> Updates mUSD-related token list items to show a non-clickable green
`"3% bonus"` label for mUSD when no claimable reward exists (only when
conversion + geo eligibility are true), expands/adjusts unit tests and
snapshots accordingly, and tweaks `formatFiat` to prefer `Intl` narrow
currency symbols.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
cc3ad61. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
Co-authored-by: Pedro Pablo Aste Kompen <wachunei@gmail.com>1 parent 0a3bbfa commit 47741a3
35 files changed
Lines changed: 1948 additions & 72 deletions
File tree
- app
- components
- UI
- Earn/constants/events
- Tokens
- TokenListControlBar
- TokenList
- TokenListItemV2
- TokenListItem
- Views
- CashTokensFullView
- Homepage
- Sections
- Cash
- Tokens
- hooks
- hooks
- util
- locales/languages
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
| 34 | + | |
34 | 35 | | |
35 | 36 | | |
36 | 37 | | |
| |||
995 | 996 | | |
996 | 997 | | |
997 | 998 | | |
| 999 | + | |
| 1000 | + | |
| 1001 | + | |
| 1002 | + | |
| 1003 | + | |
998 | 1004 | | |
999 | 1005 | | |
1000 | 1006 | | |
| |||
Lines changed: 33 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
60 | 60 | | |
61 | 61 | | |
62 | 62 | | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
63 | 74 | | |
64 | 75 | | |
65 | 76 | | |
| |||
454 | 465 | | |
455 | 466 | | |
456 | 467 | | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
457 | 479 | | |
458 | 480 | | |
459 | 481 | | |
| |||
848 | 870 | | |
849 | 871 | | |
850 | 872 | | |
| 873 | + | |
| 874 | + | |
| 875 | + | |
| 876 | + | |
| 877 | + | |
| 878 | + | |
| 879 | + | |
| 880 | + | |
| 881 | + | |
| 882 | + | |
| 883 | + | |
851 | 884 | | |
852 | 885 | | |
853 | 886 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
| 8 | + | |
7 | 9 | | |
8 | 10 | | |
9 | 11 | | |
| |||
Lines changed: 73 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
27 | | - | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
28 | 31 | | |
29 | 32 | | |
30 | 33 | | |
| |||
1248 | 1251 | | |
1249 | 1252 | | |
1250 | 1253 | | |
1251 | | - | |
| 1254 | + | |
1252 | 1255 | | |
1253 | 1256 | | |
1254 | | - | |
| 1257 | + | |
| 1258 | + | |
| 1259 | + | |
1255 | 1260 | | |
1256 | 1261 | | |
1257 | 1262 | | |
| |||
1280 | 1285 | | |
1281 | 1286 | | |
1282 | 1287 | | |
1283 | | - | |
| 1288 | + | |
1284 | 1289 | | |
1285 | 1290 | | |
1286 | 1291 | | |
1287 | 1292 | | |
| 1293 | + | |
1288 | 1294 | | |
1289 | 1295 | | |
1290 | 1296 | | |
| |||
1298 | 1304 | | |
1299 | 1305 | | |
1300 | 1306 | | |
| 1307 | + | |
| 1308 | + | |
| 1309 | + | |
| 1310 | + | |
| 1311 | + | |
| 1312 | + | |
| 1313 | + | |
| 1314 | + | |
| 1315 | + | |
| 1316 | + | |
| 1317 | + | |
| 1318 | + | |
| 1319 | + | |
| 1320 | + | |
| 1321 | + | |
| 1322 | + | |
| 1323 | + | |
| 1324 | + | |
| 1325 | + | |
| 1326 | + | |
| 1327 | + | |
| 1328 | + | |
| 1329 | + | |
| 1330 | + | |
| 1331 | + | |
| 1332 | + | |
| 1333 | + | |
| 1334 | + | |
| 1335 | + | |
| 1336 | + | |
| 1337 | + | |
| 1338 | + | |
| 1339 | + | |
| 1340 | + | |
| 1341 | + | |
| 1342 | + | |
| 1343 | + | |
| 1344 | + | |
| 1345 | + | |
| 1346 | + | |
| 1347 | + | |
| 1348 | + | |
| 1349 | + | |
| 1350 | + | |
| 1351 | + | |
| 1352 | + | |
| 1353 | + | |
| 1354 | + | |
| 1355 | + | |
| 1356 | + | |
| 1357 | + | |
| 1358 | + | |
| 1359 | + | |
| 1360 | + | |
| 1361 | + | |
| 1362 | + | |
| 1363 | + | |
| 1364 | + | |
| 1365 | + | |
| 1366 | + | |
| 1367 | + | |
| 1368 | + | |
| 1369 | + | |
1301 | 1370 | | |
1302 | 1371 | | |
1303 | 1372 | | |
| |||
Lines changed: 26 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
| 29 | + | |
29 | 30 | | |
30 | 31 | | |
31 | 32 | | |
| 33 | + | |
32 | 34 | | |
33 | 35 | | |
34 | 36 | | |
| |||
146 | 148 | | |
147 | 149 | | |
148 | 150 | | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
149 | 156 | | |
150 | 157 | | |
151 | 158 | | |
| |||
294 | 301 | | |
295 | 302 | | |
296 | 303 | | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
297 | 320 | | |
298 | 321 | | |
299 | 322 | | |
| |||
336 | 359 | | |
337 | 360 | | |
338 | 361 | | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
339 | 365 | | |
340 | 366 | | |
341 | 367 | | |
| |||
Lines changed: 72 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
33 | | - | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
34 | 37 | | |
35 | 38 | | |
36 | 39 | | |
| |||
1220 | 1223 | | |
1221 | 1224 | | |
1222 | 1225 | | |
1223 | | - | |
| 1226 | + | |
| 1227 | + | |
| 1228 | + | |
1224 | 1229 | | |
1225 | 1230 | | |
1226 | 1231 | | |
| |||
1342 | 1347 | | |
1343 | 1348 | | |
1344 | 1349 | | |
1345 | | - | |
| 1350 | + | |
1346 | 1351 | | |
1347 | 1352 | | |
1348 | 1353 | | |
1349 | 1354 | | |
| 1355 | + | |
1350 | 1356 | | |
1351 | 1357 | | |
1352 | 1358 | | |
| |||
1360 | 1366 | | |
1361 | 1367 | | |
1362 | 1368 | | |
| 1369 | + | |
| 1370 | + | |
| 1371 | + | |
| 1372 | + | |
| 1373 | + | |
| 1374 | + | |
| 1375 | + | |
| 1376 | + | |
| 1377 | + | |
| 1378 | + | |
| 1379 | + | |
| 1380 | + | |
| 1381 | + | |
| 1382 | + | |
| 1383 | + | |
| 1384 | + | |
| 1385 | + | |
| 1386 | + | |
| 1387 | + | |
| 1388 | + | |
| 1389 | + | |
| 1390 | + | |
| 1391 | + | |
| 1392 | + | |
| 1393 | + | |
| 1394 | + | |
| 1395 | + | |
| 1396 | + | |
| 1397 | + | |
| 1398 | + | |
| 1399 | + | |
| 1400 | + | |
| 1401 | + | |
| 1402 | + | |
| 1403 | + | |
| 1404 | + | |
| 1405 | + | |
| 1406 | + | |
| 1407 | + | |
| 1408 | + | |
| 1409 | + | |
| 1410 | + | |
| 1411 | + | |
| 1412 | + | |
| 1413 | + | |
| 1414 | + | |
| 1415 | + | |
| 1416 | + | |
| 1417 | + | |
| 1418 | + | |
| 1419 | + | |
| 1420 | + | |
| 1421 | + | |
| 1422 | + | |
| 1423 | + | |
| 1424 | + | |
| 1425 | + | |
| 1426 | + | |
| 1427 | + | |
| 1428 | + | |
| 1429 | + | |
| 1430 | + | |
| 1431 | + | |
1363 | 1432 | | |
1364 | 1433 | | |
1365 | 1434 | | |
| |||
0 commit comments