Skip to content

[pull] main from MetaMask:main#779

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

[pull] main from MetaMask:main#779
pull[bot] merged 4 commits into
Reality2byte:mainfrom
MetaMask:main

Conversation

@pull
Copy link
Copy Markdown

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

baptiste-marchand and others added 2 commits May 22, 2026 00:04
…s-controller to 24.1.1 (#30528)

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

<!--
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?
-->
Ensure the project uses the newer
`@metamask/notification-services-controller` version and prevent Social
AI notification controls from showing when the Social Leaderboard
feature is disabled.

## **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/GE-244

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

- [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 visibility is now controlled by an existing remote
feature flag and changes are covered by updated tests; dependency bump
may have minor integration fallout but is limited in scope.
> 
> **Overview**
> **Gates the Social AI notification settings section** so it only
appears when the `aiSocialLeaderboardEnabled` remote feature flag is
enabled (via `selectSocialLeaderboardEnabled`).
> 
> Updates unit/component-view tests and notification-state presets to
cover both flag states, and adjusts the user-storage mock defaults for
`marketing.inAppNotificationsEnabled`.
> 
> Bumps `@metamask/notification-services-controller` to `24.1.1` (and
updates lockfile accordingly).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
445bca5. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…7.79.0 (#30559)

## **Description**

Adds Predict live sports and extended-market support for additional
basketball, baseball, hockey, soccer, and tennis leagues. This expands
league parsing and supported flag filtering so newly enabled Polymarket
game events can render as game detail experiences instead of generic
markets.

This also fixes several extended sports details issues found while
validating the new leagues:

- Parses WNBA, MLB, NHL, ATP, WTA, and ITF game slugs and tennis
provider metadata.
- Uses tennis `series` and team metadata when ATP/WTA/ITF events only
include generic tennis tags.
- Keeps extended game charts on the primary moneyline outcome so World
Cup and other draw-capable markets load correctly.
- Opens extended market cards through the bottom-sheet buy flow instead
of the legacy full-screen buy preview.
- Adds loading-only chart height reservation to avoid the game details
footer jumping while the chart loads.
- Adds tennis market labels and separates tennis cards into `Game Lines`
and `1st Set` groups.
- Aligns footer and card outcome labels, order, and team colors for
tennis moneyline and first-set winner markets.

## **Changelog**

CHANGELOG entry: Added support for additional Predict sports leagues and
extended sports market details.

## **Related issues**

Fixes: PRED-925 https://consensyssoftware.atlassian.net/browse/PRED-925

## **Manual testing steps**

```gherkin
Feature: Predict extended sports markets for newly supported leagues

  Scenario: user opens supported game detail markets
    Given Predict live sports is enabled for WNBA, MLB, NHL, ATP, WTA, and ITF
    And Predict extended sports markets is enabled for NBA, WNBA, MLB, NHL, World Cup, UCL, EPL, La Liga, Serie A, Bundesliga, MLS, FIFA Friendlies, ATP, WTA, and ITF

    When the user opens a supported game market
    Then the market renders as a game details view
    And the chart loads from the primary moneyline market
    And the footer prices match the primary moneyline outcomes

  Scenario: user opens an ATP, WTA, or ITF tennis game
    Given the event has generic Tennis and Games tags
    And the event has ATP, WTA, or ITF league metadata in series or teams

    When the user opens the game details view
    Then the event is parsed into the correct tennis league
    And the tabs show Game Lines and 1st Set
    And tennis market cards show translated labels
    And the 1st Set Winner buttons use the same team colors as the footer

  Scenario: user selects an extended sports market card
    Given the extended sports market cards are visible

    When the user taps a card outcome
    Then the bottom-sheet buy flow opens for that outcome
    And the app does not navigate to the legacy full-screen buy preview
```

## **Automated testing**

- `node .yarn/releases/yarn-4.14.1.cjs jest
app/components/UI/Predict/utils/gameParser.test.ts
app/components/UI/Predict/constants/sports.test.ts
app/components/UI/Predict/providers/polymarket/utils.test.ts
app/components/UI/Predict/components/PredictActionButtons/PredictActionButtons.test.tsx
app/components/UI/Predict/components/PredictGameChart/PredictGameChart.test.tsx
app/components/UI/Predict/components/PredictGameChart/PredictGameChart.wrapper.test.tsx
app/components/UI/Predict/components/PredictGameDetailsContent/PredictGameDetailsTabsContent.test.tsx
app/components/UI/Predict/components/PredictGameDetailsContent/PredictGameOutcomesTab.test.tsx
app/components/UI/Predict/components/PredictMarketSportCard/PredictMarketSportCard.test.tsx`
  - 9 test suites passed
  - 288 tests passed
- `node .yarn/releases/yarn-4.14.1.cjs lint:tsc`

## **Screenshots/Recordings**

### **Before**

N/A - no recordings attached in this local PR draft.

### **After**

N/A - no recordings attached in this local PR draft.

## **Pre-merge author checklist**

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

#### Performance checks (if applicable)

- [x] I've tested on Android
- N/A - no Android-specific or performance-sensitive native path
changed.
- [x] I've tested with a power user scenario
- N/A - Predict sports details rendering does not depend on imported
wallet size.
- [x] I've instrumented key operations with Sentry traces for production
performance metrics
  - N/A - no new production performance operation was added.

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**
> Medium risk because it changes how sports leagues are
detected/whitelisted and how UI components select outcome tokens
(primary moneyline vs extended markets), which can affect navigation,
pricing subscriptions, and displayed teams across multiple sport
experiences.
> 
> **Overview**
> Extends Predict live/extended sports support to additional leagues
(WNBA/MLB/NHL and tennis `atp`/`wta`/`itf`), including updated league
whitelisting/types and more robust league detection from event
`series`/team metadata when tags are missing.
> 
> Standardizes **"primary" moneyline selection** via
`getPrimaryMoneylineOutcomes`, and updates the footer buttons, market
sport cards, and game charts to ignore non-moneyline extended outcomes
(especially for draw-capable leagues) and to map tennis/home-away tokens
to the correct team labels/colors.
> 
> Improves game details UX by routing outcomes-tab buys through the
shared `onBetPress` bottom-sheet flow (instead of navigation) and
reserving chart height only while loading to avoid layout jump; adds
tennis group ordering/labels (e.g., `first_set`) and corresponding i18n
strings.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
c2a0122. 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 22, 2026
@pull pull Bot added the ⤵️ pull label May 22, 2026
grvgoel81 and others added 2 commits May 22, 2026 08:09
<!--
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**
Social login onboarding analytics had gaps: several events were missing
account_type, and there was no dedicated signal when a user abandoned
the provider auth UI before completing login (especially Telegram and
cross-provider cancel flows)

This PR:

1) Adds Social Login Auth Browser Dismissed
(SOCIAL_LOGIN_AUTH_BROWSER_DISMISSED) with:
* account_type (best-effort via getSocialAccountType)
* surface (onboarding | rehydration)
* elapsed_ms

2) Fills account_type gaps on:
* Account Already Exists Page Viewed / Account Not Found Page Viewed
* Wallet Setup Failure in ChoosePassword for social login flows

3) Improves cancel detection so dismiss tracking works across providers:
* Shared helpers: isOAuthUserCancellationMessage,
isSocialLoginAuthSessionDismissed
* Broader Android Google ACM cancel mapping (canceled, One Tap cancel,
resolved cancel result)
* iOS Apple ERR_REQUEST_CANCELED and additional cancel messages

Jira: https://consensyssoftware.atlassian.net/browse/TO-754

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

## **Changelog**

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

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

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

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: Social login onboarding analytics

 Scenario: User dismisses Google login on iOS during wallet creation
    Given the user is on onboarding and opts in to analytics
    And the user taps "Continue with Google" to create a wallet

    When the user closes the in-app auth browser before login completes
    Then "Social Login Auth Browser Dismissed" is tracked with account_type "metamask_google", surface "onboarding", and elapsed_ms
    And "Social Login Failed" is tracked with failure_type "user_cancelled"

  Scenario: User dismisses Apple login on iOS during wallet creation
    Given the user is on onboarding and opts in to analytics
    And the user taps "Continue with Apple" to create a wallet

    When the user cancels the native Apple sign-in sheet
    Then "Social Login Auth Browser Dismissed" is tracked with account_type "metamask_apple" and surface "onboarding"

  Scenario: User dismisses Google login on Android during wallet creation
    Given the user is on onboarding on Android and opts in to analytics
    And the user taps "Continue with Google" to create a wallet

    When the user cancels the Google credential / One Tap UI or dismisses the browser fallback
    Then "Social Login Auth Browser Dismissed" is tracked with account_type "metamask_google" and surface "onboarding"
```

## **Screenshots/Recordings**

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

### **Before**

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

### **After**
<img width="804" height="90" alt="Screenshot 2026-05-21 at 6 47 48 PM"
src="https://github.com/user-attachments/assets/a253b236-6c58-488e-b3d8-8c9b06946319"
/>
<img width="799" height="66" alt="Screenshot 2026-05-21 at 7 34 54 PM"
src="https://github.com/user-attachments/assets/0ede3270-8e95-4b9a-aff8-6455d4145e07"
/>
<img width="806" height="84" alt="Screenshot 2026-05-21 at 7 35 10 PM"
src="https://github.com/user-attachments/assets/b6fe9b26-3291-4d91-80ca-a4d5ef489ccb"
/>

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

## **Pre-merge author checklist**

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

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

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

#### Performance checks (if applicable)

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

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

## **Pre-merge reviewer checklist**

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

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Adds new analytics events and modifies OAuth provider
cancellation/error classification on Android and iOS, which could change
how login failures are surfaced and tracked. Risk is moderate because it
touches cross-platform OAuth handlers and centralized OAuthService error
handling, but does not alter auth token exchange logic.
> 
> **Overview**
> Adds a new MetaMetrics event `SOCIAL_LOGIN_AUTH_BROWSER_DISMISSED` and
emits it from `OAuthService` when provider auth is cancelled/dismissed
(with `account_type`, `surface`, and `elapsed_ms`).
> 
> Fills `account_type` gaps for `AccountStatus` page-view + wallet
setup/import start events and for `ChoosePassword`
`WALLET_SETUP_FAILURE` tracking during social-login flows.
> 
> Refactors cancel detection into shared helpers
(`isOAuthUserCancellationMessage`, `isSocialLoginAuthSessionDismissed`)
and expands Android Google + iOS Apple handlers to classify more
cancel/dismiss outcomes (including resolved cancel results and
additional message/code patterns), with updated/added unit tests.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
4a231c8. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
)

## **Description**

Adds a fingerprint-gated build cache to
`scripts/perps/agentic/preflight.sh` so farmslot dispatches stop paying
for redundant `yarn setup` + `pod install --repo-update` + `xcodebuild`
cycles when the native dep graph hasn't changed.

**Why:** farmslot today hardcodes `--clean --wallet-setup`, forcing
~15–20 min per dispatch even when only TypeScript changed. Investigation
showed `@expo/fingerprint` (already a dep) +
`scripts/generate-fingerprint.js` (already wired) can deterministically
detect "no native change" — but the preflight path didn't use them.

**Approach:**
- New `--mode <auto|fast|rebuild-native|clean>` flag on `preflight.sh`.
Legacy `--clean`/`--rebuild` continue to work unchanged.
- Two-tier cache: shared `$MM_BUILD_CACHE_DIR` (default
`~/Library/Caches/mm-mobile-builds` on macOS,
`~/.cache/mm-mobile-builds` on Linux) keyed by fingerprint, plus a
per-worktree `.agent/build-cache/<plat>/installed.json` sidecar.
- Per-fingerprint `flock` wraps the full **decide + install + build +
store** region, so two peer worktrees at the same fingerprint produce
exactly one xcodebuild/gradle invocation. The second worker installs the
artifact the first published.
- `installed.json` records both fingerprint AND target (sim UDID / adb
serial); the fast-path skip requires both to match, so a recorded build
on one sim won't false-hit on another.
- `pod install --repo-update` is now opt-in (only `--mode clean`); plain
`pod install` runs first with a one-shot `--repo-update` retry on
failure.
- `--mode fast` is strict: missing cache OR failed cache install
hard-fails instead of silently rebuilding.
- `--check-only` stays read-only: a cache-decision that would mutate the
sim/device exits with an explanatory failure instead.

All new helpers live in `scripts/perps/agentic/lib/build-cache.sh`.
Idempotent test suites (unit + real-sim e2e) live next to it.

**Boundary:** change is fully contained under `scripts/perps/agentic/` —
no root `package.json` shortcuts, no perps-out-of-scope files. Callers
invoke `bash scripts/perps/agentic/preflight.sh --mode <…>` directly.

| Scenario | Today | After |
|---|---|---|
| Same worktree, app already installed at this fp on this sim | ~15–20
min | ~30–45 s |
| Peer worktree, shared cache hit | ~15–20 min | ~60–90 s |
| Native diff (Podfile/native module) | ~15–20 min | ~5–8 min (first
worker only; rest cache-install) |
| Cold host / `--mode clean` | ~15–20 min | unchanged (escape hatch) |

Farmslot side (`projects/metamask-mobile-farm/project.json` → `--mode
auto`) is intentionally deferred to a follow-up: the `--mode` flag must
land on `main` first since farmslot clones MM fresh per dispatch.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: N/A (developer tooling improvement; supports the farmslot
dispatch loop)

## **Manual testing steps**

Two idempotent test scripts ship with the change. Both safely stash and
restore any pre-existing `.agent/build-cache`.

```gherkin
Feature: build-cache lib + preflight --mode plumbing

  Scenario: unit suite passes
    Given a clean checkout of this branch
    When I run "bash scripts/perps/agentic/lib/test-build-cache.sh"
    Then 26 PASS lines print and exit code is 0
    And "ALL TESTS PASSED" is printed
    And re-running the command immediately also exits 0 (idempotent)

  Scenario: real-simulator cache-hit recognition (Path 1)
    Given a booted iOS simulator with MetaMask installed
    When I run "bash scripts/perps/agentic/lib/test-preflight-cache-e2e.sh"
    Then preflight logs "Cache: installed app matches fingerprint <hash>"
    And the build branch is skipped (no pod install / xcodebuild)
    And MetaMask remains installed on the simulator (no destructive ops)

  Scenario: --mode fast is strict
    Given a worktree with no cached build for the current fingerprint
    And no MetaMask installed on the simulator at the right fingerprint
    When I run "bash scripts/perps/agentic/preflight.sh --platform ios --mode fast"
    Then preflight exits non-zero with "Mode 'fast' but no cached build for fp <hash>"

  Scenario: --check-only stays read-only
    Given a shared cache hit for the current fingerprint
    And no MetaMask installed at that fingerprint
    When I run "bash scripts/perps/agentic/preflight.sh --platform ios --mode auto --check-only"
    Then preflight exits non-zero with a clear "cache hit available, but --check-only forbids install" message
    And the simulator state is unchanged

  Scenario: legacy --clean path is unchanged
    Given an existing worktree
    When I run "bash scripts/perps/agentic/preflight.sh --platform ios --clean --wallet-setup"
    Then preflight prints "Mode: clean (yarn setup → pod --repo-update → build)"
    And executes the same path as before this PR
```

Direct invocation examples (no yarn shortcuts; perps-scoped):

```bash
bash scripts/perps/agentic/preflight.sh --platform ios --mode auto --wallet-setup     # fingerprint-gated reuse
bash scripts/perps/agentic/preflight.sh --platform ios --mode fast --wallet-setup     # fail loud if no cached/installed build
bash scripts/perps/agentic/preflight.sh --platform ios --clean --wallet-setup         # legacy clean rebuild (unchanged)
```

## **Screenshots/Recordings**

N/A — script-only change, no UI surface.

### **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 (26 unit + real-sim e2e suite in
`scripts/perps/agentic/lib/`)
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable (shell — header comments + README section)
- [x] I've applied the right labels on the PR

#### Performance checks (if applicable)

- [ ] I've tested on Android — N/A (developer preflight; same code path
executes on both platforms; covered by mode flag + cache lib unit tests;
Android-real-sim e2e left to a separate Linux farmslot host)
- [ ] I've tested with a power user scenario — N/A (no runtime / wallet
path touched)
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics — N/A (developer tooling, never ships to production)

## **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 changes `preflight.sh` control flow for
iOS/Android build/install decisions and adds cross-worktree caching +
locking; mistakes could cause stale builds to be reused or unexpected
install/build skips.
> 
> **Overview**
> Adds a fingerprint-gated shared native build cache to
`scripts/perps/agentic/preflight.sh`, allowing iOS `.app` and Android
`.apk` artifacts to be reused across worktrees when the
`@expo/fingerprint` hash matches, with per-fingerprint locking to
serialize build/store.
> 
> Introduces `--mode <auto|fast|rebuild-native|clean>` to control cache
usage and rebuild strictness, updates CocoaPods behavior to avoid
`--repo-update` except in `clean` (with a one-shot retry on failure),
and tightens *read-only* semantics for `--check-only` (no installs/adb
reverse/Metro wallet steps; fails if cache would mutate state).
> 
> Adds the new `lib/build-cache.sh` helper library (artifact paths,
memoized fingerprinting, installed sidecar tracking, pruning,
flock/mkdir locks), plus smoke/e2e shell tests and README docs
describing the modes and cache semantics.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
fc1b85d. 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 merged commit c06187a into Reality2byte:main May 22, 2026
1 check failed
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.

4 participants