Skip to content

release: 8.4.2 (OTA) - #34500

Open
metamask-ci[bot] wants to merge 14 commits into
stablefrom
release/8.4.2-ota
Open

release: 8.4.2 (OTA)#34500
metamask-ci[bot] wants to merge 14 commits into
stablefrom
release/8.4.2-ota

Conversation

@metamask-ci

@metamask-ci metamask-ci Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

OTA hotfix: branch release/8.4.2-ota.

  • Native semver and build version are not bumped.
  • OTA_VERSION in app/constants/ota.ts is v8.4.2.
  • CHANGELOG.md header and production git tag both use bare 8.4.2 / v8.4.2; the -ota suffix is branch-only.

Note

Medium Risk
Persisted wallet state migration and global WebSocket routing affect all users on upgrade; logic is guarded and well-tested but mistakes could drop networks or break dapp connectivity.

Overview
OTA hotfix v8.4.2 sets OTA_VERSION to v8.4.2 and updates CHANGELOG with 8.4.2 (Arc revert) and 8.4.1 (Perps pay token, WalletConnect) entries plus compare links.

Migration 148 undoes migration 145’s premature Arc network add when the entry still matches the single default Infura RPC 145 wrote (cosmetic edits still revert; custom RPC/failovers/extra endpoints or manual Arc are left alone). It removes Arc from NetworkController and NetworkEnablementController, falls back selectedNetworkClientId and mainnet enablement when Arc was the only active EVM network, and ships extensive tests.

NitroWebSocketSetup no longer replaces global.WebSocket wholesale in production: WalletConnect relay hosts (relay.walletconnect.org / .com) use React Native’s built-in WebSocket so strict handshake requirements aren’t broken by Nitro’s extra subprotocol/Origin headers (regression from 8.3.0). Dev builds keep wss:// → Nitro routing except for those hosts; installs are idempotent. Tests cover relay routing, hostname parsing edge cases, and WalletConnect’s (url, [], undefined) constructor shape.

CI restore-node-modules-permissions also chmods *-bin/* paths (e.g. Hermes hermesc) and *.sh scripts under node_modules.

Native build numbers in Android versionCode and iOS CURRENT_PROJECT_VERSION change 6291 → 6278 while app versionName stays 8.5.0 in the snippet shown.

Reviewed by Cursor Bugbot for commit 16f3f01. Bugbot is set up for automated code reviews on this repo. Configure here.

dan437 and others added 9 commits July 27, 2026 16:16
…oller cp-8.5.0 (#33822)

## **Description**

Perps orders funded with a custom pay token fail at publish with
`MetaMask Pay: Cannot submit without quote`. The publish guard is not
the cause; it is the last thing to notice a problem that starts on the
order screen.

The order amount reaches `TransactionPayController` through a chain of
effects: `depositAmount` sets the pending amount, then `amountHuman`
triggers `updateTokenAmount`. Until that lands, the required token still
has `amountRaw: "0"`. A zero required amount produces no source amounts,
so no quote is ever requested.

Nothing gates the Place Order button in that window.
`shouldBlockBecauseOfFeesLoading` only reads `isPayTotalsLoading`, which
is false because the fetch has not started, and the no-quotes alert
cannot fire because it needs a non-empty `sourceAmounts`. Tapping there
sends an unfunded deposit to publish, which correctly rejects it.

Logs from a local build show the window lasting about three seconds
after the payment token changes, with loading false, no quotes, and the
required amount still zero. The app even emits `Perp Trade Quote
Received` with `status: success` and `0ms` latency during it.

This change treats a stale pay amount as "not ready", so the CTA stays
disabled until the controller has the real amount. Predict already
solved the same problem with its `isPaySystemSettling` machine in
`usePredictBuyConditions`; Perps never had an equivalent. Porting that
machine over is the fuller fix and is worth a follow-up, but this keeps
the hotfix small and cannot leave the button stuck, because the amount
always arrives.

The publish guard is left exactly as it is. It is the correct backstop,
and loosening it would only turn a visible error back into a silent
unfunded deposit.

## **Changelog**

CHANGELOG entry: Fixed a bug that stopped some Perps orders from being
placed when paying with another token

## **Related issues**

Fixes: CONF-1731

## **Manual testing steps**

~~~gherkin
Feature: Perps order paying with another token

  Scenario: user taps Place Order before the pay amount is ready
    Given the user opens a Perps market and chooses Long
    And the user changes "Pay with" to a token that is not Arbitrum USDC

    When the user taps Place Order as soon as the button looks tappable
    Then the button stays disabled until the fees have settled
    And no "Cannot submit without quote" error is raised

  Scenario: user places the order after the fees settle
    Given the user selected a custom pay token
    And the fees and quote have finished loading

    When the user taps Place Order
    Then the deposit and order are submitted as before

  Scenario: user pays from the existing Perps balance
    Given the Perps balance is selected as the payment method

    When the user taps Place Order
    Then the order is placed directly with no deposit transaction
~~~

## **Screenshots/Recordings**

N/A — no visual change. The only difference is that an existing button
stays disabled for a few seconds longer while the pay amount propagates.

### **Before**

Tapping Place Order in the window right after changing the pay token
fails with a "Deposit failed" toast. Reproduced on `main` with debug
logging, which captured the full chain: the pay state with `amountRaw:
"0"` and no executable quote, the publish-guard throw `MetaMask Pay:
Cannot submit without quote`, and the failed transaction with no hash.
The same user-facing toast also reproduces on 8.2.0 from a real device,
before that publish guard existed, so the ungated CTA window predates
8.3.0; the guard only made the failure visible.

### **After**

The button remains disabled through that window and the order submits
normally once the quote is ready. Verified on this branch with the same
logging: the window still appears, with loading false, no quotes and a
zero amount for about three seconds, but no tap reaches publish, no
guard error is raised, and no toast is shown.

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches Perps order submission gating and MetaMask Pay readiness for
custom tokens; logic is narrow but user-facing on a money path.
> 
> **Overview**
> Fixes a race where **Place Order** could stay enabled right after
switching to a custom pay token, because quote loading was still false
while `TransactionPayController` still had `amountRaw: "0"` and never
requested a quote—leading to **Cannot submit without quote** on publish.
> 
> `PerpsOrderView` now reads **`useTransactionPayRequiredTokens`** and
treats a stale pay amount (`amountRaw === '0'` for tokens that are not
`skipIfBalance`) as **not ready**, alongside existing pay-quote loading.
That **`isPayStateNotReady`** flag feeds
**`shouldBlockBecauseOfFeesLoading`** and fee-loading UI for
custom-token flows only; paying from the Perps balance is unchanged.
> 
> Tests mock required tokens and assert the button stays disabled with a
zero amount, enables once a real amount arrives, ignores zero amounts
when balance covers the token, and does not block Perps-balance orders.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
1e58769. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…33962)

- fix: route WalletConnect relay through built-in WebSocket (#33871)

## **Description**

**What:** Routes `relay.walletconnect.org` / `relay.walletconnect.com`
through React Native's built-in WebSocket instead of the Nitro adapter
(hostname match, both prod and dev installs). Every other endpoint keeps
the Nitro transport, so the performance work from #32472 is untouched.

**Why:** #32472 (shipped in 8.3.0) replaced `global.WebSocket` with
`react-native-nitro-websockets`. Its Android native layer
(`WebSocketConnection.cpp` `connect()`) sends `Sec-WebSocket-Protocol:
nitro-ws` (libwebsockets transmits `lws_client_connect_info.protocol` as
that request header) and an `Origin` header set to the server's own host
on every connection whose caller requested no subprotocol — which is
exactly what WalletConnect's transport does (`new WebSocket(url, [],
undefined)`). The WalletConnect relay rejects that handshake, the relay
socket never opens, `pairing.pair()` never settles, and every
WalletConnect connection on Android 8.3.0 hangs on the "Connecting to
MetaMask…" sheet. Lenient endpoints (e.g. HyperLiquid feeds) ignore the
extra headers, which is why all other websocket features work and this
slipped through.

[Slack thread where the issue is first

surfaced](https://consensys.slack.com/archives/C08U6DYNJ1G/p1785165035226969)

Android-only because the package's iOS implementation
(`NWWebSocketConnection.mm`, NSURLSession) only sets
`Sec-WebSocket-Protocol` when protocols are actually requested and sets
no Origin.

Root-cause proof (A/B test on emulator): with only the relay host routed
through the built-in WebSocket and everything else on Nitro, the relay
connects immediately and the session proposal → approval →
`wc_sessionSettle` flow completes end-to-end (verified from the dapp
side via CDP).

A follow-up to fix the Android native layer itself (bind the lws
callback via `local_protocol_name`, leave `protocol` null when no
subprotocol is requested, drop the fabricated `Origin`) is tracked in
WAPI-1574; once that lands this bypass can be removed.

## **Changelog**

CHANGELOG entry: Fixed WalletConnect connections hanging forever on
Android.

## **Related issues**

Fixes:
[WAPI-1574](https://consensyssoftware.atlassian.net/browse/WAPI-1574)

Refs: #32472

## **Manual testing steps**

Feature: WalletConnect pairing on Android

  Scenario: user connects a dapp via WalletConnect
    Given MetaMask Android (8.3.0 or main) with an unlocked wallet

When user taps WalletConnect → MetaMask on
https://metamask.github.io/test-dapp/ (or Hyperliquid) and approves the
permissions sheet
Then the loading sheet resolves, the session settles, and the dapp shows
the connected account

  Scenario: other websocket consumers stay on Nitro
    Given the fix applied

    When user opens Perps and Predictions (Polymarket)
Then prices and positions still update live over the Nitro WebSocket
transport

## **Screenshots/Recordings**

### **Before**

WalletConnect relay socket fails on every attempt; `pairing.pair()`
never settles; "Connecting to MetaMask…" sheet hangs indefinitely.

### **After**

Relay connects immediately; session proposal → approval → settle
completes; dapp receives `wc_sessionSettle` within a second of approval.

## **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.

[WAPI-1574]:

https://consensyssoftware.atlassian.net/browse/WAPI-1574?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches global `WebSocket` routing used by WalletConnect and all `wss`
traffic; behavior is well-tested but any hostname-routing bug could
affect connectivity or regress Nitro performance paths.
> 
> **Overview**
> Fixes Android WalletConnect hangs by **not** sending
`relay.walletconnect.org` / `relay.walletconnect.com` through the Nitro
WebSocket adapter, which adds handshake headers the relay rejects.
> 
> **Production** no longer replaces `global.WebSocket` with Nitro only.
It installs a **routing constructor** that keeps Nitro for compatible
`wss` URLs and delegates WalletConnect relay URLs (and non-string URLs
like `URL` objects) to React Native’s built-in `WebSocket`. **Dev**
keeps `ws://` on the built-in socket and `wss://` on Nitro, but applies
the same relay bypass for `wss` relay hosts.
> 
> Hostname matching is done with a lightweight `getWsHostname` parser
(ports, userinfo, query-string false positives). Re-install is
**idempotent** via a symbol so Fast Refresh/tests don’t nest wrappers.
Missing built-in `WebSocket` still falls back to bare Nitro but now
**logs a warning** that relay routing is lost.
> 
> Tests cover relay routing in dev and prod, other hosts staying on
Nitro, WalletConnect’s `(url, [], undefined)` shape, and the no-built-in
warning.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
4558569. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
[80fcbb9](80fcbb9)

[WAPI-1574]:
https://consensyssoftware.atlassian.net/browse/WAPI-1574?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

Co-authored-by: Alex Donesky <adonesky@gmail.com>
Runway bumped your version to 8.4.1

Co-authored-by: runway-github[bot] <73448015+runway-github[bot]@users.noreply.github.com>
…33979)

- feat(perps): block place order until the pay amount reaches the
controller cp-8.5.0 (#33822)

## **Description**

Perps orders funded with a custom pay token fail at publish with
`MetaMask Pay: Cannot submit without quote`. The publish guard is not
the cause; it is the last thing to notice a problem that starts on the
order screen.

The order amount reaches `TransactionPayController` through a chain of
effects: `depositAmount` sets the pending amount, then `amountHuman`
triggers `updateTokenAmount`. Until that lands, the required token still
has `amountRaw: "0"`. A zero required amount produces no source amounts,
so no quote is ever requested.

Nothing gates the Place Order button in that window.
`shouldBlockBecauseOfFeesLoading` only reads `isPayTotalsLoading`, which
is false because the fetch has not started, and the no-quotes alert
cannot fire because it needs a non-empty `sourceAmounts`. Tapping there
sends an unfunded deposit to publish, which correctly rejects it.

Logs from a local build show the window lasting about three seconds
after the payment token changes, with loading false, no quotes, and the
required amount still zero. The app even emits `Perp Trade Quote
Received` with `status: success` and `0ms` latency during it.

This change treats a stale pay amount as "not ready", so the CTA stays
disabled until the controller has the real amount. Predict already
solved the same problem with its `isPaySystemSettling` machine in
`usePredictBuyConditions`; Perps never had an equivalent. Porting that
machine over is the fuller fix and is worth a follow-up, but this keeps
the hotfix small and cannot leave the button stuck, because the amount
always arrives.

The publish guard is left exactly as it is. It is the correct backstop,
and loosening it would only turn a visible error back into a silent
unfunded deposit.

## **Changelog**

CHANGELOG entry: Fixed a bug that stopped some Perps orders from being
placed when paying with another token

## **Related issues**

Fixes: CONF-1731

## **Manual testing steps**

~~~gherkin
Feature: Perps order paying with another token

  Scenario: user taps Place Order before the pay amount is ready
    Given the user opens a Perps market and chooses Long
    And the user changes "Pay with" to a token that is not Arbitrum USDC

    When the user taps Place Order as soon as the button looks tappable
    Then the button stays disabled until the fees have settled
    And no "Cannot submit without quote" error is raised

  Scenario: user places the order after the fees settle
    Given the user selected a custom pay token
    And the fees and quote have finished loading

    When the user taps Place Order
    Then the deposit and order are submitted as before

  Scenario: user pays from the existing Perps balance
    Given the Perps balance is selected as the payment method

    When the user taps Place Order
    Then the order is placed directly with no deposit transaction
~~~

## **Screenshots/Recordings**

N/A — no visual change. The only difference is that an existing button
stays disabled for a few seconds longer while the pay amount propagates.

### **Before**

Tapping Place Order in the window right after changing the pay token
fails with a "Deposit failed" toast. Reproduced on `main` with debug
logging, which captured the full chain: the pay state with `amountRaw:
"0"` and no executable quote, the publish-guard throw `MetaMask Pay:
Cannot submit without quote`, and the failed transaction with no hash.
The same user-facing toast also reproduces on 8.2.0 from a real device,
before that publish guard existed, so the ungated CTA window predates
8.3.0; the guard only made the failure visible.

### **After**

The button remains disabled through that window and the order submits
normally once the quote is ready. Verified on this branch with the same
logging: the window still appears, with loading false, no quotes and a
zero amount for about three seconds, but no tap reaches publish, no
guard error is raised, and no toast is shown.

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling

guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user

SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and

[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance

Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches Perps order submission gating and MetaMask Pay readiness for
custom tokens; logic is narrow but user-facing on a money path.
> 
> **Overview**
> Fixes a race where **Place Order** could stay enabled right after
switching to a custom pay token, because quote loading was still false
while `TransactionPayController` still had `amountRaw: "0"` and never
requested a quote—leading to **Cannot submit without quote** on publish.
> 
> `PerpsOrderView` now reads **`useTransactionPayRequiredTokens`** and
treats a stale pay amount (`amountRaw === '0'` for tokens that are not
`skipIfBalance`) as **not ready**, alongside existing pay-quote loading.
That **`isPayStateNotReady`** flag feeds
**`shouldBlockBecauseOfFeesLoading`** and fee-loading UI for
custom-token flows only; paying from the Perps balance is unchanged.
> 
> Tests mock required tokens and assert the button stays disabled with a
zero amount, enables once a real amount arrives, ignores zero amounts
when balance covers the token, and does not block Perps-balance orders.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
1e58769. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
[e817797](e817797)
The zip artifact path used by the EAS/OTA pipelines strips Unix executable
bits, so consumers rely on restore-node-modules-permissions to put them back.
Its globs required an exact "bin" path segment, which never matched the
platform-suffixed directories hermes-compiler uses (linux64-bin, osx-bin,
win64-bin). Metro spawns that binary directly during bundling, so OTA pushes
failed with EACCES once React Native 0.83.6 moved hermesc out of the
react-native package, where it had lived under sdks/ and was covered
incidentally.

Also covers *.sh scripts, which are spawned directly by Xcode build phases
and packager helpers and carry the same exposure on this path.

Co-authored-by: Cursor <cursoragent@cursor.com>
…s (8.4.1) (#34005)

## **Description**

Backport of #34004 to unblock the `8.4.1` OTA release.

**This backport is required separately** because CI composite actions
resolve from the checked-out branch, not from `main`. `Runway OTA RC` is
dispatched against `release/8.4.1-ota`, so it uses that branch's copy of
`.github/actions/restore-node-modules-permissions` — meaning the `main`
fix alone does not affect this release.

Failing run:
https://github.com/MetaMask/metamask-mobile/actions/runs/30454324689/job/90593099632

```
Error: spawn .../node_modules/hermes-compiler/hermesc/linux64-bin/hermesc EACCES
```

Both `Push EAS Update (iOS)` and `Push EAS Update (Android)` fail at
Metro bundling because `hermesc` lost its executable bit in the zip
artifact round-trip and the permission-restore globs required an exact
`bin` path segment, never matching `hermes-compiler`'s `linux64-bin` /
`osx-bin` / `win64-bin` layout.

Full root-cause analysis, blast-radius review, and testing notes are in
#34004.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: OTA push for 8.4.1

  Scenario: Runway OTA RC after backport
    Given this PR is merged into release/8.4.1-ota
    When Runway OTA RC is re-run for 8.4.1
    Then Push EAS Update (iOS) and (Android) bundle without EACCES
```

After merge, re-run **Runway OTA RC** for `8.4.1`.

## **Screenshots/Recordings**

### **Before**

N/A

### **After**

N/A

## **Note for other release branches**

`release/8.4.0` and `release/8.5.0` carry the same combination (RN
`0.83.6` plus the un-patched action) and will hit this on their next OTA
push, so they likely want the same backport.

## **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.

Made with [Cursor](https://cursor.com)
#34493)

since 148 not in prod yet we "swapped" and set `148.ts` as THIS FIX and
old 148.ts becomes 149.ts. This way, cherry-picks will be easier and
numbering will be preserved.

**Context:**

Back in June, migration 145 added the Arc network to every user's
NetworkController state ahead of schedule (it was meant for a mid-June
release; Arc now ships mid-September). Migrations run sequentially and
can't be retroactively removed, so 145 still runs for anyone on it.

As a result, some users a now seeing Arc as enabled network on their
account, when it should have been hidden - unless added manually.

Note that this is unrelated to Feature Flags: Although Arc is turned off
via Feature Flags added networks aren't affected by Feature Flags
whitelists or blacklist, only non-added Networks are. This means that
when Arc was added (by the user or by migration 145) it will show to the
user regardless of Feature Flags. This is a known behavior, not a bug.
The issue is that the network is enabled when it shouldn't have been.

**Solution:**

New Migration 149:
- Undoes 145's effect, but only where the resulting Arc network
configuration has the RPC URL that has been set by 145. When other RPC
URLs, it will be considered as a "custom network" addition - user added
network manually and network was not auto-added.
- Also falls back selectedNetworkClientId to `mainnet` if the user
happened to be on the removed Arc client, mirroring the existing
precedent in migration 111.
- And manually enables `mainnet` in the unlikely event where Arc is the
only enabled network.

<!--
Please submit this PR as a draft initially.

Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.

In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.

  type=text           Section must contain non-placeholder prose.
  type=changelog      Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
                      comment but do not block the PR.

Sections without a directive are checked for structural presence only.
-->

<!-- mms-check: type=text required=true -->

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution? -->

<!-- mms-check: type=changelog required=true blocking=true -->

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: prevent Arc from showing as added for some users

<!-- mms-check: type=issue-link required=true -->

Fixes: https://consensyssoftware.atlassian.net/browse/WPN-1803

Case 1: Gradual upgrades
- Install release 7.81.0 on a fresh state (new account with seed phrase)
and setup account.
- Install release 8.1.0 ontop of existing install (triggers migration
145) -> Arc is enabled when it shouldn't.
- Install build from this PR ontop of existing install -> Arc should not
be enabled (and should not be in the default list either).

Case 2: Skip-the-line upgrades
- Install release 7.81.0 on a fresh state (new account with seed phrase)
and setup account.
- Install build from this PR ontop of existing install -> Arc should not
be enabled (and should not be in the default list either). Essentially
both migration 145 and this fix migration should run in sequence and Arc
should never appear to the user.

Case 3: Custom network preserved
- Install release 7.81.0 on a fresh state (new account with seed phrase)
and setup account.
- Add Arc manually as a custom network (Ex: with dummy RPC).
- Install build from this PR ontop of existing install -> Arc should
still be enabled with user-specific configuration.

<!-- mms-check: type=screenshot required=true -->

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

<!-- [screenshots/recordings] -->

<!-- [screenshots/recordings] -->

<!-- mms-check: type=checklist required=true -->

<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.

Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding

Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`. -->

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches persisted network and enablement state on upgrade; logic is
guarded and well-tested but a mistaken match could remove Arc or leave
users without an enabled network if edge cases are wrong.
> 
> **Overview**
> Adds **migration 148** to undo migration 145’s premature Arc network
auto-add for users who still have the untouched default Infura RPC
(`arc-mainnet.infura.io/v3/...`). It removes Arc from
`NetworkController` and `NetworkEnablementController`, resets
`selectedNetworkClientId` to mainnet when the user was on Arc, and
force-enables mainnet if Arc was the only enabled EVM network.
> 
> **User-customized Arc is preserved:** different RPC URLs, failover
URLs, extra endpoints, or manual adds are left unchanged; cosmetic edits
(name, currency, explorer) still allow reversion when the private RPC is
unchanged. Revert is skipped when `MM_INFURA_PROJECT_ID` is missing or
the literal `"null"`. Invalid controller state is validated with Sentry
reporting; enablement cleanup is skipped when that controller is invalid
or missing.
> 
> Registers migration **148** in the migrations index and adds broad
unit tests (including 145→148 sequence).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
a3ca586. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->



<!--
Please submit this PR as a draft initially.

Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.

In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.

  type=text           Section must contain non-placeholder prose.
  type=changelog      Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
                      comment but do not block the PR.

Sections without a directive are checked for structural presence only.
-->

## **Description**

<!-- mms-check: type=text required=true -->

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!-- mms-check: type=changelog required=true blocking=true -->

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry:

## **Related issues**

<!-- mms-check: type=issue-link required=true -->

Fixes:

## **Manual testing steps**

<!-- mms-check: type=manual-testing required=true -->

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- mms-check: type=screenshot required=true -->

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

<!-- mms-check: type=checklist required=true -->

<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.

Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

#### Performance checks (if applicable)

- [ ] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

Co-authored-by: maxime-oe <maxime.ouairy-ext@consensys.net>
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
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.

tommasini
tommasini previously approved these changes Aug 7, 2026
@tommasini tommasini added the rc-freeze Freeze auto release candidate builds label Aug 7, 2026
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

🚀 RC Builds Ready for Testing

Platform Link Version
iOS TestFlight Go to TestFlight and download build Unknown
Android Download from CI RC 8.4.2 (Unknown) — download APK artifact from the linked run
More Info
  • Version: 8.4.2
  • iOS Build Number: Unknown
  • Android Build Number: Unknown
  • Build Pipeline: View Pipeline

🍒 What's in this RC

Cherry-picks (22 commits)
Commit Description
0d81232cf3 Merge branch 'stable' into release/8.4.2-ota
b56e0b1093 release: 8.5.0 (#33734)
fad67ee863 release: final commit of 8.5.0
21a489a8a8 fix: restore Stellar/Arc bridge-controller patches cp-8.5.0 (#34019)
296950a77c chore(runway): cherry-pick fix: bump bridge controllers to prevent stale dest exchange rates (#34016)
35e9936291 chore(runway): cherry-pick fix: show Coinbase ramp orders in Activity when network is a name string cp-8.5.0 (#34013)
8f3e2d9264 chore(runway): cherry-pick chore: New Crowdin Translations by GitHub Action (#34014)
ceec30f79e chore(runway): cherry-pick feat(support): adopt support consent flow in AccountsMenu and AppInformation (#33936)
bb6755998c chore(runway): cherry-pick fix: remove duplicated bottom inset on the Activity screen cp-8.5.0 (#33942)
d08fdc03d5 chore(runway): cherry-pick revert: "feat: temporary 10-year anniversary app icon cp-8.5.0 (#33938)
199a834115 chore(runway): cherry-pick fix: remove default placeholder on price alerts cp-8.5.0 (#33913)
60718a8d65 chore(runway): cherry-pick fix: remove gap between symbol and price change on default token card watchlist cp-8.5.0 (#33897)
6050f53b12 chore(runway): cherry-pick feat: make watchlist row draggable cp-8.5.0 (#33896)
85127a8c58 chore(runway): cherry-pick feat(perps): block place order until the pay amount reaches the controller cp-8.5.0 (#33867)
4ba1db2058 Merge branch 'stable' into release/8.5.0
b046dbaeff release(cp): fix: restored old behavior to show Paid by MetaMask label in sponsored transactions from activity page cp-8.4.0 (#33778)
b8545cefad chore(runway): cherry-pick fix(activity): cp-8.5.0 fix bottomsheet positioning when activity is a tab (#33855)
f7c18e8383 chore(runway): cherry-pick fix(money): skip insufficient-funds alert on Max money account deposit (#33847)
d0bee37bcc chore(runway): cherry-pick fix: reorder TDP header icons cp-8.5.0 (#33835)
e08e2d11b0 chore(runway): cherry-pick fix: delegate RemoteFeatureFlagController for Accounts API balance v6 cp-8.5.0 (#33800)
ae3d7ab6f5 chore(runway): cherry-pick fix(money): show keyboard and resolve amount for fiat deposit flows cp-8.5.0 (#33795)
247eb4f9a9 release: release-changelog/8.5.0 (#33735)

Changelog (372 commits from main at RC cut)
Commit Description
534f6b4140 chore: adds Quick Buy numeric keypad vs slider A/B test (#33605)
5dc2cf650d test: MMQA-1992: Migrate smoke/fixtures Detox tests to Appium (#33507)
aa3cab8d60 test: MMQA-1991: Migrate smoke/deeplinks Detox tests to Appium (#33709)
76a29fa7df feat(support): add support consent flow core mechanism (#33424)
6ba5b090f0 feat: improve money account upgrade process cp-8.4.0 (#33427)
8d512234a7 chore(perps): opt in useNavigation to AppNavigationProp (Phase 4) (#33385)
531f925616 feat: bump transaction-pay-controller to 26.0.0 (#33719)
2fec7d955c feat(perps): add Pro order form UI (#33630)
3fb766b440 feat(agentic-cli): nudge push permission after CLI QR login (#33688)
72390ea48c fix: patch bridge controller to remove Stellar and Arc cp-8.4.0 (#33684)
934cc5d9cc chore: bump react-native-view-shot to 5.1.1 (#33603)
1b34461a29 feat: add watchlist drag and drop functionality (#33677)
e632dc202d refactor(Transactions): convert class component to functional component with hooks (#33578)
98a8cc9b35 refactor(homepage): remove trending sections A/B test and update related components (#33496)
c4cd940943 fix: show preparation state for Money Account deposits cp-8.4.0 (#33325)
32f25072ff feat: add item type extraction for list components (#33691)
c7db92788e fix(predict): route withdrawals by wallet type (#33551)
231f1a3739 chore: adds MarketCap to position cards in social Feed (#33706)
f54537a31e fix(money): show skeleton while money account resolves on home card (MUSD-1196) (#33698)
30133c23a5 fix: use text locator for Appium QR sync import-from-extension link (#33703)
fcfdbf94d8 chore: migrate assets-list selector to BigInt (ASSETS-3719) (#33700)
ba460487af chore: prefix token watchlist analytics event names (#33705)
4a135889ed feat(money): add instrumentation for money account api data service (#33701)
decd744d7a feat: support new notification services controller + segment schema (#31204)
b7e90803a3 chore: update watchlist instrumentation (#33675)
50d79e6070 chore: bump @metamask/tron-wallet-snap to ^1.33.1 (#33660)
c380719388 fix: skip calldata encoding for initial deposit batch creation (#33582)
9c7915495e fix: gate amount+fees balance check to money-account withdrawals only cp-8.4.0 (#33654)
4537ff26fa chore: bumps for assets-controllers and core-backend (#33651)
ac9b692bab chore(component-library): remove unused TextWithPrefixIcon component (#33511)
ddc5aba88c chore(component-library): remove unused SelectOption component (#33510)
dd593f4785 chore: migrate marketDetails and CollectibleOverview to BigInt (#33692)
2e66cef203 fix: label trader position CTA as Trade (#33697)
4c93620bc9 chore(component-library): remove unused SheetActions temp component (#33509)
c88ab64c7c feat(money): centralize money account balance fetching (#33516)
0a8b272a87 fix: monad assets not appearing in explore cp-8.4.0 (#33614)
14fc85f518 test: MMQA - 2025 - [Mobile] Remove antipatterns from helpers/multichain-accounts/common.ts file (#33571)
f8340eaf9b feat(perps): add reusable Lite/Pro mode toggle across entry points (#33572)
e269bfc937 refactor(perps): migrate Text and SensitiveText to MMDS (#33663)
5e87676cf1 feat: polish add-device / QR account sync UX. (#33564)
a2e70b85cf fix: skip failing tests (#33687)
d68e729c0b fix: transak native fallback for different env (#33553)
6ca0b48242 fix(bridge): tighten fiat/crypto toggle hit target (#33674)
5fdb70c757 test: Add MMC IAB tests (#31946)
647bf3b32f chore(swaps): graduate post-trade modal A/B test (#33626)
d73dde174e feat: add watchlist star to swap flow (#33566)
90dc66f6f1 chore: New Crowdin Translations by GitHub Action cp-8.4.0 (#33342)
f4af7a3a5c fix: remove approval text in swaps (#33668)
2c00f3e16c fix(ramps): resolve POL buy failure from token details page (TRAM-3713) (#33542)
49fc527619 test(onboarding): add fresh SRP wallet performance coverage (#33324)
e5cb9fb56f test(watchlist): add component view tests and framework support (#33609)
74dbb8d4aa chore(predict): opt in useNavigation to AppNavigationProp (Phase 4) (#33458)
cd436a6f5e chore(rewards): opt in useNavigation to AppNavigationProp (Phase 4) (#33453)
f47a66c98e perf(predict): memoize merged chart data (#33477)
cde83155f4 fix: Vertically center pressable Toast content (#33640)
20270b3f6a feat(perps): scaffold pro mode market layout (PerpsProMarketView) (#33560)
1d76e28d33 fix: Polish token contract copy toast icon styling (#33629)
34134361b3 chore: upgrade design system packages (v55.0.0) (#33653)
da9f3723ac refactor(perps): align PerpsPositionCard and PerpsCard with MMDS ListItem (#33552)
9c52b7e1f8 test: add component view and integration tests for tracking perps close poisition metric (#33647)
760a8028b8 fix(wallet): gate balance empty state on real refresh settlement (MUSD-1195) (#33589)
1d44eab738 chore: migrate deriveBalanceFromAssetMarketDetails to BigInt (ASSETS-3717) (#33644)
74385ec5e2 refactor: remove Cash section and update token filtering logic (#33638)
88493da3b2 perf(money): reduce Money Home and activity re-renders (MUSD-1205) (#33646)
6c4315643e style(locales): convert all-caps UI strings to sentence case (#26285)
809a08dbe0 refactor(perps): remove orphaned dead code modules (#33470)
4365f65136 feat(activity): add first-class RampsOrder support in Activity (#33624)
448e6915e7 chore: bump @metamask/tron-wallet-snap to ^1.33.0 (#33636)
3f4e3286c6 chore: remove AssetOverview Price files from util/number burndown (#33633)
e483210962 fix(perf): reflect quality gate failures in Slack category status (#33631)
0d7f7fa74f test: MMQA - 2024 - [Mobile] Remove unused methods in WalletView.ts (#33568)
de03ffcfd5 refactor: make ImportFromSecretRecoveryPhrase React Compiler compatible (#33503)
67089afe5f fix(agentic-cli): remove double top-inset on iOS AgenticCliDashboardWebview header (#33635)
4df245a3ab feat(Stellar): add Stellar related chain utils (#33480)
0313028d12 test: MMQA-2003: Migrate smoke/stake Detox tests to Appium (#33632)
7184677c4f fix: misalignment on copy button (#33591)
9d8f40a922 refactor: resolve React Compiler issues on Onboarding screen (#33482)
626583d902 refactor: make ImportNewSecretRecoveryPhrase React Compiler compatible (#33485)
fd2ec53cd5 fix: Polish perps toast for new animation (#32943)
801a438f35 refactor: merge new and recently added lists, add new pill to products (#33302)
745d8f806f chore: remove AB test for verified badge, permanently show verified b… (#33539)
8beb8007c5 refactor: Improve recently viewed ux (#33543)
30f61049cf Chore/use expo babel transformer (#33619)
04f6ce33a7 docs(Engagement): Update deeplinking doc callout (#33610)
d3b3fd4b75 feat(card): add Immersve UK SIWE auth re-entry (#33608)
4ad3bd0c21 chore: bump assets controller to v11.1.0 cp-8.3.1 (#33612)
084957e321 chore(bridge): opt in useNavigation to AppNavigationProp (Phase 4) (#33547)
c93c2a780e release: sync stable to main for version 8.3.0 (#33613)
f4950d896b feat: integrate STX failTransaction fix (bridge stuck-pending) (#33175)
d2ba1d5a69 feat(activity): clearer Activity swap & bridge row content (#33538)
df181160a5 feat(bridge): redesign bridge transaction details behind transactions-redesign flag cp-8.4.0 (#33471)
aff843fef5 perf(predict): memoize market feed items (#33475)
cc54d60ba4 chore(card): opt in useNavigation to AppNavigationProp(Phase 4) (#33441)
21e79b0964 test(perf): stabilize Appium performance metrics and flaky readiness probes (#33216)
86f07ca13f feat(activity): show account name and avatar for owned accounts in activity list (#33390)
f4a568e4fe feat: consume backend-suggested slippage in unified swap/bridge (#33431)
0c83bf18ae feat(confirmations): block hardware wallets for money account deposits (#32952)
c45035b316 refactor(perps): migrate Activity list and FillTag to MMDS (#33555)
f5b411671d refactor(perps): migrate market row to MMDS ListItem (#33554)
1b052812db refactor(perps): migrate HIP-3 debug view to MMDS components (#33452)
aa9ed4bbad fix: prevent deposit page auto-navigating to result page during editing (#33505)
2e628849ca fix(predict): stabilize parameterized selectors with weakMapMemoize (#33215)
ede6ab74fa fix: move watchlist section after predictions (#33601)
d01fed2e4d fix: Polish money toast for new animation (#32946)
78027390ce chore: remove world cup from explore (#33594)
14e36113cb fix: display 'Debit' instead of 'Debit or Credit' in MM Pay UI (#33513)
6024250fd6 feat(card): add Immersve CardHome read and sensitive details (#33557)
c583c2ebdd fix(predict): show net sell proceeds after fees cp-8.4.0 (#33449)
5af1095ded fix(money): rename "Money account benefits" heading to "Benefits" (MUSD-1197) (#33592)
c2fbf2d9c8 chore: remove backgrounds from money earn banner images cp-8.4.0 (#33584)
edf8031c3d fix(money): keep activity filter tabs stationary on selection (MUSD-1194) (#33586)
29dbcc511c feat: kick off money upgrade process in modal stack (#33587)
f3af5635aa feat(predict): add any-token withdraw Appium coverage (CONF-918) (#33490)
c8460abb03 chore: bump @react-native-community/slider to 5.2.0 (#33474)
9710d930e0 chore: bump react-native-safe-area-context to 5.8.0 (#33472)
e2826d16cb fix: Polish earn, quick-buy, rewards and gas toast for new animation (#32947)
68641eacfa fix(pay): auto-navigate to results page on Max press (#33532)
695dd604e3 chore: bump lottie-react-native to 7.3.8 (#33473)
232f642b07 fix: canonicalize typed-sign data to prevent display/signing divergence (#33187)
39f02f2058 feat(perps): show caret icon in market header clickable area cp-8.4.0 (#33495)
22d68a9327 chore: update black resources for Insights animation cp-8.4.0 (#33581)
64dfb41b19 revert: remove watchlist star filter from Trending Tokens (#33579)
aac38c85fc fix(money): prevent large balances overlapping Add button on Money card (MUSD-1183) (#33504)
9b131a8080 fix: always skip initial gas estimate for Money Account transactions (#33577)
cf1156b16e fix: Polish predict toast for new animation (#32945)
11b4152275 fix: Update DS legacy toast with iOS animation and UI polish (#32933)
a0b1a5199a feat: wire watchlist search functionality (#33530)
10c8db85fe refactor(perps): migrate market details Stats to MMDS KeyValueColumn (#33550)
2b410f8ee2 refactor(perps): migrate Cancel All Orders sheet to MMDS (#33358)
e01ff7de6c feat: add branded share token info sheet on token details (#33319)
d696ba1a1e chore: AB test Buy action (QuickBuy vs Swaps) on Top Traders token screen + feed cp-8.4.0 (#33508)
bca9a43889 fix: invalid JSON RPC errors and reduce Linea calls on wallet unlock (6 -> 2) (#33514)
c34c72b96f feat: add watchlist full empty view (#33492)
bb65abc092 refactor(onboarding): remove A/B test configurations and related components for onboarding checklist stepper (#33483)
55bcd39e7a test: MMQA - 2022 - [Mobile] Fix anti-patterns in flows/accounts.flow.ts (#33487)
a5ac016f86 feat: add QR sync SRP e2e inject path (#33238)
a12e01c403 fix: Update Base Notification toast with iOS animation and UI polish (#32938)
88142bd335 fix: react compiler issues on ChoosePassword and ManualBackupStep1 (#33481)
57018ba3c9 feat(card): add Immersve KYC webview and funding approval (#33548)
da95959b2e chore(ramp): opt in useNavigation to AppNavigationProp (Phase 4) (#33439)
e04b029f2f fix: wire tempMigrateAssetsInfoMetadataAssets3346 into AssetsController init (#33015)
65ed619300 refactor: Aligned more section across wallet and perps (#33391)
ddd741a666 fix: show token letter fallback in activity details avatar (#33467)
eb82e05240 feat(card): add Immersve funding and spending prerequisites (#33540)
6a24a7d580 fix(activity): stop rescaling human-readable ramp buy/sell amounts (#33537)
ed232b8197 chore: bump axios to ^1.18.0 to resolve moderate security advisories (#33541)
dc7702adde feat(card): add Immersve provider foundation (SIWE) (#33515)
864a026bcc chore: patch @metamask/assets-controller for suggested occurrence floors (#33411)
a6f4d69366 fix: remove whole redux state pass through for bridge selectors (#33529)
b0c757a90f fix(ramps): restore RAMPS_TRANSACTION_CONFIRMED for UB2 flows (TRAM-3738) (#33012)
0e85a6d473 chore(component-library): remove unused ListItemMultiSelectWithMenuButton temp component (#33506)
6353d274a8 chore: remove unused HeaderStandardAnimated from components-temp (#33502)
d2a18a46e0 fix: cp-8.4.0 prevent FullWindowOverlay from hiding iOS accessibility tree for Toaster (#33454)
1364bea143 feat: price alert percentage feature (#33339)
e9da46e649 refactor: Migrate transactions/withdraw/deposit progress bar to MMDS and move them above Perps title (#33361)
ce57501c7c fix: android foreground notifications (#33468)
7881e981d0 fix(money): reduce per-keystroke overhead in deposit amount screen (MUSD-1180) (#33465)
5a2edb3188 fix: update push notification content (#33103)
2f63a49452 chore: QuickBuy update direction property as trade_type (#33486)
119acda1c8 fix(money): remove "Steps" heading for single-step mUSD transfers (MUSD-1160) (#33195)
c4085d8dee chore: improve performance of the network selector (#33500)
a0732d2904 fix(money): reduce Add/Transfer bottom sheet open latency (MUSD-1161) (#33210)
2389459356 perf(predict): replace per-card 1s connection-status polling with shared subscription (#33259)
ed7f2f638d fix(money): suppress amount-update error toast on dismissed confirmation (MUSD-1188) (#33491)
bc734cd89a test: remove card detox test (#33484)
cabbe0cd5c feat: add watchlist fullscreen view (#33287)
fed77e9b6a test: MMQA-1996: Migrate smoke/notifications Detox tests to Appium (#33409)
c7b3054f7f feat(stellar): add trustline support in transaction history (#33479)
f09ae8e87c fix(ramps): dynamic per-provider BottomSheet background for checkout WebView (TMCU-1087) (#33429)
99dadfe1c1 chore: migrate Jest preset to @react-native/jest-preset (#33201)
9bc1b132cf chore: replace removed ContextContainer::Shared alias in JNI registry (#33214)
937890b6d4 chore: bump react-native-get-random-values to 2.0.0 (RN 0.85 New Arch) (#33323)
49a35ec205 chore: bump react-native-screens to 4.25.2 (#33121)
23aef41730 chore: bump react-native-svg to 15.15.5 and retarget patch (#33118)
4e58e96efc fix: cp-8.3.0 Fix return undefined token fiat amount instead of locking 1 (#33461)
6df2cbef88 chore(nav): type wallet, asset, and settings shell navigators (Phase 3) (#33306)
d27d2ec148 release: Bump main version to 8.5.0 (#33460)
48fe005243 chore: upgrade MMDS to v54.0.0 (#33455)
8cf01447e6 fix: incorrect non-evm url in useActivityBlockExplorer (#33396)
653aa5fe43 chore(nav): type Money and Ramp nested navigators with NavigatorScreenParams (phase 3) (#33227)
a13e871841 feat: add star icon on trending tokens (#33421)
cccf5bf1d6 chore: remove BUILDS_ENABLED_WITH_GH_ACTIONS_TEMPORARY flag (#32825)
cb3cd9385b chore: Revert "chore: Use expo babel transformer (#33082)" (#33440)
c14a7ba0ee feat(money): add Earn with Money account banner on supported token detail pages (MUSD-1177) cp-8.4.0 (#33412)
ad0f2ea959 feat(home): add homepage 8-button action grid AB test (#33388)
2a7bf19b47 refactor(confirmations): migrate GasFeeTokenModal to MMDS BottomSheet (#33229)
a149195b67 fix: use getPerpsDisplaySymbol on recently viewed rail cp-8.4.0 (#33436)
38781cabd8 refactor(perps): migrate Close All Positions sheet to MMDS (#33365)
9c89318d61 refactor(perps): use MMDS BannerAlert for service interruption banner (#33364)
83b08999eb perf: fix redundant RPC calls on wallet unlock (cache network health metadata + deprecate legacy balance polling) (#33379)
d5d87bf1a9 fix: pure black splash background in dark mode (iOS/Android) (#33360)
ceed3d49f9 refactor(perps): migrate provider selector UI to MMDS (#33363)
f7f64e21f8 ci: request workflows:write for crowdin translation token exchange (#33403)
f736d82ad0 chore(earn): type Earn navigators with feature param lists (Phase 3) (#33291)
ff2a6dfeec fix: raw token amounts shown in asset details activity list (#33211)
4290439de8 perf: unnecessary API calls and NFT performance issues on homepage focus (#33122)
257f20f946 chore: update follow count (#33418)
d4301edd7d fix(activity-redesign): render non-EVM swap/bridge rows with the redesigned row style (#33376)
58ae96f8ff chore: adds label for open feed rows with "Holding" / "Open" (#33404)
7a1497bc80 fix: MUSD deposit from money home page cp-8.3.0 (#33423)
90ce3cffc0 feat: integrate Sentry into QR account sync receive flow (#33316)
59950aa31e chore: emit chain name on follow-trading token events (#33349)
8e5f3a3f81 perf(earn): use memoized selectPendingApprovalIds instead of isEqual … (#33181)
fc817265a2 test: migrate card tests to appium (#33407)
d675c5e831 fix(predict): hide empty related-tag sub-tabs via activeEventsCount cp-8.3.0 (#33399)
92562db632 feat(perps): consume perps controller analytics contract in MetaMask Mobile (#33095)
c904468821 chore: memoize Swaps QuoteRow rendering (#33392)
ce85d95c49 fix(money): skip first-deposit celebration for funded restored accounts (MUSD-903) (#33335)
43eb516ad3 feat(perps): make market detail header identity a tight tap target (#33414)
a9de3d7f27 fix(perps): make market detail price/change row scroll instead of sticky (#33408)
25e0e9b9b3 fix(predict): route Popular Today to Trending cp-8.3.0 (#33373)
19a5383b64 perf(predict): stop REST price polling while live market feed is connected (#33261)
fef858cec8 feat: add support for batch sell on swaps reconciler (#33400)
5a9cc973ca fix: Windows (Git Bash) local development environment compatibility (#33138)
3dccec5762 feat: MUSD-1147 add money account apy to stablecoin earn cta (#33226)
2cb9a53156 fix: Bump react-data-query (#33402)
56721d1849 fix(activity): show one row for gasless sends with token gas fee (#33284)
c261334604 fix(predict): Design QA feedback to the redesigned Predict home and feed cp-8.3.0 (#33382)
24bacc603b perf(login): fix React Compiler blockers in Login screen (#33271)
0230e2cf66 fix(predict): Fix sports card outcome ordering (#33275)
f6dc2d58a6 perf: use createSelector in selectSelectedInternalAccount (#32792)
ff37bcbec7 feat: TDP new theming AB test (#33249)
285cd2e4e3 fix: allow isAuthenticating updates on frozen SecureKeychain (#33406)
db5c0d05d5 fix: guard Nitro Fetch headers check when Headers is unavailable (#33224)
3caf94cb55 fix(e2e): seed SOL into AssetsController for homepage network filter smoke (#33410)
daeee3b39f fix(money): fund Add mUSD via MM Pay fiat deposit instead of standalone Ramps (MUSD-1164) (#33338)
ca991e6a75 ci: run Linux CI on Namespace shadow behind NAMESPACE_SHADOW_LINUX_AUTO_DISPATCH (#33387)
52f3842c68 fix(money): update transaction data when pay token changes on deposit (#33395)
e9c295ede6 chore: support deprecating controller by controller (#33368)
eb29aa1281 fix(predict): remove redundant Live filter chip (#33383)
dd7bf15e81 feat: read stablecoins from stable-tokens LD flag in useTokenFiatRates cp-8.3.0 (#33251)
955fd0a6ff fix: show realized PnL on closed perp feed rows (#33356)
38e16cd043 chore: Use expo babel transformer (#33082)
d7606c0aa3 chore: Upgrade @metamask/delegation-controller from ^2.0.2 to ^3.0.0 (#29834)
e7c210488d chore: open trader position view from feed card tap (#33344)
322dd16d64 chore(send): type Send navigator with feature param list (Phase 3) (#33303)
cef38729cf Revert "feat(perps): enable RoE sign toggle on Auto Close TP/SL (#324… (#33375)
273908b6aa fix(money): show projected 1-year balance in USD (MUSD-1173) cp-8.3.0 (#33333)
5f2cab7c51 chore: migrate to DS slider and use haptics (#33290)
e2b7b1d0e6 chore(bridge): type Bridge navigators with feature param lists (Phase 3) (#33292)
81d497cfe3 chore(card): type Card navigators with feature param lists (Phase 3) (#33283)
c16d9c7580 fix(perps): show long orders in Activity and dedupe perps deposits + clean up (#33235)
5baa9a24cc fix(perps): use live price subscription for header display in trade/close screens (#33099)
8fe6ed511b revert: remove eslint/tsc CI caching (unsafe for cross-file lint rules) (#33370)
96abde95e9 feat: social leaderboard opt out (#32982)
e2db41a167 chore(nav): type Rewards nested navigator with NavigatorScreenParams (#33231)
42e2c2b121 chore(nav): type Predict nested navigators with NavigatorScreenParams (#33219)
8623e6f2a9 fix: ui 'no networks fee' label align center in additional networks (#32898)
35524572cc ci: request workflows:write for release changelog token exchange cp-8.3.0 (#33352)
ed92a6d57d fix(confirmations): use elevated surface on Advanced EIP-1559 modal (#33301)
0017c399e2 test: Wait for top toast before account picker in multi-srp Appium smoke (#33348)
20c7af54f8 refactor: remove unused styles and simplify PhoneCountrySelectorModal… (#33350)
db494587d1 feat(perps): redesign market detail header (TAT-3348) (#33024)
d95691f4c8 fix: MUSD-1175 MetaMask Card "Avail. balance" incorrectly changes based on preferred fiat currency cp-8.3.0 (#33293)
c59a71b642 refactor(engine): wire TransactionController into @metamask/wallet init (#32937)
60905c52f8 chore: update navigation for final step (#33326)
2ef73f3664 fix: cp-8.3.0 convert pay-flow token amounts to USD instead of relabeling (#33321)
dc305bfe56 chore: update trader feed events to match segment-schema (#33320)
234a6829b8 feat: block MetaMask Pay submissions without quotes and handle no-op quotes cp-8.3.0 (#33194)
2df685ca7e feat: migrate mobile-core-ux files from BN.js to native BigInt (#32824)
91b0f055ab test: MMQA-2000: Migrate smoke/ramps Detox tests to Appium (#33334)
ccce7d74d6 fix(predict): Trending too few markets & unstable count cp-8.3.0 (#33336)
d836d925d7 chore: deprecate ActionModal and confirmations BottomModal (#33309)
f40f575903 fix(confirmations): use elevated surface color for TextWithTooltip modal in Pure Black mode (#33300)
94bcd0bab1 fix(confirmations): use elevated surface for edit spending cap modal (#33299)
8a4a01f28c fix(confirmations): use elevated surface color in AdvancedGasPriceModal (#33297)
cdbc2efbb5 fix(confirmations): use elevated surface for AlertModal in Pure Black mode (#33298)
fcab1e8c6b fix(confirmations): use elevated surface color in ConfirmAlertModal for Pure Black (#33296)
fa65c36a22 fix(confirmations): use elevated surface color for value detail modal in Pure Black (#33242)
ea4ea5cc65 fix(confirmations): align Edit network fee sheet with elevated surfaces (#33294)
fb1708de36 fix(confirmations): use elevated surface for CustomNonceModal in Pure Black (#33239)
5d9466a042 fix(money): show USD amounts in Money toasts (MUSD-1174) (#33330)
c3a56fb1fe fix(money): keep Add mUSD tappable and route to Ramps when user has no mUSD (MUSD-1164) (#33250)
a27c73b875 feat(perps): add limit-order support to close position flow cp-8.3.0 (#33197)
9f499fb006 fix(ci): use content-based eslint cache strategy for reliable CI hits (#33327)
887370fcaf fix(predict): use correct payload for dynamic market subscriptions cp-8.3.0 (#33289)
f088cd1d34 chore: relax-price-api-condition-legacy-chart and update to time based index (#33204)
53996cdef5 fix(ci): resilient BrowserStack main reuse + fallback upload (#33277)
da9a364eed chore: New Crowdin Translations by GitHub Action cp-8.3.0 (#33009)
25ef31a7c3 docs: Add deprecation message to BaseNotification (#33123)
def77468b2 feat: show already-synced sheet on duplicate SRP re-sync (#33245)
9bcbf43731 ci: cache eslint and tsc results between ci runs (#33304)
285a54b663 test(perps): remove redundant MMDS BottomSheet mocks (#33288)
d29e494729 fix: oversubscription perps top movers (#33150)
158c8a3361 fix(design-system): remove useElevatedSurface shim from ActionListItem (#33163)
e6d3842193 fix: inject Sentry Debug IDs during Metro bundling (#33220)
f6da752451 chore: bump bridge and bridge status controller for transaction_internal_id in Unified SwapBridge Completed (#33286)
4d571e301b feat: temporary 10-year anniversary app icon cp-8.3.0 (#33280)
c4cb337879 ci: add changelog lint to catch malformed CHANGELOG.md (#33117)
d0795b6291 perf(bridge): migrate token selector to FlashList (#33230)
687f8075cb fix(swaps): backfill sparse post-trade suggestions (#33273)
c4ef40c5da fix(android): share state logs as file attachment instead of path string (#33281)
6411d21cd0 fix: show correct pending status in post strade modal cp-8.3.0 (#33279)
7f340f9e14 fix(money): open all Money account external links in the in-app browser (MUSD-1168) (#33256)
148d14ec5e test: add first integration test - Perps (#29749)
e2928774f2 refactor(perps): migrate Set slippage BottomSheet to MMDS (#33243)
b25f5ac7a2 test: MMQA-2004: Migrate smoke/swap Detox tests to Appium (#33247)
2e564e36ac chore: adds trader feed analytics events (#33252)
0ee3ace5fe fix(perps): horizontally center candle period filter buttons (#33237)
343ba5aaba feat(ramp): Headless Buy all-providers Phase 1 - in-app providers (dev-gated) (#32682)
6e619fd68e fix(activity): stuck confirmation on back after tx + missing lending deposit token icon cp-8.3.0 (#33157)
28a226411b perf(predict): replace RN Image with expo-image across Predict components (#33207)
a23ce45194 feat(money): update Money onboarding Rive animation to v24 (#33260)
d05336bf2e fix(activity): resolve speed-up/cancel dead-end and correct cancelled/failed rows cp-8.3.0 (#33071)
0b264c4c98 fix: include hyperliquid chain in trader feed fetch (#33254)
7317565b53 feat: scam questionnaire on malicious internal send flows (#30717)
65eb9a30e0 fix(money): Activity list amount does not match transaction detail page for mUSD send on Monad (MUSD-1169) (#33258)
d2026ac943 fix(money): correct mUSD casing and list it first on Monad in FAQs (MUSD-1158) (#33190)
a19809e2d4 perf: fix useMemo rest-param dependency in useSDKMethod so stringifiedParams actually memoizes (#32728)
4d61ccc302 feat: add home section watchlist (#33213)
dfef18cd12 test: Add 14 Sell flow CVT tests (#32620)
4fde051106 ci(MMQA-1667): skip native builds when PR only changes E2E/performance tests (#33180)
ac5b30b41b perf(predict): Cache homepage position-row icons with expo-image (#33208)
2684ed12c4 feat: save custom gas settings (#31649)
d5f686adda test: Update Predict E2E to wait for top toast dismiss before back tap (#33244)
cffcbe655e fix(confirmations): use elevated surface for confirmation tooltip modal (#33241)
025842a685 fix(pure-black): align Advanced details Expandable sheet with other elevated sheets (#33152)
2a5ef46f95 fix(confirmations): elevate GasFeeTokenModal surface for pure black claim bonus (#33173)
4a8ff95b4a fix(money): show mUSD withdrawal sends as mUSD instead of mUSD → USDC (MUSD-1159) (#33200)
db43869aa1 fix(money): prevent skeleton jitter and account row flash in card deposit flow (MUSD-1130) (#33039)
ed792c154e fix(snaps): Add missing UI components (#33246)
47b160716d feat(perps): show ticker next to market name in market list rows (#33191)
bb247708df ci(INFRA-3680): rename bot references from mm-token-exchange-service to metamask-ci (#33189)
27e90628f1 refactor: simplify layout nesting for OAuthrehydration, SRP error, and QR scanner (#33179)
fd7785dd44 feat: adds follow trading feed (#33115)
dd2d6f09e0 chore: bump @metamask/tron-wallet-snap to ^1.31.0 cp-8.3.0 (#33225)
2f6b4ea6d8 test(e2e): MMQA-2005 migrate trending smoke tests from Detox to Appium (#32940)
8571c4a5b6 feat: ResetPassword component to improve reauthentication flow and error handling to be react-compiler compatible (#31965)
5c106385ef feat: add new ledger device selection (#30671)
5f89af5ad9 feat(perps): enable RoE sign toggle on Auto Close TP/SL (#32404)
a957368fed fix(ramp): keep amount input visible when opening provider picker (#33132)
11ad8b794f fix(TMCU-1054): remove bg-default from NetworkVerificationInfo root (#33174)
fafc95101b chore: integrate fast-mode stream channel for focus screen views (#32556)
ffd1406246 fix(swaps): clear stale quote before opening batch sell cp-8.3.0 (#33221)
17af786de5 perf(qr): fix React Compiler blockers in QR and network cluster (#32778)
f551ffc05b fix(predict): show retryable error instead of $0 when balance fails to load (#32907)
27cb37022a fix(TMCU-1048): Remove redundant useElevatedSurface from MMDS BottomSheet callsites (#33159)
7719fa3f59 feat: introduce advanced chart analytics (#32365)
9aad058871 feat: recently viewed market list (#32999)
f010f9d598 ci: remove unused error handling during setup (#33218)
ab8d680a5c ci: verbose setup during CI (#33151)
b06f0f6188 fix(pure-black): Network pill and enabled-network list styling (#33143)
2b6e1bddac test: MMQA-1987: Migrate smoke/account-activity Detox tests to Appium (#33196)
64e149d0c0 refactor(market-insights): migrate entry card and disclaimer sheet to use MMDS components (#32861)
088d336c02 chore: update flag default value (#33209)
597b8037cb fix: better check for tron native asset cp-8.3.0 (#33206)
a1e8b199ff refactor(perps): migrate PerpsOrderTypeBottomSheet to MMDS (#33081)
921b70e4d9 feat: implement non prefix ids backwards compatiblity on ramps (#32819)
2eeab87bde fix(settings): translate getAuthLabel authentication labels (#33203)
9400c7f2c3 feat: QrSync syncing metadata (#32502)
f55b27285e feat(social-leaderboard): add TopTraders onboarding flow (#32820)
f388912d0c feat: Bump Snaps packages (#33202)
70977adff1 perf(predict): only fetch market data for the active feed tab (#32935)
801e05c110 feat(transaction-pay-controller): support metamask pay alternate caveats (#32738)
f39f661677 feat: Add minimal analytics for redesigned Predict Home V2 (#32697)
3505b358d7 perf(predict): memoize PredictPositionRow on homepage (#33185)
78a2d326f6 test: MMQA-1995: Migrate smoke/networks Detox tests to Appium (#32804)
c21e66e9cc perf: derive accounts/evmAccounts with useMemo instead of state+effect (#32721)
056a3fdc47 fix(predict): stop reporting transient network errors to Sentry (#33184)
6f0e4fd19b refactor: simplify layout nesting for backup, import, and password screens (#33177)
bb00f4705a feat: prefill token amount to be deposited in MM Pay amount page (#32889)
24080df13e feat: add watchlist star in token details (#32962)
e5e6ae04a7 feat: add more interval support for token details (#33054)
758f4d258e chore: add Quick Buy original_entry_point for trade-screen attribution (#33034)
135e7935de fix: spam warning modal not showing up cp-8.3.0 (#33154)
12f8b0e679 feat: update legend indicator subpane v2 (#33108)
6d8bd7f6f1 refactor(AgenticCliApproval): update approval page path and clean up tests- cp-8.3.0 (#33036)
d8ec071815 fix: import srp password keyboard done (#33171)
458ad3ace4 fix: MUSD-1165 Inconsistency with asset names (#33140)
30a9546f74 feat: MUSD-1140 add sentry tracing for money account balance service network requests (#32995)
1ffca01a97 fix(money): sync activity list row status with transaction toasts (MUSD-1129) (#33125)
c65d38a89a fix(money): pin activity list date headers to design format (MUSD-1125) (#33119)
---

AI Test Plan

Risk Score High Risk Medium Risk Files Changed Teams Signed Off
57/100 7 4 7 0/0
Executive Summary

Release Focus: OTA hotfix 8.4.2 that reverts the prematurely-added Arc network from all user wallets and fixes a WalletConnect regression introduced in 8.3.0 by routing WalletConnect relay hosts through the native WebSocket instead of Nitro.

Key Changes:

  • Migration 148 removes the Arc network (added prematurely by migration 145) from NetworkController state, but only when the user has not customized it; users who modified Arc's RPC, added failovers, or added it manually are unaffected
  • Migration 148 also resets selectedNetworkClientId to 'mainnet' if the user was actively connected to the Arc network at migration time
  • Migration 148 cleans up Arc entries from NetworkEnablementController's enabledNetworkMap to fully remove Arc from all controller state
  • NitroWebSocketSetup now maintains a NITRO_INCOMPATIBLE_HOSTS blocklist (relay.walletconnect.org and relay.walletconnect.com) that forces those hosts through React Native's built-in WebSocket, fixing WalletConnect pairing hangs on Android
  • WebSocket routing logic was refactored into a reusable createRoutingWebSocket factory with idempotency guards (NITRO_ROUTING_INSTALLED symbol) to prevent double-wrapping on Fast Refresh

Critical Areas: WalletConnect pairing and session establishment on Android after the Nitro WebSocket routing fix, Arc network removal migration correctness across all user state variants (default config, customized config, Arc as selected network), Network switching and RPC endpoint integrity after migration 148 runs, NetworkEnablementController state consistency post-migration, WebSocket routing correctness ensuring non-WalletConnect wss:// connections still use Nitro

Overall Risk: HIGH

Recommendation: Conditional go — the WalletConnect fix and Arc network removal are both critical correctness changes that directly impact user-facing functionality. All high-risk scenarios around WalletConnect pairing on Android, migration state integrity, and network switching must pass before release. The migration's guard logic (isDefaultArcConfiguration) must be verified against real device state to ensure no unintended data loss for users who customized Arc.

Release Scenarios (11)

High Risk Scenarios (7)

1. WalletConnect

Risk Level: HIGH

Why This Matters: NitroWebSocketSetup.ts introduced NITRO_INCOMPATIBLE_HOSTS containing relay.walletconnect.org and relay.walletconnect.com. The Android Nitro native layer was injecting a 'nitro-ws' subprotocol header and a fabricated Origin header that caused WalletConnect's strict relay server to reject the handshake, leaving pairing permanently hung (WAPI-1574). The fix routes these hosts through RN's built-in WebSocket via isNitroIncompatibleUrl(). If the hostname extraction (getWsHostname) or the Set lookup is wrong, the regression persists on Android.

Preconditions:

  • Android device running the 8.4.2 build
  • A WalletConnect-compatible dApp is accessible (e.g., app.uniswap.org or any WC v2 dApp)
  • User has at least one account with ETH on mainnet
  • No existing active WalletConnect sessions in the app

Test Steps:

  1. Open MetaMask Mobile on Android and navigate to the Browser or use a WalletConnect URI from an external dApp
  2. Initiate a WalletConnect v2 pairing by scanning a QR code or pasting a wc:// URI — verify the connection loading sheet appears
  3. Wait up to 15 seconds — verify the loading sheet resolves and does NOT hang indefinitely (this was the regression in 8.3.0)
  4. Confirm the session proposal screen appears showing the dApp's name, icon, and requested permissions
  5. Tap 'Connect' and approve the session — verify the dApp shows a connected state and MetaMask shows the active session
  6. Trigger a transaction from the dApp (e.g., a token approval or swap) — verify the MetaMask transaction confirmation sheet appears promptly
  7. Approve the transaction — verify it is submitted and the dApp receives the signed result
  8. Navigate to Settings > WalletConnect sessions — verify the session is listed and can be disconnected cleanly

Expected Outcomes:

  • WalletConnect pairing completes within 10 seconds without hanging on the loading sheet
  • Session proposal is displayed correctly with dApp metadata
  • Transaction requests from the dApp surface in MetaMask without delay
  • Session disconnect works cleanly with no orphaned state

2. WalletConnect

Risk Level: HIGH

Why This Matters: The createRoutingWebSocket factory now uses a NITRO_ROUTING_INSTALLED symbol to prevent double-wrapping on Fast Refresh. Multiple concurrent WebSocket connections to WalletConnect relays must all be routed through the built-in WebSocket. If the routing wrapper is applied multiple times or the idempotency guard misfires, concurrent sessions could use different WebSocket implementations causing inconsistent behavior.

Preconditions:

  • Android device running the 8.4.2 build
  • An existing WalletConnect v2 session was established before this test (carry over from previous scenario or pre-established)
  • A second WalletConnect-compatible dApp available for a new pairing

Test Steps:

  1. Open MetaMask Mobile on Android with an existing active WalletConnect session
  2. Verify the existing session is still active and functional by triggering a read operation from the connected dApp
  3. Initiate a second WalletConnect pairing with a different dApp using a new wc:// URI
  4. Verify the second pairing completes without affecting the first session
  5. Switch the active account in MetaMask — verify both WalletConnect sessions receive the accountsChanged event
  6. Switch the network to Polygon — verify both sessions receive the chainChanged event
  7. Disconnect the first session from Settings > WalletConnect — verify only that session is removed
  8. Verify the second session remains active and functional

Expected Outcomes:

  • Multiple concurrent WalletConnect sessions work without interference
  • Account and network change events propagate to all connected dApps
  • Individual session disconnect does not affect other sessions

3. WalletConnect

Risk Level: HIGH

Why This Matters: The NITRO_INCOMPATIBLE_HOSTS blocklist and getWsHostname extraction logic runs on both platforms. While the Nitro header bug was Android-specific, the routing code change affects iOS too. Verifying iOS WalletConnect and that other wss:// connections still use Nitro ensures the routing predicate (shouldUseNitro) correctly inverts the incompatibility check.

Preconditions:

  • iOS device running the 8.4.2 build
  • A WalletConnect-compatible dApp accessible
  • User has at least one account

Test Steps:

  1. Open MetaMask Mobile on iOS and initiate a WalletConnect v2 pairing via QR code or URI
  2. Verify the pairing completes successfully and the session proposal screen appears
  3. Approve the session and verify the dApp shows connected state
  4. Trigger a transaction from the dApp and verify the confirmation sheet appears
  5. Approve the transaction and verify it is submitted successfully
  6. Open a wss:// WebSocket connection from a dApp that is NOT WalletConnect (e.g., a price feed) — verify it connects successfully using Nitro
  7. Verify that ws:// connections (Metro HMR in dev, or any plain ws endpoint) still route through the built-in WebSocket
  8. Disconnect the WalletConnect session and verify clean teardown

Expected Outcomes:

  • WalletConnect works on iOS (should be unaffected since the Nitro header issue was Android-specific, but routing logic change applies to both platforms)
  • Non-WalletConnect wss:// connections continue to use Nitro adapter
  • ws:// connections continue to use built-in WebSocket

4. Network Management

Risk Level: HIGH

Why This Matters: Migration 148 deletes networkConfigurationsByChainId[ARC_CHAIN_ID] when isDefaultArcConfiguration() returns true. This is a destructive state mutation. If the migration runs incorrectly or the isDefaultArcConfiguration guard has a bug, users could lose their Arc network entry even if they customized it, or conversely, Arc could remain when it should be removed. The migration also cleans NetworkEnablementController state.

Preconditions:

  • Device that previously ran MetaMask Mobile version 8.4.0 or 8.4.1 (which applied migration 145 adding Arc network)
  • User has NOT customized the Arc network entry (default RPC endpoint from migration 145, no failover URLs, no additional endpoints)
  • User's selected network is NOT Arc (e.g., currently on Ethereum mainnet)

Test Steps:

  1. Update the app to 8.4.2 — migration 148 should run automatically on first launch
  2. Navigate to Settings > Networks — verify the Arc network is NO LONGER listed in the network list
  3. Verify Ethereum Mainnet is still present and correctly configured with its original RPC endpoints
  4. Verify other previously added custom networks (Polygon, Arbitrum, etc.) are still present and unmodified
  5. Tap on Ethereum Mainnet to switch to it — verify the switch succeeds and the wallet shows mainnet balance
  6. Send a small test transaction on mainnet — verify gas estimation works and transaction submits successfully
  7. Check the network selector dropdown — verify Arc does not appear as an option
  8. Navigate to Settings > About and verify the app version shows 8.4.2

Expected Outcomes:

  • Arc network is completely removed from the network list after migration
  • All other networks remain intact with correct RPC configurations
  • Network switching and transactions work normally post-migration
  • No error banners or crash on first launch after update

5. Network Management

Risk Level: HIGH

Why This Matters: Migration 148 explicitly handles the case where selectedNetworkClientId === arcNetworkClientId by resetting it to 'mainnet'. If this reset fails or the arcNetworkClientId comparison is incorrect, the app would reference a non-existent network client, potentially causing crashes or blank wallet state on every launch.

Preconditions:

  • Device that previously ran MetaMask Mobile with migration 145 applied
  • User had Arc network as their SELECTED/ACTIVE network at the time of update (selectedNetworkClientId points to Arc's networkClientId)

Test Steps:

  1. Before updating, confirm the active network is Arc (visible in the network selector at the top of the wallet)
  2. Update the app to 8.4.2 — migration 148 runs and should reset selectedNetworkClientId to 'mainnet'
  3. On first launch after update, verify the app does NOT crash or show an error about an unknown network
  4. Verify the active network has been automatically switched to Ethereum Mainnet
  5. Verify the mainnet balance is displayed correctly for all accounts
  6. Navigate to Settings > Networks — verify Arc is not listed
  7. Attempt to send a transaction on mainnet — verify the flow works end-to-end
  8. Switch to another network (e.g., Polygon) and back to mainnet — verify network switching works normally

Expected Outcomes:

  • App launches without crash when previously selected network (Arc) no longer exists
  • Active network is automatically and silently switched to Ethereum Mainnet
  • Wallet displays correct mainnet balances immediately
  • No orphaned network state causes subsequent network operations to fail

6. Network Management

Risk Level: HIGH

Why This Matters: The isDefaultArcConfiguration() guard in migration 148 is the critical safety valve that prevents data loss for users who intentionally configured Arc. The migration comment explicitly states: 'if the user replaced/removed that RPC endpoint, added a failover to it, added an additional endpoint, or added Arc manually with their own RPC, that's a real customization and the network is left alone entirely.' Any bug in this guard could silently delete user-configured network data.

Preconditions:

  • Device that previously ran MetaMask Mobile with migration 145 applied
  • User has CUSTOMIZED the Arc network entry in one of these ways: renamed it, changed the native currency symbol, added a block explorer URL, OR added a failover URL to the RPC endpoint, OR added a second RPC endpoint

Test Steps:

  1. Before updating, note the exact customizations made to the Arc network (name, currency, block explorer, additional RPC endpoints)
  2. Update the app to 8.4.2 — migration 148 should detect customization and leave Arc intact
  3. On first launch, verify the app launches without crash
  4. Navigate to Settings > Networks — verify the Arc network IS STILL PRESENT with all customizations preserved
  5. Verify the Arc network's RPC endpoints, name, currency, and block explorer URLs match what was set before the update
  6. If Arc was the selected network, verify it remains the selected network
  7. Attempt to switch to Arc and verify the network switch succeeds
  8. Verify other networks are unaffected

Expected Outcomes:

  • Customized Arc network is preserved exactly as configured by the user
  • No customization data is lost during migration
  • Arc remains selectable and functional if user had customized it
  • Migration correctly identifies customization via isDefaultArcConfiguration() returning false

7. Network Management

Risk Level: HIGH

Why This Matters: Migration 148 has a separate code path to clean up NetworkEnablementController state. The migration warns and skips this step if NetworkEnablementController state is missing or invalid. If Arc remains in the enabledNetworkMap after migration, it could cause UI inconsistencies or errors in dApp permission flows that enumerate enabled networks.

Preconditions:

  • Device that previously ran MetaMask Mobile with migration 145 applied
  • User has Arc network with default configuration (as added by migration 145)
  • User has enabled Arc in the NetworkEnablementController (Arc appears in the enabled networks list for EIP-155 namespace)

Test Steps:

  1. Before updating, verify Arc is enabled in the network enablement settings
  2. Update the app to 8.4.2
  3. On first launch, verify the app launches without crash or warning banners
  4. Navigate to any screen that lists enabled networks (e.g., account permissions, network selector)
  5. Verify Arc does not appear in any enabled networks list
  6. Verify no stale Arc chain ID entries exist in the EIP-155 namespace map
  7. Connect to a dApp and verify the network permissions sheet does not show Arc as an option
  8. Verify that enabling/disabling other networks still works correctly after the migration

Expected Outcomes:

  • Arc is fully removed from NetworkEnablementController's enabledNetworkMap
  • No orphaned Arc entries in the EIP-155 namespace map
  • Network enablement UI works correctly for all remaining networks
  • dApp network permission flows do not reference Arc

Medium Risk Scenarios (4)

1. Network Management

Risk Level: MEDIUM

Why This Matters: Migration 148 has an early exit: if ARC_CHAIN_ID is not in networkConfigurationsByChainId, it returns immediately. Fresh installs should never have had Arc added (migration 145 would have added it, but fresh 8.4.2 installs skip 145 since they start at the latest migration). Verifying this path ensures the migration's hasProperty guard works correctly.

Preconditions:

  • Fresh install of 8.4.2 (no prior migration 145 ever ran)
  • User imports a wallet or creates a new one

Test Steps:

  1. Install 8.4.2 fresh and complete onboarding (create or import wallet)
  2. Navigate to Settings > Networks — verify Arc network does NOT appear in the default network list
  3. Verify Ethereum Mainnet, Linea Mainnet, and other default networks are present
  4. Add a custom network manually — verify the add network flow works correctly
  5. Switch between networks — verify network switching works
  6. Send a test transaction on mainnet — verify the full send flow works
  7. Check that migration 148 ran without errors (no Sentry exceptions for migration 148)
  8. Verify the app version displays 8.4.2 in Settings > About

Expected Outcomes:

  • Arc network never appears for fresh installs (migration 148 exits early via hasProperty check)
  • All default networks are present and functional
  • Custom network addition works normally
  • No migration errors logged for fresh install state

2. Network Management

Risk Level: MEDIUM

Why This Matters: Migration 148 uses cloneDeep on the entire state and then performs targeted deletions on networkConfigurationsByChainId. While the migration only targets ARC_CHAIN_ID, any bug in the cloneDeep or state reconstruction could corrupt adjacent network configurations. This scenario validates that non-Arc network data is completely unaffected.

Preconditions:

  • Device running 8.4.2
  • User has multiple custom RPC endpoints configured for Ethereum mainnet
  • User has custom networks added beyond the defaults

Test Steps:

  1. Navigate to Settings > Networks and note all configured networks and their RPC endpoints
  2. For Ethereum mainnet, verify all custom RPC endpoints are intact
  3. Switch between different RPC endpoints for mainnet — verify each endpoint connects successfully
  4. Navigate to a custom network and verify its RPC configuration is unchanged
  5. Add a new custom network with a custom RPC URL — verify it is added successfully
  6. Switch to the new custom network — verify connection succeeds
  7. Remove the newly added custom network — verify removal works
  8. Verify the default network list is restored correctly after removal

Expected Outcomes:

  • All pre-existing custom RPC endpoints are preserved after migration
  • RPC endpoint switching works for all networks
  • Adding and removing custom networks works normally
  • No RPC configuration data was corrupted by migration 148

3. Transactions

Risk Level: MEDIUM

Why This Matters: The NitroWebSocketSetup refactor changes how ALL WebSocket connections are routed, not just WalletConnect. The shouldUseNitro predicate now uses isNitroIncompatibleUrl() which returns true for WalletConnect hosts and false for everything else. If the logic is inverted or the hostname extraction fails for edge-case URLs, non-WalletConnect wss:// connections could be incorrectly routed to the built-in WebSocket, degrading performance for price feeds and other real-time data.

Preconditions:

  • Android device running 8.4.2
  • User has ETH balance on Ethereum mainnet
  • A recipient address is available for testing

Test Steps:

  1. Navigate to the Send flow and enter a recipient address
  2. Enter an ETH amount and proceed to the confirmation screen
  3. Verify gas estimation loads correctly and displays a fee
  4. Submit the transaction and verify it appears in the activity feed as pending
  5. Wait for confirmation and verify the transaction status updates to confirmed
  6. Open a DeFi dApp in the browser that uses WebSocket price feeds (not WalletConnect relay)
  7. Verify the price feed WebSocket connects and updates in real time (confirming non-WalletConnect wss:// still uses Nitro)
  8. Initiate a swap or approval from the dApp and verify the MetaMask confirmation sheet appears

Expected Outcomes:

  • Send transaction flow works end-to-end on Android
  • Gas estimation is accurate and loads without errors
  • Non-WalletConnect WebSocket connections (price feeds, etc.) work correctly via Nitro
  • dApp-initiated transactions surface correctly in MetaMask

4. App Stability

Risk Level: MEDIUM

Why This Matters: Migration 148 is registered in migrations/index.ts and will run once for all users upgrading from any version where migration 148 has not yet run. The migration uses captureException from Sentry for error reporting. A failed migration that throws an unhandled exception could leave the app in an inconsistent state. The cloneDeep at the start of migrate() is the safety net — verifying the upgrade path with complex state ensures no edge cases in the migration logic cause data corruption.

Preconditions:

  • Device running 8.4.1 that has migration 145 applied
  • App is being updated to 8.4.2 (upgrade scenario, not fresh install)
  • User has a complex wallet state: multiple accounts, multiple networks, active WalletConnect sessions

Test Steps:

  1. Before updating, note the current state: active network, account balances, WalletConnect sessions, custom networks
  2. Update the app to 8.4.2 and launch it
  3. Verify the app launches without crash and migration 148 completes silently
  4. Verify all accounts are present with correct balances on the previously active network
  5. Verify all custom networks (excluding Arc if it was default) are still configured
  6. Check that any active WalletConnect sessions are still listed (they may need re-pairing but should not crash)
  7. Navigate through the main wallet screens (Home, Activity, Browser) — verify no crashes or blank screens
  8. Force-close and relaunch the app — verify state persists correctly and no migration re-runs

Expected Outcomes:

  • App upgrades cleanly from 8.4.1 to 8.4.2 without data loss
  • Migration 148 runs exactly once and does not re-run on subsequent launches
  • All wallet state (accounts, balances, custom networks) is preserved
  • No Sentry exceptions are captured for migration 148 during normal upgrade

Excluded Features - Feature Flags Disabled (99)

The following features are disabled via feature flags and should NOT be tested:

  • ASSETS3831TestFeatureFlagPermissions
  • addDeviceSyncEnabled
  • agentic_cli_notifications_enabled
  • aiSocialAusCacheRefreshEnabled
  • aiSocialLeaderboardOnboardingEnabled
  • aiSocialLeaderboardOptFlowEnabled
  • assetsGlobalWatchlistV1
  • assetsMemeCoinView
  • bitcoinTestnetsEnabled
  • brazeBannerHome
  • brazeBannerHomeMinVersion
  • brazeSegmentForwarding
  • cardIntercomSupport
  • cardTransactionHistory
  • configRegistryApiEnabled
  • confirmations_pay_hardware
  • coreMCU589AbtestHubPageDiscoveryTabs
  • coreMCU747AbtestPredictPositionsEmptyState
  • crossmintApplePayCheckout
  • earnFeatureFlagTemplate
  • earnMoneyAssetOverviewBalanceCtaEnabled
  • earnMoneyAssetOverviewFooterCtaEnabled
  • earnMoneyCardFlipAnimationEnabled
  • earnMoneyCardTiltAnimationEnabled
  • earnMoneyEarningSectionEnabled
  • earnMoneyHubEnabled
  • earnMoneyParallaxAnimationEnabled
  • earnMusdConversionAssetOverviewCtaEnabled
  • earnMusdConversionFlowEnabled
  • earnMusdConversionRewardsUiEnabled
  • earnMusdConversionTokenListItemCtaEnabled
  • earnMusdCtaEnabled
  • earnPooledStakingServiceInterruptionBannerEnabled
  • earnStablecoinLendingServiceInterruptionBannerEnabled
  • earnMoneyBalanceAnimationEnabled
  • forceRampsStagingEnvironment
  • fullPageAccountList
  • googleLoginIosUnsupportedBlockingEnabled
  • hapticsKillSwitch
  • homeTMCU1209AbtestHomepageBalanceBreakdown
  • homeTMCU470AbtestTrendingSections
  • homeTMCU725AbtestHomepagePerpsPillsEmptyState
  • homeTMCU828AbtestOnboardingChecklistStepper
  • homeTMCU926AbtestDiscoveryPills
  • immersveOnboardingEnabled
  • ledgerDmk
  • legacyIosGoogleConfigEnabled
  • metalCardCheckoutEnabled
  • moneyActivityMockDataEnabled
  • moneyEnableCardActivityEnrichment
  • moneyHomeScreenEnabled
  • moneyShowMoneyAccountAddress
  • pepsSamplePhasedRolloutFlag
  • perpsAdvancedChartEnabled
  • perpsDefaultPayTokenWhenNoBalanceEnabled
  • perpsMyxProviderEnabled
  • perpsPerpGtmOnboardingModalEnabled
  • perpsPerpTradingServiceInterruptionBannerEnabled
  • perpsRecentlyAddedEnabled
  • perpsRecentlyViewedEnabled
  • perpsSlippageConfig
  • perpsCompetitionBannerEnabled
  • perpsMarketAboutEnabled
  • perpsProModeEnabled
  • platformNewLinkHandlerSystem
  • platformTestStructure
  • predictClobV2UseLegacyClobHost
  • predictFeedBanner
  • predictFeedCarousel
  • predictGtmOnboardingModalEnabled
  • predictHomeRedesign
  • predictHotTab
  • predictSportsFeed
  • predictTabFeaturedCarousel
  • predictWimbledon
  • predictWorldCup
  • predictHomepageDiscoveryNbaChampionEnabled
  • rampsServiceDisruptionModal
  • rampsTransakWidgetUrlProxy
  • rewardsAnnouncementModalEnabled
  • rewardsBitcoinEnabled
  • rewardsDropsEnabled
  • rewardsEnableMusdDeposit
  • rewardsEnableMusdHolding
  • rewardsFirstPredictOnUsEnabled
  • rewardsMissingEnrolledAccounts
  • rewardsReferralCodeEnabled
  • rewardsReferralEnabled
  • rewardsTronEnabled
  • socialAiAssetDetailsQuickBuy
  • socialAiTSA495AbtestCardRotationInterval
  • solanaOnboardingModal
  • solanaTestnetsEnabled
  • stellarAccounts
  • tempoConfig
  • tokenDetailsV2ButtonLayout
  • tokenDiscoveryBrowserEnabled
  • tronStaking
  • walletHomeOnboardingSteps

Generated by AI Test Plan Analyzer (claude-sonnet-4-6) at 2026-08-07T18:21:05.647Z

AI generated test plan (JSON): Available as artifact test-plan-8.4.2 in the build workflow

Co-authored-by: Cursor <cursoragent@cursor.com>
sleepytanya
sleepytanya previously approved these changes Aug 7, 2026
@sleepytanya
sleepytanya marked this pull request as ready for review August 7, 2026 21:00
@sleepytanya
sleepytanya requested a review from a team as a code owner August 7, 2026 21:00

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 175aa80. Configure here.

Comment thread app/constants/ota.ts
* Kept here (not only in ota.config.js) so changes there do not alter the Expo fingerprint and break CI.
*/
export const OTA_VERSION: string = 'vX.XX.X';
export const OTA_VERSION: string = 'v8.4.2';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OTA targets wrong runtime line

High Severity

OTA_VERSION is set to v8.4.2 for this release/8.4.2-ota hotfix, but RUNTIME_VERSION still comes from package.json as 8.5.0 and is what Expo publishes as runtimeVersion. OTA clients only fetch updates for their native runtime, so this bundle would target 8.5.0 installs rather than the 8.4.x line this release is meant to patch.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 175aa80. Configure here.

Comment thread android/app/build.gradle
targetSdkVersion rootProject.ext.targetSdkVersion
versionName "8.5.0"
versionCode 6291
versionCode 6278

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Native build numbers inconsistently reverted

Medium Severity

Android versionCode and iOS CURRENT_PROJECT_VERSION drop from 6291 to 6278, but versionName / MARKETING_VERSION stay at 8.5.0. OTA branches are supposed to match the already-shipped native build identity; this partial revert leaves store/build metadata inconsistent and can break fingerprint or store upload assumptions if a native artifact is produced from the branch.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 175aa80. Configure here.

This PR updates the change log for 8.4.2. (Hotfix - no test plan
generated.)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Documentation-only changelog and link updates; no application code
changes.
> 
> **Overview**
> Documents **v8.4.2** and **v8.4.1** in `CHANGELOG.md` and refreshes
the release compare links at the bottom of the file.
> 
> **8.4.2** records a single fix: Arc no longer shows up as an
added/enabled network for users who got it from a pre-release default
migration (#34445). **8.4.1** entries cover Perps custom pay-token order
placement and WalletConnect relay reliability (#33822, #33871). The
`[Unreleased]` → `v8.5.0` link now compares from `v8.4.2`, with new
links for `8.4.2` and `8.4.1`.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
c0bc7bb. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
Co-authored-by: Tatiana Bobritsky <sleepytanya@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

⏭️ Smart E2E selection skipped - PR targets a release or stable branch (release/* or stable)

All E2E tests pre-selected.

View GitHub Actions results

@sonarqubecloud

sonarqubecloud Bot commented Aug 7, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rc-freeze Freeze auto release candidate builds size-XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants