chore: sync stable into release/7.68.0#27282
Merged
chloeYue merged 75 commits intorelease/7.68.0from Mar 10, 2026
Merged
Conversation
) - refactor(analytics): migrate Batch 2-11: metamask-earn (#26292) ## **Description** Phase 2 analytics migration (Batch 2-11): migrate Stake/Earn's `useMetrics` hook and `MetaMetrics.getInstance()` calls from the legacy MetaMetrics system to the new analytics system. **Reason**: Deprecate MetaMetrics in favour of the shared analytics utility and AnalyticsController. **Changes**: Stake components and hooks now use `useAnalytics` from `hooks/useAnalytics/useAnalytics` and import `MetaMetricsEvents` directly from `core/Analytics`; `withMetaMetrics` utility now uses `analytics.trackEvent()` and `AnalyticsEventBuilder` instead of `MetaMetrics.getInstance().trackEvent()` and `MetricsEventBuilder`; test mocks updated accordingly. ### Changes **Source files (6)**: - `LearnMoreModalFooter.tsx`, `StakingButtons.tsx`, `StakingBalance.tsx`, `StakeButton/index.tsx`: replaced `useMetrics` with `useAnalytics`; `MetaMetricsEvents` now imported from `core/Analytics` - `usePoolStakedDeposit/index.ts`: replaced `useMetrics` with `useAnalytics` (also migrated as it's the source for a listed test file) - `withMetaMetrics.ts`: replaced `MetaMetrics.getInstance().trackEvent()` with `analytics.trackEvent()` and `MetricsEventBuilder` with `AnalyticsEventBuilder` **Test files (3)**: - `StakeButton.test.tsx`: replaced `useMetrics` mock with `useAnalytics` mock; added transitive `useMetrics` mock for unmigrated `useStablecoinLendingRedirect` dependency; replaced `MetricsEventBuilder` with `AnalyticsEventBuilder` - `usePoolStakedDeposit.test.tsx`: replaced `useMetrics` mock/import with `useAnalytics`; replaced `MetricsEventBuilder` with `AnalyticsEventBuilder` - `withMetaMetrics.test.ts`: replaced `MetaMetrics.getInstance()` spy with `analytics` module mock; updated `MetaMetricsEvents` import from `core/Analytics` ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-298 (Batch 2-11) ## **Manual testing steps** ```gherkin Feature: Stake/Earn analytics Scenario: user triggers a stake/earn flow event Given app is open and user is in a stake/earn flow When user performs an action that triggers analytics (e.g. stake button, unstake button, learn more, view staked positions) Then the event is tracked on Mixpanel ``` ## **Screenshots/Recordings** N/A – analytics migration, no UI change. ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > This is a broad analytics plumbing migration across Stake/Earn UI and transaction hooks; risk is mainly missed/changed event emission or metadata due to swapped builders and tracking surfaces, not user-facing flow changes. > > **Overview** > Migrates Stake/Earn (Earn CTA, staking balance/buttons, learn-more modal, and pooled-stake deposit hook) from legacy `useMetrics`/`MetaMetrics.getInstance()` tracking to the new analytics stack via `useAnalytics`, `analytics.trackEvent`, and `AnalyticsEventBuilder`. > > Updates related unit tests to mock `useAnalytics`/`analytics` instead of `useMetrics`/MetaMetrics, including a new mock for `useStablecoinLendingRedirect` to avoid transitive legacy metrics behavior and keep navigation assertions stable. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 8971698. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> [b5b8c71](b5b8c71) Co-authored-by: Nico MASSART <NicolasMassart@users.noreply.github.com>
) - refactor(analytics): migrate Batch 3-1: mobile-platform (#26312) ## **Description** Phase 3 analytics migration (Batch 3-1): migrate Authentication core's `Authentication.ts` from `MetaMetrics.getInstance()` to the new analytics system. **Reason**: Deprecate MetaMetrics in favour of the shared analytics utility and AnalyticsController. **Changes**: `Authentication.ts` now uses `analytics.isEnabled()` from `app/util/analytics/analytics` instead of `MetaMetrics.getInstance().isEnabled()`; test mocks updated to mock the analytics utility instead of MetaMetrics. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-301 (Batch 3-1) ## **Manual testing steps** ```gherkin Feature: Authentication analytics Scenario: user triggers an authentication flow event Given app is open and user is in an authentication flow When user performs an action that triggers analytics (e.g. unlock wallet, login) Then the event is tracked on Mixpanel ``` ## **Screenshots/Recordings** N/A – analytics migration, no UI change. ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Small refactor limited to the metrics-consent check after unlocking the wallet; main risk is a regression in opt-in navigation if `analytics.isEnabled()` differs from the old `MetaMetrics` behavior. > > **Overview** > `Authentication.unlockWallet` now uses the shared `analytics.isEnabled()` helper (from `util/analytics/analytics`) instead of `MetaMetrics.getInstance().isEnabled()` when deciding whether to route users to the metrics opt-in screen after login. > > Unit tests were updated to mock and spy on the new `analytics` helper rather than `MetaMetrics`, keeping the same enabled/disabled behavior expectations. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit a7de545. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> [e4effa3](e4effa3) Co-authored-by: Nico MASSART <NicolasMassart@users.noreply.github.com>
…Action cp-7.67.0 (#26457) - chore: New Crowdin translations by Github Action cp-7.67.0 (#26152) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Localization-only JSON string changes; low functional risk aside from potential missing/renamed keys affecting UI text rendering. > > **Overview** > Updates German locale strings (`locales/languages/de.json`) with a large batch of Crowdin changes, including **new translation keys** for features like Market Insights, homepage sections, device authentication/biometrics messaging, network management, and MetaMask Card freeze/unfreeze flows. > > Also revises many existing strings (mostly English-to-German fixes and copy updates) across swap/bridge, perps activity, QR scanning, permissions/connect flows, and various error/toast messages, with some removals/renames (e.g., `merkl_rewards`). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e3e2bd4. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com> [9b792be](9b792be) Co-authored-by: MetaMask Bot <37885440+metamaskbot@users.noreply.github.com> Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
… to fix stale cache on slow connections cp-7.67.0 (#26334) - fix(perps): connection-aware ensureReady() to fix stale cache on slow connections cp-7.67.0 (#26324) ## **Description** Fixes [TAT-2597](https://consensys-mesh.atlassian.net/browse/TAT-2597) and [TAT-2598](https://consensys-mesh.atlassian.net/browse/TAT-2598): After the preload PR merged, slow connections caused StreamChannels to exhaust 150 polling retries (30s) in `ensureReady()` and silently give up, leaving users with stale REST cache and no live WebSocket data — positions not appearing after trade, missing prices. **Root Cause:** `StreamChannel.ensureReady()` used blind polling (`isReady` every 200ms × 150 retries) with no awareness of WebSocket connection state. On slow connections, the connection had not even established yet, so polling burned through all retries before data could arrive. **Fix:** - `PerpsConnectionManager.waitForConnection()` — exposes init/reconnect promises so channels can `await` instead of blind-polling - `StreamChannel.ensureReady()` — detects `isConnecting` state and awaits the connection promise via `awaitConnectionThenConnect()` **Result:** PriceStreamChannel retries dropped from **33 → 0** on device after this fix. ## **Changelog** CHANGELOG entry: Fixed stale cache on slow connections where positions and prices were not updating after a trade ## **Related issues** Fixes: [TAT-2597](https://consensys-mesh.atlassian.net/browse/TAT-2597), [TAT-2598](https://consensys-mesh.atlassian.net/browse/TAT-2598) ## **Manual testing steps** ```gherkin Feature: Perps live data on slow connections Scenario: user opens a trade on a slow connection Given the app is connected to a slow 3G network And the user has navigated to the Perps trading screen When user opens a new position Then the position appears immediately in the positions list And price stream connects without excessive retries Scenario: user recovers from network drop Given the user is viewing live perps positions And the network connection drops momentarily When the network connection is restored Then live WebSocket data resumes without stale cache ``` ## **Screenshots/Recordings** ### **Before** <!-- PriceStreamChannel: 33 retries before data appears, positions missing on slow connections --> ### **After** <!-- PriceStreamChannel: 0 retries, positions appear immediately --> ## **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. [TAT-2597]: https://consensyssoftware.atlassian.net/browse/TAT-2597?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ [TAT-2598]: https://consensyssoftware.atlassian.net/browse/TAT-2598?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ [TAT-2597]: https://consensyssoftware.atlassian.net/browse/TAT-2597?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes connection/retry timing and sequencing for Perps WebSocket subscriptions; regressions could delay or prevent live data if the new await/sentinel logic misfires under edge cases (disconnects, rapid resubscribe). > > **Overview** > Perps stream channels now become **connection-aware**: `StreamChannel.ensureReady()` detects `PerpsConnectionManager`'s `isConnecting` state and waits on a new `waitForConnection()` promise, then retries `connect()` (with duplicate-wait suppression and polling fallback on rejection). > > Retry scheduling was tightened by clearing `deferConnect` timers on fire and centralizing the retry delay via `PERPS_CONSTANTS.ConnectRetryDelayMs`; `MarketDataChannel` now uses this constant as well. Tests were expanded to cover the new await/deferral behavior and the new `PerpsConnectionManager.waitForConnection()` contract. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 39e206b. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> [43cf1d8](43cf1d8) [TAT-2597]: https://consensyssoftware.atlassian.net/browse/TAT-2597?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ [TAT-2598]: https://consensyssoftware.atlassian.net/browse/TAT-2598?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ [TAT-2597]: https://consensyssoftware.atlassian.net/browse/TAT-2597?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ Co-authored-by: abretonc7s <107169956+abretonc7s@users.noreply.github.com>
…66.0 (#26337) - fix: Fix StorageService Key Encoding cp-7.66.0 (#26268) ## **Description** ### Problem The `redux-persist-filesystem-storage` library has two problematic behaviors when handling arbitrary keys in `StorageService`: 1. **Slashes (`/`) create subdirectories**: Keys containing slashes are stored in subdirectories, making them unreachable via `getAllKeys`. This breaks the `clear` method for affected keys. 2. **Hyphens (`-`) get corrupted**: The library's internal `fromFileName` function converts hyphens to colons (`:`), meaning keys like `simple-key` are returned as `simple:key` by `getAllKeys`. This causes a permanent mismatch between stored keys and returned keys. ### Solution This PR introduces URI-style encoding for problematic characters in **both namespace and key** portions of storage keys: - `/` → `%2F` (prevents subdirectory creation) - `-` → `%2D` (prevents hyphen-to-colon corruption) - `%` → `%25` (prevents double-encoding issues) The encoding is applied via shared utility functions (`encodeStorageKey`/`decodeStorageKey`) used by both: - `mobileStorageAdapter` in `storage-service-init.ts` - Migration 118 which stores snap source code ### Backward Compatibility **This change is backward compatible and will NOT break existing production keys.** - Existing keys like `storageService:TokenListController:tokensChainsCache:0x1` are **unaffected** because: - The namespace (`TokenListController`) has no special characters → encoding produces identical output - Colons (`:`) are **not encoded** - they pass through unchanged - The key portion (`tokensChainsCache:0x1`) contains no hyphens or slashes - **Strings without `-`, `/`, or `%` characters produce identical output when encoded** - This means all current production keys work exactly as before, while future keys with special characters will be handled correctly ### Examples ``` # No special characters → unchanged (backward compatible) storageService:TokenListController:tokensChainsCache:0x1 → storageService:TokenListController:tokensChainsCache:0x1 # Snap ID with slashes and hyphens → encoded storageService:SnapController:npm:@metamask/bip32-keyring-snap → storageService:SnapController:npm:@MetaMask%2Fbip32%2Dkeyring%2Dsnap # Namespace with hyphen → encoded storageService:Some-Controller:some-key → storageService:Some%2DController:some%2Dkey # Key with slashes → encoded (prevents subdirectory creation) storageService:TestController:nested/path/key → storageService:TestController:nested%2Fpath%2Fkey ``` ### Files Changed | File | Change | |------|--------| | `app/core/Engine/utils/storage-service-utils.ts` | New utility with `encodeStorageKey`/`decodeStorageKey` functions | | `app/core/Engine/utils/storage-service-utils.test.ts` | 35 unit tests for the encoding utilities | | `app/core/Engine/controllers/storage-service-init.ts` | Apply encoding in `mobileStorageAdapter` methods | | `app/core/Engine/controllers/storage-service-init.test.ts` | 22 new tests for key and namespace encoding behavior | | `app/store/migrations/119.ts` | Encode snap IDs when storing snap source code | ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: StorageService key handling issues with `redux-persist-filesystem-storage` ## **Manual testing steps** ```gherkin Feature: StorageService key encoding Scenario: Keys with hyphens are stored and retrieved correctly Given the app is running When StorageService stores a key containing hyphens (e.g., "npm:@metamask/bip32-keyring-snap") Then the key is encoded as "npm:@MetaMask%2Fbip32%2Dkeyring%2Dsnap" on disk And getAllKeys returns the original key "npm:@metamask/bip32-keyring-snap" And getItem with the original key returns the stored data Scenario: Keys with slashes are stored and retrieved correctly Given the app is running When StorageService stores a key containing slashes (e.g., "nested/path/key") Then the key is stored as a single file (not in subdirectories) And getAllKeys returns the original key "nested/path/key" And clear removes the key correctly Scenario: Existing keys with colons remain unchanged Given existing production keys like "storageService:TokenListController:tokensChainsCache:0x1" When the app starts with this fix Then the existing keys are still accessible And no migration is required for existing data ``` ## **Screenshots/Recordings** N/A - No UI changes ### **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 - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes how persistent storage keys are constructed and enumerated, which could impact read/write/clear behavior for stored controller data if encoding is applied inconsistently or assumptions about existing on-disk keys differ. > > **Overview** > Fixes mobile `StorageService` persistence by **encoding both `namespace` and `key` components** before writing to `redux-persist-filesystem-storage` (and decoding on `getAllKeys`) to avoid `/` creating subdirectories and `-` being corrupted. > > Introduces shared `encodeStorageKey`/`decodeStorageKey` utilities and updates migration `119` to encode snap IDs when persisting snap `sourceCode`; expands/updates unit tests to cover encoding/decoding behavior and the updated migration expectations. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit bb0e8d6. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Cursor <cursoragent@cursor.com> [5d11a21](5d11a21) Co-authored-by: Andre Pimenta <andrepimenta7@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
…r account switch (#26349) - fix: cp-7.66.0 refresh staked balance after account switch (#26332) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** fix refresh staking balance after account switch <!-- 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** <!-- 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 refresh staking balance after account switch ## **Related issues** Fixes: #26323 ## **Manual testing steps** ```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** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/1a720a48-83e6-45e0-84e7-29b2cb3479e7 ### **After** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/826a347b-e003-4bd6-8816-8bec2b66c423 ## **Pre-merge author checklist** - [ ] 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. ## **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] > **Low Risk** > Small, localized change to a `useEffect` dependency plus a new test; main risk is accidental extra refresh calls impacting performance or causing redundant network requests. > > **Overview** > Refresh behavior on the `Wallet` screen is updated so `AccountTrackerController.refresh` is re-triggered when `selectedInternalAccount` changes (added to the relevant `useEffect` dependency list), fixing stale balance/staking data after an account switch. > > Tests are updated to cover this regression by asserting `refresh` is called again when `AccountsController.internalAccounts.selectedAccount` changes, and snapshots are updated accordingly. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit a15a4d1. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> [c70f38d](c70f38d) Co-authored-by: Salim TOUBAL <salim.toubal@outlook.com>
…ount with getClaimPayoutFromReceipt cp-7.66.0 (#26361) - refactor(musd): replace decodeMerklClaimAmount with getClaimPayoutFromReceipt cp-7.66.0 (#26342) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** The mUSD claim transaction amount was displaying the cumulative total reward (from Merkl distributor calldata `amounts[0]`) instead of the actual per-transaction payout. This caused incorrect amounts in the Activity list and transaction detail views — e.g., if a user made multiple claims, each one would show the running total rather than what was actually claimed in that specific transaction. The fix introduces `getClaimPayoutFromReceipt()` which extracts the real payout from the ERC-20 `Transfer` event in the transaction receipt logs (emitted when the Merkl distributor transfers mUSD to the user). This is used as the primary source for confirmed transactions across: - Activity list (`decodeMusdClaimTx`) - Transaction detail hero (`useClaimAmount`) - Confirmation flow (`useMerklClaimAmount`) ## **Changelog** CHANGELOG entry: Fixed mUSD claim transactions showing incorrect cumulative total instead of per-transaction payout amount ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: mUSD claim transaction amount display Scenario: user views a confirmed mUSD claim transaction in Activity Given user has made one or more mUSD claim transactions from this device And at least one claim transaction is confirmed When user navigates to the Activity tab Then the claim transaction shows the correct per-transaction payout amount (not cumulative total) Scenario: user views claim transaction details Given user has a confirmed mUSD claim transaction visible in Activity When user taps on the claim transaction Then the detail view shows the correct claimed amount matching the actual payout Scenario: user views a pending mUSD claim in the Activity list Given user has a pending mUSD claim transaction When user views the transaction in Activity Then the amount shows "Not available" until the transaction confirms And once confirmed, the correct payout amount appears ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes how `musdClaim` amounts are derived in Activity/details/confirmation flows, relying on receipt log parsing and BigInt decoding; incorrect log matching or missing receipts could cause amounts to be blank or wrong. > > **Overview** > **Fixes incorrect mUSD claim amounts** by switching from decoding the Merkl claim calldata (cumulative total) to extracting the per-transaction payout from the ERC-20 `Transfer` event in the transaction receipt via new `getClaimPayoutFromReceipt()`. > > Updates `musdClaim` display/amount computation in the Activity list (`decodeMusdClaimTx`), transaction details hero (`useClaimAmount`), and confirmation flow hook (`useMerklClaimAmount`, which now prefers receipt payout when confirmed and falls back to the async unclaimed-amount calculation when pending). Tests are updated to validate receipt-log extraction and the new UI behavior. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit c66b845. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> [0ef570f](0ef570f) Co-authored-by: Patryk Łucka <5708018+PatrykLucka@users.noreply.github.com>
…28hj-76wf cp-7.66.0 (#26427) - chore: allow list audit finding GHSA-378v-28hj-76wf cp-7.66.0 (#26386) add bn.js affected by an infinite loop. No fix available yet (latest is 5.2.1, affected <=5.2.3). Suppressing for now to unblock CI. GHSA-378v-28hj-76wf <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** <!-- 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** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** ```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** <!-- 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** - [ ] 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. ## **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] > **Low Risk** > Configuration-only change to suppress a specific audit warning; no runtime logic changes, but it reduces audit signal for this known issue. > > **Overview** > Updates Yarn config to ignore the `bn.js` npm audit advisory `GHSA-378v-28hj-76wf` (ID `1113402`) in `npmAuditIgnoreAdvisories`, to unblock CI until a fix is available. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 6560f97. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> [ebce642](ebce642) Co-authored-by: sethkfman <10342624+sethkfman@users.noreply.github.com>
…ted to super bowl banner on carousel (#26375) - chore(predict): cp-7.66.0 remove code related to super bowl banner on carousel (#26363) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** The Carousel previously had special handling for the Predict Superbowl banner: it could replace the entire carousel with a single `PredictMarketSportCardWrapper` when a Superbowl slide with a `marketId` was present, and hid that slide from the normal carousel. This change removes that integration. **What changed:** - **Carousel (`index.tsx`):** Removed Predict/Superbowl imports, the `predictSuperbowlSlide` and `predictSuperbowlMarketId` memos, the early return that rendered `PredictMarketSportCardWrapper`, the filter that excluded `PREDICT_SUPERBOWL_VARIABLE_NAME` from visible slides, and the `handleSportCardDismiss` / `handlePredictSuperbowlLoad` callbacks (including "Banner Display" tracking for the Superbowl card). - **Tests (`index.test.tsx`):** Removed the `PredictMarketSportCardWrapper` mock, the `PREDICT_SUPERBOWL_VARIABLE_NAME` import, and the entire "Carousel Predict Superbowl Integration" describe block and its five tests (render with/without marketId, props, tracking). The Carousel no longer has any Superbowl-specific behavior; any such slides from Contentful would now be treated as normal carousel slides. <!-- 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** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** ```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** <!-- 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** - [ ] 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. ## **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] > **Low Risk** > Removes a time-bound/feature-specific code path and its tests without touching core navigation or data handling; main risk is unintended behavior if Contentful still serves Superbowl slides. > > **Overview** > Removes the Carousel’s special-case Predict Superbowl behavior so it no longer replaces the carousel with a `PredictMarketSportCardWrapper` when a Superbowl slide is present. > > This deletes Superbowl-specific slide detection/metadata handling, explicit filtering of the Superbowl slide from `visibleSlides`, and related dismiss/load callbacks + “Banner Display” tracking. The test suite is updated by dropping the Predict Superbowl mock and all associated integration tests. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 4bde723. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> [6eb88ac](6eb88ac) Co-authored-by: Caainã Jeronimo <caainaje@gmail.com>
…sion and musd_claim transaction types to transaction-controller metrics_properties (#26433) - feat: cp-7.66.0 MUSD-357 added musd_conversion and musd_claim transaction types to transaction-controller metrics_properties (#26383) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** Added musd_conversion and musd_claim transaction types to transaction-controller metrics_properties <!-- 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** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: added musd_conversion and musd_claim transaction types to transaction-controller metrics_properties ## **Related issues** Fixes: [MUSD-357: Add musdConversion and musdClaim Transaction Types to "Transaction *" Events](https://consensyssoftware.atlassian.net/browse/MUSD-357) ## **Manual testing steps** ```gherkin Feature: mUSD transaction analytics classification Scenario: user submits mUSD conversion or claim transaction Given user has an mUSD conversion or mUSD claim transaction in the wallet flow When the wallet emits general transaction lifecycle events Then analytics include a specific transaction_type value And transaction_type is "musd_conversion" for conversion transactions And transaction_type is "musd_claim" for claim transactions ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> N/A ### **After** <!-- [screenshots/recordings] --> 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. ## **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] > **Low Risk** > Small, additive change limited to analytics `transaction_type` labeling plus test coverage; low risk aside from potential downstream dashboard/event-name expectations. > > **Overview** > Adds analytics classification for nested mUSD transactions by mapping `TransactionType.musdConversion` and `TransactionType.musdClaim` to `transaction_type` values `musd_conversion` and `musd_claim` in `getTransactionTypeValue`. > > Extends the existing parameterized test to cover these new nested transaction type mappings. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 3aa4ee5. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> [435a464](435a464) Co-authored-by: Matthew Grainger <46547583+Matt561@users.noreply.github.com>
This PR updates the change log for 7.66.0. (Hotfix - no test plan generated.) Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com> Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->
## **Description**
<!--
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?
-->
sync release/7.67.0 with stable
## **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:
## **Related issues**
Fixes:
## **Manual testing steps**
```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**
<!-- 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**
- [ ] 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.
## **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: runway-github[bot] <73448015+runway-github[bot]@users.noreply.github.com>
Co-authored-by: Caainã Jeronimo <caainaje@gmail.com>
Co-authored-by: Matthew Grainger <46547583+Matt561@users.noreply.github.com>
Co-authored-by: Prithpal Sooriya <prithpal.sooriya@consensys.net>
Co-authored-by: Michal Szorad <michal.szorad@consensys.net>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
Co-authored-by: Juanmi <95381763+juanmigdr@users.noreply.github.com>
Co-authored-by: Bruno Nascimento <brunonascimentodev@gmail.com>
Co-authored-by: Ale Machado <alejandro@macha.do>
Co-authored-by: Bryan Fullam <bryan.fullam@consensys.net>
Co-authored-by: Aslau Mario-Daniel <marioaslau@gmail.com>
Co-authored-by: sethkfman <10342624+sethkfman@users.noreply.github.com>
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
Co-authored-by: Cal-L <cal.leung@consensys.net>
Co-authored-by: Bruno Nascimento <bruno.nascimento@consensys.net>
Co-authored-by: Alejandro Garcia Anglada <aganglada@gmail.com>
Co-authored-by: OGPoyraz <omergoktugpoyraz@gmail.com>
Co-authored-by: Matthew Walsh <matthew.walsh@consensys.net>
Co-authored-by: Florin Dzeladini <florin.dzeladini@consensys.net>
Co-authored-by: MetaMask Bot <37885440+metamaskbot@users.noreply.github.com>
Co-authored-by: Nick Gambino <35090461+gambinish@users.noreply.github.com>
Co-authored-by: Vince Howard <vincenguyenhoward@gmail.com>
Co-authored-by: sahar-fehri <sahar.fehri@consensys.net>
Co-authored-by: George Weiler <georgejweiler@gmail.com>
Co-authored-by: George Marshall <george.marshall@consensys.net>
Co-authored-by: George Marshall <georgewrmarshall@users.noreply.github.com>
Co-authored-by: sophieqgu <37032128+sophieqgu@users.noreply.github.com>
Co-authored-by: Wei Sun <wei.sun@consensys.net>
Co-authored-by: ieow <4881057+ieow@users.noreply.github.com>
Co-authored-by: himanshu <himanshuchawla2014@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Andre Pimenta <andrepimenta7@gmail.com>
Co-authored-by: Salim TOUBAL <salim.toubal@outlook.com>
Co-authored-by: Patryk Łucka <5708018+PatrykLucka@users.noreply.github.com>
Co-authored-by: chloeYue <105063779+chloeYue@users.noreply.github.com>
- feat: Fix for Pull to Refresh IAB gesture bug (#26373) ## **Description** Pull-to-refresh gesture was intercepting taps on buttons near the top of the page (e.g., Polymarket "Sign Up" / "Log In" buttons). The gesture handler called `stateManager.activate()` immediately in `onTouchesDown` for the pull zone (`y < 50px`), stealing the touch from the WebView before knowing whether the user intended to tap or pull. ### Changes **Deferred activation for pull-to-refresh**: Instead of activating immediately, the gesture enters a `pending_refresh` state in `onTouchesDown`. New `onTouchesMove` and `onTouchesUp` handlers measure the movement delta: - Downward movement >10px → activate pull-to-refresh - Horizontal/upward movement >10px → fail and let WebView handle - Finger lifts with <10px movement (tap) → fail and let WebView handle **`Gesture.Simultaneous` instead of `Gesture.Race`**: Deferred activation requires that the Native gesture (WebView scroll) does not cancel our Pan while it is deciding. `Gesture.Simultaneous` allows both to run independently — taps pass through to the WebView while our Pan stays in BEGAN state deciding, and when Pan activates for a real pull at the top of the page, the WebView has nothing to scroll so both coexist without visual conflict. ### Why not other approaches - `Gesture.Race` + deferred activation: Native wins the race and cancels Pan before `onTouchesMove` fires - `Gesture.Race` + immediate activation + synthetic JS click replay: Pull-to-refresh works but synthetic events have `isTrusted = false` — React ignores them - `Gesture.Exclusive` + deferred activation: Blocks Native while Pan is in BEGAN — nothing works ## **Changelog** CHANGELOG entry: Fixed pull-to-refresh gesture intercepting taps on buttons near the top of the page in the in-app browser ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-352 ## **Manual testing steps** ```gherkin Feature: Browser gesture tap passthrough Scenario: User taps a button near the top of a webpage Given the user is on polymarket.com in the in-app browser And the page is scrolled to the top (not scrolled at all) When user taps the "Log In" or "Sign Up" button Then the login/signup modal should appear Scenario: User pulls to refresh from the top of the page Given the user is on any webpage in the in-app browser And the page is scrolled to the top When user places finger near the top of the page and drags downward Then the refresh indicator should appear And the page should reload when pulled past the threshold Scenario: User swipes back from the left edge Given the user has navigated to at least one page in the in-app browser When user swipes from the left edge of the screen toward the right Then the browser should navigate back to the previous page Scenario: User swipes forward from the right edge Given the user has navigated back at least once in the in-app browser When user swipes from the right edge of the screen toward the left Then the browser should navigate forward Scenario: User scrolls normally in the center of the page Given the user is on any webpage in the in-app browser When user scrolls up or down in the center of the page Then the page should scroll normally without triggering any gestures ``` ## **Screenshots/Recordings** ### **Before** <!-- Tapping buttons near the top of the page (e.g. Polymarket Sign Up/Log In) shows button animation but does not trigger the action --> ### **After** <!-- Tapping the same buttons now correctly opens the login/signup flow --> https://github.com/user-attachments/assets/75c70094-6f39-4086-aab4-368cc6b81177 ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes low-level gesture coordination between the WebView native handler and a manual-activation Pan gesture, which could affect navigation/scroll/tap behavior across devices. Added tests reduce regression risk but gesture interactions are inherently sensitive to edge cases. > > **Overview** > Fixes an in-app browser bug where pull-to-refresh could steal taps near the top of the page by introducing **deferred pull-to-refresh activation**: touches in the pull zone now enter a `pending_refresh` state and only activate refresh after moving downward more than `PULL_MOVE_ACTIVATION` (10px), while horizontal/upward movement or lifting the finger fails the gesture and lets the WebView handle the tap. > > Switches WebView gesture composition from `Gesture.Race` to `Gesture.Simultaneous` so the WebView’s native gesture can continue receiving taps while the Pan gesture decides whether to activate, and extends unit tests/mocks to cover the new `onTouchesMove`/`onTouchesUp` paths and the new constant. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit af9d1b7. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> [9b336fc](9b336fc) Co-authored-by: Aslau Mario-Daniel <marioaslau@gmail.com> Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> <!-- 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? --> CI is broken due to a vulnerability with bn.js <img width="538" height="612" alt="image" src="https://github.com/user-attachments/assets/9cdeb857-cfde-4e95-aeb9-154de3722904" /> <!-- 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 Fixes: ```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] ``` <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> <!-- [screenshots/recordings] --> <!-- [screenshots/recordings] --> - [ ] 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. - [ ] 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] > **Low Risk** > Dependency-only upgrade via Yarn `resolutions`; low behavioral risk, with main concern being potential big-number edge-case differences in packages relying on `bn.js`. > > **Overview** > Updates `bn.js` to patched releases by pinning `bn.js@4.11.6`→`4.12.3` and `bn.js@5.2.1`→`5.2.3` via `package.json` `resolutions`, and bumps the app’s `bnjs4`/`bnjs5` aliases accordingly. > > Aligns TypeScript typings by moving `@types/bnjs5` to `@types/bn.js@^5.2.0`, with corresponding `yarn.lock` updates to remove the older `@types/bn.js`/`bn.js` versions. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 8b51e85. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…tle in activity details cp-7.67.0 (#26530) - fix: MUSD-368 fixed left-aligned header title in activity details cp-7.67.0 (#26495) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** Fixes UI bug where the mUSD conversion header was left-aligned on Android in the activity details view. <!-- 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** <!-- 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 UI bug where the mUSD conversion header was left-aligned on Android in the activity details view ## **Related issues** Fixes: [MUSD-368: Conversion header in activity list is left-aligned on Android](https://consensyssoftware.atlassian.net/browse/MUSD-368) ## **Manual testing steps** ```gherkin Feature: Centered navbar title in shared title options Scenario: user opens a screen that uses shared navigation title options on Android Given user is on an Android screen configured with getNavigationOptionsTitle When the screen header is rendered Then the header title is centered ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <img width="1080" height="2340" alt="image" src="https://github.com/user-attachments/assets/1224d29f-370c-4183-ae82-b486c401da96" /> <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> <img width="1080" height="2340" alt="image" src="https://github.com/user-attachments/assets/1fc92cd3-6f3d-48e3-882e-3e5e7eb36bd8" /> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Single UI-only navigation option tweak (`headerTitleAlign: 'center'`) with minimal behavioral impact and no security/data implications. > > **Overview** > Fixes an Android header alignment issue by explicitly setting `headerTitleAlign: 'center'` in `getNavigationOptionsTitle` (Navbar) so screens using the shared title options render a centered header title instead of left-aligned. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 1606ec1. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> [43ae73c](43ae73c) Co-authored-by: Matthew Grainger <46547583+Matt561@users.noreply.github.com> Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
- feat: cp-7.67.0 metamask pay live token balances (#26134) ## **Description** Bumps `@metamask/transaction-pay-controller` to include live on-chain balance validation and refresh for MetaMask Pay transactions. ## **Changelog** CHANGELOG entry: null ## **Related issues** Relates to MetaMask/core#7935 ## **Manual testing steps** ## **Screenshots/Recordings** ### **Before** ### **After** ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Upgrades core transaction/pay controller dependencies and alters transaction handling (gas fee auto-updates and metrics) for additional transaction types, which could impact transaction submission behavior and test stability. > > **Overview** > MetaMask Pay dependencies are updated (notably `@metamask/transaction-pay-controller` `v16` and `@metamask/transaction-controller` `v62.18+`), pulling in live on-chain balance validation/refresh and associated controller stack bumps via `yarn.lock`. > > To support new relay-based deposit flows, the PR introduces `RELAY_DEPOSIT_TYPES` (including `perps`/`predict` variants), disables automatic gas fee updates for all relay deposits, and extends transaction metrics mapping so the new transaction types emit distinct analytics values. > > Smoke test fixtures for mUSD conversion are updated to work with the new Pay balance validation by seeding an ERC20 stub contract code on Anvil and making `createMusdFixture` async. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 3a08273. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> [1b1705e](1b1705e) Co-authored-by: Matthew Walsh <matthew.walsh@consensys.net> Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
…hind rampsUnifiedBuyV2 feature flag cp-7.67.0 (#26538) - fix(ramps): gate RampsController.init() behind rampsUnifiedBuyV2 feature flag cp-7.67.0 (#26458) ## **Description** `RampsController.init()` was firing on every app startup regardless of the `rampsUnifiedBuyV2` feature flag, making unnecessary v2 API calls when V2 is disabled: - `GET v2/regions/countries` - `GET v2/regions/{region}/tokens` - `GET v2/regions/{region}/providers` **Note:** The `GET /geolocation` call is not gated by this change — it is also called independently by the existing `useDetectGeolocation` hook outside of `RampsController`, so it continues to fire regardless of the V2 flag. This PR gates the `init()` call behind the `rampsUnifiedBuyV2` remote feature flag using the established `initMessenger` pattern (same approach as `AssetsController`, `NetworkController`, `DeFiPositionsController`, etc.). The `RampsController` is always instantiated (preserving persisted state and messenger registration), but the eager network calls are skipped when V2 is disabled. When V2 is eventually enabled, `init()` fires as before, and `useHydrateRampsController` continues to handle the hydration path independently. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: [TRAM-3278](https://consensyssoftware.atlassian.net/browse/TRAM-3278) ## **References** - Incident: [incident-metamask-1469](https://app.firehydrant.io/org/consensys/incidents/9926d359-d5d1-468b-bea6-95cdbf09b890/incident/overview) (SEV1 — Buy/Sell quotes not loading, 2026-02-23) - GitHub Issue: #26534 ## **Manual testing steps** ```gherkin Feature: Gate RampsController.init() behind feature flag Scenario: user launches app with V2 feature flag disabled Given the rampsUnifiedBuyV2 remote feature flag is disabled When user launches the app Then RampsController.init() is not called And no v2 API calls are made (countries, tokens, providers) Scenario: user launches app with V2 feature flag enabled Given the rampsUnifiedBuyV2 remote feature flag is enabled And active is true and minimumVersion is set to a version <= current app version When user launches the app Then RampsController.init() is called as before And v2 API calls proceed normally ``` ## **Screenshots/Recordings** <div> <a href="https://www.loom.com/share/4d70e0f505b04adcadff0b4ed206794f"> <p>Implement feature flag logic for Ramps Controller - Watch Video</p> </a> <a href="https://www.loom.com/share/4d70e0f505b04adcadff0b4ed206794f"> <img style="max-width:300px;" src="https://cdn.loom.com/sessions/thumbnails/4d70e0f505b04adcadff0b4ed206794f-39b0c7d113eff0a2-full-play.gif#t=0.1"> </a> </div> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. [TRAM-3278]: https://consensyssoftware.atlassian.net/browse/TRAM-3278?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes startup initialization behavior for `RampsController` and adds a new init-messenger dependency on remote feature-flag state; risk is mainly around mis-gating causing missing initialization or unexpected API calls. > > **Overview** > `RampsController.init()` is now conditionally invoked at startup based on the remote `rampsUnifiedBuyV2` feature flag (including minimum app version checks), preventing eager V2 network calls when the flag is off. > > This introduces a dedicated `RampsControllerInitMessenger` that can read `RemoteFeatureFlagController:getState`, wires it into the controller init plumbing (`CONTROLLER_MESSENGERS`), and expands tests to cover enabled/disabled/invalid flag states and error handling while ensuring the controller is still always instantiated. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit a5471c0. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Cursor <cursoragent@cursor.com> [a68265a](a68265a) [TRAM-3278]: https://consensyssoftware.atlassian.net/browse/TRAM-3278?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ Co-authored-by: Amitabh Aggarwal <aggarwal.amitabh@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
…tate changes (#26809) - fix(perps): recover connection after app state changes cp-7.67.1 (#26780) ## **Description** Fixes Perps WebSocket connectivity issues when: 1. **App returns from background** — after a few minutes in background, the OS silently kills the WebSocket but `PerpsConnectionManager` still reports `isConnected = true`. No code path detected the stale connection or triggered reconnection. 2. **WiFi/network drops and restores** — toggling WiFi, airplane mode, or losing cellular signal kills the WebSocket, but since the app stays in `active` state, the existing `AppState`-based recovery (if any) never fires. ### Root Cause `PerpsConnectionManager` had no lifecycle awareness of: - **React Native `AppState` transitions** (background → foreground) - **Network connectivity changes** (offline → online via `@react-native-community/netinfo`) Arthur's prior fix ([#26334](#26334)) made `StreamChannel.ensureReady()` connection-aware to avoid blind polling on slow connections, but it only helps when a reconnection is **already in progress** (`isConnecting = true`). After background resume or WiFi restore, nobody triggers the reconnection in the first place. ### Fix - **`AppState` listener** — on `active`, cancels any pending grace period and runs `validateAndReconnect()` - **`NetInfo` listener** — tracks `wasOffline` state; on offline → online transition, runs `validateAndReconnect()` - **`validateAndReconnect(context)`** — shared method that sends a lightweight `ping()` health check to the active provider. If the ping fails (stale WebSocket), marks the connection as lost and triggers `reconnectWithNewContext({ force: true })` which reinitializes the controller, validates with a fresh health check, and preloads all stream subscriptions. - **Cleanup** — both listeners are properly removed in `cleanupStateMonitoring()` ## **Changelog** CHANGELOG entry: Fixed Perps WebSocket not reconnecting after app resume from background or WiFi/network toggle ## **Related issues** Fixes: connectivity loss after backgrounding app, WiFi off/on not recovering Perps data ## **Manual testing steps** ```gherkin Feature: Perps connection recovery Scenario: App returns from background after several minutes Given the user has navigated to the Perps trading screen And the user has an open position When the user backgrounds the app for 3+ minutes And the user returns to the app Then the Perps WebSocket reconnects automatically And positions, prices, and account data resume updating Scenario: WiFi is toggled off and back on Given the user is viewing live Perps positions And WiFi is connected When the user turns WiFi off And waits a few seconds And turns WiFi back on Then the Perps WebSocket reconnects after network is restored And live data resumes without requiring navigation away Scenario: Airplane mode is toggled Given the user is on the Perps trading screen When the user enables airplane mode And then disables airplane mode Then the connection recovers and live data resumes ``` ## **Screenshots/Recordings** ### **Before** After backgrounding or WiFi toggle, Perps shows stale data with no automatic recovery. User must navigate away and back to restore the connection. ### **After** Connection automatically recovers via health-check ping and force reconnection. Live data resumes within seconds. ## **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** - [x] 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 Perps connection lifecycle and reconnection paths; regressions could cause reconnect loops or delayed/stuck loading during flaky connectivity. > > **Overview** > Improves Perps WebSocket resilience by adding AppState and NetInfo listeners in `PerpsConnectionManager` to detect background→foreground and offline→online transitions, validate the connection via provider `ping()`, and force a reconnect when stale. > > Adds network-restore retry/backoff knobs (`NetworkRestoreMaxRetries`, `NetworkRestoreRetryBaseMs`) and ensures cleanup of new subscriptions/timers on teardown; reconnection now explicitly calls `PerpsController.disconnect()` before `init()` to avoid skipping re-init on a dead socket. > > Updates `usePerpsHomeData` to treat WebSocket-backed sections (positions/orders/activity) as loading while `isConnecting`, preventing brief empty-state flashes during reconnection. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit b3aab14. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> [c4f83e4](c4f83e4) Co-authored-by: Alejandro Garcia Anglada <aganglada@gmail.com>
…ener causing reconnection race (#26998) - fix(perps): remove duplicate AppState listener causing reconnection race cp-7.67.2 (#26982) ## **Description** After long backgrounds (5+ min), Perps failed to reload positions, 24h price change was missing, and closing positions threw "BTC is not tradeable asset". After closing a position and backgrounding for >20s, the closed position would reappear on foreground. **Root causes:** 1. **Duplicate AppState listener race** — `usePerpsConnectionLifecycle` hook and `PerpsConnectionManager.setupStateMonitoring()` both fired on foreground. The `force` reconnect path cancelled the hook's in-flight `connect()` and ran a competing `performReconnection()`, cleaning up prewarm subscriptions mid-flight and leaving positions/prices without data. 2. **Stale cache after grace-period disconnect** — `performActualDisconnection()` (fires after 20s grace period) did not clear stream channel caches or reset subscriber state (`hasReceivedFirstUpdate`). On next foreground, the old closed position was served from cache until the throttle window passed. 3. **`isPreloading` not reset on disconnect** — If a preload was in-flight when the grace period fired, `isPreloading` stayed `true`. The next `connect()` would silently skip all subscription prewarm, leaving positions and prices with no data. **Fixes:** - Remove the manager-level AppState listener (hook already handles foreground recovery) - Fix `isInternetReachable` null handling in NetInfo listener (`null` treated as offline was blocking network-restore reconnects) - Add `isPreloading` concurrency guard to `preloadSubscriptions()` to prevent concurrent calls racing on reconnect - Call `clearCache()` on all stream channels in `performActualDisconnection()` — wipes stale positions, resets `hasReceivedFirstUpdate`, puts UI into loading state on next foreground - Reset `isPreloading = false` in `performActualDisconnection()` alongside `hasPreloaded` The NetInfo listener from #26780 is kept — it handles the distinct offline→online restore scenario. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: TAT-2598 ## **Manual testing steps** ```gherkin Feature: Perps reconnection after long background Scenario: user returns to Perps after long background Given the user has open Perps positions And the app has been backgrounded for 5+ minutes When user foregrounds the app Then positions load correctly And 24h price change is displayed And closing a position succeeds without "not tradeable asset" error Scenario: closed position does not reappear after background Given the user closes a Perps position and sees the success toast And the app has been backgrounded for more than 20 seconds When user foregrounds the app Then the closed position is NOT shown in the positions list And no stale "already closed" error appears on interaction Scenario: user returns after network loss Given the user has open Perps positions And airplane mode was enabled then disabled while app was backgrounded When user foregrounds the app Then the connection is restored And positions load correctly ``` ## **Screenshots/Recordings** ### **Before** Positions blank, 24h change missing, close position fails with "BTC is not tradeable asset". Closed positions reappear after >20s background. ### **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. ## **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 Perps connection lifecycle (reconnect/disconnect, NetInfo handling, preload guards) and could impact data freshness and reconnection reliability if regressions occur, though changes are localized and well-covered by tests. > > **Overview** > Prevents a foreground reconnection race by **removing the manager-level `AppState` listener** so only the lifecycle hook initiates foreground recovery. > > Hardens reconnect/disconnect behavior by **clearing all Perps stream channel caches on grace-period expiry**, resetting subscriber `hasReceivedFirstUpdate`, and resetting the in-flight preload state (`isPreloading`) so subsequent `connect()` calls reliably prewarm subscriptions. > > Improves offline→online recovery by treating `NetInfo.isInternetReachable: null` as “unknown” and falling back to `isConnected`, and expands `PerpsConnectionManager` tests to cover these concurrency, cache-clearing, and network edge cases. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 72739b2. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> [7c541c0](7c541c0) --------- Co-authored-by: abretonc7s <107169956+abretonc7s@users.noreply.github.com> Co-authored-by: Alejandro Garcia <alejandro.garcia@consensys.net>
- fix: Ensure `redux-persist-filesystem-storage` returns a promise and throws correctly cp-7.67.2 (#26979) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** This PR adjusts our existing patch for `redux-persist-filesystem-storage` to always return a promise for `setItem` so it can be awaited correctly, fixing potential race conditions. This was broken when the patch originally was created by adding brackets to an arrow function and not returning. The PR also fixes a bug where not passing in a callback would cause errors to be swallowed. Additionally, this PR moves our existing patch to use the built-in Yarn patch feature (because creating new patches with `patch-package` seems broken). ## **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: Improve reliability of persistence ## **Related issues** Fixes: ## **Manual testing steps** ```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** <!-- 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** - [ ] 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. ## **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 persistence write behavior by changing the patched `redux-persist-filesystem-storage` `setItem` control flow and error propagation, which could affect app startup/migrations if any callers depend on the old callback-only semantics. Also introduces an iOS-only side effect (exclude-from-backup) after writes. > > **Overview** > This PR updates the Yarn patch for `redux-persist-filesystem-storage` so `setItem` **always returns a Promise** that can be awaited, rather than potentially relying on callback chaining. > > It also fixes error handling so write failures are **thrown when no callback is provided** (instead of being swallowed), and adds an optional `isIOS` flag to run `ReactNativeBlobUtil.ios.excludeFromBackupKey(...)` after successful writes on iOS. > > Dependency wiring is switched from a normal semver dependency to Yarn’s built-in `patch:` reference for `redux-persist-filesystem-storage@4.2.0`, with corresponding `yarn.lock` updates. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 192a5c8. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> [02ac109](02ac109) Co-authored-by: Frederik Bolding <frederik.bolding@gmail.com>
…27042) - chore: Bump `snaps-controllers` cp-7.67.2 (#26992) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** Bump `snaps-controllers` to the latest version which includes a mitigation for production issues where the source code of Snaps is unavailable. ## **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: Fixed an issue with running Snaps ## **Related issues** Fixes: ## **Manual testing steps** ```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** <!-- 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** - [ ] 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. ## **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** > Updates a core Snaps dependency used at runtime; even a patch bump can affect Snap execution/permissions and should be regression-tested with common Snaps flows. > > **Overview** > Bumps `@metamask/snaps-controllers` from `^18.0.1` to `^18.0.2` (with corresponding `yarn.lock` updates) to pick up the latest fixes. > > Includes a small transitive dependency update within that package (notably `@metamask/json-rpc-engine` to `^10.2.3`). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 67b823f. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> [4b57dcd](4b57dcd) Co-authored-by: Frederik Bolding <frederik.bolding@gmail.com>
# 🚀 v7.67.1 Testing & Release Quality Process Hi Team, As part of our new **MetaMask Release Quality Process**, here’s a quick overview of the key processes, testing strategies, and milestones to ensure a smooth and high-quality deployment. --- ## 📋 Key Processes ### Testing Strategy - **Developer Teams:** Conduct regression and exploratory testing for your functional areas, including automated and manual tests for critical workflows. - **QA Team:** Focus on exploratory testing across the wallet, prioritize high-impact areas, and triage any Sentry errors found during testing. - **Customer Success Team:** Validate new functionalities and provide feedback to support release monitoring. ### GitHub Signoff - Each team must **sign off on the Release Candidate (RC)** via GitHub by the end of the validation timeline (**Tuesday EOD PT**). - Ensure all tests outlined in the Testing Plan are executed, and any identified issues are addressed. ### Issue Resolution - **Resolve all Release Blockers** (Sev0 and Sev1) by **Tuesday EOD PT**. - For unresolved blockers, PRs may be reverted, or feature flags disabled to maintain release quality and timelines. ### Cherry-Picking Criteria - Only **critical fixes** meeting outlined criteria will be cherry-picked. - Developers must ensure these fixes are thoroughly reviewed, tested, and merged by **Tuesday EOD PT**. --- ## 🗓️ Timeline and Milestones 1. **Today (Friday):** Begin Release Candidate validation. 2. **Tuesday EOD PT:** Finalize RC with all fixes and cherry-picks. 3. **Wednesday:** Buffer day for final checks. 4. **Thursday:** Submit release to app stores and begin rollout to 1% of users. 5. **Monday:** Scale deployment to 10%. 6. **Tuesday:** Full rollout to 100%. --- ## ✅ Signoff Checklist Each team is responsible for signing off via GitHub. Use the checkbox below to track signoff completion: # Team sign-off checklist - [ ] Mobile Platform This process is a major step forward in ensuring release stability and quality. Let’s stay aligned and make this release a success! 🚀 Feel free to reach out if you have questions or need clarification. Many thanks in advance # Reference - Testing plan sheet - https://docs.google.com/spreadsheets/d/1tsoodlAlyvEUpkkcNcbZ4PM9HuC9cEM80RZeoVv5OCQ/edit?gid=404070372#gid=404070372
# 🚀 v7.67.2 Testing & Release Quality Process Hi Team, As part of our new **MetaMask Release Quality Process**, here’s a quick overview of the key processes, testing strategies, and milestones to ensure a smooth and high-quality deployment. --- ## 📋 Key Processes ### Testing Strategy - **Developer Teams:** Conduct regression and exploratory testing for your functional areas, including automated and manual tests for critical workflows. - **QA Team:** Focus on exploratory testing across the wallet, prioritize high-impact areas, and triage any Sentry errors found during testing. - **Customer Success Team:** Validate new functionalities and provide feedback to support release monitoring. ### GitHub Signoff - Each team must **sign off on the Release Candidate (RC)** via GitHub by the end of the validation timeline (**Tuesday EOD PT**). - Ensure all tests outlined in the Testing Plan are executed, and any identified issues are addressed. ### Issue Resolution - **Resolve all Release Blockers** (Sev0 and Sev1) by **Tuesday EOD PT**. - For unresolved blockers, PRs may be reverted, or feature flags disabled to maintain release quality and timelines. ### Cherry-Picking Criteria - Only **critical fixes** meeting outlined criteria will be cherry-picked. - Developers must ensure these fixes are thoroughly reviewed, tested, and merged by **Tuesday EOD PT**. --- ## 🗓️ Timeline and Milestones 1. **Today (Friday):** Begin Release Candidate validation. 2. **Tuesday EOD PT:** Finalize RC with all fixes and cherry-picks. 3. **Wednesday:** Buffer day for final checks. 4. **Thursday:** Submit release to app stores and begin rollout to 1% of users. 5. **Monday:** Scale deployment to 10%. 6. **Tuesday:** Full rollout to 100%. --- ## ✅ Signoff Checklist Each team is responsible for signing off via GitHub. Use the checkbox below to track signoff completion: # Team sign-off checklist - [ ] Mobile Platform This process is a major step forward in ensuring release stability and quality. Let’s stay aligned and make this release a success! 🚀 Feel free to reach out if you have questions or need clarification. Many thanks in advance # Reference - Testing plan sheet - https://docs.google.com/spreadsheets/d/1tsoodlAlyvEUpkkcNcbZ4PM9HuC9cEM80RZeoVv5OCQ/edit?gid=404070372#gid=404070372
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->
## **Description**
This PR updates the change log for 7.67.3.
<!--
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**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: null
## **Related issues**
Fixes:
## **Manual testing steps**
```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**
<!-- 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**
- [ ] 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.
## **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: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
# 🚀 v7.67.3 Testing & Release Quality Process Hi Team, As part of our new **MetaMask Release Quality Process**, here’s a quick overview of the key processes, testing strategies, and milestones to ensure a smooth and high-quality deployment. --- ## 📋 Key Processes ### Testing Strategy - **Developer Teams:** Conduct regression and exploratory testing for your functional areas, including automated and manual tests for critical workflows. - **QA Team:** Focus on exploratory testing across the wallet, prioritize high-impact areas, and triage any Sentry errors found during testing. - **Customer Success Team:** Validate new functionalities and provide feedback to support release monitoring. ### GitHub Signoff - Each team must **sign off on the Release Candidate (RC)** via GitHub by the end of the validation timeline (**Tuesday EOD PT**). - Ensure all tests outlined in the Testing Plan are executed, and any identified issues are addressed. ### Issue Resolution - **Resolve all Release Blockers** (Sev0 and Sev1) by **Tuesday EOD PT**. - For unresolved blockers, PRs may be reverted, or feature flags disabled to maintain release quality and timelines. ### Cherry-Picking Criteria - Only **critical fixes** meeting outlined criteria will be cherry-picked. - Developers must ensure these fixes are thoroughly reviewed, tested, and merged by **Tuesday EOD PT**. --- ## 🗓️ Timeline and Milestones 1. **Today (Friday):** Begin Release Candidate validation. 2. **Tuesday EOD PT:** Finalize RC with all fixes and cherry-picks. 3. **Wednesday:** Buffer day for final checks. 4. **Thursday:** Submit release to app stores and begin rollout to 1% of users. 5. **Monday:** Scale deployment to 10%. 6. **Tuesday:** Full rollout to 100%. --- ## ✅ Signoff Checklist Each team is responsible for signing off via GitHub. Use the checkbox below to track signoff completion: # Team sign-off checklist - [ ] Mobile Platform This process is a major step forward in ensuring release stability and quality. Let’s stay aligned and make this release a success! 🚀 Feel free to reach out if you have questions or need clarification. Many thanks in advance # Reference - Testing plan sheet - https://docs.google.com/spreadsheets/d/1tsoodlAlyvEUpkkcNcbZ4PM9HuC9cEM80RZeoVv5OCQ/edit?gid=404070372#gid=404070372
Contributor
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
Resolved conflicts between stable (7.67.3) and release/7.68.0: Build/version: take release/7.68.0 versions (7.68.0, build 3939) - android/app/build.gradle, ios project, bitrise.yml Dependencies: take release/7.68.0 versions - package.json: assets-controllers v100.0.3, smart-transactions v22.6.0, transaction-controller v62.19.0, transaction-pay-controller v16.1.2 - yarn.lock: take release/7.68.0 Source code: take release/7.68.0 (newer analytics hooks, nav types, auth) - DaimoPayModal, VerifyIdentity: useAnalytics over useMetrics - PerpsOrderView: removed NavigationProp generic (nav v6 prep) - Login: added useAuthCapabilities - Authentication.test: type fix (undefined as never) - babel.config.tests: added rewards/card env var exclusions Config: OTA_VERSION kept at v7.67.2 (latest from stable) Locales: take release/7.68.0 (14 language files with newer translations) Made-with: Cursor
Contributor
🔍 Smart E2E Test Selection⏭️ Smart E2E selection skipped - base branch is not main (base: release/7.68.0) All E2E tests pre-selected. |
Collaborator
|
No release label on PR. Adding release label release-7.68.0 on PR, as PR was added to branch 7.68.0 when release was cut. |
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.
Summary
This PR syncs the latest changes from
stableintorelease/7.68.0.Why is this needed?
release/7.68.0is missing 74 commits fromstable, including:Action Required
Please review and resolve any merge conflicts manually.
If there are conflicts, they will appear in this PR. Resolve them to ensure the release branch has all the latest fixes from stable.
Merge with "Create a merge commit" — do NOT squash.
Note
Medium Risk
Touches transaction/explorer navigation paths and balance-fetch fallback behavior, which can affect user routing and displayed balances across multiple networks if misconfigured.
Overview
Syncs
stableintorelease/7.68.0, bringing in recent release notes/OTA version bumps and a patched@metamask/assets-controllerschange to only synthesize zero balances when the chain was explicitly requested and supported.Updates Bridge transaction details UX so “View on block explorer” consistently opens the in-app
WEBVIEWflow (and, for bridges, routes through the Bridge modal stack), with tests adjusted accordingly. Also expands transaction details block-explorer resolution to fall back toPopularList(e.g., Arbitrum/Polygon/BNB) when the currentnetworkConfigurationslack a block-explorer URL, with new coverage inTransactionDetailstests.Written by Cursor Bugbot for commit 3f6baad. This will update automatically on new commits. Configure here.