Skip to content

[pull] main from MetaMask:main#626

Merged
pull[bot] merged 10 commits intoReality2byte:mainfrom
MetaMask:main
Mar 24, 2026
Merged

[pull] main from MetaMask:main#626
pull[bot] merged 10 commits intoReality2byte:mainfrom
MetaMask:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Mar 24, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

weitingsun and others added 10 commits March 24, 2026 17:46
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
New workflow **runway_ios_rc_workflow** is created. We are using this
workflow in Runway for RC release to iOS. If there is a change in OTA
version in ota.ts, then we call Push OTA update workflow and push an OTA
update to iOS RC. If not, we are going to call Build Mobile App workflow
and build a new iOS RC.

Note: added **runway_android_rc_workflow**

Success workflow runs: 
Regular build:
https://github.com/MetaMask/metamask-mobile/actions/runs/23260145017
OTA Push:
https://github.com/MetaMask/metamask-mobile/actions/runs/23267287137

## **Changelog**

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

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

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

CHANGELOG entry: Added new workflow runway_ios_rc_workflow 

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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



<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Adds new GitHub Actions workflows that can dispatch builds, OTA
updates, and iOS TestFlight uploads; misconfiguration could trigger the
wrong release path or fail deployments. Changes are CI/release-pipeline
only, with no runtime app behavior impact beyond the `OTA_VERSION`
constant value change.
> 
> **Overview**
> Adds **Runway RC GitHub Actions workflows** for `ios` and `android`
that, on `workflow_dispatch`, detect whether `app/constants/ota.ts`’s
`OTA_VERSION` changed vs the current release tag (or `main`) and then
either **dispatch `push-eas-update.yml`** (requires resolving a PR
number) or **invoke the reusable `build.yml`** for `main-rc` builds.
> 
> The iOS workflow additionally **uploads the generated IPA to
TestFlight** (with a step summary) after a successful build. Separately
simplifies `build.yml` branch selection by switching `source_branch`
handling to `inputs.source_branch || github.ref_name`, and updates
`OTA_VERSION` to a placeholder value.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b8641bc. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

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

Adds a canonical repo-local skill authoring standard directly in
`.agents/skills/repo-skill-authoring/SKILL.md` so agents can create and
update MetaMask Mobile repo-local skills with a minimal file set.

This PR introduces the `repo-skill-authoring` skill as the canonical
artifact in `.agents/skills/`, keeps a thin Claude skill shim that
points directly to it, and removes the redundant docs SSOT, Cursor
command shim, Claude command shim, and per-skill `AGENTS.md` entry.

## **Changelog**

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

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

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

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

N/A

## **Screenshots/Recordings**

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

### **Before**

N/A

### **After**

N/A

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk documentation/config-only change that adds new agent skill
guidance without impacting runtime app code.
> 
> **Overview**
> Adds a new canonical repo-local agent skill, `repo-skill-authoring`,
defining the standard structure, naming rules, and authoring workflow
for skills under `.agents/skills/`.
> 
> Registers the skill for the OpenAI/Codex harness via
`agents/openai.yaml` and adds a minimal Claude shim in `.claude/skills/`
that points back to the canonical `.agents` `SKILL.md`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
4cc1eb1. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!-- CURSOR_AGENT_PR_BODY_BEGIN -->
## **Description**

This PR addresses 5 E2E tests that each had a single failure in CI over
the past 24 hours, making them candidates for flakiness fixes:

1. **send-erc20-token.spec.ts** - Unmocked request to
`digest.dev-api.cx.metamask.io` causing test cleanup failure
2. **card-button.spec.ts** - Login rehydration timing out after 31832ms
3. **alert-system.spec.ts** - Login rehydration timing out after 31830ms
4. **stake-action-smoke.spec.ts** - Earn button not visible after
15488ms
5. **network-manager2.spec.ts** - ADB reverse port cleanup error
(transient CI issue)

### Changes made:
- **Added `digest.dev-api.cx.metamask.io` to allowlist** - This market
digest API endpoint was being called by the send flow but wasn't mocked,
causing test failures
- **Increased `loginToApp` timeout from 30s to 45s** - The login flow
with rehydration was occasionally timing out on slower CI runs
- **Increased `waitForAppReady` timeout from 15s to 20s** - More time
for app initialization before login attempts
- **Added explicit retry intervals** - Better retry behavior during app
stabilization
- **Increased earn button visibility timeout from 30s to 45s** - The
staking test needs more time for balance API mocks to load on CI

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: Flaky E2E test failures from Slack #metamask-mobile-dev flaky
test report (Mar 23-24, 2026)

## **Manual testing steps**

```gherkin
Feature: E2E Test Stability

  Scenario: Tests complete successfully with improved timeouts
    Given the E2E test suite runs on CI
    
    When the send-erc20-token test runs
    Then the digest API requests should be allowlisted and not cause failures
    
    When the card-button or alert-system tests run
    Then the login should complete within the 45s timeout
    
    When the stake-action-smoke test runs  
    Then the earn button should appear within the 45s timeout
```

## **Screenshots/Recordings**

N/A - Infrastructure/timeout changes only

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

[Slack
Thread](https://consensys.slack.com/archives/C02U025CVU4/p1774339846368199?thread_ts=1774339846.368199&cid=C02U025CVU4)

<div><a
href="https://cursor.com/agents/bc-6a2d3255-83dc-54c2-bac3-5ecfa24b279e"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-web-light.png"><img
alt="Open in Web" width="114" height="28"
src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a>&nbsp;<a
href="https://cursor.com/background-agent?bcId=bc-6a2d3255-83dc-54c2-bac3-5ecfa24b279e"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img
alt="Open in Cursor" width="131" height="28"
src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;</div>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: cmd-ob <cmd-ob@users.noreply.github.com>
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

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

## **Changelog**

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

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

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

CHANGELOG entry: added the Money home screen empty state scaffold.

## **Related issues**

Fixes: 
- [MUSD-542: Money home screen empty
state](https://consensyssoftware.atlassian.net/browse/MUSD-542)

## **Manual testing steps**

```gherkin
Feature: Money home screen

  Scenario: user navigates to the Money home screen
    Given user is on the MetaMask wallet home screen
    And the "Cash" section is visible

    When user taps the "Cash" section header
    Then user is navigated to the Money home screen
```

## **Screenshots/Recordings**

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

### **Before**
N/A - Money home screen doesn't exist
<!-- [screenshots/recordings] -->

### **After**

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


https://github.com/user-attachments/assets/600d4e48-ea22-47ec-90cc-790f76d6f574

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Medium risk because it adds a new navigation stack and changes the
Cash section header navigation based on a new remote/env feature flag,
which could affect routing if misconfigured. Most functionality is UI
scaffolding behind a disabled-by-default flag with tests covering the
new selector and navigation behavior.
> 
> **Overview**
> Introduces a new **feature-flagged `Money` home screen scaffold**
(header, balance summary, action buttons, position/how-it-works
sections, potential earnings list, MetaMask Card promo, and footer),
with placeholder handlers and conditional rendering of the potential
earnings section based on eligible conversion tokens.
> 
> Wires the screen into navigation via new `Routes.MONEY` entries and
`MoneyScreenStack`, and updates the homepage `CashSection` header to
route to `Routes.MONEY.ROOT` when enabled (otherwise keeping the
existing cash tokens full view).
> 
> Adds the `moneyHomeScreenEnabled` remote flag (with
`MM_MONEY_HOME_SCREEN_ENABLED` env fallback), updates test babel
overrides for env handling, and includes comprehensive unit tests plus
new `en.json` strings and CODEOWNERS patterns for `Money` paths.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
cf4fb8a. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

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

This PR will provide a fix for hardware wallet to gas free network like
Monad and Sei.
Due to currently Hardware wallet is not supported for EIP 7702 gas
sponsorship, and Swap feature is not working for hardware wallet user.

This fix will fall back the Gasless transaction to User pay gas previous
model so that user can still do the swap and sign transaction like
bfore.

This is temporately fix for current version of extensions, and we will
do a proper support in the future.

Similar to extension PR:
MetaMask/metamask-extension#40915
Ticket:
https://consensyssoftware.atlassian.net/jira/software/c/projects/NEB/boards/3738/backlog?selectedIssue=NEB-767


## **Changelog**

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

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

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

CHANGELOG entry: Hardware wallet user will fall back to use `User pay
gas` for those Gasless network due to hardware wallet not supported in
Gasless network like Sei and Monad.

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: Gas sponsorship disabled for hardware wallet accounts

  Scenario: Hardware wallet user does not use gas sponsorship on sponsored network
    Given the user has added a hardware wallet account (Ledger or QR-based)
    And the hardware wallet account is selected as the active account
    And the user has added a gas-sponsored network (e.g. Monad)

    When the user attempts to perform a swap a dapp interaction or send a transaction on the sponsored network
    Then the transaction should not use gas sponsorship
    And the UI should not display any gas sponsorship labels (e.g. "No network fee", "Paid by MetaMask")
    And the user should see the normal network gas fee
    And the transaction should follow the standard user-pays-gas flow
```

## **Screenshots/Recordings**

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

### **Before**

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

> With HW account: 

Network list: 
<img width="392" height="800" alt="Screenshot 2026-03-18 at 16 05 48"
src="https://github.com/user-attachments/assets/601c30cc-fd78-456e-87b5-cc70e7ce3433"
/>

Tx flow: 
<img width="392" height="800" alt="Screenshot 2026-03-18 at 15 53 04"
src="https://github.com/user-attachments/assets/7c7b60cf-3f79-4701-a1e5-1fbba2bfe84e"
/>
<img width="392" height="800" alt="Screenshot 2026-03-18 at 15 55 20"
src="https://github.com/user-attachments/assets/a3258815-f1d2-4abf-8b22-209b73a0fbba"
/>
<img width="392" height="800" alt="Screenshot 2026-03-18 at 15 55 47"
src="https://github.com/user-attachments/assets/9275c82c-e56a-47ad-a203-a34f67ed6ed9"
/>


### **After**

> With HW account: 

Network list: 
<img width="392" height="800" alt="Screenshot 2026-03-18 at 16 06 19"
src="https://github.com/user-attachments/assets/03a296be-17fe-4387-baa0-23bae3ba00eb"
/>

Tx flow:
<img width="392" height="800" alt="Screenshot 2026-03-18 at 15 49 55"
src="https://github.com/user-attachments/assets/b39bc1b0-4b28-4e06-ae06-a381458ba7f6"
/>
<img width="392" height="800" alt="Screenshot 2026-03-18 at 15 50 29"
src="https://github.com/user-attachments/assets/76a31213-9ecd-4290-b407-58ffb8d82f48"
/>


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

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches gasless sponsorship and transaction publishing paths
(including 7702 delegation), which can affect whether transactions are
sponsored vs user-paid and could change behavior on supported chains.
Changes are scoped to hardware-wallet detection gates with added tests,
reducing regression risk.
> 
> **Overview**
> Hardware wallet accounts now **opt out of gasless / EIP-7702
sponsorship**, forcing swaps/bridge and confirmations to use the normal
*user-pays-gas* path.
> 
> This adds an `accountSupports7702` gate to `TransactionControllerInit`
so `Delegation7702PublishHook` and `isEIP7702GasFeeTokensEnabled` only
activate for keyrings that support 7702, and updates
`useIsGaslessSupported`/`useIsGasIncluded7702Supported` (via new
`useIsHardwareWalletForBridge`) to report unsupported for hardware
signers.
> 
> Network selection UI (`NetworkSelector`, `NetworkMultiSelectorList`,
`CustomNetwork`) now hides the “No network fee” sponsored label for
hardware wallets, and a patched `@metamask/bridge-status-controller`
waits for approval tx confirmation when required. Tests were
added/updated to cover the new hardware-wallet gating behavior.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
83f66fc. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
Co-authored-by: Julien Fontanel <julien.fontanel@consensys.net>
Co-authored-by: Frederic HENG <frederic.heng@consensys.net>
Co-authored-by: Arafet (CN - Hong Kong) <52028926+arafetbenmakhlouf@users.noreply.github.com>
Co-authored-by: tommasini <46944231+tommasini@users.noreply.github.com>
… render errors (#27816)

---

## **Description**

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

Previously, `ErrorBoundary` was mounted as a child of `ThemeProvider`,
`NavigationProvider`, `FeatureFlagOverrideProvider`, and all other
providers in `Root/index.tsx`. This meant that any error thrown during
the initialization or render of those providers would bypass the error
boundary entirely, resulting in an unrecoverable blank crash.

This PR moves `ErrorBoundary` to wrap the entire `PersistGate` content
tree — above all providers — so that errors from any part of the tree
are caught and the user sees the error screen with recovery options
rather than an unrecoverable crash.

Two companion fixes were required to make `ErrorBoundary` work correctly
outside provider context:

- `useStyles.ts`: falls back to `mockTheme` when
`useAppThemeFromContext()` returns `null` or `undefined` (e.g. when a
component using `useStyles` is rendered inside `ErrorBoundary` before
`ThemeProvider` is available).
- `ErrorBoundary/index.js`: uses optional chaining
(`this.context?.colors`) to safely access theme colors when the theme
context is absent; also changes the `ScrollView` import back to
`react-native` (instead of `react-native-gesture-handler`) since
`ErrorBoundary` now renders outside any gesture-handler context.

## **Changelog**

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

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

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

CHANGELOG entry: Fixed unrecoverable crash when a core provider fails to
render by moving ErrorBoundary to wrap the entire component tree

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: Error boundary catches provider-level render errors

  Background:
    Given I have the MetaMask Mobile app installed

  Scenario: app displays error screen instead of blank crash when a provider throws
    Given the app is launching for the first time
    And a provider in the component tree throws a render error

    When the app finishes loading
    Then I should see the ErrorBoundary error screen
    And I should be able to tap "Reset app" to recover

  Scenario: normal app launch is unaffected
    Given the app is launching normally
    And no providers throw errors

    When the app finishes loading
    Then I should land on the wallet home screen
    And the app should function normally
```

## **Screenshots/Recordings**
After intentionally throwing an error on `FeatureFlagOverrideProvider`
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**
<img width="359" height="755" alt="image"
src="https://github.com/user-attachments/assets/fd23c8ce-6ec1-4045-83e4-54fb4976f326"
/>

N/A

### **After**

<img width="349" height="736" alt="image (6)"
src="https://github.com/user-attachments/assets/721fa8c1-882f-41b7-83ac-f5319537b8d8"
/>

N/A

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- Generated with the help of the pr-description AI skill -->

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Moderate risk because it changes the root component hierarchy and
error-handling scope, which can affect startup/render order and recovery
behavior across the app.
> 
> **Overview**
> **Expands crash coverage at app startup** by moving `ErrorBoundary` in
`Root/index.tsx` to wrap all providers (and the snaps webview), so
errors thrown during provider initialization/render are caught and
surfaced via the error UI instead of a blank crash.
> 
> **Hardens theming and UI dependencies outside provider context** by
falling back to `mockTheme` in `useStyles` and `ErrorBoundary` when
theme context is missing, and switching `ErrorBoundary`’s `ScrollView`
import to `react-native` (updating the Wallet snapshot accordingly).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
2f344cf. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Remove the campaigns-specific feature flag (`rewardsCampaignsEnabled`)
and simplify the rewards feature flag logic. Campaigns functionality is
now controlled by the main `rewardsEnabled` feature flag.

## **Related issues**

https://consensyssoftware.atlassian.net/browse/RWDS-1129

## **Manual testing steps**

1. Enable the rewards feature flag
2. Navigate to the Rewards section
3. Verify campaigns display correctly and all campaign interactions work

## **Screenshots/Recordings**

N/A

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs)
- [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
- [x] I've properly set the pull request status:
  - [ ] In case it's not

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR

## **Changelog**

CHANGELOG entry: [removed]: Remove rewardsCampaignsEnabled feature flag;
campaigns are now controlled by rewardsEnabled

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Moderate risk because it changes rewards navigation routes and removes
feature-flag gating around campaign fetching/opt-in, which could expose
campaigns UI/requests more broadly if other guards are missing.
> 
> **Overview**
> **Removes the dedicated campaigns feature flag**
(`rewardsCampaignsEnabled`) across selectors, hooks, and
`RewardsController`, so campaign fetching/participant status/opt-in now
rely on the main rewards enablement and subscription presence.
> 
> **Refactors Rewards campaigns UI/navigation**: renames rewards
campaign route constants, splits campaign details into
`OndoCampaignDetailsView` and a new `SeasonOneCampaignDetailsView`,
removes `PreviousSeasonView`/tile paths, and updates tiles to navigate
based on `CampaignType` with unsupported types becoming non-interactive.
> 
> **Updates campaigns data flow and UX**: adds `featured` to
`CampaignDto` and uses it to drive `CampaignsPreview` selection,
introduces `campaignsHasLoaded`/`hasLoaded` to distinguish first-load
skeletons vs error states, stops client-side sorting to preserve API
order, and tweaks Earn Rewards geo-loading rendering and mUSD visibility
(treats `UNKNOWN` as non-UK). Also localizes completed-campaign date
text via new `rewards.campaign.ended_date` string.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
9de8adc. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…71.0 (#27879)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

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

`branch.json` had `useTestInstance: true` and `debugMode: true`, which
forced **all builds** — including production RC — to initialize the
Branch SDK against the **test environment**. Branch short links (e.g.
`metamask.app.link/1WkF6GmE40b`) are created in the **live** Branch
dashboard, so the test-instance SDK could never resolve them: the test
and live environments are separate databases.

This was the root cause of the "This page doesn't exist" error when
opening Branch deepview short links (e.g. from Twitter/X). The SDK
returned `+clicked_branch_link: false` and `+non_branch_link` with the
raw URL because the test environment had no record of live links.

The fix sets both values to `false` so the SDK uses the live key from
the native configuration (`Info.plist` / `AndroidManifest.xml`),
matching the environment where links are actually created.

**Note:** The same `branch.json` content is also present at
`android/app/src/main/assets/branch.json` — both platforms are affected.
This PR fixes the root config; the Android copy should also be
verified/updated.

## **Changelog**

CHANGELOG entry: Fixed Branch.io deep links not resolving by switching
SDK from test to live environment

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: Branch short link deep linking

  Background:
    Given I have a production RC build installed
    And the app is using the live Branch key

  Scenario: user opens a Branch short link from cold start
    Given the app is not running

    When user taps a Branch deepview link (e.g. https://metamask.app.link/1WkF6GmE40b)
    Then the app should open
    And the user should be navigated to the intended destination (e.g. Trending page)
    And the "This page doesn't exist" modal should NOT appear

  Scenario: user opens a Branch short link from warm start (app backgrounded)
    Given the app is running in the background

    When user taps a Branch deepview link
    Then the app should come to foreground
    And the user should be navigated to the intended destination

  Scenario: user opens a direct universal link (non-Branch)
    Given the app is installed

    When user taps https://link.metamask.io/trending
    Then the Trending page should open normally
    And behavior should be unchanged from before this PR
```

## **Screenshots/Recordings**

### **Before**

N/A

### **After**

N/A

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk config-only change, but it affects deep link behavior across
builds by switching Branch initialization away from the test
environment.
> 
> **Overview**
> Disables `debugMode` and `useTestInstance` in `branch.json`, ensuring
the Branch SDK initializes against the **live** environment rather than
the test instance.
> 
> This should restore proper resolution of production Branch short
links/deepviews that previously failed when the app was forced to use
the test Branch database.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
33fcef1. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Updates `.cursor/rules/unit-testing-guidelines.mdc` with clearer
guidance for theme-related mocks in unit tests:

- Prefer `mockTheme` (real design tokens) instead of hardcoded hex
values.
- Mock `useTailwind()` with the correct return shape (supports
`tw.style(...)`, and only add `tw.color(...)` when the component under
test uses it).

This is intended to reduce churn and align new tests with the
`@metamask/design-tokens/color-no-hex` ESLint rule.

Related / prior `color-no-hex` PRs:
- #26958
- #26963
- #27008
- #27030
- #27031
- #27149
- #27150
- #27151

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: Cursor unit testing guidelines

  Scenario: guidance for theme-related mocks is clear
    Given a developer is writing or updating a unit test
    When they follow the updated theme mocking guidance
    Then they can avoid hardcoded hex colors and mock useTailwind without type/shape mismatches
```

## **Screenshots/Recordings**

### **Before**

N/A

### **After**

N/A

## **Pre-merge author checklist**

- [x] I've followed MetaMask Contributor Docs and MetaMask Mobile Coding
Standards.
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable (N/A)
- [x] I've documented my code using JSDoc format if applicable (N/A)
- [x] I've applied the right labels on the PR (see labeling guidelines).
Not required for external contributors.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: documentation-only change that updates testing guidance
without affecting runtime behavior.
> 
> **Overview**
> Updates `.cursor/rules/unit-testing-guidelines.mdc` to add **Theme
Mocking Rules** that steer tests toward using the shared `mockTheme` and
away from hardcoded hex design tokens (to align with
`@metamask/design-tokens/color-no-hex`).
> 
> Adds concrete mock examples for `useTheme`, `useStyles`, and
`useTailwind()` (including the correct return shape), plus an explicit
anti-pattern example of local hex color mock objects.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
6227068. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Adds 5 new view tests covering previously untested send scenarios:
- EVM ETH happy path (Amount → Recipient → Review button enabled)
- Invalid address disables Review with error text
- Token contract address opens SendAlertModal; cancel closes it
- Amount exceeding balance shows Insufficient funds on Continue
- ERC-1155 Amount screen shows NFT name and Next button lifecycle

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

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

## **Changelog**

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

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

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

CHANGELOG entry:

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

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

## **Pre-merge reviewer checklist**

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk since changes are limited to component-view tests and test
mocks, with no production logic modifications.
> 
> **Overview**
> Adds new component-view coverage for **EVM send flows**, including ETH
happy path navigation, invalid recipient validation, insufficient-funds
gating, and the token-contract recipient warning modal (with modal
`CANCEL_BUTTON`/`ACKNOWLEDGE_BUTTON` test IDs).
> 
> Extends the component-view `Engine` mock to include
`AssetsContractController.getTokenStandardAndDetails`, enabling tests to
simulate token contract address detection and reset mock behavior
between cases.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b4acf8f. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
@pull pull Bot added the ⤵️ pull label Mar 24, 2026
@pull pull Bot merged commit 9874d9c into Reality2byte:main Mar 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants