[pull] main from MetaMask:main#838
Merged
Merged
Conversation
…PI (#31724) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> <!-- mms-check directive vocabulary — read by .github/scripts/shared/pr-template-checks.ts at module load to build the validation plan. Directives are invisible in rendered markdown and must NOT be removed or edited without updating the validator registry. type=text Section must contain non-placeholder prose. type=changelog Section must have a valid CHANGELOG entry: line. type=issue-link Section must have a Fixes:/Closes:/Refs: line with a value. type=manual-testing Section must have real testing steps or an explicit N/A. type=screenshot Section must have evidence (image/URL) or an explicit N/A. type=checklist Section must have all checkboxes consciously checked. required=true|false Whether a missing/invalid section runs the validator at all. blocking=true|false Whether a failure of this check fails the CI workflow. Default: false — failures are shown as warnings in the sticky comment but do not block the PR. Sections without a directive are checked for structural presence only. --> ## **Description** Updated `MoneyOnboardingView` to use latest Rive animation and API syntax. <!-- mms-check: type=text required=true --> <!-- 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? --> ## **Changelog** <!-- mms-check: type=changelog required=true blocking=true --> <!-- 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: updated MoneyOnboardingView to use latest Rive animation and API syntax ## **Related issues** <!-- mms-check: type=issue-link required=true --> Fixes: [MUSD-996: Update MoneyOnboardingView to use latest Rive animation and API](https://consensyssoftware.atlassian.net/browse/MUSD-996) ## **Manual testing steps** <!-- mms-check: type=manual-testing required=true --> ```gherkin Feature: Updated Rive Money Onboarding Flow Scenario: user can access latest onboarding flow Given user has not already seen the onboarding flow When user clicks the Money balance card on Wallet home **or** the Money navbar button Then latest Money onboarding flow is rendered Scenario: user can navigate forward using the continue button Given user has not already seen the onboarding flow When user taps the continue button Then user moves forward to the next onboarding step Scenario: user can navigate backwards and forwards through the onboarding flow Given user has not already seen the onboarding flow When user taps the left (forward) or right (backward) edge of the screen Then onboarding flow navigates in the correct direction Scenario: user can exit out of the onboarding flow Given user has not already seen the onboarding flow When user taps the close "X" button Then user is redirected to Money Home ``` ## **Screenshots/Recordings** <!-- mms-check: type=screenshot required=true --> <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> N/A - Old Rive animation file ### **After** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/c9e507bc-c10b-4ba3-9355-90d71baff3f1 ## **Pre-merge author checklist** <!-- mms-check: type=checklist required=true --> <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [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. #### Performance checks (if applicable) - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [x] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [x] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] 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.
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.
type=text Section must contain non-placeholder prose.
type=changelog Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
comment but do not block the PR.
Sections without a directive are checked for structural presence only.
-->
## **Description**
The snap management tests (disable, enable, remove) were failing at
times in the pipeline because `tapSettings()` has a nested retry loop
that fights itself under `disableSynchronization: true`— once the
account menu overlay opens, the tab bar is hidden, and retries can never
recover.
Replaced with a step-by-step navigation helper that uses explicit waits
between each tap.
<!--
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?
-->
## **Changelog**
<!-- mms-check: type=changelog required=true blocking=true -->
<!--
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:
## **Related issues**
<!-- mms-check: type=issue-link required=true -->
Fixes:
## **Manual testing steps**
<!-- mms-check: type=manual-testing required=true -->
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- mms-check: type=screenshot required=true -->
<!-- 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**
<!-- mms-check: type=checklist required=true -->
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [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.
#### Performance checks (if applicable)
- [x] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [x] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [x] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [ ] 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.
… prices cp-7.82.0 (#31801) ## **Description** This PR fixes severe JS-thread performance degradation on the Predict market details screen (`PredictMarketDetails` / `PredictGameDetailsContent`). When opening a market with a live price feed — most noticeably a live soccer game — the JS thread FPS would collapse to near 0, making the screen unusable. **Reason for the change:** The live Polymarket WebSocket price stream drives high-frequency updates. The code was (1) doing an `O(subscriptions × tokens)` `new Set(key.split(','))` allocation on *every* incoming price message, and (2) re-rendering the entire details screen on every single message because nothing was throttled or memoized. Profiling showed `performWorkOnRoot` (React render) consuming ~70% of the trace, with `new Set()`/`Object.assign`/`JSON.stringify` allocation churn dominating self-time. **Improvements:** - **`WebSocketManager`** - Precompute the parsed `Set<tokenId>` per subscription once at subscribe time instead of rebuilding it (`new Set(key.split(','))`) on every message. This removes the single largest self-time hotspot. - Coalesce/throttle price emission with a leading + trailing edge (250ms, mirroring the existing orderbook throttle) so subscribers are notified at most ~4×/sec instead of at the full WebSocket message rate. - Clean up the new timer/buffer/Set state on disconnect and full cleanup. - **`useLiveMarketPrices`** — skip the state update entirely when an incoming tick carries no actual value change (`price`/`bestBid`/`bestAsk`), preventing redundant re-renders. - **`usePredictPrices`** — memoize the per-render `JSON.stringify(queries)` so it only runs when the queries change. - **`useOpenOutcomes`** - Disable the live price subscription for game markets, where its result is never rendered (the game branch runs its own subscriptions). Removed a redundant full-screen re-render source. - Preserve object identity for outcomes/tokens whose computed price did not change, so only rows that actually changed get a new reference. - **`PredictMarketDetails`** — memoize `handleBackPress`/`handleBuyPress`/`handleClaimPress` so stable callbacks no longer defeat child memoization. - **`PredictGameDetailsContent`** and **`PredictMarketOutcome`** — wrap in `React.memo` so a parent re-render no longer re-renders these subtrees/rows when their props are unchanged. **Result:** JS-thread FPS went from ~0 → mid-50s on live game events, and regular markets from ~25–35 → comparable smoothness, with re-renders now scoped to the components whose data actually changed. ## **Changelog** CHANGELOG entry: Fixed severe performance degradation on the Predict market details screen for markets with live price updates. ## **Related issues** Fixes: [PRED-1014](https://consensyssoftware.atlassian.net/browse/PRED-1014) ## **Manual testing steps** ```gherkin Feature: Predict market details performance with live prices Scenario: user opens a live game market Given a live soccer game market is available in Predict And the JS-thread FPS monitor / performance overlay is enabled When the user opens the PredictGameDetailsContent screen Then the screen remains responsive And the JS-thread FPS stays in a healthy range (not collapsing toward 0) Scenario: user opens a regular market with live prices Given a regular open market with live price updates is available in Predict When the user opens the PredictMarketDetails screen Then the outcomes list updates live without re-rendering unchanged rows And the JS-thread FPS stays in a healthy range Scenario: live prices still update correctly Given the user is on a market details screen When the underlying token prices change over the WebSocket feed Then the displayed prices/odds update to reflect the new values ``` ## **Screenshots/Recordings** ### **Before** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/1cc444f5-a693-4584-80f8-072305a3147c ### **After** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/1fe95b3c-1fb4-4fa0-a794-8450cbe08f88 ## **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. #### Performance checks (if applicable) - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [x] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [x] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **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. [PRED-1014]: https://consensyssoftware.atlassian.net/browse/PRED-1014?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
…cy regions (#31763) ## **Description** <!-- 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? --> Cardholders whose residency falls in a geo-restricted region must not be able to link their Money Account to the MetaMask Card. Previously the linkage flow had no residency gating, so users in blocked countries/states could attempt (and surface UI for) Money Account card linkage. This PR adds residency-based blocking for Money Account ↔ card linkage: - **Residency capture**: `BaanxProvider` now maps `countryOfResidence` and `usState` from the `/v1/user` KYC payload onto `CardAccountStatus` (normalized to uppercase), and these fields are added to the `CardAccountStatus` type. - **Residency utils** (`app/components/UI/Card/util/residency.ts`): `buildCardResidencyRegion` derives a region code, using the `US-{STATE}` pattern (e.g. `US-CA`) for US residents so blocked lists can target specific states. `isCardResidencyInBlockedRegions` matches a region against a blocked list and **fails open** when residency is unknown. - **Selectors** (`app/selectors/cardController.ts`): adds `selectCardCountryOfResidence`, `selectCardUsState`, `selectCardResidencyRegion`, and `selectIsCardResidencyBlocked`, reusing the existing mUSD conversion blocked-region flag (`selectMusdConversionBlockedCountries`). `selectCardAvailableTokens` now suppresses Money Account placeholder funding entries when residency is blocked (active funding rows are preserved). - **Linkage hook** (`useMoneyAccountCardLinkage`): exposes `isResidencyBlocked`, forces `canLink=false`, and fails closed across `openLinkCardSheet`, `startLinkFlow`, the post-auth pending-link effect, and `confirmLinkInBackground`. Each blocked path tracks `CARD_MONEY_ACCOUNT_LINKING_FAILED` with the new `RESIDENCY_BLOCKED` reason. - **UI**: `MoneyHomeView` hides the card section (link/upsell) when residency is blocked while still showing `manage` mode for already-linked cards. `MoneyOnboardingCard` auto-completes/skips the card step when residency is blocked and the card is not already linked. ## **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: Blocked Money Account to MetaMask Card linkage for cardholders in geo-restricted residency regions. ## **Related issues** Fixes: CARD-413 ## **Manual testing steps** ```gherkin Feature: Money Account card linkage residency blocking Scenario: Cardholder in a blocked region cannot link their Money Account Given a cardholder whose KYC residency is in a blocked region (e.g. country "GB" or state "US-CA") And the blocked region is present in the mUSD conversion blocked-region list When the user opens the Money home screen Then the MetaMask Card link/upsell section is hidden And the Money Account funding placeholder is not shown in the card funding list Scenario: Blocked cardholder attempting to link fails closed Given a cardholder whose residency is blocked When the user triggers the link card flow Then no navigation or delegation occurs And an error toast is shown And a CARD_MONEY_ACCOUNT_LINKING_FAILED event is tracked with reason "RESIDENCY_BLOCKED" Scenario: Already-linked card remains manageable in a blocked region Given a cardholder whose residency is blocked And the card is already linked to the Money Account When the user opens the Money home screen Then the card section is shown in "manage" mode Scenario: Cardholder in an allowed region can link normally Given a cardholder whose residency is not in any blocked region When the user opens the Money home screen and starts the link flow Then the link flow proceeds as before ``` ## **Screenshots/Recordings** ### **Before** N/A ### **After** N/A ## **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. #### Performance checks (if applicable) - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [x] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [x] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] 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. <!-- Generated with the help of the pr-description AI skill -->
) ## **Description** <!-- mms-check: type=text required=true --> <!-- 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? --> The Money balance card on the wallet home screen used to alternate its CTA between **Earn** (when the money-account balance was 0) and **Add** (when funded). Because the balance is resolved asynchronously from cache on startup, the button visibly flipped from "Earn" to "Add" as the cached balance loaded. Per the accepted solution in MUSD-987, this collapses the CTA to a single, stable **Add** button regardless of balance state. `buttonLabelKey`/`buttonTestId` are now constants and the state branches only decide the button variant and container testID (error/unavailable/empty/new-user/funded are unchanged). Dead code left behind by the change is removed: the `EARN_BUTTON` testID and the unreferenced `homepage.sections.money_empty_state` / `money_filled_state` locale blocks (`en.json` only — other locales flow from the localization pipeline). ## **Changelog** <!-- mms-check: type=changelog required=true blocking=true --> <!-- 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: Fixed the Money balance card CTA flipping from "Earn" to "Add" on startup by always showing a single "Add" button. ## **Related issues** <!-- mms-check: type=issue-link required=true --> Fixes: https://consensyssoftware.atlassian.net/browse/MUSD-987 ## **Manual testing steps** <!-- mms-check: type=manual-testing required=true --> ```gherkin Feature: Money balance card CTA Scenario: user with no money balance opens the wallet home Given the user has a money account with a 0 balance When the wallet home screen loads Then the Money balance card shows a single "Add" button And the button does not change from "Earn" to "Add" as the balance resolves Scenario: user with a money balance opens the wallet home Given the user has a money account with a balance greater than 0 When the wallet home screen loads Then the Money balance card shows the "Add" button And pressing it starts the deposit flow ``` ## **Screenshots/Recordings** <!-- mms-check: type=screenshot required=true --> <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> The CTA rendered "Earn" for a 0 balance and flipped to "Add" once the cached balance resolved (see attached recording on MUSD-987). ### **After** <!-- [screenshots/recordings] --> <img width="1206" height="2622" alt="image" src="https://github.com/user-attachments/assets/2a9ee5c3-18f0-4ecd-a90d-566fd50a09cd" /> The CTA always renders "Add". ## **Pre-merge author checklist** <!-- mms-check: type=checklist required=true --> <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [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. #### Performance checks (if applicable) - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [x] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [x] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [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.
…oney pages (MUSD-968) (#31735) ## **Description** Balances, the percentage/APY value, and the primary action button row sat at different vertical positions on the **Home** page and the **Money account** page, producing a visible layout shift ("jumping") when navigating between the two screens. This aligns the Money account page's content rhythm to the Home page (Home left untouched as the source of truth): - `MoneyBalanceSummary`: normalized the top offset and tightened the balance→APY gap to match Home's balance block. - `MoneyActionButtonRow`: content-size the action buttons by removing the `ButtonBase` `min-height`/`h-full`/stretch hack, so **Add / Send / Card** share the same height and top position as Home's **Buy / Swap / Send / Receive** buttons. The balance, APY/percentage value, and action-button row now hold their vertical position across both screens. ## **Changelog** <!-- mms-check: type=changelog required=true blocking=true --> CHANGELOG entry: Fixed inconsistent vertical alignment of the balance, APY/percentage, and action buttons between the Home and Money account pages. ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MUSD-968 ## **Manual testing steps** ```gherkin Feature: Consistent alignment between Home and Money account pages Scenario: Balance, APY and action buttons stay in place when switching pages Given I am on the Home page And I note the vertical position of the balance, the percentage value, and the action button row When I navigate to the Money account page Then the balance, the APY value, and the action button row are at the same vertical positions And the action buttons are the same height as on the Home page And there is no visible vertical jump when switching between the pages ``` ## **Screenshots/Recordings** ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/8cec1f1e-21c2-4701-a833-ec6cfec5f783 ## **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. #### Performance checks (if applicable) - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [x] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [x] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **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.
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
## **Description**
This PR integrates the Extension Activity adapter prototype into Mobile
using a temporary vendored implementation, while preparing the code for
a future shared `@metamask/activity-adapters` package.
The change normalizes Mobile activity data sources into a common
`ActivityListItem` shape:
- Accounts API EVM transactions are mapped with `mapApiEvmTransactions`
- Local EVM transactions are mapped with `mapLocalTransaction`
- Non-EVM keyring transactions are mapped with `mapKeyringTransaction`
Mobile then renders normalized activity rows with `ActivityListItemRow`,
while preserving Mobile-specific behavior such as Figma-specific row
copy/styling, legacy transaction-details navigation, pending local EVM
speed up/cancel handling, account/network filtering, token-poisoning
protection, and bridge/token enrichment.
A key part of this PR is the `ActivityAdapterEnvironment` boundary.
Adapter internals no longer directly depend on hidden Mobile/Extension
shims for host-specific utilities. Instead, dependencies such as
`toAssetId`, native asset lookup, token metadata, calldata parsing,
wrapped-token configuration, status constants, and ERC-20 transfer log
topics are passed through an explicit environment object. This makes the
current vendored implementation closer to the shape needed for
externalization.
This PR also includes the scaffold for the redesigned Activity screen
from TMCU-854. The redesigned screen is fully gated behind the remote
feature flag `tmcuActivityRedesignEnabled`, which defaults to `false` in
E2E feature-flag mocks. When the flag is disabled, `ActivityView`
renders the existing legacy Activity implementation. When the flag is
explicitly enabled, `ActivityView` lazy-loads and renders the new
`ActivityScreen`.
The feature-flag boundary was hardened so that only
`tmcuActivityRedesignEnabled === true` enables the redesigned screen.
The redesigned screen is lazy-loaded, so its component tree and
dependencies are not evaluated on the flag-off path.
To preserve existing Activity E2E behavior while the flag is off, the
adapter-backed legacy Activity path keeps the existing row test
contract:
- Activity rows expose `transaction-item-${index}`
- Activity statuses expose `transaction-status-${index}`
- Swap and bridge rows use the richer legacy Activity titles where
bridge history is available, e.g. `Swap ETH to
- USDC` and `Bridge to Optimism`
Follow-up externalization work should move `app/util/activity-adapters`
into a shared package, keep `ActivityAdapterEnvironment` as the host
dependency contract, provide Mobile and Extension environment
implementations, move parity fixtures into the package test suite, and
replace Mobile vendored imports with package imports once published.
Follow-up redesign work should keep new Activity UI/data wiring scoped
under `app/components/Views/ActivityScreen/**` or redesign-only hooks
until the feature flag is intentionally enabled for rollout.
## **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:
Refs:
- https://consensyssoftware.atlassian.net/browse/TMCU-797
- https://consensyssoftware.atlassian.net/browse/TMCU-854
## **Manual testing steps**
```gherkin
Feature: Activity adapters and Activity redesign feature flag isolation
Scenario: legacy Activity remains active when redesign flag is disabled
Given tmcuActivityRedesignEnabled is disabled or missing
When the user opens the Activity tab
Then the legacy Activity view is rendered
And existing transaction rows expose transaction-item-* test IDs
And existing transaction statuses expose transaction-status-* test IDs
Scenario: redesigned Activity screen renders when redesign flag is enabled
Given tmcuActivityRedesignEnabled is true
When the user opens the Activity tab
Then the redesigned Activity screen is rendered
And the legacy Activity transaction tab UI is not rendered
Scenario: adapter-backed Activity rows preserve legacy swap and bridge titles
Given the user has swap or bridge activity with bridge history available
When the user opens the Activity tab with tmcuActivityRedesignEnabled disabled
Then swap rows show the rich swap title
And bridge rows show the rich bridge destination title
```
## **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**
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [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.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [ ] 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**
> Touches transaction list merging, deduplication, and
navigation/speed-up-cancel flows where regressions could hide or
mislabel activity; mitigated by heavy test coverage and flag-gated
redesign entry (per PR description).
>
> **Overview**
> Introduces a **unified Activity stack** on top of shared
`ActivityListItem` adapters: **`ActivityList`** merges paginated
Accounts API EVM history, enriched local EVM txs, and non-EVM keyring
activity (chain enablement, hash/nonce dedup, malicious-token filtering,
bridge rows), then renders most rows via new **`ActivityListItemRow`**
(localized titles/statuses, token + fiat amounts, network badge, legacy
swap/bridge title overrides). Pending locals still use
**`TransactionElement`**; non-EVM bridges use
**`MultichainBridgeTransactionListItem`**, with
**`useUnifiedTxActions`** for speed-up/cancel (incl. Ledger/QR).
>
> Adds **`ActivityScreen`** scaffold (animated header, search
placeholder, type/network filter chips + sheets,
**`ActivityEmptyState`** CTAs) wired to **`ActivityList`**, plus
supporting hooks (`useTransactionsQuery`, `useLocalActivityItems`,
`useTransactionAutoScroll`) and API **`normalizeTransaction`** /
transformation helpers, with broad unit tests.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
7510782. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: vinnyhoward <vincenguyenhoward@gmail.com>
Co-authored-by: Ramon Acitores <ramon.acitores@consensys.net>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Ramon AC <36987446+racitores@users.noreply.github.com>
## **Description** <!-- mms-check: type=text required=true --> <!-- 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? --> Addresses the design-review polishes for the Money account screens (MUSD-993): 1. **Add funds sheet** — renamed the fiat row to **Debit card or Apple Pay** (Card icon) and added a coming-soon **Bank account** row, matching the design. The Debit card or Apple Pay row is always active and opens the MM Pay deposit flow. 2. **APY tooltip** — updated the variability copy (Veda / Steakhouse Financial) and added "Money account is powered by Monad." 3. **How it works FAQ** — the supported no-fee deposit tokens are now derived from the `earnMoneyDepositNoFeeTokens` remote flag (with a bundled per-chain fallback so the list is never empty) instead of a hard-coded list. Chain ids resolve to friendly network names; mUSD shows in the per-chain "which tokens can I deposit" list but is excluded from the inline "converts to mUSD" sentence. 4. **Yield FAQ** — appended the APY-variability / Veda–Steakhouse disclaimer. 5. **Deposit FAQ** — limited the funding-methods sentence to "debit card, credit card, or Apple Pay". 6. **Money home layout** — the "Add funds" CTA now renders once at the bottom (previously a misplaced mid-list instance in the empty state), and a divider separates every content section. 7. **What you get** — "Send" instead of "Transfer". ## **Changelog** <!-- mms-check: type=changelog required=true blocking=true --> <!-- 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: Polished the Money account screens — refreshed the Add funds payment options, APY and FAQ copy, made the supported-token list dynamic, and fixed the home layout spacing and Add funds button placement. ## **Related issues** <!-- mms-check: type=issue-link required=true --> Fixes: https://consensyssoftware.atlassian.net/browse/MUSD-993 ## **Manual testing steps** <!-- mms-check: type=manual-testing required=true --> ```gherkin Feature: Money account design review polishes Scenario: Add funds sheet payment options Given I am on the Money account home screen When I tap "Add" Then I see "Convert crypto", "Debit card or Apple Pay", the mUSD amount, "Bank account" (Coming soon) and "External address" (Coming soon) And tapping "Debit card or Apple Pay" opens the MM Pay deposit flow Scenario: How it works FAQ tokens are dynamic Given I open the "How it works" page When I expand "Which tokens can I deposit into the Money Account?" Then the per-chain token list reflects the no-fee remote config with friendly network names Scenario: Money home layout Given I am on the Money account home screen Then the "Add funds" button appears once at the bottom And each content section is separated by a divider ``` ## **Screenshots/Recordings** <!-- mms-check: type=screenshot required=true --> <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/663f7d86-1858-4384-809c-1bae4111f24e <img width="1206" height="2622" alt="image" src="https://github.com/user-attachments/assets/0de9e1c5-e634-472f-b028-86528978168a" /> <img width="1206" height="2622" alt="image" src="https://github.com/user-attachments/assets/cf27a558-6400-48e1-aa09-6fc6f07fdcc8" /> <img width="1206" height="2622" alt="image" src="https://github.com/user-attachments/assets/68b26e87-bc8a-4c78-b599-77da2c0f4116" /> <img width="1206" height="2622" alt="image" src="https://github.com/user-attachments/assets/f0c492ac-9ab7-4263-afe7-38d3cd81c737" /> _Screenshots to be attached during review — UI polish; reference designs are in the Figma links on the MUSD-993 ticket._ ## **Pre-merge author checklist** <!-- mms-check: type=checklist required=true --> <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [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. #### Performance checks (if applicable) - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [x] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [x] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [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.
## **Description**
Unifies PnL abbreviation across the three Social Leaderboard surfaces
(homepage carousel, leaderboard list, trader profile headline) so the
same value renders identically everywhere. The trader profile's 30D
Return previously showed
un-abbreviated values (e.g. `+$117,166.82`); the leaderboard rows used a
K-only formatter that produced `+$1,200K` for million-dollar values. Now
all three use one shared formatter:
- **Sub-$1K** renders the actual value with 2 decimal places (e.g.
`+$500.24`, `+$0.50`)
- **≥$1K** abbreviates with K/M/B/T tier suffixes and 1 decimal trimmed
(e.g. `+$5.1K`, `+$117.2K`, `+$1.2M`, `+$1M`)
- Zero renders as `$0.00` with no sign
- Tier-boundary rounding promotes correctly: `999_999` → `+$1M` (not
`+$1000K`)
**What changed**
- New `formatSignedAbbreviatedUsd` in
`SocialLeaderboard/utils/formatters.ts` is the single source of truth.
Co-located helpers (`shortenAbsCurrency`, `renderBucket`,
`CURRENCY_BUCKETS`) live in the same file.
- `StatsRow` (profile 30D Return) drops its local `formatPnlWithCents` +
`formatWithThreshold` import in favor of the shared formatter.
- `TopTraderCard` + `TraderRow` (homepage carousel and leaderboard list)
import the shared formatter directly via the existing cross-route
`eslint-disable` pattern.
- The thin `formatPnl` wrapper in
`Homepage/Sections/TopTraders/utils/formatPnl.ts` and its test file are
deleted. Two consumers updated.
- Tests in `formatters.test.ts`, `StatsRow.test.tsx`,
`TraderProfileView.test.tsx`, `TopTraderCard.test.tsx`, and
`TraderRow.test.tsx` updated to assert the new format.
**Visible behavior changes**
- Trader profile 30D Return: `+$117,166.82` → `+$117.2K`. The PM-driven
request that started this work.
- Homepage carousel + leaderboard list PnL: rows over `$1M` now
correctly promote to M (`+$1.2M`) instead of staying in K (`+$1,200K`).
Sub-$1M rows gain one decimal of precision (`+$963K` → `+$963.1K`).
- Zero PnL: no longer shows a `+` sign (was `+$0` in old `formatPnl`,
now `$0.00`). Consistent with how the profile view renders zero.
## **Changelog**
CHANGELOG entry: Unified the PnL number formatting on the social
leaderboard so the same value renders the same way everywhere (trader
profile, leaderboard list, homepage carousel). Large values now
abbreviate to K/M/B/T with one decimal
(e.g. $1.2M); sub-$1K values keep two decimal places.
## **Related issues**
Refs: N/A — surfaced during TSA-628 / social leaderboard polish work.
PM-driven request: trader profile 30D Return needed to abbreviate
($1.2M) for parity with the rest of the surfaces. Filing as a follow-up
to the perps rollout work.
## **Manual testing steps**
```gherkin
Feature: Unified PnL abbreviation across the social leaderboard
Scenario: Trader profile 30D Return shows abbreviated value for large
numbers
Given the user opens a trader profile whose 30D return is $1,170,000
Then the headline reads "+$1.2M" (not "+$1,170,000.00" or "+$1,170K")
Scenario: Leaderboard list row abbreviates million-dollar PnL correctly
Given a leaderboard trader with $1,200,000 PnL
When the leaderboard list renders
Then the row reads "+$1.2M" (not "+$1,200K")
Scenario: Homepage Top Traders carousel matches the leaderboard format
Given the same trader appears in the homepage Top Traders carousel
Then the carousel card renders the same "+$1.2M" string as the
leaderboard list
Scenario: Sub-$1K values keep two decimal places
Given a trader profile with a 30D return of $500.236
Then the headline reads "+$500.24" (not "+$500" or "+$500K")
Scenario: Zero PnL renders neutrally with no sign
Given a trader profile with a 30D return of exactly $0
Then the headline reads "$0.00" (no leading + or -)
```
## **Screenshots/Recordings**
### **Before**
<img width="450" height="973" alt="Screenshot 2026-06-15 at 10 14 43 PM"
src="https://github.com/user-attachments/assets/eb6dbf7a-f688-4749-b6c2-08c2bf2e445b"
/>
<img width="446" height="973" alt="Screenshot 2026-06-15 at 10 14 33 PM"
src="https://github.com/user-attachments/assets/0be54128-0bd2-443c-8b12-25bf416be40b"
/>
### **After**
<img width="446" height="973" alt="Screenshot 2026-06-15 at 10 12 41 PM"
src="https://github.com/user-attachments/assets/ecb18b8c-f45b-4ac5-ac2f-f7aa4d2245e7"
/>
<img width="446" height="973" alt="Screenshot 2026-06-15 at 10 12 27 PM"
src="https://github.com/user-attachments/assets/fd50cbfe-04e4-4f59-8d6f-bb42996e2a79"
/>
## **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.
#### Performance checks (if applicable)
- [x] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [x] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [x] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **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.
## **Description** <!-- mms-check: type=text required=true --> Bringing the following changes to the client: ```markdown ## [1.26.0] ### Added - Add `signProofOfOwnership` client request method ([#327](MetaMask/snap-tron-wallet#327)) - This method silently signs `metamask:proof-of-ownership:<nonce>:<address>` messages with the account's secp256k1 key via TronWeb's `signMessageV2` - Add support for `keyring_createAccounts` method to enable batch account creation ([#308](MetaMask/snap-tron-wallet#308)). ``` ## **Changelog** <!-- mms-check: type=changelog required=true blocking=true --> CHANGELOG entry: null ## **Related issues** <!-- mms-check: type=issue-link required=true --> n/a ## **Manual testing steps** <!-- mms-check: type=manual-testing required=true --> n/a ## **Screenshots/Recordings** <!-- mms-check: type=screenshot required=true --> <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** n/a ### **After** n/a ## **Pre-merge author checklist** <!-- mms-check: type=checklist required=true --> <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [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. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] 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.
…1803) ## **Description** Migrates `import-srp` and `delete-account` from Detox (`SmokeWalletPlatform`) to Appium (`SmokeAccounts`) as part of the ongoing smoke-test framework migration. Changes include: - New Appium specs under `tests/smoke-appium/accounts/` - Removal of the Detox counterparts from `tests/smoke/wallet/` and `tests/smoke/multichain-accounts/` - Cross-framework fixes in `ImportSrpView` (replaces `device.getPlatform()` with `PlatformDetector`, adds Appium iOS seed-phrase input handling) - New `iosAppiumXPath` selector variant in `resolve()` for platform-specific iOS locators ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: Detox-to-Appium SmokeAccounts migration — test infrastructure only ## **Manual testing steps** ```gherkin Feature: SmokeAccounts Appium account flows Scenario: import SRP account on Android Given a device with the Appium smoke test runner When I run the import-srp Appium spec on Android Then the test imports an SRP and verifies Account 1 is selected Scenario: delete account on iOS Given a device with the Appium smoke test runner When I run the delete-account Appium spec on iOS Then the test deletes the imported account and verifies it is removed from the account list ``` ## **Screenshots/Recordings** ### **Before** N/A — E2E test migration only; no user-facing UI changes. ### **After** N/A — E2E test migration only; no user-facing UI changes. ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Style](https://github.com/MetaMask/metamask-mobile/blob/main/docs/readme/coding-style.md) - [x] I've completed the PR template and read the [Ready for review](https://github.com/MetaMask/metamask-mobile/blob/main/docs/readme/ready-for-review.md) guide - [x] I've included tests if applicable and/or updated snapshots - [x] I've documented my code with [JSDoc](https://jsdoc.app/) if applicable - [x] I've applied the right labels for this PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)) #### Performance checks (if applicable) - [x] I tested on an Android device or emulator and timing performance was acceptable - [x] I tested this change with the `power user` performance scenario and timing performance was acceptable - [x] I instrumented this change with Sentry traces if applicable ## **Pre-merge reviewer checklist** - [ ] I've followed the [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Style](https://github.com/MetaMask/metamask-mobile/blob/main/docs/readme/coding-style.md) - [ ] I've read the [How to review a MetaMask Mobile PR](https://github.com/MetaMask/metamask-mobile/blob/main/docs/readme/reviewing.md) guide - [ ] I've checked what automated tests report, and I've considered whether this change should have caused any failures to resolve differently - [ ] I've manually tested the change, following the manual testing steps in the pull request description, and that what's being tested reflects the user's perspective, not the presence of the change itself - [ ] I've checked that any documentation linked from this PR, or that I expect to update from this change, is accurate and up to date Made with [Cursor](https://cursor.com)
## **Description** The price change percentage shown on the Token Details page frequently diverges from the Trending page percentage, sometimes dramatically. This PR addresses the client-side root causes. ### Fix 1 — Defensive sort for historical prices (`useTokenHistoricalPrices.ts`) The historical-prices API occasionally returns data in reverse chronological order (newest-first). Since the client uses `prices[0]` as the 24h-ago baseline, reverse-sorted data makes the baseline equal the *current* price, yielding 0% or near-0% change. A defensive sort ensures `prices[0]` is always the oldest entry. ### Fix 2 — Use spot-prices percentage for legacy chart instead of deriving from historical prices (`useTokenPrice.ts`, `exchange-rates.ts`) The legacy chart derived its percentage from `currentPrice - historicalPrices[0]`. For newly-listed or volatile tokens, the `historical-prices` API can return incomplete data (e.g. only 10 hours of data when 24 hours is requested), causing inaccurate percentages. The spot-prices API (`v3/spot-prices`) already returns pre-computed percentage changes (`pricePercentChange1d`, `pricePercentChange7d`, `pricePercentChange30d`, `pricePercentChange1y`); the same values the Trending page displays. However, these fields were being discarded: - **EVM path**: The core `fetchTokenContractExchangeRates` function fetched full market data but stripped everything except `.price` in its final reduce - **Non-EVM path**: `fetchTokenExchangeRates` called the same API but only extracted `.price`, discarding percentage fields **What changed:** - **Core (`@metamask/assets-controllers`)**: Added optional `includeMarketData` parameter to `fetchTokenContractExchangeRates`. When `true`, returns full `MarketDataDetails` (including percentage changes) instead of price-only. Defaults to `false` for backward compatibility. ([core PR #9042](MetaMask/core#9042)) - **Mobile (`exchange-rates.ts`)**: Added `includeMarketData` flag to `fetchTokenExchangeRates` and `getTokenExchangeRate`. Non-EVM branch now preserves the full API response when the flag is set. Removed the redundant `getTokenSpotPriceWithMarketData` function. - **Mobile (`useTokenPrice.ts`)**: Single `useEffect` now calls `getTokenExchangeRate({ includeMarketData: true })` to get both the price and percentage data in one API call. For supported time ranges (1D, 1W, 1M, 1Y), the spot-prices percentage overrides the historical-prices-derived one. For imported tokens, reads percentage from Redux (already available via `TokenRatesController`). Unsupported ranges (3M, 3Y, All) fall back to the historical-prices derivation. ### Fix 3 — Tighten "no data" overlay for legacy chart with insufficient time coverage (`useTokenHistoricalPrices.ts`, `PriceChart.tsx`) Previously the chart only checked if the API returned at least 5 data points before rendering. This meant a 1D request that returned only 10 hours of data (many data points but covering less than half the requested period) would still render a misleading chart. **What changed:** - **`useTokenHistoricalPrices.ts`**: Added a `hasInsufficientTimeCoverage()` check that compares the actual time span of returned data against the expected duration for each time period (1D = 24h, 1W = 7d, etc.). If the data covers less than **95%** of the expected duration, the hook sets `hasInsufficientCoverage: true`. HTTP 204 (no content) responses also set the flag. - **`PriceChart.tsx`**: The "no data" overlay now also shows when `hasInsufficientCoverage` is true, even if there are 5+ data points. - The flag is threaded through `useTokenPrice` → `TokenDetails` → `AssetOverviewContent` → `Price` → `PriceLegacy`/`PriceAdvanced` → `PriceChart`. ## Example SpaceX on Base — Reverse-sorted historical data (Fix 1) + Incomplete historical data (Fix 2) **Trending page shows:** `+98,964%` **Token Details (legacy chart) before fix:** `-80%` (or `-0.00%` with reverse-sorted data) The `historical-prices` API returned only ~10 hours of data for this newly-listed token, starting after the major pump. Using `historicalPrices[0]` as the baseline gave a post-pump price, making the percentage wildly incorrect. **After fix:** Uses `pricePercentChange1d` from the spot-prices API (same source as Trending page) → `+98,720%` ✅ ## **Changelog** CHANGELOG entry: Fixed percentage mismatch between Trending page and Token Details page caused by reverse-sorted historical price data, discarded spot-prices percentage fields for both EVM and non-EVM tokens, and added 95% time-coverage check to show "no data" overlay for incomplete historical data ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/ASSETS-3288 ## **Manual testing steps** ```gherkin Feature: Token Details percentage accuracy Scenario: Legacy chart percentage matches trending page for newly-listed tokens Given user is on the Trending page and sees a newly listed token (e.g. on Base chain) When user taps into Token Details and the legacy chart loads Then the displayed percentage should closely match the trending percentage And the amount change should be consistent with the percentage Scenario: Non-EVM token percentage matches trending page Given user is on the Trending page filtered to Solana When user taps a trending Solana token into Token Details Then the displayed 1D percentage should match the trending percentage Scenario: Switching time ranges works correctly Given user is on Token Details for any token When user switches between 1D, 1W, 1M, 1Y time ranges Then each range should show the spot-prices-derived percentage And 3M, 3Y, All should fall back to historical-prices-derived percentage Scenario: Insufficient time coverage shows no-data overlay Given the historical-prices API returns less than 95% of the requested time period When user is on Token Details for a newly-listed token on 1D Then the chart should show the "No chart data" overlay instead of a partial chart Scenario: Stable tokens remain unaffected Given user is on the Trending page and sees a major token (e.g. SOL, ETH) When user taps into Token Details Then the percentage should remain within 0-2% of the trending percentage (unchanged behavior) ``` ## **Screenshots/Recordings** ### **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 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. #### Performance checks (if applicable) - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [x] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [x] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **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** > Touches token pricing UX across legacy/advanced charts and exchange-rate fetching; incorrect coverage or spot-% override could still mislead users, but behavior is guarded by tests and falls back to historical derivation for unsupported ranges. > > **Overview** > Aligns Token Details price-change % and legacy chart behavior with Trending by fixing historical-price handling and using spot-prices market data. > > **Historical prices:** `useTokenHistoricalPrices` now sorts API results chronologically, exports `hasInsufficientTimeCoverage()` (95% of the requested period), sets `hasInsufficientCoverage` on short spans and HTTP 204, and threads that flag through `useTokenPrice` → `PriceChart`, which shows the insufficient-data overlay even when there are enough points. > > **Spot-prices %:** `fetchTokenExchangeRates` / `getTokenExchangeRate` gain optional `includeMarketData`; `useTokenPrice` fetches full market data for non-imported tokens (with a fetch-id guard on token switch) and overrides `priceDiff` / `comparePrice` from Redux or API fields (`pricePercentChange1d`, etc.) for 1D/1W/1M/1Y. Bridge Redux only stores numeric rates when the payload is a number. `@metamask/assets-controllers` bumps to **^109.1.0**. > > **Tests:** Coverage for coverage math, chart overlay, exchange-rate call signatures, stale fetch clearing, and advanced-chart OHLCV mocks aligned to **prevBar** baseline. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit f1665a5. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.
type=text Section must contain non-placeholder prose.
type=changelog Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
comment but do not block the PR.
Sections without a directive are checked for structural presence only.
-->
## **Description**
Fix percentage buttons when withdrawing from predict into money account.
## **Changelog**
<!-- mms-check: type=changelog required=true blocking=true -->
<!--
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:
## **Related issues**
<!-- mms-check: type=issue-link required=true -->
Fixes: https://consensyssoftware.atlassian.net/browse/CONF-1559
## **Manual testing steps**
NA
## **Screenshots/Recordings**
NA
## **Pre-merge author checklist**
<!-- mms-check: type=checklist required=true -->
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [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.
#### Performance checks (if applicable)
- [X] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [X] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [X] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [ ] 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.
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.
type=text Section must contain non-placeholder prose.
type=changelog Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
comment but do not block the PR.
Sections without a directive are checked for structural presence only.
-->
## **Description**
<!-- mms-check: type=text required=true -->
QuickBuy treated USD as the canonical fiat unit, with
inconsistent/mislabeled conversions (a `€` symbol rendered on a USD
number, `currencyExchangeRate` meaning different things on EVM vs
non-EVM, hardcoded `$` headlines). This makes the user's display
currency the single canonical fiat unit across state, slider, balances,
and totals. Deriving USD only at the analytics boundary, where the
schema contractually requires `amount_usd`.
https://github.com/user-attachments/assets/05701682-8392-4f63-8304-2420a488a061
<img height="790" alt="Simulator Screenshot - iPhone 17 Pro - 2026-06-16
at 10 06 26"
src="https://github.com/user-attachments/assets/a82f96e8-cd60-4526-9c75-a07a37312c3c"
/>
<img height="790" alt="Simulator Screenshot - iPhone 17 Pro - 2026-06-16
at 10 13 52"
src="https://github.com/user-attachments/assets/1b773a6e-e77e-4c8e-a51e-41103d803cd8"
/>
<img height="790" alt="Simulator Screenshot - iPhone 17 Pro - 2026-06-16
at 10 06 59"
src="https://github.com/user-attachments/assets/a7b7ad4c-a533-483c-9471-18afa3652a80"
/>
## **Changelog**
<!-- mms-check: type=changelog required=true blocking=true -->
<!--
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**
<!-- mms-check: type=issue-link required=true -->
Fixes: https://consensyssoftware.atlassian.net/browse/TSA-633
## **Manual testing steps**
<!-- mms-check: type=manual-testing required=true -->
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- mms-check: type=screenshot required=true -->
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
NA
### **After**
NA
## **Pre-merge author checklist**
<!-- mms-check: type=checklist required=true -->
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [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.
#### Performance checks (if applicable)
- [x] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [x] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [ ] 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.
---------
Co-authored-by: Xavier Brochard <xavier.brochard@consensys.net>
Co-authored-by: Cursor <cursoragent@cursor.com>
After BrowserStack session enrichment, extract the installed app size
from profiling data and publish it to Sentry as an `app_size_mb`
measurement (unit: megabyte), using the same publisher and DSN as the
per-test timing metrics.
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.
type=text Section must contain non-placeholder prose.
type=changelog Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
comment but do not block the PR.
Sections without a directive are checked for structural presence only.
-->
## **Description**
<!-- mms-check: type=text required=true -->
This PR extends the E2E performance reporting pipeline to track
installed app size over time in Sentry.
After a BrowserStack session is enriched with profiling data, the
`app_size` metric (in MB) is extracted from the profiling summary and
published to Sentry as an `app_size_mb` measurement with `megabyte`
unit. It reuses the existing `publishPerformanceScenarioToSentry`
publisher and DSN, so no new infrastructure is needed.
Changes:
- `types.ts`: add `app_size` to `ProfilingData` metrics; `appSizeMb` to
`ProfilingSummary`
- `PerformanceTracker.ts`: add optional `appSizeMb` field to
`MetricsOutput`
- `BrowserStackEnricher.ts`: extract `app_size` into
`profilingSummary.appSizeMb`
- `PerformanceSentryPublisher.ts`: add `app_size_mb` measurement
(megabyte unit); allow publishing when only `appSizeMb` is set and
`steps` is empty
- `PerformanceReporter.ts`: call `publishAppSizeToSentry()` after
enrichment
- `PerformanceSentryPublisher.test.ts`: 3 new tests covering
`app_size_mb`
## **Changelog**
<!-- mms-check: type=changelog required=true blocking=true -->
CHANGELOG entry: null
## **Related issues**
<!-- mms-check: type=issue-link required=true -->
Refs: https://consensyssoftware.atlassian.net/browse/MMQA-1974
## **Manual testing steps**
<!-- mms-check: type=manual-testing required=true -->
This is a CI/test-infrastructure-only change (files under
`tests/reporters/`). There is no UI or runtime app behaviour to test
manually.
To verify:
1. Merge and let a nightly BrowserStack E2E run complete.
2. Open the Sentry project used for E2E performance metrics.
3. In Discover / Performance, query `measurements.app_size_mb` — values
should appear for each test session that has profiling data.
Unit tests covering the new behaviour can be run locally:
```bash
yarn jest tests/reporters/providers/sentry/PerformanceSentryPublisher.test.ts
```
## **Screenshots/Recordings**
<!-- mms-check: type=screenshot required=true -->
N/A — no UI changes. Sentry data will only be visible after a CI run
with the merged branch.
### **Before**
N/A
### **After**
N/A
## **Pre-merge author checklist**
<!-- mms-check: type=checklist required=true -->
- [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.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **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.
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
## **Description** <!-- mms-check: type=text required=true --> <!-- 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? --> The "Earn on your crypto" screen (`MoneyPotentialEarningsView`) was registered inside the Money tab stack, so it rendered with the bottom tab navigation bar still visible and the CTA sitting above it — it was not a true full-page screen as per the design. This PR promotes `MoneyPotentialEarningsView` from the Money tab stack (`MoneyTabScreenStack`) to a top-level native stack route in `MainNavigator`, mirroring the existing Money confirmations/onboarding pattern. As a result the bottom tab navigation bar is no longer rendered on this screen and the "Convert your crypto" CTA sits at the true bottom edge of the screen with safe-area padding. No changes were needed to the view itself or to the navigation calls (the route name resolves to the new top-level registration). ## **Changelog** <!-- mms-check: type=changelog required=true blocking=true --> <!-- 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: Changed the "Earn on your crypto" screen to a full-page layout, removing the bottom navigation bar. ## **Related issues** <!-- mms-check: type=issue-link required=true --> Fixes: https://consensyssoftware.atlassian.net/browse/MUSD-994 ## **Manual testing steps** <!-- mms-check: type=manual-testing required=true --> ```gherkin Feature: Earn on your crypto full-page screen Scenario: user opens Earn on your crypto from the Money home screen Given the user is on the Money home screen And the "Earn on your crypto" section shows eligible tokens When the user taps the section header or "View all" Then the "Earn on your crypto" screen opens as a full page And the bottom tab navigation bar is not visible And the "Convert your crypto" CTA is pinned to the bottom of the screen with padding ``` ## **Screenshots/Recordings** <!-- mms-check: type=screenshot required=true --> <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/0dbe0051-1d6c-4c4e-b875-dfa38dd1e8cf ## **Pre-merge author checklist** <!-- mms-check: type=checklist required=true --> <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [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. #### Performance checks (if applicable) - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [x] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [x] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [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.
…31740) ## **Description** When the `assetsUnifyState` feature flag is enabled, the active fiat currency shown across the UI is read from `AssetsController.selectedCurrency` (via `selectCurrentCurrency` -> `getCurrencyRateControllerCurrentCurrency`). However, the General Settings "Base currency" picker only wrote the selection to `CurrencyRateController.setCurrentCurrency`. Nothing ever wrote `AssetsController.selectedCurrency`, and the controller does not auto-sync from `CurrencyRateController`. As a result, with the flag on, tapping a currency closed the picker but the selection silently no-opped and the displayed currency stayed on `USD`. With the flag off the UI reads `CurrencyRateController.currentCurrency`, so the bug did not reproduce. This PR contains two changes: 1. `selectCurrency` now also calls `AssetsController.setSelectedCurrency(currency)`, so the selection applies regardless of the flag state. `setSelectedCurrency` updates `selectedCurrency` and triggers a price refetch in the new currency. 2. Migration `143` copies `CurrencyRateController.currentCurrency` into `AssetsController.selectedCurrency`. Migration `139` had defaulted `selectedCurrency` to `'usd'` without preserving the user's existing currency, so without this, enabling the flag would silently reset existing non-USD users to USD. ## **Changelog** CHANGELOG entry: Fixed a bug where changing the base currency in General Settings had no effect. ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: Base currency selection in General Settings Scenario: user changes the base currency with assetsUnifyState enabled Given the assetsUnifyState feature flag is enabled And the user is on Settings > General When the user opens the "Base currency" picker And the user selects "EUR - Euro" Then the selected base currency updates to EUR And fiat values across the app are displayed in EUR Scenario: existing non-USD user upgrades with assetsUnifyState enabled Given a user had previously selected EUR as their base currency When the app upgrades and runs migration 143 And the assetsUnifyState feature flag is enabled Then the user's base currency remains EUR (not reset to USD) ``` ## **Screenshots/Recordings** ### **Before** <!-- Selecting a currency closed the picker but it remained USD --> ### **After** <!-- Selecting a currency now applies and persists --> ## **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 - [ ] 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. --------- Co-authored-by: Cursor <cursoragent@cursor.com>
…31765) ## **Description** Mobile half of TSA-702. The deeplink contract change (see paired social-api PR) renames the `notification_event` query param on `social-trader-position` URLs to `notification_subtype` for parity with NAAP. This PR updates the mobile deeplink handler to parse the new name, forwards the value through navigation to `TraderPositionView`, and includes it on the `SOCIAL_FOLLOW_TRADING_TOKEN_SCREEN_VIEWED` analytics event so click-attribution can distinguish spot vs perp opens in analytics. **What changed** - `handleSocialTraderPositionUrl.ts` — parses `notification_subtype` (was `notification_event`), fires the existing `SOCIAL_FOLLOW_TRADING_NOTIFICATION_CLICKED` event with the new property key, and forwards `notificationSubtype` as a navigation param to `TraderPositionView`. - `TraderPositionView.tsx` — reads `notificationSubtype` from route params and includes it on the `SOCIAL_FOLLOW_TRADING_TOKEN_SCREEN_VIEWED` event when present. - `socialLeaderboardEvents.ts` — adds `NOTIFICATION_SUBTYPE: 'notification_subtype'` as an analytics property key. - `NavigationService/types.ts` — adds optional `notificationSubtype` to both `TraderPositionViewParams` union branches. **Backwards compatibility** Missing `notification_subtype` does not break navigation — the analytics property is omitted via a spread guard when absent. Routes that don't originate from a notification tap (in-app row taps, deeplinks without a subtype) work unchanged. **Paired PR** This depends on the social-api rename ([PR #89](consensys-vertical-apps/va-mmcx-social-api#89)) landing for the new param name to appear on real deeplinks. Until both ship, notification-tap analytics will be missing the subtype property — but routing/destination behavior is unchanged. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TSA-702 ## **Manual testing steps** ```gherkin Feature: Notification deeplink forwards subtype through to analytics Scenario: Tap a notification with a spot subtype Given the user taps a social-trader-position deeplink with notification_subtype=follow_newtrade_buy When the deeplink handler runs Then the user lands on TraderPositionView for the given position And the SOCIAL_FOLLOW_TRADING_NOTIFICATION_CLICKED event fires with notification_subtype=follow_newtrade_buy And once the screen renders, SOCIAL_FOLLOW_TRADING_TOKEN_SCREEN_VIEWED fires with notification_subtype=follow_newtrade_buy Scenario: Tap a notification with a perp subtype Given the user taps a social-trader-position deeplink with notification_subtype=follow_newtrade_perp_long When the deeplink handler runs Then navigation and analytics propagate notification_subtype=follow_newtrade_perp_long end-to-end Scenario: Legacy deeplinks without a subtype still work Given the user taps a social-trader-position deeplink with no notification_subtype query param When the deeplink handler runs Then navigation completes normally And the SOCIAL_FOLLOW_TRADING_TOKEN_SCREEN_VIEWED event fires WITHOUT a notification_subtype property ``` ## **Screenshots/Recordings** N/A — analytics-only change, no visible UI. ### **Before** N/A ### **After** N/A ## **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. #### Performance checks (if applicable) - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [x] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [x] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **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.
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.
type=text Section must contain non-placeholder prose.
type=changelog Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
comment but do not block the PR.
Sections without a directive are checked for structural presence only.
-->
## **Description**
Fix broken perps section headers in Explore
<!-- mms-check: type=text required=true -->
<!--
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?
-->
## **Changelog**
<!-- mms-check: type=changelog required=true blocking=true -->
<!--
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: fix broken perps section headers in Explore
## **Related issues**
<!-- mms-check: type=issue-link required=true -->
Fixes: https://consensyssoftware.atlassian.net/browse/ASSETS-3367
## **Manual testing steps**
<!-- mms-check: type=manual-testing required=true -->
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- mms-check: type=screenshot required=true -->
<!-- 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/ce6366fb-b54e-4c6b-be49-7219327f3250
## **Pre-merge author checklist**
<!-- mms-check: type=checklist required=true -->
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [ ] 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).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] 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.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [ ] 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.
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.
type=text Section must contain non-placeholder prose.
type=changelog Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
comment but do not block the PR.
Sections without a directive are checked for structural presence only.
-->
## **Description**
<!-- mms-check: type=text required=true -->
Display card transactions as mUSD rather than vmUSD
Also remove the linked requirement before fetching card transactions,
since you can still fetch them even if you are logged out.
## **Changelog**
<!-- mms-check: type=changelog required=true blocking=true -->
CHANGELOG entry: display money card transactions as mUSD
## **Related issues**
<!-- mms-check: type=issue-link required=true -->
Fixes: N/A
## **Manual testing steps**
<!-- mms-check: type=manual-testing required=true -->
```gherkin
Feature: money account card transactions
Scenario: user looks at activity list
Given you have a money account with at least one card transaction
When you look at the activity item in the list
Then the token shown in the row will be mUSD
```
## **Screenshots/Recordings**
### **Before**
<img width="1170" height="2532" alt="Simulator Screenshot - iPhone 16e -
2026-06-16 at 16 27 11"
src="https://github.com/user-attachments/assets/7da817b3-91ea-4852-837d-b3c4a01e008a"
/>
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
<img width="1170" height="2532" alt="Simulator Screenshot - iPhone 16e -
2026-06-16 at 16 27 19"
src="https://github.com/user-attachments/assets/0a6c71bd-9439-40a1-8870-38ebabe6834e"
/>
## **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.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **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.
…31822) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> <!-- mms-check directive vocabulary — read by .github/scripts/shared/pr-template-checks.ts at module load to build the validation plan. Directives are invisible in rendered markdown and must NOT be removed or edited without updating the validator registry. type=text Section must contain non-placeholder prose. type=changelog Section must have a valid CHANGELOG entry: line. type=issue-link Section must have a Fixes:/Closes:/Refs: line with a value. type=manual-testing Section must have real testing steps or an explicit N/A. type=screenshot Section must have evidence (image/URL) or an explicit N/A. type=checklist Section must have all checkboxes consciously checked. required=true|false Whether a missing/invalid section runs the validator at all. blocking=true|false Whether a failure of this check fails the CI workflow. Default: false — failures are shown as warnings in the sticky comment but do not block the PR. Sections without a directive are checked for structural presence only. --> ## **Description** <!-- mms-check: type=text required=true --> Batch sell was reporting smart transactions (STX) as disabled on all networks except Ethereum mainnet and Sepolia, even when STX was enabled for the user and the Sentinel liveness API returned `smartTransactions: true` for chains like BSC, Base, and Polygon. Unified Swap/Bridge already refreshes STX liveness on entry via `useRefreshSmartTransactionsLiveness`, which calls `SmartTransactionsController.fetchLiveness` and populates `livenessByChainId` in Redux. Batch sell never triggered that fetch, so only the controller defaults (mainnet + sepolia) were present and `selectSmartTransactionsEnabled` returned false for every other chain. This change adds the same liveness refresh to the first batch sell screen (`BatchSellTokenSelect`), keyed off the active source chain (`activeChainId`), matching the BridgeView pattern. When the user switches chain pills, liveness is refetched for the newly selected chain. ## **Changelog** <!-- mms-check: type=changelog required=true blocking=true --> <!-- 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** <!-- mms-check: type=issue-link required=true --> Fixes: #31821 ## **Manual testing steps** <!-- mms-check: type=manual-testing required=true --> ```gherkin Feature: Batch sell smart transaction liveness Scenario: STX is enabled on a non-Ethereum batch sell network Given smart transactions are opted in in Settings > Advanced Given the wallet has tokens on BSC (or Base / Polygon / Arbitrum / Linea) When the user opens Batch sell token select And selects the non-Ethereum network pill And proceeds through review to fetch quotes Then quote requests include stx_enabled true (when other STX gates pass) And batch sell submission passes isStxEnabled true Scenario: STX liveness refreshes when switching batch sell networks Given the user is on Batch sell token select with multiple eligible networks When the user switches between network pills Then liveness is fetched for each selected chain (verify via Redux livenessByChainId or network inspector) ``` Additional verification: - Confirm Ethereum mainnet and Sepolia batch sell behavior is unchanged. - Confirm batch sell still respects STX opt-out (Settings toggle off → STX false). ## **Screenshots/Recordings** <!-- mms-check: type=screenshot required=true --> <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> <img width="1047" height="418" alt="Screenshot 2026-06-16 at 11 27 20 AM" src="https://github.com/user-attachments/assets/97164095-a6e6-464c-abac-4c486f4202b0" /> ### **After** <!-- [screenshots/recordings] --> <img width="1641" height="574" alt="Screenshot 2026-06-16 at 11 22 41 AM" src="https://github.com/user-attachments/assets/d8d54a76-160d-443b-aef0-1ca7024ecdf7" /> ## **Pre-merge author checklist** <!-- mms-check: type=checklist required=true --> <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [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. #### Performance checks (if applicable) - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [x] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [x] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] 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.
…#31751) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> <!-- mms-check directive vocabulary — read by .github/scripts/shared/pr-template-checks.ts at module load to build the validation plan. Directives are invisible in rendered markdown and must NOT be removed or edited without updating the validator registry. type=text Section must contain non-placeholder prose. type=changelog Section must have a valid CHANGELOG entry: line. type=issue-link Section must have a Fixes:/Closes:/Refs: line with a value. type=manual-testing Section must have real testing steps or an explicit N/A. type=screenshot Section must have evidence (image/URL) or an explicit N/A. type=checklist Section must have all checkboxes consciously checked. required=true|false Whether a missing/invalid section runs the validator at all. blocking=true|false Whether a failure of this check fails the CI workflow. Default: false — failures are shown as warnings in the sticky comment but do not block the PR. Sections without a directive are checked for structural presence only. --> ## **Description** <!-- mms-check: type=text required=true --> <!-- 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? --> Adds currentPriceLineColorOverride prop to AdvancedChart - Adds currentPriceLineColorOverride?: string to AdvancedChartProps and the ChartFeatures template interface, baking it into window.CONFIG.theme.currentPriceColor at HTML creation time - Updates createLastPriceLine (candle chart) and createLineLastPriceLine (line chart) in chartLogic.js to read currentPriceColor || successColor so the override applies without touching candle up-colors, volume, or line-chart series color - Consumers that don't pass the prop get an empty string → falsy → existing successColor fallback; no visual change to the token detail chart - Fixes a race condition in the initial*ColorRef hot-swap pattern: the three color-override refs (initialLineColorRef, initialSuccessColorRef, initialErrorColorRef) are now snapshotted synchronously inside useMemo rather than in a post-render useEffect. This prevents SET_THEME_COLORS from seeing "colors already match" and skipping a needed hot-swap when a theme change and a color override change land in the same render cycle. Motivation The current-price horizontal line currently uses successColor (green), which is also used for candle up-colors and volume. A per-consumer override is needed so Perps can render a white price line without changing candle colors globally. Test plan - [ ] All existing AdvancedChart unit tests pass (yarn jest app/components/UI/Charts/AdvancedChart/) - [ ] Token detail chart: current-price line unchanged (still green/successColor) — no currentPriceLineColorOverride passed - [ ] After this merges, the Perps migration PR adds currentPriceLineColorOverride={colors.text.default} to PerpsAdvancedChart and verifies the price line renders white (dark mode) / near-black (light mode) without affecting candle colors ## **Changelog** <!-- mms-check: type=changelog required=true blocking=true --> <!-- 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** <!-- mms-check: type=issue-link required=true --> Fixes: https://consensyssoftware.atlassian.net/browse/TAT-3152 ## **Manual testing steps** <!-- mms-check: type=manual-testing required=true --> ```gherkin Feature: Advanced chart current price color Scenario: chart colors update after live price direction changes Given the token details chart is loaded with a custom current price line color When live price data changes the token chart direction from positive to negative Then the chart updates its line and candle colors without rebuilding the WebView And the current price horizontal line keeps the custom current price line color ``` ## **Screenshots/Recordings** <!-- mms-check: type=screenshot required=true --> <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** N/A <!-- [screenshots/recordings] --> ### **After** N/A <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- mms-check: type=checklist required=true --> <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [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. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] 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.
## **Description** We aren’t permitted to render Money account UI elements when users are geo-blocked. This PR uses the new feature flag `moneyAccountGeoBlockedCountries` and hides - Money balance card on home, instead showing money hub (as it does when money account is disabled) - Money navbar button, instead restoring the activity buton - Wallet home Contentful banners are not shown ## **Changelog** CHANGELOG entry: geo-block money account in unavailable regions ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MUSD-828 ## **Manual testing steps** Feature: Money geo-blocking ``` Background: Given the Money account feature flag is enabled Scenario: User in a blocked country sees no Money UI Given the "moneyAccountGeoBlockedCountries" flag has blockedRegions ["GB"] And the detected geolocation is "GB" When the user opens the app Then the Money balance card is not rendered on the wallet home screen And the bottom nav shows the Activity tab instead of the Money tab And the Activity clock icon is not rendered in the wallet header And the growth banners are not rendered on the wallet home screen Scenario: User in an unblocked country sees all Money UI Given the "moneyAccountGeoBlockedCountries" flag has blockedRegions ["GB"] And the detected geolocation is "US" When the user opens the app Then the Money balance card is visible on the wallet home screen And the bottom nav shows the Money tab And the Activity clock icon is visible in the wallet header And the growth banners are visible on the wallet home screen Scenario: Growth banners are visible when Money is disabled entirely Given the Money account feature flag is disabled And the "moneyAccountGeoBlockedCountries" flag has blockedRegions ["GB"] And the detected geolocation is "GB" When the user opens the app Then the growth banners are visible on the wallet home screen Scenario: Empty blocked regions list allows all users through Given the "moneyAccountGeoBlockedCountries" flag has blockedRegions [] And the detected geolocation is "GB" When the user opens the app Then the Money balance card is visible on the wallet home screen And the bottom nav shows the Money tab Scenario: Country-region code is matched by country prefix Given the "moneyAccountGeoBlockedCountries" flag has blockedRegions ["GB"] And the detected geolocation is "GB-ENG" When the user opens the app Then the Money balance card is not rendered on the wallet home screen And the bottom nav shows the Activity tab instead of the Money tab Scenario: Default blocklist applies when no remote flag is configured Given the "moneyAccountGeoBlockedCountries" remote flag is not set And the MM_MONEY_ACCOUNT_GEO_BLOCKED_COUNTRIES env var is not set And the detected geolocation is "GB" When the user opens the app Then the Money balance card is not rendered on the wallet home screen And the bottom nav shows the Activity tab instead of the Money tab Scenario: Env var blocklist is used when remote flag is absent Given the "moneyAccountGeoBlockedCountries" remote flag is not set And the MM_MONEY_ACCOUNT_GEO_BLOCKED_COUNTRIES env var is set to "US" And the detected geolocation is "US" When the user opens the app Then the Money balance card is not rendered on the wallet home screen And the detected geolocation is "GB" When the user opens the app Then the Money balance card is visible on the wallet home screen ``` ## **Screenshots/Recordings** ### **Before** <img width="1170" height="2532" alt="Simulator Screenshot - iPhone 16e - 2026-06-16 at 14 04 01" src="https://github.com/user-attachments/assets/eabba171-2235-46d5-98c9-aced14e5f0de" /> ### **After** <img width="1170" height="2532" alt="Simulator Screenshot - iPhone 16e - 2026-06-16 at 14 00 13" src="https://github.com/user-attachments/assets/48c2f31c-7560-4342-97cb-0558f440f075" /> ## **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. #### Performance checks (if applicable) - [X] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [X] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [X] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] 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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )