[pull] main from MetaMask:main#320
Merged
Merged
Conversation
… cp-7.59.0 (#22552) ## **Description** This PR fixes a critical UX issue where users without HyperLiquid deposits were blocked from viewing Perps market data, but more importantly, it implements a comprehensive architectural improvement to separate read and write operations in the HyperLiquid provider. ### The Problem Users who had never traded on HyperLiquid before (no on-chain deposits) encountered "Perps temporarily offline" errors when trying to view the Perps screen. Investigation revealed that: 1. Builder fee approval requires on-chain deposits to succeed 2. The previous implementation (PR #22242) moved builder fee approval to `ensureReady()` for performance optimization 3. **Root cause**: `ensureReady()` was being called in 15+ read-only methods (validation, data fetching, balance checks) 4. This caused read operations to trigger wallet signatures and block the UI when builder fee approval failed ### The Solution #### 1. Non-Blocking Builder Fee Approval - Wrapped builder fee approval in try-catch within `ensureReady()` - Allows initialization to complete even if builder fee fails - Builder fee is still checked explicitly before actual trading operations #### 2. Race Condition Prevention - Added pending promise deduplication using Maps - Prevents multiple concurrent calls from triggering duplicate signature requests - Eliminates "DEX abstraction already set" and "Referrer already set" error spam #### 3. Architectural Improvement: Separation of Read/Write Operations P **Removed `ensureReady()` from 15 read-only methods** and replaced with minimal client initialization: **High Priority (Called from validation hooks/screen init):** - `getAccountState()` - Balance and account data - `getPositions()` - Position data - `getOpenOrders()` - Open orders - `getMarketDataWithPrices()` - Market prices - `calculateFees()` - Fee calculation **Medium Priority (Historical data):** - `getOrderFills()`, `getOrders()`, `getFunding()` - `getUserNonFundingLedgerUpdates()`, `getUserHistory()`, `getHistoricalPortfolio()` **Lower Priority (Market discovery):** - `getMarkets()`, `getAvailableHip3Dexs()`, `getAvailableDexs()`, `ping()` ### Benefits #### � Better User Experience - Users can view Perps data immediately without builder fee approval - Validation never blocks on initialization steps #### � Performance Improvements - Eliminated DEX abstraction network call on every validation - Read operations are instant (no network overhead) - Faster screen initialization and validation #### � Architectural Clarity - Clear separation: Read operations = view data, Write operations = trade - Validation is truly read-only (no side effects) - Builder fee approval only runs when actually needed (during trading) #### � Reliability - No more "already set" error spam - Race conditions eliminated - Graceful degradation (view data even if setup incomplete) ### Technical Details **Before:** ```typescript async getAccountState() { await this.ensureReady(); // Triggers: DEX abstraction, referral, builder fee // ... fetch data } ``` **After:** ```typescript async getAccountState() { // Read-only operation: only need client initialization this.ensureClientsInitialized(); this.clientService.ensureInitialized(); // ... fetch data } ``` Write operations (placeOrder, editOrder, etc.) correctly keep `ensureReady()` to ensure full initialization before trading. ## **Changelog** CHANGELOG entry: Fixed Perps "temporarily offline" error for new users and improved performance by optimizing read operations ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TAT-2060 ## **Manual testing steps** ```gherkin Feature: Perps data viewing without builder fee approval Scenario: New user views Perps market data Given user has never traded on HyperLiquid (no deposits) And user has not approved builder fee When user opens Perps screen Then market data and prices load successfully And no wallet signature prompts appear And no "temporarily offline" errors occur Scenario: Existing user places order Given user has approved builder fee in the past When user opens order form and enters order details Then order validation completes without signatures When user clicks "Place Order" button Then builder fee approval is checked before order placement And order executes successfully Scenario: Race condition prevention Given multiple operations triggered simultaneously (e.g., validation + balance check) When all operations call ensureReady() concurrently Then only one initialization sequence runs And no "already set" errors appear in logs ``` ## **Screenshots/Recordings** ### **Before** - Users without deposits saw "Perps temporarily offline" - Console showed multiple "DEX abstraction already set" errors - Validation triggered wallet signature prompts ### **After** - All users can view Perps data immediately - No error spam in console - Validation is instant and read-only - Builder fee approval only triggers when placing actual orders ## **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] > Separates read vs write paths in HyperLiquid provider (read ops no longer block on builder fee), adds promise deduping for init/approvals, updates close-position slippage for full closes, and refreshes wallet account on each sign. > > - **HyperLiquid Provider (architecture/perf)** > - Split initialization: read-only methods now only ensure clients, skipping `ensureReady()` (e.g., `getPositions`, `getOrders`, `getOpenOrders`, `getFunding`, `getAccountState`, `getMarkets`, `getMarketDataWithPrices`, `getAvailable*`, `ping`, `getMaxLeverage`, `calculateFees` fetch path). > - Builder fee approval made non-blocking in `ensureReady()`; explicitly enforced before trading ops (`placeOrder`, `editOrder`, `cancel*`, `closePosition(s)`, `updatePositionTPSL`). > - Added promise deduplication for init/approvals (`ensureReadyPromise`, `pendingBuilderFeeApprovals`) to prevent concurrent signature/race conditions. > - `disconnect()` now clears pending promises and resets client init state. > - **Close Position UI/Tests** > - Always pass `slippage` context; for full close set `slippage.usdAmount` to `undefined` to bypass $10 min; tests updated to assert this. > - **Wallet Integration** > - `HyperLiquidWalletService.signTypedData` re-reads the current account on each sign to handle account switches. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 445297f. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Michal Szorad <michal.szorad@consensys.net>
…ket details due to loading skeletons (#22505) <!-- 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** - Super quick one that addresses an issue with the sticky tabs (outcomes, etc) not working correctly after the introduction of the loading skeletons <!-- 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: NA ## **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** <img width="420" alt="image" src="https://github.com/user-attachments/assets/3f41621f-9230-4a6a-8202-f1a1e489fa7e" /> ## **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] > Computes `stickyHeaderIndices` based on loading state and renders tab bar separately from tab content so sticky tabs work correctly with loading skeletons. > > - **PredictMarketDetails (`PredictMarketDetails.tsx`)**: > - Compute `stickyHeaderIndices` via `useMemo`, returning `[]` during initial loading and `[1]` otherwise; pass to `ScrollView`. > - Separate rendering of sticky tab bar (`renderCustomTabBar()`) from tab content, showing the tab bar during loading and only rendering tab content when `market` is loaded. > - Minor restructuring around skeleton display to avoid interfering with sticky behavior. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit ef40812. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…22503) <!-- 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** - Created new accounts.ts utility module to centralize account tree management - Migrated account tree logic from PredictController and hooks to accounts utility - Updated usePredictActivity, usePredictBalance, usePredictClaimToasts, usePredictDeposit, usePredictDepositToasts, usePredictPositions, and useUnrealizedPnL hooks - Removed useWithdrawToasts hook (consolidated into deposit toasts) - Added comprehensive test coverage for new accounts utility - Updated PredictController and PredictPositionsHeader to use new utility <!-- 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: 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] > Extracts `getEvmAccountFromSelectedAccountGroup` and refactors PredictController, hooks, and UI to use it for address resolution, with updated toasts/formatting and comprehensive tests. > > - **Core/Controller**: > - Replace direct `AccountsController.getSelectedAccount()` usage with `getSigner().address` backed by `getEvmAccountFromSelectedAccountGroup()` across `getPositions`, `getActivity`, `getUnrealizedPnL`, `getAccountState`, `getBalance`, `clearPendingDeposit`. > - Add accounts utility import and integrate into signer/address resolution. > - **Utilities**: > - Add `utils/accounts.ts` with `getEvmAccountFromSelectedAccountGroup`. > - **Hooks/UI**: > - Update `usePredictBalance`, `usePredictDeposit`, `usePredictDepositToasts`, `usePredictClaimToasts`, `usePredictPositions`, `usePredictActivity`, `useUnrealizedPnL`, and `PredictPositionsHeader` to derive `selectedAddress` via accounts utility (remove Redux address selector usage). > - Deposit toast confirmed amount now formatted via `formatPrice`. > - **Tests**: > - Add unit tests for accounts utility and update existing tests to mock `AccountTreeController` and new address flow across hooks, controller, and views. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 3481cd3. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Luis Taniça <matallui@gmail.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**
- Adjust button heights and spacing in PredictKeypad for better UX
- Implement dynamic label formatting in PredictMarketOutcome buttons
- Use bullet separator (•) when both labels are ≤6 characters
- Use newline separator when either label exceeds 6 characters
- Adjust button height dynamically based on label length
- Update insufficient funds message to show available balance
- Improve error message copy for better user understanding
- "Not enough funds. You can use up to {amount}." (was "Insufficient
funds...")
- "Minimum amount is {amount}" (was "Minimum bet is {amount}")
- Add comprehensive test coverage for button label formatting scenarios
<!--
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: 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]
> Refines Predict keypad/button layout, adds dynamic outcome button
label formatting, and updates Buy Preview errors to show max usable
amount with new copy, plus tests and i18n updates.
>
> - **Predict UI**:
> - **Outcome buttons (`PredictMarketOutcome`)**: Add dynamic label
formatting (bullet vs newline) with `MAX_LABEL_LENGTH=6`, center text,
and increase button height when labels are long.
> - **Keypad (`PredictKeypad`)**: Tighten spacing and set fixed heights
for quick-amount and "Done" buttons.
> - **Buy Preview (`PredictBuyPreview`)**:
> - Compute `maxBetAmount` and render updated error copy: "Not enough
funds. You can use up to {{amount}}." and "Minimum amount is {{amount}}"
via i18n.
> - **Tests**:
> - Add comprehensive tests for outcome label formatting and update
validation/error expectations across Buy Preview.
> - **i18n (`locales/languages/en.json`)**:
> - Update `prediction_insufficient_funds` and `prediction_minimum_bet`
strings to new copy with amount placeholders.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3f7bbb2. 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**
Updates bitcoin to `1.5.0`, which places accounts info under encrypted
state
<!--
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: 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]
> Update `@metamask/bitcoin-wallet-snap` from `^1.4.5` to `^1.5.0` in
`package.json` and `yarn.lock`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f6e0b97. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…2170) ## **Description** Updates the default button size for BottomSheetHeader close (X) and back (<) buttons from Medium (MD) to Large (LG) to align with the BottomSheet standardization specifications. This change makes all BottomSheets consistent by default without requiring individual components to explicitly set the button size. ## **Changelog** CHANGELOG entry: null ## **Related issues** Part of: https://consensyssoftware.atlassian.net/browse/MDP-343 <img width="450" height="397" alt="Screenshot 2025-11-04 at 4 44 57 PM" src="https://github.com/user-attachments/assets/08fb3eee-7d14-4e91-af13-694ab8d93802" /> ## **Manual testing steps** ```gherkin Feature: BottomSheetHeader button size update Scenario: View updated button sizes in Storybook Given Storybook is running When I navigate to BottomSheetHeader component Then I should see the close button (X) is size LG (32x32px) And I should see the back button (<) is size LG (32x32px) ``` ## **Screenshots/Recordings** ### **Before** Close and back buttons were size MD (28x28px with 20x20px icons) <img width="422" height="174" alt="Screenshot 2025-11-04 at 3 45 52 PM" src="https://github.com/user-attachments/assets/91a44051-2ef6-4b20-94b9-86b395ec92a2" /> ### **After** Close and back buttons are now size LG (32x32px with 24x24px icons) <img width="420" height="168" alt="Screenshot 2025-11-04 at 3 40 07 PM" src="https://github.com/user-attachments/assets/c8dd306e-fadb-45ff-8d9c-58f57cdf5e24" /> ## **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] > Sets `BottomSheetHeader` back/close `ButtonIcon` size to LG by default and updates affected consumers and snapshots. > > - **Component Library**: > - `BottomSheets/BottomSheetHeader`: Back and close `ButtonIcon` now default to `size=LG`. > - **App UI**: > - Remove redundant `size` overrides for `BottomSheetHeader` close/back buttons in Bridge selectors and related screens to rely on new default. > - **Tests/Snapshots**: > - Update snapshots across BottomSheet-based modals/views to reflect `32x32` buttons with `24x24` icons (was `28x28` with `20x20`). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 737d5bb. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Use Relay strategy for Predict deposits. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: [#5945](MetaMask/MetaMask-planning#5945) ## **Manual testing steps** ## **Screenshots/Recordings** ### **Before** ### **After** ## **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] > Wires Transaction Pay to Relay using delegation (with 7702 auth), adds exact batch caveat support, treats Predict deposits as Polygon USDC.e receives, and ignores skipIfBalance tokens in insufficient balance alerts. > > - **Payments/Engine**: > - **Transaction Pay init**: Pass `getDelegationTransaction` and always use `Relay` strategy; add init messenger for delegation and 7702 signing; hook up in `CONTROLLER_MESSENGERS`. > - **Messengers**: Extend Transaction Controller init messenger (incl. `addTransactionBatch`); add Transaction Pay init messenger. > - **Delegation**: > - **New caveat**: Add `exactExecutionBatch` builder and register in caveat builder; validation of inputs; unit tests. > - **Utils**: Build delegation transactions (encode redeem delegations, EIP-7702 authorization list, batch/single execution modes); tests and snapshots. > - **UI**: > - **TransactionDetailsSummary**: Treat `predictDeposit` as bridge receive to `Polygon` with `POLYGON_USDCE`; remove special-case title and use default; update tests. > - **Alerts**: > - **Insufficient Pay Token**: Exclude tokens with `skipIfBalance` from total; test added. > - **Deps**: > - Bump `@metamask/transaction-pay-controller` to `^5.0.0`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit ec1b6af. 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** - Change pendingDeposits state from boolean flags to batch ID strings - Update selector to return undefined instead of false for cleared deposits - Add batch ID tracking to deposit toasts for better transaction matching - Update hook to convert batch ID to boolean for backward compatibility - Delete deposit entries instead of setting to false when clearing - Add 'pending' state before batch ID is assigned - Clear deposit state on errors in depositWithConfirmation - Fix all related tests to expect batch ID strings and undefined values <!-- 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: 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] > Switch pending deposit tracking from booleans to batch IDs, update toasts/selectors to use batch IDs, and adjust controller logic and tests accordingly. > > - **PredictController**: > - Change `state.pendingDeposits` to map addresses to batch ID `string` (was `boolean`). > - On deposit: clear previous entry, set to `'pending'`, then replace with real `batchId`; validate chain ID; clear pending on errors/user cancel. > - `clearPendingDeposit` now deletes address entry instead of setting `false`. > - **Hooks**: > - `usePredictDeposit`: selector now returns batch ID; exposes `isDepositPending` via `!!batchId`. > - `usePredictDepositToasts`: reads batch ID and passes `transactionBatchId` (ignores `'pending'`). > - `usePredictToasts`: accepts optional `transactionBatchId` and matches by `batchId` when provided, otherwise falls back to nested type; handles clear on status changes. > - **Selectors**: > - `selectPredictPendingDepositByAddress` returns `string | undefined` (was `boolean | false`). > - **Tests**: > - Update deposit tests to expect batch IDs and `undefined` after clear; add cases for preserving state on different `batchId` and replacing old batch on new deposit. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 4c554f3. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->
## **Description**
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->
This PR addresses two issues related to the Card feature and onboarding
experience:
- Delegation refresh issue: After completing a successful delegation,
some data were not properly updated when navigating back to the CardHome
screen. This fix ensures all relevant data refresh correctly to reflect
the latest state.
- KYC WebView permissions: Removed a property that was preventing the
KYC WebView during onboarding from requesting camera and microphone
access, restoring the expected behavior for KYC verification.
## **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: Data not refreshing properly on CardHome after
successful delegation
CHANGELOG entry: KYC WebView not requesting camera and microphone access
during onboarding
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] 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]
> Adds a post-delegation delay and cache clear to refresh Card data,
consolidates loading/navigation handling, removes token priority update,
and re-enables KYC camera/mic prompts.
>
> - **Card — Spending Limit
(`app/components/UI/Card/Views/SpendingLimit/SpendingLimit.tsx`)**:
> - Aggregate loading state via `isProcessing` + `isDelegationLoading`
(`isLoading`); block back/cancel while loading; update button
`disabled`/`loading` states.
> - On confirm: validate SDK (error toast if missing), submit
delegation, wait 3s,
`dispatch(clearCacheData('card-external-wallet-details'))`, show success
toast, then navigate back.
> - Remove token priority update flow and related utilities; simplify
logic.
> - **Tests (`SpendingLimit.test.tsx`)**:
> - Remove token-priority mocks/tests; adjust expectations to await 3s
delay, cache clear, success toast, and navigation.
> - Add/modify loading and navigation blocking/cancel behavior tests.
> - **Onboarding — KYC WebView
(`app/components/UI/Card/components/Onboarding/KYCWebview.tsx`)**:
> - Remove `mediaCapturePermissionGrantType` to allow camera/microphone
permission prompts.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
4e1ae30. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…9.0 (#22521) ## **Description** Bumping multichain accounts deps (and other related peers). The main major change is for the `multichain-account-service` that will now report errors to sentry when anything goes wrong for automatic account creations. The other change (that was already covered here) is the `MultichainAccountService.init` which is now `async`. ## **Changelog** CHANGELOG entry: null ## **Related issues** N/A ## **Manual testing steps** N/A ## **Screenshots/Recordings** ### **Before** ### **After** ## **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] > Upgrades multichain account service and related controllers to latest majors and allows `ErrorReportingService:captureException` in the service messenger. > > - **Engine/Messenger**: > - Permit `ErrorReportingService:captureException` in `getMultichainAccountServiceMessenger`. > - **Dependencies**: > - Bump `@metamask/multichain-account-service` to `^3.0.0`. > - Bump `@metamask/account-tree-controller` to `^3.0.0`. > - Bump `@metamask/assets-controllers` to `^88.0.0`. > - Bump `@metamask/earn-controller` to `^10.0.0`. > - Update corresponding peer deps in `yarn.lock`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 05c9641. 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**
- Bunch of minor visual tweaks from the earlier bug bash
<!--
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: NA
## **Manual testing steps**
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] 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]
> Tightens recurrence visibility and tweaks icon size and divider color
across Predict UI.
>
> - **Predict UI tweaks**:
> - Show recurrence only when `market.recurrence !== Recurrence.NONE` in
`PredictMarketMultiple`.
> - Reduce empty-state illustration to `72x72` in
`PredictPositionEmpty`.
> - Change divider to `bg-default` in `PredictPositionsHeader` before
unrealized PnL section.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
89e36d8. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->
## **Description**
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->
trigger `Release PR Approval` action on PR approval that target
`release/` branches
## **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]
> Adds a `pull_request_review` (submitted) trigger to the `Release PR
Approval` GitHub Actions workflow.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0580a5f. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: sethkfman <10342624+sethkfman@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**
This PR adds local geoblocking functionality for Germany (DE) and
Romania (RO) to the Predict feature.
**What is the reason for the change?**
The Predict feature needs to comply with regional regulations by
restricting access for users in specific countries. While the provider
(Polymarket) performs its own eligibility checks, we need an additional
layer of local geoblocking to ensure compliance.
**What is the improvement/solution?**
- Created a new constants file (`geoblock.ts`) that defines the list of
geo-blocked countries
- Added a private method `isLocallyGeoblocked()` to check if a user's
country is in the blocked list
- Modified the `refreshEligibility()` method to apply local geoblocking
after the provider's eligibility check
- When a provider returns `isEligible: true` but the country is in our
blocked list, we override it to `isEligible: false`
- The user's country code is preserved in the state for tracking and
analytics purposes
## **Changelog**
CHANGELOG entry: null
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: Predict geoblocking for DE and RO
Scenario: user from Germany is blocked from using Predict
Given app is running with Predict feature enabled
And user's location is detected as Germany (DE)
When user attempts to access Predict feature
Then user sees geoblocking message indicating feature is not available in their region
Scenario: user from Romania is blocked from using Predict
Given app is running with Predict feature enabled
And user's location is detected as Romania (RO)
When user attempts to access Predict feature
Then user sees geoblocking message indicating feature is not available in their region
Scenario: user from United States can access Predict
Given app is running with Predict feature enabled
And user's location is detected as United States (US)
When user attempts to access Predict feature
Then user successfully accesses the Predict feature
Scenario: provider blocks user but local check passes
Given app is running with Predict feature enabled
And provider's eligibility check returns ineligible
When user attempts to access Predict feature
Then user sees geoblocking message regardless of local geoblocking status
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- No geoblocking - users from DE and RO could access Predict if
provider allowed -->
### **After**
<!-- Users from DE and RO are blocked even if provider allows access -->
## **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.
---
## **Test Coverage**
This PR includes comprehensive unit and integration tests:
### Unit Tests (7 tests)
- `isLocallyGeoblocked()` method with DE, RO, and non-blocked countries
- Edge cases: empty string, lowercase, extra spaces, partial matches
### Integration Tests (7 tests)
- `refreshEligibility()` with local geoblocking logic
- Provider eligible + locally blocked countries (DE, RO)
- Provider eligible + allowed countries (US)
- Provider ineligible scenarios
- Edge cases: undefined, null, empty string countries
### Constants Tests (4 tests)
- Validation of GEO_BLOCKED_COUNTRIES array structure and contents
**Total: 18 new tests, all passing ✅**
### Files Changed
- `app/components/UI/Predict/constants/geoblock.ts` (new file)
- `app/components/UI/Predict/controllers/PredictController.ts`
(modified)
- `app/components/UI/Predict/controllers/PredictController.test.ts`
(tests added)
- `app/components/UI/Predict/constants/geoblock.test.ts` (new test file)
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Introduces a local geo-block list (DE, RO) and updates
PredictController to override provider eligibility based on it, with
comprehensive unit tests.
>
> - **PredictController (`controllers/PredictController.ts`)**:
> - Add `GEO_BLOCKED_COUNTRIES` import and private
`isLocallyGeoblocked()`.
> - Update `refreshEligibility()` to override provider `isEligible` to
false when country is locally blocked; preserve `country` in state.
> - **Constants (`constants/geoblock.ts`)**:
> - New `GEO_BLOCKED_COUNTRIES` list with `DE` and `RO`.
> - **Tests**:
> - New `constants/geoblock.test.ts` validating structure and entries.
> - Expanded `PredictController.test.ts` covering local geoblocking
flows (DE/RO block, allowed countries, undefined/null/empty), and
`isLocallyGeoblocked` edge cases.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
84cfbae. 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**
This PR adds a new cursor rule to enforce consistent feature flag usage
across the codebase. The rule prevents developers from creating new
feature flag selectors using `createSelector` and instead requires them
to use the `useFeatureFlag` hook.
**Reason for change:**
- The codebase has multiple patterns for accessing feature flags
(selectors vs hooks), leading to inconsistency
- New feature flag selectors are being created in various locations,
making it harder to maintain and migrate to a unified approach
- The `useFeatureFlag` hook provides a cleaner, more React-friendly API
for accessing feature flags in components
**Improvement/solution:**
- Added `.cursor/rules/feature-flag-guidelines.mdc` that automatically
applies to all files
- The rule explicitly forbids creating new `createSelector` instances
for feature flags
- The rule enforces using the `useFeatureFlag` hook from
`app/components/hooks/FeatureFlags/useFeatureFlag.ts`
- Provides clear examples of forbidden patterns and required patterns
- Includes migration guidance for existing code
## **Changelog**
CHANGELOG entry: null
## **Related issues**
Fixes:
## **Manual testing steps**
Feature: Feature flag guidelines enforcement
Scenario: developer attempts to create a new feature flag selector
Given a developer is working on a new feature that requires a feature
flag
When they try to create a new selector using createSelector for the
feature flag
Then the cursor rule should warn/prevent this pattern and suggest using
useFeatureFlag hook instead
Scenario: developer uses useFeatureFlag hook correctly
Given a developer needs to access a feature flag in a component
When they use the useFeatureFlag hook with a FeatureFlagNames enum value
Then the cursor rule should not flag any issues and the code should work
as expected## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
N/A - This is a development tooling change that doesn't affect the UI.
### **After**
<!-- [screenshots/recordings] -->
N/A - This is a development tooling change that doesn't affect the UI.
## **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 (N/A - cursor rule file, no
tests needed)
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable (N/A - markdown documentation file)
- [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]
> Adds a Cursor rule that mandates using the `useFeatureFlag` hook and
forbids creating new `createSelector`-based feature flag selectors.
>
> - **Tooling/Rules**:
> - Add `/.cursor/rules/feature-flag-guidelines.mdc`:
> - Enforces using `useFeatureFlag` and forbids new `createSelector`
feature flag selectors.
> - Includes usage steps, migration guidance, enforcement criteria, and
a single exception for `selectRemoteFeatureFlags`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
50faa30. 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** In this PR: - I enabled EAS updates for internal users. That's is all envs except for production and dev. However, with check automatically set to false, the users will not receive updates. - Fix Rive Animation issues on Android and iOS based on the PRs below iOS: rive-app/rive-react-native#344 Android: rive-app/rive-react-native#389 Builds: https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/fd79ecf5-0141-4a3f-91ab-cd9681648fe4 ## **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:Enabled EAS updates for preview channel ## **Related issues** Fixes:Rive animation with EAS updates introduced ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I’ve followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Enables EAS updates on the preview channel (no auto-check), surfaces OTA details in App Information, and patches Rive to load file:// assets on iOS/Android. > > - **OTA Updates**: > - Enable EAS Updates for `preview` channel with `runtimeVersion`, `updateUrl`, and `checkAutomatically: NEVER` via `scripts/update-expo-channel.js` (updates Android `meta-data` and iOS `Expo.plist`). > - Add `UPDATE_URL` export in `app/constants/ota.ts`. > - **Settings UI**: > - App Information view now displays `Expo Project ID`, `Update ID`, `channel`, `runtimeVersion`, `OTA Update URL`, `Check Automatically`, and status when revealed. > - Tests added to verify OTA info visibility and values. > - `expo-updates` mock extended with `url`, `checkAutomatically`, and resolved async methods. > - **Rive Animation (patch)**: > - Android: replace Volley-only path with `ResourceLoader` factory supporting `file://` (direct FS) and HTTP (Volley). > - iOS: split URL asset loading into file vs remote handlers; relax URL validation to allow file URLs. > - Apply Yarn patch to `rive-react-native@9.3.4` in `package.json`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 7b1d329. 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>
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 : )