Skip to content

[pull] main from MetaMask:main#730

Merged
pull[bot] merged 9 commits into
Reality2byte:mainfrom
MetaMask:main
May 5, 2026
Merged

[pull] main from MetaMask:main#730
pull[bot] merged 9 commits into
Reality2byte:mainfrom
MetaMask:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented May 5, 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 : )

tommasini and others added 9 commits May 5, 2026 08:52
<!--
Please submit this PR as a draft initially.

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

In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->

## **Description**
Bump axios to 1.15.1
<!--
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**

<!--
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.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk dependency bump limited to `axios` via Yarn
resolutions/lockfile, with potential for minor runtime behavior changes
in HTTP requests.
> 
> **Overview**
> Updates the Yarn `resolutions` override to `axios@^1.15.1` and
refreshes `yarn.lock` to pull in `axios@1.15.2`.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
c6c6073. 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.
-->

## **Description**

The Top Traders homepage section would silently disappear whenever the
leaderboard API call failed. This happened because the section guard
condition treated a failed fetch, where isLoading is false and traders
is empty. Identically to a genuinely empty result set, causing return
null.
We now show the default error state when that happens and while the user
Retries the request the skeleton is also activated while the request is
in-flight.

<img height="800" alt="Simulator Screenshot - iPhone 17 Pro - 2026-04-29
at 16 17 58"
src="https://github.com/user-attachments/assets/470ba09e-1bbf-4be5-8365-3a871fb6f8e9"
/>

## **Changelog**

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

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

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

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

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

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

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

<!--
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.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Moderate UI/telemetry change: alters Top Traders section render gating
and adds new SocialService error telemetry (Logger extras + Sentry
breadcrumbs) across multiple hooks, which could affect user-visible
states and error reporting but not security-sensitive logic.
> 
> **Overview**
> Prevents the homepage **Top Traders** section from disappearing on
leaderboard fetch failures by distinguishing *empty* vs *error* vs
*background refetch* states, rendering an `ErrorState` with Retry, and
showing skeletons while a retry is in-flight (while keeping cached
traders visible on refetch failures).
> 
> Adds shared SocialService telemetry helpers (`socialServiceTelemetry`)
and updates Social Leaderboard hooks to emit enriched `Logger.error`
extras and Sentry breadcrumbs (including endpoint, coarse error
category, and optional HTTP status/query params), with tests
updated/expanded accordingly.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
fcbc39b. 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.
-->

## **Description**

Bumps AI-controller version which fixes the "What's Happening" (feature
flag gated) section display error.
<!--
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: no-changelog

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

<!--
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.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk dependency bump limited to `@metamask/ai-controllers`, but it
can still change runtime behavior in AI/feature-flagged UI flows.
> 
> **Overview**
> Updates the `@metamask/ai-controllers` dependency from `^0.6.0` to a
pinned `0.6.3` version.
> 
> Refreshes `yarn.lock` accordingly, including updated transitive
requirements (notably `@metamask/messenger` and
`@metamask/base-controller`) for the new `ai-controllers` release.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
812cdb4. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

**Problem:** iOS yarn cache download stalls account for **28% (~18
runs)** of the 64 Setup Environment CI failures on `main` over 30 days
(Mar 16 – Apr 16, 2026). The 610MB yarn cache downloads at 0.3-2.8 MB/s
on Cirrus macOS self-hosted runners
(`ghcr.io/cirruslabs/macos-runner:tahoe`), with tar extraction sometimes
hanging for 9+ minutes until the action times out.

See
[INFRA-3580](https://consensyssoftware.atlassian.net/browse/INFRA-3580)
for the full root cause analysis.

**Investigation data:**

Examined 6 iOS E2E setup failures from Apr 8-10:

| Run | What happened |
|-----|---------------|
| 24268253971 | Cache hit, 582MB downloaded at ~2.6 MB/s (3.8min), **tar
extraction hung 9.4min → timeout** |
| 24236471310 | Action timeout during `bundle show cocoapods` |
| 24227213798 | Foundry download failure (covered by PR #29255) |
| 24226340316 | Generic action timeout |
| 24220368199 | **Corepack download stalled** — `repo.yarnpkg.com` hung
4.8min |
| 24217223040 | **Corepack download stalled** — same, hung 2.6min |

**iOS E2E full setup timing (Cirrus macOS runners):**

| Period | Samples | Min | Max | Avg | Median | P95 |
|--------|---------|-----|-----|-----|--------|-----|
| Apr 8-10 (failure period) | 15 | 180s | 202s | 189s | 187s | 202s |
| Apr 22-23 (recent) | 15 | 188s | 267s | 208s | 204s | 267s |

iOS setup takes ~2x longer than Android (189-208s vs 103-136s) due to
Ruby, Bundler, CocoaPods, and Detox on top of shared steps.

**Solution — two changes:**

1. **`restore-keys` fallback** — Currently the yarn cache is exact-match
only. On cache miss (e.g., `yarn.lock` changed), it triggers a full
610MB re-download. Adding `restore-keys` lets yarn reuse a stale cache
and only update the diff. Pattern already used by Bundler cache in the
same file (line 272).

2. **`continue-on-error: true`** — If the cache download or tar
extraction stalls, the job currently fails entirely. With
`continue-on-error`, a stalled cache is skipped and `yarn install
--immutable` runs without cache (slower but succeeds). Pattern already
used by CocoaPods specs cache in the same file (line 333).

### Why `restore-keys` is safe

The concern: could `restore-keys` restore a stale `node_modules` from
`main` with different package versions?

**No.** `yarn install --immutable` guarantees that `node_modules` will
exactly match `yarn.lock` when it finishes, regardless of cache state.
The cache is just a starting point — yarn adds, removes, or changes
whatever is needed to reconcile. `--immutable` only prevents `yarn.lock`
modifications, not `node_modules` updates.

Example: main merges a PR updating package X from v1.0→v1.1. Your PR
branch (not rebased) still has X@v1.0 in `yarn.lock`. `restore-keys`
restores main's cache with X@v1.1. `yarn install --immutable` runs →
installs X@v1.0 per your lockfile. Same outcome as a cold install — the
lockfile is always the source of truth. Cache only affects **speed**,
not **correctness**.

### `continue-on-error` — needs team input

This makes the cache step non-blocking. If the 610MB download stalls or
tar extraction hangs (actual observed failure: 9.4min hang), the step
fails gracefully and `yarn install --immutable` runs without cache
(slower ~60-90s but succeeds).

**Pros:** stalled cache no longer kills the job; `yarn install
--immutable` still produces correct `node_modules`; pattern already used
by CocoaPods specs cache.

**Cons:** cache failures become silent (job passes but slower); reduces
visibility into cache infra problems.

> **This change can be removed from the PR if the team prefers
cache-or-fail behavior.** The `restore-keys` change alone still adds
value.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:
[INFRA-3580](https://consensyssoftware.atlassian.net/browse/INFRA-3580)
(partial — addresses iOS yarn cache download stall sub-cause)

## **Manual testing steps**

```gherkin
Feature: CI resilience for yarn cache

  Scenario: Yarn cache miss uses partial match fallback
    Given yarn.lock has changed since the last cached run

    When the "Restore Yarn cache" step runs
    Then it falls back to a partial key match via restore-keys
    And yarn install only updates the diff instead of full re-download

  Scenario: Stalled cache download doesn't block the job
    Given the yarn cache download stalls on a Cirrus macOS runner

    When the "Restore Yarn cache" step times out
    Then the step is marked as failed but the job continues (continue-on-error)
    And yarn install --immutable runs without cache
```

## **Screenshots/Recordings**

N/A — CI workflow changes only, no UI impact.

### **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).
_(N/A — CI workflow YAML only, no application code changes)_
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable _(N/A — CI workflow
configuration, validated by CI run on this PR)_
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable _(N/A — CI workflow YAML, no code)_
- [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.

[INFRA-3580]:
https://consensyssoftware.atlassian.net/browse/INFRA-3580?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
[INFRA-3580]:
https://consensyssoftware.atlassian.net/browse/INFRA-3580?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> CI-only workflow change; it may reduce visibility into cache failures
but doesn’t affect runtime code or dependency correctness.
> 
> **Overview**
> Improves resilience of the `setup-e2e-env` composite action’s Yarn
`node_modules` cache restore.
> 
> The Yarn cache step now uses `restore-keys` to allow partial cache
matches when `yarn.lock` changes, and is marked `continue-on-error:
true` so cache download/extraction failures don’t fail the job and `yarn
install --immutable` can proceed without cache.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
2718150. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…ng (#29334)

## **Description**

### Problem

CocoaPods CDN rate limiting accounts for **7% (~4 runs)** of Setup
Environment CI failures on `main` over 30 days (Mar 16 – Apr 16, 2026),
per INFRA-3580 analysis. The error signatures are:
- `CDN: trunk URL couldn't be downloaded ... Response: 429 Too Many
Requests`
- HTTP/2 framing layer errors during `pod install`

### Root Cause

The current flow in `setup-e2e-env/action.yml` **defeats its own
CocoaPods specs cache**:

1. `actions/cache@v4` restores `~/.cocoapods/repos` (including trunk
specs) — **100% cache hit rate** observed
2. `pod repo remove trunk || true` immediately **deletes** the restored
trunk specs
3. `pod install --repo-update` must re-download the **entire** trunk
from `cdn.cocoapods.org` — thousands of HTTP requests

This maximises CDN pressure on every single iOS CI run, increasing the
surface area for 429 rate-limit errors.

**When trunk exists locally**, `--repo-update` performs an incremental
delta update — minimal CDN requests, fast.
**Without trunk** (after removal), `--repo-update` downloads everything
from scratch — heavy CDN load, slow, triggers 429s.

### Why `pod repo remove trunk` was added

The step was added in PR #28433 (commit `bc06cd5123`, Apr 8, 2026) as
part of the macOS Sequoia → Tahoe migration for Xcode 26.x support. It
was added proactively with the comment "prevent stale specs" — no review
comments discussed the rationale, and no specific CDN failure motivated
it.

Since Cirrus runners are **ephemeral** (VMs destroyed after each job —
[confirmed by Cirrus Labs](https://cirrus-runners.app/): *"Every job is
executed in a reproducible isolated environment which is completely
destroyed after the job is finished"*), the only way trunk specs exist
at the start of `pod install` is via the `actions/cache` restore. There
is no leftover state from previous jobs. The `--repo-update` flag
already handles staleness by fetching deltas when trunk exists locally.

### Data

**Pod install timing (successful runs, with trunk removal + full CDN
re-download):**

| Run ID | Duration | Notes |
|--------|----------|-------|
| 24887670082 | 116s (1m 56s) | Full CDN download after trunk removal |
| 24887265337 | ~100s | Cache hit, trunk removed, re-downloaded |
| 24888574759 | ~120s | Cache hit, trunk removed, re-downloaded |

**CocoaPods specs cache hit rate:** 100% (exact or restore-key match in
all sampled runs)

**Cache flow (current, counterproductive):**
- Cache restore: ~1 MB restored from GitHub Actions cache → trunk specs
present
- `pod repo remove trunk`: deletes restored specs → trunk gone
- `pod install --repo-update`: full CDN download → thousands of requests
→ 429 risk

### Solution

1. **Remove standalone `pod repo remove trunk` step** — let cached specs
be used on first attempt for incremental `--repo-update` (low CDN load)
2. **Move trunk removal to `on_retry_command`** — only clean on failure
(handles corrupt/stale cache edge case)
3. **Increase `max_attempts` from 2 to 3** — matches other retry steps
in the same file; CDN rate limits may need a third attempt
4. **Increase `retry_wait_seconds` from 30 to 60** — CDN 429 backoff
windows need longer wait than apt mirror desyncs
5. **Add `::warning::` annotation on retry** — makes CDN failures
visible in GitHub Actions UI
6. **Add `COCOAPODS_DISABLE_STATS=true`** — eliminates unnecessary
analytics network calls during CI

**First attempt (happy path):** cached trunk specs + incremental
`--repo-update` → few HTTP requests, low CDN load
**On failure:** trunk removed for clean slate → full CDN download on
retry, warned in Actions UI
**Second/third attempt:** fresh download from CDN with 60s backoff
between attempts

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Refs: INFRA-3580

## **Manual testing steps**

N/A — CI infrastructure change. Validated by any iOS E2E workflow run
(retry logic is transparent in the happy path). The `pod install` step
behavior is identical when the first attempt succeeds.

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

- [ ] 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)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes the iOS CI dependency install flow and retry behavior, which
could affect build stability if cache state differs from expectations,
but it is limited to CI setup and guarded by retries.
> 
> **Overview**
> Improves iOS E2E CI CocoaPods installation reliability by **stopping
the unconditional `pod repo remove trunk` cleanup** so the restored
CocoaPods specs cache can be used on the first `pod install
--repo-update` attempt.
> 
> The CocoaPods install retry policy is strengthened (attempts 2→3, wait
30s→60s), and trunk cleanup is moved into `on_retry_command` with a
GitHub Actions `::warning::` annotation; `COCOAPODS_DISABLE_STATS=true`
is added to reduce extra network calls during CI.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
13ce7a7. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

This PR extracts the final Mobile CI status gate into a composite action
while preserving the existing `Check all jobs pass` status check name.

Why:

- The final gate decides whether the workflow should pass after standard
CI, E2E build/test jobs, fork-only skips, and merge queue skips
complete.
- Keeping that logic in a dedicated action makes the workflow easier to
maintain and keeps the pass/fail decision consistent.

What changed:

- Added `.github/actions/ci-status-gate`.
- Updated `.github/workflows/ci.yml` so `Check all jobs pass` calls the
composite action.
- Removed the intermediate `All jobs pass` job.
- Preserved current handling for failed jobs, cancelled jobs, skipped
E2E jobs, fork PR skips, merge queue skips, and E2E readiness blocking.
- Added a step summary table that explains each job result evaluated by
the gate.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

No public issue: CI maintenance refactor.

## **Manual testing steps**

Validated the workflow files locally:

```bash
actionlint -color -config-file .github/actionlint.yaml .github/workflows/ci.yml
ruby -e 'require "yaml"; YAML.load_file(".github/workflows/ci.yml"); YAML.load_file(".github/actions/ci-status-gate/action.yml")'
git diff --check
```

Validated extracted gate behavior in the public test fork:
https://github.com/consensys-test/metamask-mobile-test

- Non-ignorable app-code PR with `pr-not-ready-for-e2e`: `Check all jobs
pass` failed as expected because `block_merge_for_e2e_readiness=true`.
  - PR: consensys-test#3
- Gate:
https://github.com/consensys-test/metamask-mobile-test/actions/runs/25321128954/job/74237306086

- Locale-only PR without readiness blocking: E2E build/test jobs
skipped, and the final gate accepted those skips.
  - PR: consensys-test#2
- Gate:
https://github.com/consensys-test/metamask-mobile-test/actions/runs/25318425027/job/74223723784

- Locale-only PR with `pr-not-ready-for-e2e`: E2E jobs stayed skipped
and `Check all jobs pass` passed.
  - PR: consensys-test#2
- Gate:
https://github.com/consensys-test/metamask-mobile-test/actions/runs/25321510460/job/74234336146

- Standard CI failure: `Check all jobs pass` failed when a required
standard CI job failed.
  - PR: consensys-test#4
- Gate:
https://github.com/consensys-test/metamask-mobile-test/actions/runs/25321403908/job/74233562352

- E2E job failure: `Check all jobs pass` failed when an E2E smoke job
failed.
  - PR: consensys-test#6
- E2E job:
https://github.com/consensys-test/metamask-mobile-test/actions/runs/25328925239/job/74257209475
- Gate:
https://github.com/consensys-test/metamask-mobile-test/actions/runs/25328925239/job/74259419260

- Build job failure: `Check all jobs pass` failed when an E2E build job
failed.
  - PR: consensys-test#5
- Build job:
https://github.com/consensys-test/metamask-mobile-test/actions/runs/25331281786/job/74265395383
- Gate:
https://github.com/consensys-test/metamask-mobile-test/actions/runs/25331281786/job/74267776538

## **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
- [x] I've documented my code using JSDoc format if applicable
- [x] I've applied the right labels on the PR if applicable.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR where applicable.
- [ ] I confirm that this PR addresses the described change and includes
the necessary testing evidence.
## Description
https://consensyssoftware.atlassian.net/browse/RWDS-1239
https://consensyssoftware.atlassian.net/browse/RWDS-1190
https://consensyssoftware.atlassian.net/browse/RWDS-1215

Adds support for the Perps Trading Competition rewards campaign. Users
can view campaign details, join via a guided tour, track their stats
(rank, PnL, notional volume and margin thresholds), browse the
leaderboard, and monitor the prize pool — which scales from \$10k to
\$50k based on total notional volume. Geo-restricted users see a locked
CTA. Once opted in, the CTA switches to "Open Position" navigating
directly to the Perps tab.

New screens: campaign details, stats, and full leaderboard. All
data-driven from the existing campaign/leaderboard backend
infrastructure.

## Changelog

CHANGELOG entry: **Added**: Rewards Perps Trading Campaign — details
page, stats page, leaderboard page, prize pool, tour, and opt-in flow.

## Screenshots
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-04-28 at 15 31 25"
src="https://github.com/user-attachments/assets/005c0faf-0a1f-4f9e-ade8-68bd4479b6ff"
/>

###
----------------------------------------Qualified----------------------------------------

<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-04-29 at 15 24 21"
src="https://github.com/user-attachments/assets/29114a1b-45c3-4a42-b1f1-b8c316163692"
/>
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-04-29 at 15 24 28"
src="https://github.com/user-attachments/assets/0f482e11-eff2-463e-b7fb-206f3769a19f"
/>


<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-04-28 at 17 28 50"
src="https://github.com/user-attachments/assets/e52b7b84-2110-4b1d-b746-695c5ae1a756"
/>
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-04-28 at 17 29 33"
src="https://github.com/user-attachments/assets/15e3bdc0-ca0e-4f3b-a968-be2a10639005"
/>

###
----------------------------------------Pending----------------------------------------

<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-04-29 at 15 30 03"
src="https://github.com/user-attachments/assets/7b2e1f9c-0344-4f42-8da5-7294441f9fe0"
/>
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-04-29 at 15 28 25"
src="https://github.com/user-attachments/assets/3b1953b0-d855-4f82-a31b-fc006ccf8537"
/>
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-04-29 at 15 30 03"
src="https://github.com/user-attachments/assets/13481cbd-521b-468b-aa35-20f2500f69c5"
/>
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-04-29 at 15 32 31"
src="https://github.com/user-attachments/assets/7a10c0fd-6b48-42d1-b8fd-24edddce7f9f"
/>



### ----------------------------------------Split
View----------------------------------------
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-04-28 at 17 36 22"
src="https://github.com/user-attachments/assets/2aeaa9ee-7cff-4757-82c3-1fdcaa381d2e"
/>
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-04-28 at 17 36 38"
src="https://github.com/user-attachments/assets/092e8364-3954-45d9-91fc-79c3d20f2942"
/>
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-04-28 at 17 37 38"
src="https://github.com/user-attachments/assets/cde2b994-3036-4513-a7c8-d2dd1ee7ce4e"
/>
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-04-28 at 17 50 45"
src="https://github.com/user-attachments/assets/286168c1-7096-49d2-af89-e9103abe0ae1"
/>
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-04-28 at 18 00 11"
src="https://github.com/user-attachments/assets/a7b3c258-120a-42a9-91cf-a67d6bb250dc"
/>


### ---------------------------------Powered by
HyperTracker------------------------------
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-05-01 at 11 44 51"
src="https://github.com/user-attachments/assets/69f47feb-1d7d-4c3e-ac7e-f1f4c403eac6"
/>
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-05-01 at 11 44 56"
src="https://github.com/user-attachments/assets/41f19668-199d-4acb-8c60-9902a214171e"
/>





<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Adds new Rewards navigation routes and multiple Perps campaign
views/CTAs, plus refactors shared leaderboard/prize-pool logic that
could affect existing Ondo rendering and testIDs. Risk is moderate due
to new conditional UI flows and reused components across campaigns.
> 
> **Overview**
> Adds a new **Perps Trading rewards campaign** user flow with dedicated
`details`, `leaderboard`, and `stats` screens, wiring them into
`RewardsNavigator`, `CampaignTile` navigation (including tour routing),
and deeplink handling (`campaign=perps-comp`).
> 
> Refactors campaign UI to improve reuse: extracts a shared
`CampaignLeaderboard` (rows/skeleton/separator + shared test IDs) and
updates `OndoLeaderboard` to use it; splits `CampaignStatsSummary` into
`OndoCampaignStatsSummary` (renamed test IDs) and reuses its
`StatCell`/tags in new Perps stats components.
> 
> Unifies prize pool tier computation by introducing
`computePrizePoolProgress` and migrating
`OndoPrizePool`/`OndoLeaderboardView` off bespoke
`getCurrentPrize`/progress logic. Adds extensive test coverage for the
new Perps views/components and updated Ondo stats/leaderboard behavior.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
fcf01e2. 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: sophieqgu <sophieqgu@gmail.com>
…29607)

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

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

In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->

## **Description**

Show 5 year projected balane on money account deposit page.

## **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: https://consensyssoftware.atlassian.net/browse/CONF-1296

## **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**
<img width="396" height="854" alt="Screenshot 2026-05-01 at 5 54 30 PM"
src="https://github.com/user-attachments/assets/8fd76b2f-92be-437c-a32e-5a203f3d4788"
/>

## **Pre-merge author checklist**

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

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

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

#### Performance checks (if applicable)

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

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

## **Pre-merge reviewer checklist**

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

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk UI-only change that adds a derived display value based on
APY; main risk is incorrect math/formatting or missing APY data causing
the line to disappear.
> 
> **Overview**
> Shows a *projected 5-year balance* line on the custom amount
confirmation when the transaction type is `moneyAccountDeposit`,
replacing the usual `PayTokenAmount` display in that case.
> 
> Adds a new `ProjectedFiveYearBalance` component that pulls vault APY
via `useMoneyAccountBalance`, computes 5-year compounding with
`BigNumber`, formats via `useFiatFormatter`, and safely returns `null`
for loading/invalid inputs; includes unit tests and a new i18n string
`confirm.custom_amount.projected_five_year_balance`.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
8c256e1. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…home page redesign enabled (#29100)

<!--
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**

Multiple E2E tests were disabling the `homepageRedesignV1` and
`homepageSectionsV1` feature flags to work around the redesigned
homepage UI. This caused a test/production parity gap — tests were
running against the old homepage while production users see the new
redesigned version.

This PR removes all `homepageRedesignV1: false` / `homepageSectionsV1:
false` mock overrides and adapts the affected tests to work with the new
redesigned homepage. The key change is that network switching now
requires navigating to `TokensFullView` first (via the Tokens section
header) since the network filter control bar only exists there, not on
the homepage itself.

### Changes

- Removed `homepageRedesignV1` and `homepageSectionsV1` flag overrides
from 7 test files and 1 mock helper
- Added `navigateToTokensFullView()`,
`navigateBackFromTokensFullView()`, and
`openNetworkManagerFromHomepage()` methods to the `NetworkManager` page
object
- Updated network switching flows in `per-dapp-selected-network`,
`batch-transaction`, `stake-action-smoke`, `network-manager`, and
`network-manager2` specs to go through `TokensFullView`
- Added `tapSelectAllPopularNetworks()` steps in `incoming-transactions`
tests to handle single-network fixtures
- Added Sepolia-specific token fixture via `withTokens()` for the custom
network filter test

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes:
[MMQA-1712](https://consensyssoftware.atlassian.net/browse/MMQA-1712)

## **Manual testing steps**

Scenario 1: Network manager tests pass with redesigned homepage
- Given the app launches with homepage redesign feature flags enabled
(production defaults)
- When user navigates to the Tokens section from the homepage
- Then the TokensFullView screen is displayed with a network filter
control bar
- And user can open the network manager and switch networks

Scenario 2: Incoming transactions test with single-network fixture
- Given the app launches with only Ethereum enabled in the network map
- When user navigates to TokensFullView and selects all popular networks
- And user navigates back to homepage and taps the Activity tab
- Then incoming transactions are displayed correctly

Scenario 3: Dapp per-network transaction with redesigned homepage
- Given the app is connected to a dapp on a custom Localhost network
- When user switches networks via TokensFullView network manager
- Then the dapp retains its per-dapp selected network
- And transactions are confirmed on the correct network

## **Screenshots/Recordings**

### **Before**

<!-- Tests forced homepageRedesignV1: false to use old homepage UI -->

### **After**

<!-- Tests use production-default feature flags with redesigned homepage
enabled -->

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

[MMQA-1712]:
https://consensyssoftware.atlassian.net/browse/MMQA-1712?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk since changes are limited to E2E test code and mocks, but it
may cause CI failures if the redesigned homepage navigation or selectors
change again.
> 
> **Overview**
> Updates multiple mobile E2E smoke specs to run against the
**redesigned homepage defaults** by removing overrides that forced
`homepageRedesignV1`/`homepageSectionsV1` off.
> 
> Introduces new `NetworkManager` page-object helpers to reach the
network filter via `TokensFullView`, and rewires network-switching steps
across confirmation, network-manager, stake, and incoming-transactions
tests (including selecting *all popular networks* where single-network
fixtures would hide activity).
> 
> Adjusts fixtures/mocks to match the new flows (e.g.,
`withPopularNetworks()` usage, removing explicit `withNetworkEnabledMap`
in the mUSD fixture, and updating the mUSD happy-path assertion to the
Cash section container).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
61dc1b7. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@pull pull Bot locked and limited conversation to collaborators May 5, 2026
@pull pull Bot added the ⤵️ pull label May 5, 2026
@pull pull Bot merged commit dd0a6ab into Reality2byte:main May 5, 2026
3 of 15 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants