[pull] main from MetaMask:main#583
Merged
pull[bot] merged 11 commits intoReality2byte:mainfrom Mar 6, 2026
Merged
Conversation
<!--
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**
Increase JS bundle 1 MB
<!--
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: workflow-only change that just relaxes the CI bundle-size
gate by 1 unit and doesn’t affect runtime code.
>
> **Overview**
> **CI bundle-size gating has been relaxed slightly.** The
`js-bundle-size-check` step in `.github/workflows/ci.yml` now allows an
iOS `main.jsbundle` size threshold of `53` instead of `52` when running
`./scripts/js-bundle-stats.sh`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3c0f0a4. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…dictMarketDetails) (#27012) ## Summary First component view tests for the Predict feature area (MMQA-1529). Tests use Engine spies and real user interactions — no mocked hooks or selectors — following the integration-test doctrine: each test models a complete user journey, not an isolated unit behavior. ### Infrastructure added | File | Purpose | |---|---| | `tests/component-view/presets/predict.ts` | State preset with `predictTradingEnabled` remote feature flag, `PredictController` state, `PreferencesController.privacyMode`, and `TransactionController` | | `tests/component-view/renderers/predict.tsx` | `renderPredictFeedView` and `renderPredictFeedViewWithRoutes`, wrapped with `QueryClientProvider` (required by `PredictBalance` which uses `@tanstack/react-query`) | | `tests/component-view/renderers/predictMarketDetails.tsx` | `renderPredictMarketDetailsView` and `renderPredictMarketDetailsViewWithRoutes` with `initialParams` support for route params | | `tests/component-view/fixtures/predict.ts` | Shared `MOCK_PREDICT_MARKET` fixture used across both test files | | `app/components/UI/Predict/Predict.testIds.ts` | Added `PredictSearchSelectorsIDs` (`SEARCH_BUTTON`, `CLEAR_BUTTON`, `ERROR_STATE`) and `getPredictSearchSelector.resultCard(index)` helper; all raw strings replaced with constants | | `tests/component-view/mocks.ts` | Updated to support Predict engine context | ### PredictFeed tests (12) - Search overlay opens when the user presses the search icon - `getMarkets` called with the debounced typed query - Search overlay closes when the user presses Cancel - Clear button hides after user clears the input - No-results message includes the typed query - **Data completeness**: result card shows title + Yes/No tokens after `getMarkets` resolves - Tapping a result card navigates to market details - Back button navigates to wallet - Balance card renders and `getBalance` is called on mount - Add Funds triggers `trackGeoBlockTriggered` with `attemptedAction: deposit` - Error state shown when all `getMarkets` retries fail - Retry press calls `getMarkets` again after an error ### PredictMarketDetails tests (5) - `getMarket` called with `marketId` from route params on mount - **Data completeness**: title + Yes/No bet buttons visible after `getMarket` resolves - Pressing a bet button triggers `trackGeoBlockTriggered` while ineligible - `trackMarketDetailsOpened` called after market and positions load - Back button navigates to Predict root ### Key implementation constraints - The main feed (`PagerView` + `FlashList`) never renders in the test environment — it is gated by `{layoutReady && <PredictFeedTabs />}` and `layoutReady` stays false without native layout events. Tests focus on the search overlay which does render. - Market card navigation targets `Routes.PREDICT.ROOT` (nested navigator), not `MARKET_DETAILS` directly. - `PredictBalance` requires `QueryClientProvider`; renderer wraps with `{ retry: false }` to surface errors immediately. ## Test plan ```bash yarn jest -c jest.config.view.js PredictFeed.view.test PredictMarketDetails.view.test --runInBand --silent --coverage=false ``` - [x] All 17 tests pass - [x] No ESLint errors (`yarn eslint app/components/UI/Predict/views/**/*.view.test.tsx`) 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: changes are primarily test-only infrastructure plus refactors of `testID` strings in Predict UI components/tests. Main risk is breaking existing E2E/unit tests that rely on previous hard-coded selector strings. > > **Overview** > **Adds component view tests for Predict.** Introduces new Predict component-view test suites for `PredictFeed` and `PredictMarketDetails` that validate real user flows (search, navigation, balance loading, error/retry) via `Engine.context.PredictController` spies. > > **Builds supporting test infrastructure and normalizes selectors.** Adds Predict-specific component-view renderers, Redux state preset, and a shared `MOCK_PREDICT_MARKET` fixture; extends component-view `Engine` mocks with a stubbed `PredictController`. Updates `PredictFeed` and multiple unit tests to replace hard-coded `testID` strings with new constants/helpers in `Predict.testIds.ts` (feed/search/market-details selectors, skeleton/empty-state IDs). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 8ba8bca. 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>
## **Description**
Fix charting library url config
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: null
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low-risk configuration-only change, but a missing/incorrect
`MM_CHARTING_LIBRARY_URL` secret/value could cause builds or OTA updates
to use the wrong charting assets.
>
> **Overview**
> Fixes charting library URL configuration by introducing
`MM_CHARTING_LIBRARY_URL` as a first-class env var across the build
system.
>
> The OTA push workflow (`push-eas-update.yml`) now injects
`MM_CHARTING_LIBRARY_URL` from GitHub secrets, `builds.yml` defines the
default URL, and `scripts/build.sh` exports it into the generated `.env`
for Expo update/build steps.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
18c053a. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…arket details (#26281) <!-- 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** 1. **Why**: Users with no perps balance saw an unclear flow (e.g. no preselected pay token, or Long/Short with no way to fund). 2. **What**: (a) When the user has no perps balance and the pay-with-any-token allowlist is enabled, we preselect the allowlist token with the highest USD balance in the order Pay row. (b) When they have no perps balance and no such token can be preselected, we show a single "Add funds" CTA on the market details screen instead of Long/Short; tapping it navigates to the perps confirmation stack and opens the deposit flow. - **New hook** `useDefaultPayWithTokenWhenNoPerpsBalance`: returns the allowlist token with highest balance when `availableBalance <= PERPS_MIN_BALANCE_THRESHOLD`, otherwise `null`. Respects `perpsPayWithAnyTokenAllowlistAssets`. - **Constant** `PERPS_MIN_BALANCE_THRESHOLD` (0.01) in `perpsConfig.ts` for the "no perps balance" threshold and minimum token balance for preselection. - **PerpsPayRow**: uses the hook; when pending config has no selected token, either preselects that token (via `setPayToken` + `setSelectedPaymentToken`) or sets selected payment to Perps balance (`null`). - **PerpsMarketDetailsView**: uses `usePerpsLiveAccount`, the new hook, and `useConfirmNavigation`. When `showAddFundsCTA` (no position, not at OI cap, balance < 0.01, and hook returns `null`), footer shows "Add funds" only; `handleAddFunds` calls `navigateToConfirmation({ stack: Routes.PERPS.ROOT })` then `depositWithConfirmation()`. Otherwise Long/Short buttons are shown as before. ## **Changelog** CHANGELOG entry: When users have no perps balance, the app now preselects the allowlist token with the highest balance for payment when available, and shows an "Add funds" button on the market details screen when no token can be preselected. ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TAT-2569 ## **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] --> <img width="1206" height="2622" alt="simulator_screenshot_EB73FD6D-B607-4611-8B08-3C6B63737730" src="https://github.com/user-attachments/assets/33674552-1be0-41fd-9006-5159f1c0bbe9" /> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes the perps funding/payment-token selection and deposit entrypoint from `PerpsMarketDetailsView`, which can affect how users land in confirmations and which token is preselected. Logic is gated by balance thresholds/allowlists but still touches trading UX flows and error handling. > > **Overview** > Improves the *zero/low perps balance* onboarding flow by adding `useDefaultPayWithTokenWhenNoPerpsBalance`, which selects the allowlisted pay-with-any-token asset with the highest fiat balance (above `PERPS_MIN_BALANCE_THRESHOLD`) while excluding the current provider’s native chain. > > `PerpsPayRow` now uses this hook to auto-preselect that token when pending trade config has no selected token; otherwise it keeps defaulting to Perps balance (`null`). `PerpsMarketDetailsView` conditionally replaces Long/Short with a single **Add funds** CTA when balance is below threshold and no default token exists; pressing it navigates to the Perps confirmation stack and triggers `depositWithConfirmation()`, logging any deposit errors. > > Adds supporting config (`PERPS_MIN_BALANCE_THRESHOLD`, provider chain-id mapping + `getPerpsProviderChainId`), expands Perps view state fixtures for component tests, and updates/adds unit tests covering the new behaviors. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 13930fc. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
<!-- CURSOR_SUMMARY --> > [!NOTE] > **Low Risk** > Low risk localization-only changes, but a few keys change structure/names (e.g., `seed_phrase_warning_explanation` array→string, `homepage.sections.more_predictions`→`view_more`) which could cause missing/incorrect text if the app expects the old format. > > **Overview** > Updates German, Greek, Spanish, and French locale JSONs with new/expanded strings for several UI areas, including perps order details, AI market insights (new feedback copy), predictions fee breakdown, ramps order details/notifications, mUSD conversion quick-convert copy, card PIN/cashback screens, rewards bonus-code messaging, trending *stocks*, and hardware wallet connection/error flows. > > Also adjusts some existing keys/labels (including a couple key renames and a `seed_phrase_warning_explanation` value type change) to match updated UI text requirements. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 66f4a23faa727b6e6122f76cd504dbbe87efaab6. 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>
<!-- 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? --> Migrate `Skeleton` component (Card scope only) from internal component to design system component. ## **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: https://consensyssoftware.atlassian.net/browse/DSYS-274 ## **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** https://github.com/user-attachments/assets/3b82cbe7-977a-4e0f-afe1-ad5c9dc95e1e ### **After** https://github.com/user-attachments/assets/db1812f4-083d-45a9-996f-4a8cdbea5e20 ## **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** > Medium risk because it swaps the loading placeholder implementation in Card UI flows; visual/animation behavior and prop compatibility may differ, potentially impacting loading states and tests. > > **Overview** > Introduces a new `components-temp/Skeleton` wrapper around the design-system `Skeleton`, disabling autoplay in E2E/Jest via `autoPlay={!isE2E && !process.env.JEST_WORKER_ID}`. > > Updates Card-scope screens (`CardHome` and `SpendingLimitProgressBar`) to import this new Skeleton instead of the legacy internal component, and adjusts the legacy `components/Skeleton` deprecation notice to point to the temp wrapper. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 12decef. 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** Add select quotes functionality in swaps. <!-- 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: add select quotes functionality ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/SWAPS-3642, https://consensyssoftware.atlassian.net/browse/SWAPS-4149, https://consensyssoftware.atlassian.net/browse/SWAPS-4203 ## **Manual testing steps** ```gherkin Ensure AC pass ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches quote-selection and fee-formatting logic and introduces a new navigation flow, which could affect which quote is executed and what costs are displayed if edge cases (expired/refreshing quotes, missing requestId) are mishandled. > > **Overview** > Adds a new **Quote Selector** screen that lists sorted swap/bridge quotes by estimated *total cost* and lets users pick a specific quote; the `rate` row in `QuoteDetailsCard` now navigates to this selector via new `rate-info-button`/`rate-arrow-button` actions. > > Introduces `selectedQuoteRequestId` to the bridge Redux slice and threads it through `selectBridgeQuotes` and `useBridgeQuoteData` so a manually chosen quote becomes the `activeQuote` (with auto-reset when the selection is no longer valid/available). > > Refactors fiat/amount display by adding `useDisplayCurrencyValue` and switching `TokenInputArea` to use it (and the renamed `useFormattedBalanceWithThreshold`), and updates `formatNetworkFee` to correctly handle gasless quotes via `includedTxFees` with a `gasFee.effective` fallback. Includes new route wiring (`Routes.BRIDGE.QUOTE_SELECTOR_VIEW`), i18n strings, and extensive new/updated unit tests covering the selector UI, analytics (`useTrackAllQuotesSortedEvent`), and various BridgeView behaviors (Blockaid banner, approval disclaimer, input constraints, sponsored-network handling). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 701dd24. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…tions (#27147) ## **Description** Deposit and withdraw toast handlers were incorrectly invalidating positions and activity queries, causing unnecessary refetches. This change scopes those invalidations to only the `claim` type, where they are actually relevant. Balance and unrealized PnL queries remain invalidated for all types. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: Predict query invalidations Scenario: Deposit completes without refetching positions/activity Given the user has a pending deposit transaction When the deposit transaction is confirmed Then balance and unrealized PnL queries are invalidated And positions and activity queries are NOT invalidated Scenario: Claim completes and refetches all relevant data Given the user has a pending claim transaction When the claim transaction is confirmed Then balance, unrealized PnL, positions, and activity queries are all invalidated ``` ## **Screenshots/Recordings** <!-- Not applicable — logic-only 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 - [ ] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low-risk change limited to React Query cache invalidation; it only reduces unnecessary refetches after deposit/withdraw confirmations and should not affect transaction execution. > > **Overview** > Fixes `usePredictToastRegistrations` query invalidation so **on `confirmed` transactions** it always invalidates `balance` and `unrealizedPnL`, but only invalidates `positions` and `activity` when the transaction `type` is `claim`. > > This prevents deposit/withdraw toast flows from triggering unnecessary `positions`/`activity` refetches while keeping claim-related data refresh behavior intact. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e157a2e. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…ers (#27146) <!-- 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? --> Upgrades the smart E2E selector's AI provider stack and adds token usage and cost reporting to make it easier to monitor and compare provider costs. ### Provider changes - **Default provider switched to OpenAI** (`openai → anthropic → google` priority) - **OpenAI model**: `gpt-5.2-chat-latest` - **Anthropic model**: `claude-sonnet-4-6` (was `claude-opus-4-5-20251101`) ### SDK upgrades - `openai`: `^4.77.0` → `^6.25.0` - `@anthropic-ai/sdk`: `^0.71.0` → `^0.78.0` - Fixed breaking change from openai v6: `ChatCompletionMessageToolCall` is now a discriminated union — added `toolCall.type === 'function'` guard before accessing `.function` ### Error visibility - Provider `isAvailable()` catch blocks now log the actual API error instead of silently returning `false` - Availability check output now distinguishes between missing API key and failed API call ### Token cost tracking - Added `LLMUsage` type to `LLMResponse` — all three providers now return `inputTokens` / `outputTokens` per API call - `analyzeWithAgent` accumulates totals across iterations and prints a cost report on completion - `MODEL_PRICING` table added to `config.ts` (keyed to the three active models) ## **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: Smart E2E provider selection and cost tracking Scenario: user runs analyzer with valid OpenAI key Given E2E_OPENAI_API_KEY is set to a valid key When user runs node -r esbuild-register tests/tools/e2e-ai-analyzer --pr <number> -p openai Then the output shows "✅ OpenAI GPT is available" And a "💰 Token Usage Report" is printed with input tokens, output tokens, and total cost in USD Scenario: user runs analyzer with missing API key Given E2E_OPENAI_API_KEY is not set When user runs node -r esbuild-register tests/tools/e2e-ai-analyzer --pr <number> Then the output shows "❌ OpenAI GPT is not available — missing E2E_OPENAI_API_KEY" And the analyzer falls back to the next available provider Scenario: user runs analyzer with an invalid API key Given E2E_OPENAI_API_KEY is set to an invalid value When user runs node -r esbuild-register tests/tools/e2e-ai-analyzer --pr <number> Then the output shows "⚠️ OpenAI API error: <error message>" And the output shows "❌ OpenAI GPT is not available — API call failed (see warning above)" Scenario: user runs analyzer with only Anthropic key set Given E2E_OPENAI_API_KEY is not set and E2E_CLAUDE_API_KEY is valid When user runs node -r esbuild-register tests/tools/e2e-ai-analyzer --pr <number> Then Anthropic is used as the active provider And the token report shows model "claude-sonnet-4-6" with cost in USD ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Medium risk due to major `openai` SDK upgrade and provider/model default changes that can alter analyzer behavior and costs, though the impact is confined to test tooling. > > **Overview** > Updates the `tests/tools/e2e-ai-analyzer` provider stack by upgrading `openai` to v6 and `@anthropic-ai/sdk`, switching the default provider priority to **OpenAI → Anthropic → Google**, and updating the default OpenAI/Anthropic model IDs. > > Adds **token usage + estimated cost reporting**: introduces `LLMUsage` on `LLMResponse`, populates usage from all three providers, accumulates totals across agent iterations in `analyzeWithAgent`, and prints a final report using a new `MODEL_PRICING` table. > > Improves provider diagnostics by logging underlying API errors during `isAvailable()` checks and making availability output distinguish between missing API keys and failed API calls; also adds an OpenAI v6 tool-call type guard (`toolCall.type === 'function'`) when decoding tool uses. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 8389bd8. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** This PR splits out the `app/components/UI/Perps` portion of the color-no-hex lint migration from #26651 into its own reviewable batch. The change applies the same test-only updates from the original PR for Perps files, including replacing hardcoded hex usage in tests and aligning theme mocks to shared `mockTheme` patterns where applicable. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: - Part of #26651 ## **Manual testing steps** ```gherkin Feature: Perps color-no-hex lint batch split Scenario: validate updated Perps test files Given the branch `chore/color-no-hex-perps-batch-3` When running targeted test suites for updated files Then all targeted suites pass When running eslint on Perps files in this local workspace Then lint execution is blocked by local environment config (`@typescript-eslint/no-parameter-properties` rule missing) ``` Commands used: - `yarn jest --watchman=false app/components/UI/Perps/Views/PerpsTPSLView/PerpsTPSLView.test.tsx app/components/UI/Perps/components/PerpsLeverageBottomSheet/PerpsLeverageBottomSheet.test.tsx app/components/UI/Perps/components/PerpsLimitPriceBottomSheet/PerpsLimitPriceBottomSheet.test.tsx app/components/UI/Perps/components/PerpsPositionCard/PerpsPositionCard.test.tsx --runInBand` - `yarn jest --watchman=false app/components/UI/Perps/utils/transactionDetailStyles.test.ts --runInBand` - `yarn eslint app/components/UI/Perps --max-warnings=0` (blocked locally by missing rule definition) ## **Screenshots/Recordings** ### **Before** N/A (test-only changes) ### **After** N/A (test-only changes) ## **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 - [ ] 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** > Primarily test refactors plus an ESLint override to enforce `color-no-hex` in `app/components/UI/Perps`; main risk is new lint enforcement causing CI/local lint failures if any remaining hex usage was missed. > > **Overview** > Adds `app/components/UI/Perps/**/*` to the ESLint override that *errors* on `@metamask/design-tokens/color-no-hex`. > > Updates Perps unit/view tests to comply by removing hardcoded hex colors and `#`-prefixed bug/PR strings, standardizing theme/style mocks to use the shared `mockTheme` (and in a few cases calling real style functions) so assertions and mocked styles reference theme tokens instead of literal hex values. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit bdc53b5. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…#27148) ## **Description** Replaces the custom controller-level implementations in `usePredictPositionsForHomepage` and `usePredictMarketsForHomepage` with thin wrappers around the Predict team's existing React Query-backed hooks (`usePredictPositions`, `usePredictMarketData`). This removes ~300 lines of manual caching (Map + TTL), staleness guards (`requestIdRef`), unmount protection (`isMountedRef`), and request deduplication that React Query handles automatically. Key changes: - `usePredictPositionsForHomepage` now delegates to `usePredictPositions`, accepts an options object `{ maxPositions?, claimable? }`, and returns `totalClaimableValue` - `usePredictMarketsForHomepage` now delegates to `usePredictMarketData` - `PredictionsSection` no longer manually computes `totalClaimable` or calls `refreshClaimable` after claiming (React Query handles cache invalidation) - All tests updated to mock team hooks instead of `Engine.context.PredictController` <details> <summary>Implementation Plan</summary> # Refactor Predictions Homepage Hooks to Use Team Hooks ## Problem `usePredictPositionsForHomepage` directly calls `Engine.context.PredictController.getPositions()` and implements its own module-level caching (Map + TTL), staleness guards (`requestIdRef`), and unmount protection (`isMountedRef`). The Predict team already has `usePredictPositions` which wraps the same controller call with React Query, providing automatic caching (5s stale time), deduplication, error handling, and optimistic polling -- all for free. The same applies to `usePredictMarketsForHomepage` which directly calls `PredictController.getMarkets()` with its own cache, while the team has `usePredictMarketData` with pagination support. ## Current vs Team Hook Comparison ### Positions | Aspect | `usePredictPositionsForHomepage` (current) | `usePredictPositions` (team) | |--------|-------------------------------------------|------------------------------| | Data source | `Engine.context.PredictController.getPositions()` | Same, via React Query `queryFn` | | Caching | Manual Map + 60s TTL | React Query, 5s stale time | | Staleness guard | `requestIdRef` counter | React Query built-in | | Unmount safety | `isMountedRef` | React Query built-in | | Filtering | `maxPositions` slice, `claimable` param | `claimable` select filter, `marketId` filter | | Account tracking | `selectSelectedInternalAccountFormattedAddress` | `getEvmAccountFromSelectedAccountGroup()` | | Return shape | `{ positions, isLoading, error, refresh }` | React Query result (`{ data, isLoading, error, refetch }`) | ### Markets `usePredictMarketsForHomepage` directly calls `PredictController.getMarkets()` with manual caching, while `usePredictMarketData` provides the same with pagination and error handling. ## Changes ### 1. `usePredictPositionsForHomepage` -- delegate to `usePredictPositions` - Change signature to options object `({ maxPositions?, claimable? })` - Remove manual state, caching, refs, and `useEffect` - Add `totalClaimableValue` to return type ### 2. `usePredictMarketsForHomepage` -- delegate to `usePredictMarketData` - Remove module-level cache, manual state, refs - Map `marketData` to `markets`, `isFetching` to `isLoading` ### 3. `PredictionsSection` -- update call sites - Use options object for claimable call - Remove local `totalClaimable` reduce - Remove `refreshClaimable()` from `handleClaim` (React Query handles it) - Remove `refreshClaimable` from `refresh` callback </details> ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: Feedback from Predict team (Luis) about using their existing hooks ## **Manual testing steps** ```gherkin Feature: Predictions section uses team hooks Scenario: Positions load correctly Given user has prediction positions When user views the homepage Predictions section Then positions are displayed correctly Scenario: Trending markets load correctly Given user has no prediction positions When user views the homepage Predictions section Then trending market cards are displayed in the carousel Scenario: Claim button works Given user has claimable positions When user taps the Claim button Then the claim is processed and positions update automatically ``` ## **Screenshots/Recordings** N/A -- internal refactor with no UI changes. ## **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** > Refactors data-fetching for the homepage Predictions section to rely on shared React Query hooks, which may subtly change caching/refresh behavior and when claimable amounts update. UI logic is mostly unchanged but depends on new hook return shapes (`refetch`, `totalClaimableValue`). > > **Overview** > **Refactors the homepage Predictions section to use the Predict team’s React Query hooks instead of controller calls + manual caching.** `usePredictMarketsForHomepage` now wraps `usePredictMarketData` and `usePredictPositionsForHomepage` wraps `usePredictPositions`, replacing the old `refresh` APIs with `refetch` and adding `totalClaimableValue` for claimable positions. > > `PredictionsSection` is updated to use the new hook signatures, show the claim button based on `totalClaimableValue`, and simplify pull-to-refresh to always `refetch` positions + markets (no separate claimable refresh; claim no longer triggers a manual refresh). > > Tests are updated accordingly, including mocking `usePredictPositions`/`usePredictMarketData` in `Homepage.test.tsx` and adjusting section/hook tests to the new `refetch`/options-object APIs. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit fa612f2. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 : )