[pull] main from MetaMask:main#295
Merged
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**
This PR unifies the approach for all test resourced:
- FixtureServer
- MockServer
- `n` Dapps server
- Anvil-Manager
- CommandQueueServer
All servers now follow the same structure and all implement the same
interface. This means that the management of each service belongs to its
own class reducing the need to have as many helper function in
`FixtureHelper.ts` as we used to.
Each resource now follows:
```typescript
interface Resource {
stop(): Promise<void>;
start(): Promise<void>;
isStarted(): boolean;
getServerPort(): number;
getServerStatus(): ServerStatus;
getServerUrl?: string;
}
```
This also lays the foundation for 100% non deterministic port allocation
as each resource will manage its own port instead of being derived from
outside and passed in to helper functions.
<!--
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]
> Unifies E2E test infra around a `Resource` interface, introduces
class-based servers (MockServerE2E, DappServer, enhanced
Fixture/CommandQueue/Anvil), removes legacy helpers, and updates tests
and configs accordingly.
>
> - **E2E Infrastructure**
> - Introduce `ServerStatus` and unified `Resource` interface; refactor
`FixtureServer`, `CommandQueueServer`, and `AnvilManager` to implement
it (add start/stop/status/port/url APIs).
> - Add `DappServer` (static file server via `serve-handler`) and
replace legacy `e2e/create-static-server.js`.
> - Replace function-based mock server with class-based
`e2e/api-mocking/MockServerE2E.ts` (proxy handling, allowlist,
live-request validation, health endpoints).
> - Rename stop methods for consistency (e.g., `ganache.quit()` ->
`stop()`, `AnvilManager.quit()` -> `stop()`).
> - **Fixture Helper**
> - Consolidate lifecycle management: start/stop servers inline,
`createMockAPIServer`, dapp/local-node handlers, cleanup and
live-request validation.
> - Remove old start/stop helpers; use `getServerPort()`/`getServerUrl`
where needed.
> - **Tests**
> - Update specs to new APIs (`withFixtures`, `MockServerE2E`,
`FixtureServer.start/stop`, `localNode.stop`).
> - Ensure `origin` is included in mocked POST bodies; adjust
timeouts/intervals; launch args use dynamic ports.
> - **Removals/Additions**
> - Remove `e2e/api-mocking/mock-server.ts` and
`e2e/create-static-server.js`.
> - Add `@types/serve-handler` dev dependency.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
8e55cf5. 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** Fix the inconsistent size of the close button in the "Swap" page "Select Token" bottom sheet and "Select Network" bottom sheet. We also took some time to refactor `BridgeNetworkSelectorBase` to use components from the design system similar to how `BridgeTokenSelectorBase` does it. <!-- 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: Fix the inconsistent size of the close button in the "Swap" page "Select Token" bottom sheet and "Select Network" bottom sheet. ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/SWAPS-3186 ## **Manual testing steps** ```gherkin When user navigates to swap page, the close icon button should much the size of the one presented in "select network"and "select tokens" bottom sheets. ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <img width="807" height="197" alt="image" src="https://github.com/user-attachments/assets/af7c767f-6240-4b4e-91e2-d79ce2e877fd" /> <img width="807" height="197" alt="image" src="https://github.com/user-attachments/assets/7418b099-7ca3-445f-86b5-6d0fff492880" /> <img width="807" height="197" alt="image" src="https://github.com/user-attachments/assets/270c1caa-6b72-4164-8bc8-6179ff0d4ee9" /> <!-- [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] > Standardizes close button sizing in Swap/Bridge token and network selectors and refactors the network selector base to the design-system header. > > - **UI — Bottom sheets**: > - Unify close button to `32x32` with `24px` icon via `ButtonIconSizes.Lg` in `BridgeTokenSelectorBase` and `BridgeNetworkSelectorBase` (affects source/dest token and network selectors). > - Refactor `BridgeNetworkSelectorBase` to use `BottomSheetHeader`; remove custom `Box`/`useStyles`, simplify header layout and content scroll. > - **Tests**: > - Update snapshots for `BridgeSource/DestTokenSelector` and `BridgeSource/DestNetworkSelector` to reflect header/layout and button size changes. > - Minor formatting tweak in `TokenInputArea.test.tsx`. > - **Misc**: > - Minor log formatting in `FontPreloader.preloadFontsNative`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 0925372. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** The `build-android-e2e` workflow now skips restoring the Gradle cache on runs where it's unused. Gradle dependencies are only needed for the full build, not for repack. This should save ~1.5 minutes per repack run. ## **Changelog** CHANGELOG entry: null ## **Related issues** N/A ## **Manual testing steps** N/A ## **Screenshots/Recordings** Test workflow runs: - Cache miss (different fingerprint id, restored previous cache): https://github.com/MetaMask/metamask-mobile/actions/runs/18980303557/job/54219367591 - Cache hit: https://github.com/MetaMask/metamask-mobile/actions/runs/18980303557/job/54232880801 ## **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] > Skips Gradle cache restoration on repack runs and keys APK/artifact caches to Gradle config, updating build/repack conditions accordingly. > > - **CI** (`.github/workflows/build-android-e2e.yml`): > - **Caching**: > - Add Gradle config hash to APK and build artifact cache keys. > - Restore Gradle cache only when APK cache misses. > - **Build flow**: > - Build APKs only on APK cache miss; repack only on APK cache hit. > - Update cache/save conditions to align with APK cache status. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit b2ee7d9. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** The XCode cache was continuously expanding in size because upon a cache miss, the previous cache was still restored and combined with the new updated dependencies. The workflow has been updated to no longer restore the XCode cache upon cache miss. This should save ~1.5 minutes per build. ## **Changelog** CHANGELOG entry: null ## **Related issues** N/A ## **Manual testing steps** N/A ## **Screenshots/Recordings** Test workflows: - Cache miss: https://github.com/MetaMask/metamask-mobile/actions/runs/18978738172/job/54205482403 - Cache hit + repack: https://github.com/MetaMask/metamask-mobile/actions/runs/18978738172/job/54210918267 - Cache hit + rebuild: https://github.com/MetaMask/metamask-mobile/actions/runs/18981164360/job/54217839569 ## **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] > Updates iOS E2E workflow to use a versioned Xcode cache key and remove restore-keys to avoid restoring stale caches. > > - **CI / GitHub Actions** > - **` .github/workflows/build-ios-e2e.yml`**: > - Xcode cache: add `env` var `XCODE_CACHE_VERSION: 1` and include it in cache `key`. > - Remove `restore-keys` from Xcode derived data cache to prevent restoring previous caches. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 26a45bb. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description**
PR to upgrade `@metamask/assets-controllers` package. It introduces
multiple breaking changes:
- Fetching exchangeRates from price api and fallback to crypto compare.
- Changes to selector calls to ignore manually selected non-evm assets.
- Changes to the number of networks enabled by default from
`@metamask/controller-utils`.
- This one makes a significant amount of changes to initial state and
onboarding.
- New events added to `AccountTrackerController`.
## **Changelog**
CHANGELOG entry: Fetch currency rates using price api and fallback to
crypto compare
## **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] -->
https://github.com/user-attachments/assets/3272157d-b239-4da5-b8f6-a520cbca0b3a
### **After**
<!-- [screenshots/recordings] -->
https://github.com/user-attachments/assets/627db2ca-8458-454b-9d08-587295d1f8f1
## **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]
> Switches currency rates to the Price API (with normalization), enables
more EVM mainnets by default, and updates selectors/tests and configs
accordingly.
>
> - **Engine/Controllers**:
> - `CurrencyRateController`: initialize with `tokenPricesService`
(Price API) and normalize persisted `currencyRates`.
> - `NetworkController` defaults: add Infura failovers and names for
`arbitrum-mainnet`, `bsc-mainnet`, `optimism-mainnet`,
`polygon-mainnet`, `sei-mainnet`.
> - `NetworkEnablementController` (patched): default-enable `Arbitrum`,
`BNB Chain`, `OP`, `Polygon`, `Sei`.
> - `AccountTrackerController` messenger: listen to
`NetworkController:networkAdded` and `KeyringController:unlock`.
> - **Selectors**:
> - Balances/Assets: include
`MultichainAssetsController.allIgnoredAssets` in calculations; wire
through in selectors; convert multichain asset selectors to memoized
selectors.
> - **UI/Tests**:
> - `AddressSelector` tests/snapshots: expect new EVM networks in
list/order.
> - `OnboardingSuccess`: remove network auto-add side effects; drop
associated test.
> - **E2E/Config**:
> - Allowlist `price.api.cx.metamask.io`; add Infura mock for
`sei-mainnet`; update initial background state and snapshots with new
networks and enabled map.
> - **Dependencies**:
> - Bump `@metamask/assets-controllers` to `^86.0.0`; use patched
`@metamask/network-enablement-controller`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
5ab6311. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Bernardo Garces Chapero <bernardo.chapero@consensys.net>
Co-authored-by: salimtb <salim.toubal@consensys.net>
…erps market details (#22090) ## **Description** ### Problem Users navigating from Perps Market Details to the Activity/Transactions view were unable to go back to the previous Perps screen. The back button was missing, leaving them stuck in the Activity tab. The user also doesn't directly route into the Perps tab. **Root Cause:** The `navigateToActivity()` function navigated directly to `Routes.TRANSACTIONS_VIEW`, which is a tab based screen (not a stack screen). This broke the navigation hierarchy, as jumping from a stack screen to a tab screen eliminates the navigation stack and back button. ### Solution Created a stack based Activity route `Routes.PERPS.ACTIVITY` that reuses the existing `ActivityView` component, enabling proper back navigation while maintaining all existing functionality as well as making the perps tab active ## **Changelog** CHANGELOG entry: Added stack based `Routes.PERPS.ACTIVITY` route with conditional back button support in `ActivityView` header. Users can now navigate back from Activity view to previous Perps screens while maintaining backward compatibility with existing tab based navigation. ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MDP-390 ## **Manual testing steps** ```gherkin Feature: Back navigation from Activity View Scenario: User navigates from Perps Market Details to Activity and back Given user is on Perps Market Details screen for BTC/USD And user has Perps transactions history When user taps "Go to Activity" button Then Activity view opens with Perps transactions tab selected And back button is visible in the header When user taps the back button Then user returns to Perps Market Details screen for BTC/USD And market data is still displayed ``` ## **Screenshots/Recordings** https://github.com/user-attachments/assets/c791622e-e055-4dff-8be7-db0a25a9128c ### **Before** <img width="500" alt="before" src="https://github.com/user-attachments/assets/0d6580b0-874c-4406-9033-444236843a60" /> ### **After** <img width="500" alt="before" src="https://github.com/user-attachments/assets/f2d45a1c-0aa2-4789-9c73-beab229a262f" /> ## **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] > Introduce `Routes.PERPS.ACTIVITY` and update Perps navigation to use it with optional back button, ensuring return from Activity to Perps; update types, routes, components, and tests. > > - **Navigation/Routes**: > - Add `Routes.PERPS.ACTIVITY` and register screen in `app/components/UI/Perps/routes/index.tsx` using `ActivityView` (header hidden). > - Update perps nav handlers to `navigate(Routes.PERPS.ACTIVITY, { redirectToPerpsTransactions: true, showBackButton: true })`. > - Extend `PerpsNavigationParamList` with `PerpsActivity` params (`redirectToPerpsTransactions`, `redirectToOrders`, `showBackButton`). > - **ActivityView**: > - Add optional in-view back header when `showBackButton` is true; hide default header via `setOptions({ headerShown: false })`. > - Handle back press with `canGoBack()`; keep existing tabs and filters behavior. > - **Perps Components**: > - `PerpsRecentActivityList`: "See All" now routes to `Routes.PERPS.ACTIVITY` with perps redirect + back button. > - **Tests**: > - Update/add tests for new route and params in `PerpsRecentActivityList.test.tsx`, `usePerpsNavigation.test.ts`, and `ActivityView/index.test.tsx` (including back button visibility/behavior). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 0a0f2c9. 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**
**What is the reason for the change?**
Users with corrupted `metaMetricsId` values (such as `""`, `"null"`, or
other invalid strings) were experiencing empty remote feature flags,
preventing them from receiving A/B test variants, gradual rollouts, and
platform-specific configurations.
**Root Cause:**
The `#getMetaMetricsId` method in `MetaMetrics.ts` only checked for
falsy values (`!metametricsId`), which failed to catch corrupted strings
like `""` (2-character string containing two double-quotes). This
corrupted ID would then be passed to `RemoteFeatureFlagController`,
where `generateDeterministicRandomNumber("")` would throw an error
during user segmentation processing, preventing feature flags from being
cached.
**What is the improvement/solution?**
Added a simple length validation check (`metametricsId.length < 32`) to
detect and regenerate corrupted IDs. Valid IDs are at least 32
characters (UUIDv4 = 36 chars, Hex = 66 chars), so this single check
catches all known corruptions:
- `""` (length 2)
- `"null"` (length 4)
- `"undefined"` (length 9)
- Any other short corrupted strings
The fix applies the same validation to both legacy Mixpanel IDs and new
MetaMetrics IDs, ensuring consistency and preventing crashes in
`RemoteFeatureFlagController`.
## **Changelog**
CHANGELOG entry: Fixed a bug where corrupted analytics IDs prevented
users from receiving remote feature flags
## **Related issues**
Fixes: #[ISSUE_NUMBER]
## **Manual testing steps**
```gherkin
Feature: MetaMetrics ID corruption recovery
Scenario: user with corrupted metaMetricsId gets feature flags
Given the user has a corrupted metaMetricsId stored (e.g., '""')
When the app initializes MetaMetrics
Then a new valid UUID is generated and stored
And remote feature flags are successfully fetched and cached
And the corruption is logged for monitoring
Scenario: user with valid metaMetricsId continues normally
Given the user has a valid metaMetricsId (length >= 32)
When the app initializes MetaMetrics
Then the existing ID is preserved
And remote feature flags work correctly
Scenario: legacy Mixpanel ID validation
Given the user has a legacy Mixpanel ID
When the ID length is >= 32
Then the legacy ID is migrated to MetaMetrics storage
When the ID length is < 32
Then a new UUID is generated instead
```
### **Unit Test Coverage**
Run the following to verify all corrupted ID scenarios are handled:
```bash
yarn jest app/core/Analytics/MetaMetrics.test.ts -t "corrupted ID validation"
```
Tests cover:
- ✅ JSON-stringified empty string (`""`)
- ✅ Too short IDs (`"abc"`)
- ✅ String literals (`"null"`, `"undefined"`)
- ✅ Invalid UUID formats
- ✅ Valid UUID acceptance
- ✅ Valid hex format acceptance
- ✅ Corrupted legacy Mixpanel ID rejection
## **Screenshots/Recordings**
This record goest over a branch switch from main to this branch with the
metametrics hardcoded to a string inside of a string
https://github.com/user-attachments/assets/9fc5bb8f-d61c-461d-8b6a-6315de36c6b8
### **Before**
User state with corrupted ID:
```json
{
"metaMetricsId": "\"\"",
"RemoteFeatureFlagController": {
"remoteFeatureFlags": {},
"cacheTimestamp": 0
}
}
```
Console logs would show silent failures in feature flag processing, with
users missing out on:
- A/B test variants
- Gradual feature rollouts
- Platform-specific configurations
### **After**
With the fix applied:
```
MetaMetrics: Corrupted metaMetricsId detected and regenerated. Invalid value: ""
```
User state after fix:
```json
{
"metaMetricsId": "12345678-1234-4567-89ab-123456789012",
"RemoteFeatureFlagController": {
"remoteFeatureFlags": {
"backendWebSocketConnection": { "value": true },
"perpsPerpTradingGeoBlockedCountriesV2": { "blockedRegions": [...] }
},
"cacheTimestamp": 1699564800000
}
}
```
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
---
## **Additional Context**
### **Files Changed**
- `app/core/Analytics/MetaMetrics.ts`: Added length validation to
`#getMetaMetricsId` method
- `app/core/Analytics/MetaMetrics.test.ts`: Added comprehensive test
suite for corrupted ID scenarios
### **Performance Impact**
- Negligible: Single length check is O(1) operation
- No additional API calls or storage operations
### **Backward Compatibility**
- ✅ Fully backward compatible
- ✅ Automatically heals users with existing corrupted IDs
- ✅ No migration required
- ✅ No user action needed
### **Monitoring**
The fix includes logging when corrupted IDs are detected:
```typescript
Logger.log(
`MetaMetrics: Corrupted metaMetricsId detected and regenerated. Invalid value: ${metametricsId}`,
);
```
This allows us to:
- Track how many users are affected
- Identify potential sources of corruption
- Monitor if the issue persists or is resolved
### **Security Considerations**
- No security implications
- Corrupted ID values are logged (for debugging), but they contain no
PII
- New generated UUIDs follow existing security practices
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Adds strict ID validation (UUIDv4 or legacy hex) for MetaMetrics,
regenerating corrupted IDs and migrating valid Mixpanel hex IDs.
>
> - **Analytics (`app/core/Analytics/MetaMetrics.ts`)**:
> - Validate stored `metaMetricsId` using `uuid.validate`; regenerate
with `uuidv4()` and log when invalid or corrupted.
> - Accept legacy Mixpanel ID only if it’s a valid hex address
(`isHexAddress(legacyId.toLowerCase())`); migrate to `METAMETRICS_ID`.
> - Import `validate` (uuid) and `isHexAddress` for the above checks.
> - **Tests (`app/core/Analytics/MetaMetrics.test.ts`)**:
> - Add cases covering valid hex Mixpanel IDs (including uppercase),
rejection of non-hex Mixpanel IDs, and multiple corruption scenarios
(`""`, short strings, `"null"`, `"undefined"`, invalid UUID), plus
acceptance of valid UUIDv4.
> - Use `uuid.validate` and `isHexAddress` assertions; update
expectations for storage interactions.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0bddd52. 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** Upgrade create-release-pr workflow to latest version which upgrades auto-changelog from v4 to v5 <!-- 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: https://consensyssoftware.atlassian.net/browse/INFRA-3013 ## **Manual testing steps** Testing using a metamask-mobile fork repository in consensys-test org https://github.com/consensys-test/metamask-mobile-test-workflow/actions/runs/19055114162/job/54423576490 ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** N/A - CICD Only <!-- [screenshots/recordings] --> ### **After** N/A - CICD Only <!-- [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] > Update `.github/workflows/create-release-pr.yml` to use `MetaMask/github-tools` reusable workflow at `749c0972` and set matching `github-tools-version`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 83f8d3d. 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 increases the height of the keyboard buttons from `40px` to `48px` to improve usability. This also ensures the text isn't cut off at the default size, `32px`. ## **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 - ui fix ## **Related issues** Fixes: https://consensys.slack.com/archives/C09GRCNR6JF/p1761754304249019 ## **Manual testing steps** ```gherkin Feature: Keypad Scenario: user interacts with keyboard buttons Given the user is on a screen with keyboard input fields When user interacts with the on-screen keyboard Then they should see larger buttons (48px) ``` ## **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/cf5f5eb8-2ac2-42cb-8bdc-fd5a528de044 ### **After** https://github.com/user-attachments/assets/e1bbab6e-38e2-49b4-a638-ab3c76d61a41 ## **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] > Increases keypad (including delete) button height from 40 to 48 across the app to match text size and improve touch targets. > > - **UI — Keypad**: > - Update `height` from `40` to `48` for keypad buttons in `app/components/Base/Keypad/components.tsx` (`keypadButton`, `keypadDeleteButton`). > - **Snapshots Updated**: > - Reflect new 48px keypad button height in `Keypad` and across views using it: `BridgeView`, `EarnInputView`, `EarnWithdrawInputView`, and Ramp `BuildQuote` snapshots. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 3fa251d. 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? --> Update assets-controllers with a set of changes for DeFi position fetching: Introduces timeouts and retries. Only fetches current account. Prevents any calls before onboarding is finished. ## **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: Changed how DeFi positions are fetch in the client to reduce amount of calls ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/ASSETS-1295 ## **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] > Updates DeFi positions to use account-tree scoped selection and enabled-network filtering, plus dependency bump to assets-controllers ^87. > > - **Selectors**: > - Replace `selectLastSelectedEvmAccount` with `selectSelectedInternalAccountByScope(EVM_SCOPE)` in `selectDeFiPositionsByAddress` and `selectDefiPositionsByEnabledNetworks`. > - Return `{} (NO_DATA)` when no EVM account or no enabled EVM networks; pass through `undefined` when no positions and `null` when stored as such. > - Filter positions by enabled `EIP155` networks only; add deprecation note to `selectDeFiPositionsByAddress`. > - **Engine/Messenger**: > - Delegate actions/events to `AccountTreeController` (`getAccountsFromSelectedAccountGroup`, `selectedAccountGroupChange`); remove `AccountsController`/`unlock` usage. > - **Tests**: > - Update selector tests to the account-tree model and new return semantics (`{} | undefined | null`). > - **Dependencies**: > - Upgrade `@metamask/assets-controllers` to `^87.0.0`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit c91c19d. 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?
-->
## **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]
> Unskips the perps “Add funds” E2E test that deposits $80 and verifies
the updated balance.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
a46be4a. 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** Moves the send native token spec due to flakiness: https://consensys.slack.com/archives/C02U025CVU4/p1762243312142959 <!-- 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] > Moves the send native asset E2E spec to `e2e/specs/quarantine/send-native-token.failing.ts`, marking it as a failing quarantine test that exercises send, 50%, and max flows against a local Anvil RPC. > > - **Tests**: > - Move/mark the send native asset E2E spec as failing in `e2e/specs/quarantine/send-native-token.failing.ts`. > - Covers sending ETH with fixed amount, 50%, and max. > - Uses `FixtureBuilder` with custom local RPC (Anvil) and app login/setup. > - Verifies confirmations via Activity tab. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit dbba7a1. 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?
-->
## **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]
> Updates onboarding performance test to use MetaMetrics "Continue"
button, remove security modal steps, and add visibility helpers in
screen objects.
>
> - **Tests (performance/onboarding)**:
> - Update
`appwright/tests/performance/onboarding/new-wallet-account-creation.spec.js`
to tap `MetaMetricsScreen.tapContinueButton()` and remove
`SkipAccountSecurityModal` visibility/continue steps.
> - **Screen Objects**:
> - `wdio/screen-objects/Onboarding/MetaMetricsScreen.js`:
> - Add `continueButton` getter and `tapContinueButton()` with
visibility wait.
> - `wdio/screen-objects/Onboarding/OnboardingScreen.js`:
> - Add `isScreenTitleVisible()` to assert visibility of
`createNewWalletButton`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
2c1a388. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description** Fixes bug where chat would render before historical candles would load. In this scenario, we would only render the latest candles (subscribes to via websocket connection) so the chart would appear broken since we were only rendering a single candle. This PR introduces logic to only render the chart after historical candles are fetched successfully. ## **Changelog** CHANGELOG entry: Only render perps candlestick chart when historical candles are fetched successfully ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TAT-1962 ## **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** https://github.com/user-attachments/assets/32df06f9-1252-4df1-87c5-4de053257656 ## **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] > Render the Perps chart only after historical candles are fetched (else show a skeleton), backed by a new hasHistoricalData flag in usePerpsPositionData and updated tests. > > - **UI (PerpsMarketDetailsView)**: > - Render `TradingViewChart` only when `hasHistoricalData` is true; otherwise show `Skeleton` placeholder. > - Compute `tpslLines` via `useMemo` and pass to chart. > - **Hook (`usePerpsPositionData`)**: > - Add `hasHistoricalData` state; set true only when valid historical candles exist. > - Return `null` `candleData` until historical data loads; update on refresh with same gating. > - Maintain live candle logic, merging only when historical data is present; update refresh logic to set flag appropriately. > - **Tests**: > - Update mocks/usages to include `hasHistoricalData`. > - Adjust expectations for empty candles (`undefined`) and loading/default states in `usePerpsMarketStats.test` and `usePerpsPositionData.test`. > - Ensure `PerpsMarketDetailsView` test accounts for gated chart rendering. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit f67f84b. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…22000) <!-- 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. Adds a new analytics event RAMPS_USER_DETAILS_FETCHED to track when user details are fetched during the deposit flow, enabling better visibility into user authentication patterns across different screens. 2. Adds `fetchOnMount` config property to `useDepositUser` which will eliminate extra calls for user details that were previously being fetched 3x when the deposit feature was opened. <!-- 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? 3. What is the improvement/solution? --> ### Changes - **New Analytics Event**: `RAMPS_USER_DETAILS_FETCHED` tracks: - `logged_in`: User authentication status - `region`: User's country code (with fallback to selected region) - `location`: Screen where the fetch occurred - **Enhanced Hooks**: - Added optional `screenLocation`, `onMount` and `shouldTrackFetch` parameters to `useDepositUser` - **Integration Points**: - `BuildQuote` screen - `useDepositRouting` hook ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: added new analytics tracking event when user details are fetched ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TRAM-2771 ## **Manual testing steps** ```gherkin Feature: User details fetched analytics Scenario: user opens the deposit feature Then user details tracking event is triggered and can be seen in segment ``` ## **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 - [ ] 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] > Introduces `RAMPS_USER_DETAILS_FETCHED` analytics and a configurable `useDepositUser` (screenLocation, shouldTrackFetch, fetchOnMount), updates routing and deposit screens to pass context, and extends analytics enums/tests. > > - **Analytics**: > - Add `RAMPS_USER_DETAILS_FETCHED` event to `AnalyticsEvents` and `MetaMetrics.events` enums/options. > - **Hooks**: > - Enhance `useDepositUser` with config: `screenLocation`, `shouldTrackFetch`, `fetchOnMount`; track fetch success/401; optional fetch-on-mount; maintain logout on 401. > - Update `useDepositRouting` to accept `screenLocation` and to use `useDepositUser` with tracking (no mount fetch) and pass context. > - **Screens/Flows**: > - Pass `screenLocation` via `useDepositRouting` in `AdditionalVerification`, `EnterAddress`, `KycProcessing`, and `KycWebviewModal`. > - Use `useDepositUser({ screenLocation: 'BuildQuote Screen', shouldTrackFetch: true, fetchOnMount: true })` in `BuildQuote`. > - **Tests/Utils**: > - Expand `useDepositUser` tests for config + analytics and 401 handling; simplify mock implementations. > - Adjust `useDepositRouting` tests (analytics expectation) and wire `screenLocation`. > - Strengthen test utils (`createMockSDKReturn` typed, add defaults like `selectedRegion`). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 25ac4b4. 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 implements a mechanism for optimistic updates when
selling/claiming market positions.
Reason being that Polymarket sometimes takes a long time to update the
positions data in their API (5-30 seconds).
With this approach, we store an array in memory of the last sold/claimed
positions for the past 5 minutes.
When obtaining positions from the API, we then filter out anything that
we know was sold/claimed recently.
In addition, a fix to the `claimablePositions` state was added, so
claimed positions can be stored on a per account basis.
This required some changes to the Claim confirmations logic.
One last thing was that the `usePredictPositions()` hook now returns
claimable positions directly from the Predict controller state. This
allows for refreshing claimable positions across different parts of the
UI simultaneously (e.g., when claiming positions, we want to clear the
claimable positions list across the whole UI immediately).
## **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] -->
https://github.com/user-attachments/assets/a7927d4b-0860-490f-9f70-d321d2d02001
## **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 optimistic filtering of recently sold/claimed positions and
migrates claimable positions to be keyed by account, updating selectors,
controller, provider, hooks, and UI accordingly.
>
> - **State & Selectors**
> - Change `PredictController.state.claimablePositions` from array to `{
[address]: PredictPosition[] }`; mark as `usedInUi`.
> - Update selectors to accept `address` and add
`selectPredictClaimablePositionsByAddress`.
> - **Controller**
> - Add `getSigner()` helper and use across
preview/place/deposit/withdraw/claim flows.
> - `getPositions` defaults to `polymarket` and stores claimables per
`address`.
> - Add `confirmClaim({ providerId })` to notify provider and clear
claimed positions for current address.
> - **Provider (Polymarket)**
> - Implement optimistic tracking of `recentlySoldPositions` (5‑min
TTL); filter in `getPositions`.
> - Support `confirmClaim({ positions, signer })` and add sold IDs on
SELL in `placeOrder` (using `preview.positionId`).
> - `previewOrder` accepts `signer`, preserves rate limiting; utils
include `positionId` for SELL.
> - **Hooks & UI**
> - Use selected address with new selectors in header/claim
toasts/confirmations.
> - `usePredictPositions`: when `claimable`, read positions from
controller state; default address fallback `'0x0'`.
> - `PredictSellPreview`: pass `positionId` to preview.
> - **Tests & Fixtures**
> - Update/extend tests for new state shape, optimistic filtering,
default provider, and address fallbacks.
> - Adjust initial background state fixture to new `PredictController`
schema.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
6d6142b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**
This PR performs comprehensive cleanup of the Perps codebase to
eliminate technical debt and improve maintainability through better
documentation and code organization.
### What is the reason for the change?
**Technical Debt Accumulated**: As the Perps feature evolved over
multiple iterations (HIP-3 upgrade, stream architecture migration, new
features), several issues accumulated:
1. **Unused Code**: 23 files (~52KB) with zero production references
remained in the codebase
2. **Incomplete Features**: Arbitrum L2 withdrawal feature
implementation was started but never completed/activated
3. **Outdated Documentation**: `PERPS_ARCH.md` in the component
directory was outdated and didn't follow project conventions
4. **Pattern Migrations Incomplete**: Modal components were replaced by
View pattern, but old Modal components remained
5. **Maintainability**: With 400+ files in the Perps directory, unused
code made navigation and contribution more difficult
### What is the improvement/solution?
**Three-Phase Cleanup**:
**Phase 1: Code Deletion** (23 files removed)
- Removed unused performance optimization features (image prefetch
hooks)
- Removed orphaned Arbitrum L2 features (7 files for unimplemented
withdrawal monitoring)
- Removed orphaned utilities with comprehensive tests but zero usage
- Removed deprecated modal components replaced by View pattern
**Phase 2: Documentation Improvement**
- Created comprehensive `docs/perps/perps-architecture.md` - High-level
architectural overview
- Created detailed `docs/perps/perps-screens.md` - All 16 views
documented with data flow
- Followed project conventions (snake_case naming, signal-over-noise
style)
- Migrated old `PERPS_ARCH.md` to proper docs location
**Phase 3: Verification**
- Exhaustive verification: searched entire codebase for all imports
- All 4,275 Perps tests passing
- No TypeScript errors introduced
- Test coverage maintained
-
### Files Deleted by Category
**Performance Optimization (Unused):**
- `hooks/usePerpsImagePrefetch.ts` + test - Image prefetch feature never
adopted
**Error Tracking (Replaced):**
- `hooks/usePerpsErrorTracking.ts` - Replaced by direct
`track(MetaMetricsEvents.PERPS_ERROR)` calls
**Arbitrum L2 Feature (Unimplemented):**
- `hooks/useArbitrumTransactionMonitor.ts` + test
- `services/ArbitrumWithdrawalService.ts` + test
- `utils/arbitrumWithdrawalDetection.ts` + test
- `utils/arbitrumWithdrawalTransforms.ts`
**Orphaned Utilities (Well-Tested, Zero Usage):**
- `utils/blockchainUtils.ts` + test - Replaced by
`usePerpsBlockExplorerUrl()` hook
- `utils/transactionUtils.ts` + test - 7-day lookback calculator never
called
- `components/TradingViewChart/utils/chartCalculations.ts` + test -
Chart component doesn't use these
**Modal Components (Replaced by View Pattern):**
- `components/PerpsCancelAllOrdersModal/` (3 files)
- `components/PerpsCloseAllPositionsModal/` (3 files)
**Also Deleted:**
- `app/components/UI/Perps/PERPS_ARCH.md` - Migrated to docs/perps/
**Total:** 23 files deleted (~52KB dead code)
### Verification Process
**For each file, verified:**
- ✅ Zero direct imports across entire codebase
- ✅ Not exported from any index files
- ✅ No dynamic or string-based references
- ✅ No usage in E2E tests
- ✅ Tests pass after deletion
**Test Fixes:**
- Fixed `PerpsFundingTransactionView.test.tsx` - Removed dead mock for
deleted `blockchainUtils`
## **Changelog**
CHANGELOG entry: Cleaned up Perps codebase by removing unused code and
improving documentation
## **Related issues**
Internal maintenance - no specific issue
## **Manual testing steps**
```gherkin
Feature: Perps Codebase Cleanup
Scenario: All core functionality still works
Given user opens Perps feature
When user navigates through all screens (Home, Markets, Order Entry, Positions)
Then all screens load correctly
And all functionality works as before
And no errors appear in console
Scenario: Trading flow unaffected
Given user is on PerpsOrderView
When user places a market order
Then order executes successfully
And fees calculate correctly
And position appears in positions list
Scenario: Position management unaffected
Given user has open positions
When user closes a position
Then position closes successfully
And P&L calculates correctly
Scenario: Documentation accuracy
Given developer opens docs/perps/perps-architecture.md
When developer reviews hook and component lists
Then all referenced files exist in codebase
And architecture diagrams are current
Scenario: View components replace modal components
Given user clicks "Close All Positions" from HomeView
When modal appears
Then PerpsCloseAllPositionsView is used (not Modal component)
And "Cancel All Orders" uses PerpsC ancelAllOrdersView
```
## **Screenshots/Recordings**
### **Before**
**Codebase State:**
- 417 total Perps files
- 23 files with zero references (dead code)
- Incomplete Arbitrum L2 feature files
- Modal components alongside View replacements
- Documentation in wrong location
**Issues:**
- Confusing for new contributors (which components to use?)
- Increased maintenance burden
- Outdated documentation
### **After**
**Codebase State:**
- 394 total Perps files (-23 files, -5.5%)
- Zero dead code files remaining
- Clean architectural patterns (Views only, no Modal/View duplication)
- Comprehensive documentation in proper location
**Improvements:**
- Clearer codebase structure
- Better developer onboarding (comprehensive docs)
- Easier to navigate and maintain
- Documented architectural patterns
**Test Results:**
```
Test Suites: 190 passed, 190 total
Tests: 4,275 passed, 2 skipped, 4,277 total
Time: 53.6 seconds
```
**TypeScript Validation:**
```
✅ No new TypeScript errors introduced
✅ No errors related to deleted files
```
**Documentation Created:**
- `docs/perps/perps-architecture.md` (460 lines) - High-level
architectural overview
- `docs/perps/perps-screens.md` (934 lines) - All 16 views documented
- `app/components/UI/Perps/README.md` (117 lines) - Developer quickstart
**Files Deleted:**
```bash
# 23 files total
hooks/usePerpsImagePrefetch.ts + test
hooks/usePerpsErrorTracking.ts
hooks/useArbitrumTransactionMonitor.ts + test
services/ArbitrumWithdrawalService.ts + test
utils/blockchainUtils.ts + test
utils/transactionUtils.ts + test
utils/arbitrumWithdrawalDetection.ts + test
utils/arbitrumWithdrawalTransforms.ts
components/TradingViewChart/utils/chartCalculations.ts + test
components/PerpsCancelAllOrdersModal/* (3 files)
components/PerpsCloseAllPositionsModal/* (3 files)
app/components/UI/Perps/PERPS_ARCH.md
```
## **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 (all existing tests pass, fixed
one test file)
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable (created comprehensive docs)
- [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.
---
## **Impact Summary**
| Metric | Before | After | Improvement |
|--------|--------|-------|-------------|
| **Total Files** | 417 | 394 | -23 files (-5.5%) |
| **Dead Code** | ~52KB | 0KB | -52KB (100% removal) |
| **Unused Hooks** | 3 | 0 | 100% removed |
| **Unused Components** | 2 modal dirs | 0 | 100% removed |
| **Unused Utils** | 6 | 0 | 100% removed |
| **Documentation Pages** | 1 (outdated) | 3 (comprehensive) | +200% |
| **Test Coverage** | ~95% | ~95% | Maintained |
| **Tests Passing** | 4,275 | 4,275 | No regressions |
## **Key Achievements**
✅ **Zero Functionality Lost** - All deletions exhaustively verified as
unused
✅ **Zero Breaking Changes** - All 4,275 tests passing
✅ **Better Documentation** - Comprehensive architectural docs following
project conventions
✅ **Improved Maintainability** - Cleaner codebase, easier navigation
✅ **Pattern Consistency** - Removed modal/view duplication, clear
patterns
## **For Reviewers**
**What to verify:**
1. All Perps functionality works (trading, positions, withdrawals, etc.)
2. Documentation references match actual files in codebase
3. No console errors when navigating Perps screens
4. Tests pass locally
**Low risk because:**
- Exhaustive verification: zero references found for all deleted files
- High test coverage maintained (95%)
- All automated tests passing
- Only deleted provably unused code
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Removes dead Perps code and deprecated modals, adds comprehensive
architecture/screens docs, and updates a funding transaction test to use
the block explorer hook.
>
> - **Perps cleanup and docs**:
> - Remove unused code: Arbitrum withdrawal monitoring
(hooks/services/utils + tests), image prefetch hooks, chart calculation
utils, deprecated modal components (`PerpsCancelAllOrdersModal`,
`PerpsCloseAllPositionsModal`) and their tests/styles, and
`app/components/UI/Perps/PERPS_ARCH.md`.
> - Add comprehensive documentation: `docs/perps/perps-architecture.md`
and `docs/perps/perps-screens.md`.
> - **Tests**:
> - Update `PerpsFundingTransactionView.test.tsx` to use
`usePerpsBlockExplorerUrl` and clean up mocks.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f1a2ada. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Co-authored-by: Nick Gambino <35090461+gambinish@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? --> Following the changes we made for caching the API, we now need to implement a cascade, as each method in the aggregator depends on the previous ones. To support this, we made some parameters required in the SDK: https://github.com/consensys-vertical-apps/va-mmcx-onramp-sdk/pull/147 We also refined the loading states in this PR to ensure they don’t block each other. This change will prevent the 'flash' that happened when opening the aggregator. ## **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: Improved buy/sell feature loading time. ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TRAM-2746?atlOrigin=eyJpIjoiZTU2ZTNlYzZiZjJkNGM0MjllNmFhMTBmZjhmM2YzZTIiLCJwIjoiaiJ9 ## **Manual testing steps** ```gherkin Feature: Cascading data fetching on BuildQuote screen Scenario: User opens the BuildQuote screen Given the user is on the Home screen And no data has been fetched yet When the user presses the "Buy" button And the bottom sheet opens And the user presses "Buy" again in the bottom sheet Then the BuildQuote screen should open And the app should first fetch Regions And once Regions are loaded, it should fetch Fiat Currencies And once Fiat Currencies are loaded, it should fetch Crypto Currencies And once Crypto Currencies are loaded, it should fetch Payment Methods And each dependent component should show a loading state until its required data is available And the "Get Quotes" button should remain disabled until all data is loaded ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/d38f40e1-30b5-4c9f-bf0d-fcb55b7bbd5e ### **After** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/a802ad10-791b-4799-9912-b58f94e843e5 **∼2s to load, no flashes** ## **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] > Refactors `BuildQuote` to load data incrementally with precise loading states, updates hooks/SDK params accordingly, and bumps `@consensys/on-ramp-sdk` to 2.1.12. > > - **UI — `BuildQuote`**: > - Integrates `isFetchingLimits` and refines `isFetching` aggregation; disables actions until required data is present. > - Adds skeletons/guards for region, fiat, asset, balance, and payment method selectors (`AmountInput`, `AssetSelectorButton`, `PaymentMethodSelector`). > - Adjusts region change flow to re-query default fiat without payment method dependency. > - **Hooks**: > - `useFiatCurrencies`: removes payment method param; splits `isFetchingFiatCurrency` (default) vs `isFetchingFiatCurrencies` (list); returns selected currency accordingly. > - `useCryptoCurrencies`: drops payment method IDs; fetches with `(regionId, fiatCurrencyId)`. > - `useLimits`: exposes `isFetching` and `queryGetLimits`. > - **SDK Context (`sdk/index.tsx`)**: > - Initializes `selectedPaymentMethodId` to `null` and stops persisting it to Redux. > - **Tests & Snapshots**: > - Update unit tests to new hook signatures/flags and revised loading/UI states. > - **Deps**: > - Bump `@consensys/on-ramp-sdk` from `2.1.11` to `2.1.12`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 10a71b7. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description**
Updates Hip3 risk disclaimer.
## **Changelog**
CHANGELOG entry: Updates Hip3 risk disclaimer.
## **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]
> Makes the perps risk disclaimer source dynamic (based on market),
updates copy to "TradingView.", and adjusts i18n and tests accordingly.
>
> - **Perps UI (`PerpsMarketDetailsView.tsx`)**:
> - Add `riskDisclaimerParams` (from `market.marketSource` fallback to
`"Hyperliquid"`) and pass to `strings('perps.risk_disclaimer', ...)`.
> - Update link label text to `TradingView.`
> - **i18n (`locales/languages/en.json`)**:
> - Change `perps.risk_disclaimer` to use `Powered by {{source}}. Price
chart powered by`.
> - **Tests (`PerpsMarketDetailsView.test.tsx`)**:
> - Expect `TradingView.` label and keep URL
`https://www.tradingview.com/` in link-open assertions.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
dae3aa8. 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**
Increases timeout of multi srp spec file and removes synchronization
enable step.
<!--
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]
> Increase account visibility assertion timeout to 20s and remove a
sync-enable step in the multi-SRP e2e test.
>
> - **E2E Test
(`e2e/specs/identity/account-syncing/multi-srp.spec.ts`)**:
> - Increase assertion timeout to `20000` for account visibility checks.
> - Remove `device.enableSynchronization()` before verifying accounts
after importing the second SRP.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d637d8c. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description** This pull request adds support for a new "unified buy" button to the `FundActionMenu` component, which conditionally appears based on the result of the `useRampsUnifiedV1Enabled` hook. The changes update both the UI logic and the associated tests to ensure the new button is rendered and behaves as expected. Additional test coverage is added for the new feature, and new selector/test IDs and localization strings are introduced. **Feature: Unified Buy Button Integration** * Added a new "unified buy" button to the `FundActionMenu`, which is shown only when `useRampsUnifiedV1Enabled` returns true. The button uses its own test ID and localized label/description, and its navigation currently matches the standard buy button. The visibility of the existing "deposit" and "buy" buttons is updated to be mutually exclusive with the unified buy button. (`FundActionMenu.tsx`, `WalletActionsBottomSheet.selectors.ts`, `en.json`) [[1]](diffhunk://#diff-da0da05b6572b7ac895a5e513d491d8f73c7c9d01d1ce4035b5dc5c402eb3db5R37) [[2]](diffhunk://#diff-da0da05b6572b7ac895a5e513d491d8f73c7c9d01d1ce4035b5dc5c402eb3db5R54) [[3]](diffhunk://#diff-da0da05b6572b7ac895a5e513d491d8f73c7c9d01d1ce4035b5dc5c402eb3db5R107-R142) [[4]](diffhunk://#diff-da0da05b6572b7ac895a5e513d491d8f73c7c9d01d1ce4035b5dc5c402eb3db5L129-R160) [[5]](diffhunk://#diff-da0da05b6572b7ac895a5e513d491d8f73c7c9d01d1ce4035b5dc5c402eb3db5L175-R211) [[6]](diffhunk://#diff-6c99823ce7c6a0af29e6a36f587b71f2e6107cd6e4a059f60e63836198415d66R6) [[7]](diffhunk://#diff-c31c440a532cfa87d12df6a7c76ac83d0e80ee9b8b7fe38a274204000eaa0948R2959-R2960) **Testing: Expanded Test Coverage** * Updated and expanded tests in `FundActionMenu.test.tsx` to mock the new hook, verify the conditional rendering of the unified buy button, and ensure its navigation behavior matches the standard buy button. (`FundActionMenu.test.tsx`) [[1]](diffhunk://#diff-9d0f1d3a614826d7433c48bcc9735f974b5c2d84a875695b50ac701ce391d247R17) [[2]](diffhunk://#diff-9d0f1d3a614826d7433c48bcc9735f974b5c2d84a875695b50ac701ce391d247R58) [[3]](diffhunk://#diff-9d0f1d3a614826d7433c48bcc9735f974b5c2d84a875695b50ac701ce391d247R84-R87) [[4]](diffhunk://#diff-9d0f1d3a614826d7433c48bcc9735f974b5c2d84a875695b50ac701ce391d247R137) [[5]](diffhunk://#diff-9d0f1d3a614826d7433c48bcc9735f974b5c2d84a875695b50ac701ce391d247L224-R231) [[6]](diffhunk://#diff-9d0f1d3a614826d7433c48bcc9735f974b5c2d84a875695b50ac701ce391d247R242-R255) [[7]](diffhunk://#diff-9d0f1d3a614826d7433c48bcc9735f974b5c2d84a875695b50ac701ce391d247R303-R316) ## **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: Adds a unified Buy button behind a feature flag ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TRAM-2804 ## **Manual testing steps** ```gherkin Feature: Unified Buy button Scenario: User wants to buy a token Given unified v1 feature flag is off When user opens the Buy menu Then they see Deposit and Buy buttons Scenario: User wants to buy a token Given unified v1 feature flag is on When user opens the Buy menu Then they see a single Buy button ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <img width="399" alt="image" src="https://github.com/user-attachments/assets/6e4719b3-c2f4-4265-8d3a-466b1e914a88" /> ### **After** <img width="399" height="2622" alt="image" src="https://github.com/user-attachments/assets/4742e980-d830-480d-8620-a62f20dc99ad" /> ## **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 feature-flagged unified Buy button to `FundActionMenu`, updates visibility logic, selectors, i18n, and tests to support it. > > - **UI/FundActionMenu**: > - Add `buy-unified` action in `FundActionMenu.tsx` controlled by `useRampsUnifiedV1Enabled`; uses existing Buy navigation and analytics (skips when `customOnBuy`). > - Adjust visibility: hide legacy `buy` and `deposit` when unified is enabled; keep existing `sell` behavior; update memo deps. > - Extend `ActionConfig.type` with `"buy-unified"` in `FundActionMenu.types.ts`. > - **Testing**: > - Expand `FundActionMenu.test.tsx` to mock `useRampsUnifiedV1Enabled`, verify conditional rendering of `BUY_UNIFIED_BUTTON`, and ensure navigation matches Buy. > - **E2E Selectors**: > - Add `WalletActionsBottomSheetSelectorsIDs.BUY_UNIFIED_BUTTON`. > - **Localization**: > - Add `fund_actionmenu.buy_unified` and `fund_actionmenu.buy_unified_description` strings in `en.json`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 18f1131. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…1) (#21869) # Deep Link Consolidation - Phase 1: Core Types & Normalizer Fixes: https://github.com/MetaMask/mobile-planning/issues/2343 https://consensyssoftware.atlassian.net/jira/polaris/projects/MWMR/ideas/view/8845676?selectedIssue=MWMR-10 ## Overview This PR introduces the foundational infrastructure for consolidating MetaMask Mobile's fragmented deep link handling system. It creates a unified representation and normalization layer for all deep links, establishing a consistent pattern for handling `metamask://` and `https://` protocols. ## Problem The current deep link system has routing logic spread across multiple files using nested switch-case statements, making it difficult to: - Understand the complete set of supported deep links - Maintain consistency across different protocols - Add new deep link actions - Test deep link handling comprehensively ## Solution This PR implements: 1. **Unified Type System** - Single source of truth for deep link structure 2. **CoreLinkNormalizer** - Converts all deep link formats to a standardized representation 3. **Protocol Conversion** - Bidirectional transformation between `metamask://` and `https://` formats 4. **Comprehensive Testing** - 30 test cases covering all functionality ## Testing ### Run Tests ```bash yarn jest app/core/DeeplinkManager/CoreLinkNormalizer.test.ts ``` **Expected Output:** ``` PASS app/core/DeeplinkManager/CoreLinkNormalizer.test.ts ✓ All 30 tests passing ``` ### Run Linting ```bash yarn eslint 'app/core/DeeplinkManager' --fix ``` ### Run TypeScript Check ```bash yarn lint:tsc ``` All commands should pass without errors. ## Examples ### Normalizing a Deep Link ```typescript import { CoreLinkNormalizer } from './core/DeeplinkManager/CoreLinkNormalizer'; // Normalize a metamask:// link const link = CoreLinkNormalizer.normalize( 'metamask://swap?from=ETH&to=DAI&amount=100', 'qr-code' ); console.log(link); // { // protocol: 'metamask', // action: 'swap', // params: { // from: 'ETH', // to: 'DAI', // amount: '100', // swapPath: 'swap?from=ETH&to=DAI&amount=100' // }, // source: 'qr-code', // timestamp: 1698765432000, // originalUrl: 'metamask://swap?from=ETH&to=DAI&amount=100', // normalizedUrl: 'https://link.metamask.io/swap?from=ETH&to=DAI&amount=100', // isValid: true, // isSupportedAction: true, // isPrivateLink: false, // requiresAuth: false // } ``` ### Converting Protocols ```typescript // Convert to metamask:// protocol const metamaskUrl = CoreLinkNormalizer.toMetaMaskProtocol(link); // 'metamask://swap?from=ETH&to=DAI&amount=100' ``` ### Building Deep Links ```typescript // Build a new deep link const sendLink = CoreLinkNormalizer.buildDeeplink('metamask', 'send', { to: '0x1234567890abcdef', value: '1000000000000000000', hr: true }); // 'metamask://send?to=0x1234567890abcdef&value=1000000000000000000&hr=1' ``` ### Validating Deep Links ```typescript // Check if a URL is a supported deep link const isValid = CoreLinkNormalizer.isSupportedDeeplink('metamask://swap'); // true const isInvalid = CoreLinkNormalizer.isSupportedDeeplink('metamask://unknown-action'); // false ``` ## Backward Compatibility This PR introduces new infrastructure but **does not modify existing deep link handling**. The new system runs in parallel with the existing system and has no impact on current functionality. The next PR (Legacy Adapter) will provide the bridge between this new system and the existing deep link handlers. ### Follows Guidelines - ✅ AAA test pattern (Arrange, Act, Assert) - ✅ No "should" in test descriptions - ✅ One behavior per test - ✅ Comprehensive edge case coverage - ✅ Proper TypeScript types (no `any`) - ✅ All dependencies mocked - ✅ JSDoc comments on public methods - ✅ MetaMask coding standards ## Next Steps **Phase 1, PR 2**: Legacy Adapter - Create `LegacyLinkAdapter` to bridge new and old systems - Implement conversion between CoreUniversalLink and legacy formats - Enable gradual migration without breaking changes **Phase 2**: Universal Router - Create `UniversalRouter` singleton - Implement handler registry - Define handler interfaces **Phase 3**: Integration - Integrate router into DeeplinkManager - Add feature flag for gradual rollout - Full migration from legacy system ## Risk Assessment **Risk Level**: Low **Rationale:** - No modifications to existing code - Isolated to new files - Comprehensive test coverage - No runtime impact until integration ## Related Documentation - Project Prompt: `/DEEPLINK_CONSOLIDATION_PROMPT.md` - Implementation Summary: `/.kylan-docs/deep-link-consolidation-pr1-summary.md` --- ## Reviewer Checklist - [ ] All tests pass (`yarn jest app/core/DeeplinkManager/CoreLinkNormalizer.test.ts`) - [ ] No linting errors (`yarn eslint 'app/core/DeeplinkManager' --fix`) - [ ] TypeScript compiles without errors (`yarn lint:tsc`) - [ ] Code follows MetaMask coding guidelines - [ ] Test coverage is comprehensive (30 test cases) - [ ] No breaking changes to existing functionality - [ ] JSDoc comments are clear and accurate - [ ] Type definitions are appropriate and safe <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Introduces a unified deep link normalizer and core link types, adds tests, updates hr handling, and registers the ramp action. > > - **Core deep link infrastructure**: > - **CoreLinkNormalizer** (`app/core/DeeplinkManager/CoreLinkNormalizer.ts`): normalizes deeplinks, converts protocols, validates support, and builds links. > - **Types** (`app/core/DeeplinkManager/types/CoreUniversalLink.ts`): defines `CoreUniversalLink`/`CoreLinkParams` and action/protocol groupings (auth-required, SDK, ramp, perps, supported protocols, default action). > - **Tests** (`app/core/DeeplinkManager/CoreLinkNormalizer.test.ts`): covers normalization, protocol conversion, validation, and param handling. > - **Deeplink handling tweaks**: > - Ensures `hr` is treated boolean (`!!params.hr`) in `handleMetaMaskDeeplink` and parsed from `'1'` in `extractURLParams`. > - **Constants**: > - Adds `ACTIONS.RAMP` to `app/constants/deeplinks.ts`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit eb455f3. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: SteP-n-s <stylianos.panagakos@consensys.net>
## **Description** This PR enhances the Carousel component with a polished empty state experience and fixes several animation flow issues: 1. **Added Rive Confetti Animation to Empty Card**: Integrated the `Carousel_Confetti.riv` animation as a background layer that triggers when the empty card transitions to the main stage, playing once before auto-dismiss. 2. **Fixed Last Card Dismissal Flow**: Resolved bugs where: - The empty card would appear and disappear too quickly without proper animation - Cards would reappear after dismissal on app reload - The last card's close animation was being interrupted by Redux state updates 3. **Improved Animation Sequencing**: Ensured smooth transitions where: - The last non-empty card fades out - The empty card properly transitions from background to main stage - Confetti animation plays during the 1000ms idle period - The carousel then auto-dismisses without visual glitches The implementation uses animated value listeners to detect when the empty card reaches full visibility, ensuring the confetti animation only triggers at the right moment in the transition sequence. ## **Changelog** CHANGELOG entry: Enhanced carousel empty state with confetti animation and improved dismissal flow animations ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/jira/software/c/projects/DSYS/boards/1888?selectedIssue=DSYS-175 ## **Manual testing steps** ```gherkin Feature: Carousel empty state animation Scenario: User dismisses last carousel card Given the wallet page displays a carousel with 1+ slides When user clicks the close button on the last slide Then the card fades out smoothly And the empty state card transitions from background to main stage And confetti animation plays once as the empty card becomes visible And after 1000ms the carousel auto-dismisses with fold-up animation And the carousel does not reappear on app reload Scenario: Empty card does not show on reload when all slides dismissed Given all carousel slides have been dismissed When user closes and reopens the app Then the carousel does not render And no empty state card appears ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** ### **After** https://github.com/user-attachments/assets/50db5a1a-2ce4-4326-a071-3f7db0524d5a When theres no more card https://github.com/user-attachments/assets/b0597dd0-cade-4835-9785-60944237162b --- ## **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 confetti-animated empty state and refactors carousel transitions to reliably dismiss the last card and auto-hide the carousel. > > - **Carousel/Empty State**: > - **Rive Confetti**: Triggers on empty card when `emptyStateOpacity` ~1 using an Animated listener; robust error handling and cleanup for timers/listeners. > - **Auto-dismiss**: Uses `ANIMATION_TIMINGS.EMPTY_STATE_IDLE_TIME` (2000ms) to fold up via `useTransitionToEmpty`. > - **Last-card flow**: Tracks dismissal with `dismissingLastCardRef` to keep the empty card visible during the final transition; conditionally injects `empty` slide; resets flags in transition callback. > - **Transition fixes**: Adjusts current/next card animation states when transitioning to the empty card; only passes `onTransitionToEmpty` when empty card is current. > - **StackCard**: > - Removes empty-card handling and `onTransitionToEmpty`; always renders regular card layout. > - **Animations**: > - Centralizes timings via `AnimationDuration`; updates card enter/exit and empty-state idle/fold timings in `animations/animationTimings.ts`. > - **Tests**: > - Expands `StackCardEmpty` tests (timeouts, listener setup/cleanup, overlay) and mocks `rive-react-native`. > - Updates transition hook tests to use shared `ANIMATION_TIMINGS` and fake timers. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 614648b. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
… fails cp-7.58.0 (#22142) <!-- 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** Improved error catching block to know when feature flag update fails <!-- 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] > Improve feature flag update error logging and update onboarding tests to handle security modal and use the “I Agree” CTA. > > - **Engine**: > - Refine error handling in `app/core/Engine/controllers/remote-feature-flag-controller-init.ts` to log a clearer message on failure: `Logger.log('Feature flags update failed: ', error)`; retain success log `Feature flags updated`. > - **Tests**: > - `remote-feature-flag-controller-init.test.ts`: > - Mock `Logger` and add assertions for success and failure logs when `updateRemoteFeatureFlags` resolves/rejects. > - Preserve checks for controller initialization, arguments, and disabled behavior. > - **Onboarding E2E/Appwright**: > - `appwright/tests/performance/onboarding/new-wallet-account-creation.spec.js`: handle `SkipAccountSecurityModal` and switch from `tapContinueButton` to `tapIAgreeButton`. > - `wdio/screen-objects/Onboarding/MetaMetricsScreen.js`: remove `continueButton`/`tapContinueButton`; use `iAgreeButton` and `tapIAgreeButton`. > - `wdio/screen-objects/Onboarding/OnboardingScreen.js`: remove unused `isScreenTitleVisible` method. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 854f2a8. 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**
- Various visual tweaks on the predict market details screen
- Moves the resolved outcomes dropdown below the active outcome list
<!--
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: NA
## **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]
> Adjusts outcome status rendering to show Winner/Loser text with icon
and tweaks resolved outcomes list styling; adds new localization
strings.
>
> - **UI/Predictions**:
> - `PredictMarketOutcome.tsx`: Replace icon-only result with
`Winner`/`Loser` label (i18n) and show confirmation icon only for
winners; remove previous winner badge.
> - `PredictMarketDetails.tsx`: Update resolved outcomes list spacing
and conditional text color; add confirmation icon when the leading token
is first.
> - **Localization**:
> - Add `predict.outcome_winner` and `predict.outcome_loser` to
`locales/languages/en.json`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
363f272. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description** The network badges for the tokens are missing a border ## **Changelog** CHANGELOG entry:null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MDP-381 ## **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** `~` ### **Before** <img width="500" alt="Simulator Screenshot - iPhone 16 Pro Max - 2025-11-04 at 11 57 17" src="https://github.com/user-attachments/assets/27f35526-db30-4ee3-85cf-61554fa38bda" /> ### **After** <img width="500" alt="Simulator Screenshot - iPhone 16 Pro Max - 2025-11-04 at 12 08 40" src="https://github.com/user-attachments/assets/97ae6d44-cdb7-4b2a-b642-5a2ac5e5fc36" /> <!-- [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] > Set the token network badge border to white and update BridgeView snapshots accordingly. > > - **UI**: > - `TokenButton`: Remove custom `networkBadge` style and stop passing it to `Badge`, resulting in a white (`#ffffff`) border for `BadgeVariant.Network`. > - **Tests**: > - Update `BridgeView` snapshots to reflect the white network badge border. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit ad56eed. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Convert quotes copy from title case to sentence case ## **Changelog** CHANGELOG entry:null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MDP-382 ## **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** `~` ### **Before** <img width="500" height="2868" alt="Simulator Screenshot - iPhone 16 Pro Max - 2025-11-04 at 11 34 48" src="https://github.com/user-attachments/assets/36bbc25e-b786-4dbe-abaa-75bdb7edc181" /> <!-- [screenshots/recordings] --> ### **After** <img width="500" alt="Simulator Screenshot - iPhone 16 Pro Max - 2025-11-04 at 11 57 17" src="https://github.com/user-attachments/assets/ade40e0a-1af0-4bff-9682-515846894ed1" /> ## **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] > Converts Bridge quote details copy to sentence case and updates i18n, tests, and snapshots accordingly. > > - **Bridge UI – Quote details**: > - Change labels to sentence case: `Network fee`, `Price impact`, `Minimum received`. > - **i18n**: > - Update English strings in `locales/languages/en.json` to sentence case for corresponding Bridge keys (`network_fee`, `price_impact`, `minimum_received`). > - **Tests**: > - Adjust `QuoteDetailsCard.test.tsx` expectations and snapshots to match new casing. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 6654c36. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
#22149) ## **Description** This PR adds comprehensive test coverage for UUID version 4 validation in the MetaMetrics ID generation logic and fixes related TypeScript type errors. **What is the reason for the change?** The validation logic at `MetaMetrics.ts:313-316` checks that stored MetaMetrics IDs are valid UUIDv4 format using `validate()` and `version()` checks. However, there were no test cases covering the `version(metametricsId) !== 4` condition, and several existing tests were using invalid UUIDs (NIL UUID with all zeros) which is not a version 4 UUID. Additionally, TypeScript was reporting errors because `getMetaMetricsId()` was typed to return `Promise<string | undefined>`, but the implementation always returns a string (generates a new UUID if none exists). **What is the improvement/solution?** 1. **Added 4 new test cases** to cover UUID version validation: - Regenerates ID when stored ID is version 1 UUID (time-based) - Regenerates ID when stored ID is version 3 UUID (MD5-based) - Regenerates ID when stored ID is version 5 UUID (SHA1-based) - Regenerates ID when stored ID is NIL UUID (all zeros) 2. **Fixed 3 existing tests** that were incorrectly using `'00000000-0000-0000-0000-000000000000'` (NIL UUID, version 0) as test data. Changed to use valid UUIDv4 format `'12345678-1234-4234-b234-123456789012'`. 3. **Fixed TypeScript errors**: - Changed `getMetaMetricsId()` return type from `Promise<string | undefined>` to `Promise<string>` in `MetaMetrics.ts` - Updated `ControllerInitRequest` type to reflect that `metaMetricsId` is always provided at runtime - Added temporary `@ts-expect-error` comment in `Engine.ts` (see Related issues below) All tests now pass and properly validate that only UUIDv4 format is accepted. ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: #22148 > **Note**: This PR adds a temporary `@ts-expect-error` comment in `Engine.ts` to handle a type compatibility issue. The complete fix (restructuring Engine constructor parameters) will be addressed in the follow-up issue #22148 to avoid scope creep. ## **Manual testing steps** ```gherkin Feature: MetaMetrics UUID Version Validation Scenario: user has corrupted MetaMetrics ID with wrong UUID version Given the app has a stored MetaMetrics ID that is not version 4 UUID When the app initializes and MetaMetrics configures Then a new valid UUIDv4 should be generated And the new ID should be stored And a log message should indicate the corrupted ID was detected Scenario: user has valid UUIDv4 MetaMetrics ID Given the app has a stored valid version 4 UUID When the app initializes and MetaMetrics configures Then the existing UUID should be preserved And no new ID should be generated ``` **Testing commands:** ```bash # Run the specific test suite yarn jest app/core/Analytics/MetaMetrics.test.ts # Run with coverage yarn test:unit:coverage -- app/core/Analytics/MetaMetrics.test.ts ``` ## **Screenshots/Recordings** N/A - This is a test coverage and TypeScript fix PR with no UI changes. ### **Before** - 3 tests failing due to NIL UUID validation - TypeScript errors for `metaMetricsId` type mismatches - No test coverage for UUID version validation ### **After** - All 57 tests passing (54 existing + 3 newly fixed tests) - 4 new test cases covering UUID version validation (v1, v3, v5, NIL) - TypeScript errors resolved - Complete test coverage for the UUID validation logic ## **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.
Fixes: https://github.com/MetaMask/mobile-planning/issues/2340 This PR implements dynamic signature parameter verification for deeplinks by respecting the `sig_params` query parameter when validating signed URLs. ### What is the reason for the change? Previously, the client-side signature verification was verifying ALL URL parameters when checking deeplink signatures. However, the server-side `link-signer-api` supports signing only specific parameters (listed in `sig_params`), allowing for flexible link generation where additional parameters can be added without breaking the signature. The client verification logic was not aligned with this server behavior. ### What is the improvement/solution? Updated the `canonicalize()` function in `verifySignature.ts` to: - Check for the presence of `sig_params` in the URL - When present, only include the parameters listed in `sig_params` (plus `sig_params` itself) in the canonical URL used for signature verification - Maintain backward compatibility by falling back to the old behavior (verify all params) when `sig_params` is absent This enables: - **Dynamic signing**: Server can sign links with arbitrary parameter subsets - **Forward compatibility**: New unsigned parameters can be added to links without invalidating signatures - **Alignment**: Client verification now matches server signing logic Added comprehensive unit tests covering: - Basic `sig_params` functionality - Edge cases (empty values, missing parameters, special characters) - Backward compatibility scenarios - Parameter sorting and canonicalization ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: <!-- Add issue number if applicable --> ## **Manual testing steps** ```gherkin Feature: Dynamic deeplink signature verification Scenario: user opens a deeplink with sig_params Given a signed deeplink URL contains sig_params=channel,source And the URL has additional unsigned parameters When the app verifies the signature Then only the parameters listed in sig_params are used for verification And the signature validation succeeds Scenario: user opens a legacy deeplink without sig_params Given a signed deeplink URL without sig_params parameter When the app verifies the signature Then all parameters (except sig) are used for verification And backward compatibility is maintained ``` ## **Screenshots/Recordings** Not applicable - internal signature verification logic change with no UI impact. ## **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 (✅ Added 10 new comprehensive unit tests) - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable (✅ Added inline comments explaining critical logic) - [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). <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Updates canonicalization to verify only parameters listed in `sig_params` (plus `sig_params`), with legacy fallback when absent, and adds comprehensive tests for these cases. > > - **Deeplink signature verification (`verifySignature.ts`)**: > - Update `canonicalize(url)` to, when `sig_params` is present, include only listed existing params plus `sig_params`, then sort and build the canonical URL. > - Preserve legacy behavior by removing `sig` and sorting all params when `sig_params` is absent. > - **Tests (`verifySignature.test.ts`)**: > - Add cases covering inclusion of only `sig_params`-listed params, inclusion of `sig_params` itself, empty/missing params, multiple params with sorting, special characters, trailing commas, and backward compatibility without `sig_params`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 41551fe. 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 is to temporally disable the prediction automation test.
<!--
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]
> Comments out the prediction market smoke test jobs and removes them
from report dependencies in both Android and iOS E2E workflows.
>
> - **CI / GitHub Actions**:
> - **Android**:
> - Disable `prediction-market-android-smoke` job (commented out).
> - Remove `prediction-market-android-smoke` from
`report-android-smoke-tests.needs`.
> - **iOS**:
> - Disable `prediction-market-ios-smoke` job (commented out).
> - Remove `prediction-market-ios-smoke` from
`report-ios-smoke-tests.needs`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
818e339. 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** - fix market details header - fix market feed header - fix avatars <!-- 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] > Refactors Predict headers and avatar sizing, passes `title`/`image` to market details for instant header render, and adds `estimateLineCount` with tests. > > - **Predict UI**: > - **Market Details header**: New structure/alignment using `estimateLineCount`; accepts `title`/`image` from route params; spacing and icon sizes tweaked. > - **Feed header**: Adjusts vertical padding (`pt-2 pb-4`). > - **Avatars/images**: Standardize to `w-10 h-10` in market cards and position details; minor skeleton/card margin tweaks in `PredictBalance`. > - **Navigation**: > - Extends `PredictMarketDetails` params with optional `title` and `image`. > - Updates `PredictMarketSingle`/`Multiple` to pass `title` and `image` when navigating; tests updated accordingly. > - **Utils & Tests**: > - Adds `estimateLineCount` in `utils/format` and extensive unit tests. > - Updates `PredictMarketDetails` to use the utility and adjusts related mocks/tests. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 10a03fa. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Update copy for perps trade action menu ## **Changelog** CHANGELOG entry:null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MDP-378 ## **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** `~` ### **Before** <img width="500" alt="Simulator Screenshot - iPhone 16 Pro Max - 2025-11-04 at 13 09 26" src="https://github.com/user-attachments/assets/9e207819-4ef9-40c4-96c2-56d5ddf06064" /> ### **After** <img width="500" alt="Simulator Screenshot - iPhone 16 Pro Max - 2025-11-04 at 13 08 45" src="https://github.com/user-attachments/assets/0685f22a-c19f-4886-b59b-76678bb2b80d" /> ## **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] > Updates the `perps_description` string in `locales/languages/en.json` from “Trade perp contracts” to “Trade perps contracts”. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 0e57cca. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…22143) ## **Description** Remove padding and border radius from order type bottom sheet ## **Changelog** CHANGELOG entry:null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MDP-392 ## **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** `~` ### **Before** <img width="500" alt="image" src="https://github.com/user-attachments/assets/2662e9b0-adaa-4fc3-b89d-128b32f2c478" /> ### **After** <img width="500" alt="Simulator Screenshot - iPhone 16 Pro Max - 2025-11-04 at 11 22 56" src="https://github.com/user-attachments/assets/84b8a77e-5512-4a6c-9876-13c9a4f8e7ae" /> ## **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] > Removes container horizontal padding and option border radius in `PerpsOrderTypeBottomSheet` styles. > > - **UI/Styles** (`app/components/UI/Perps/components/PerpsOrderTypeBottomSheet/PerpsOrderTypeBottomSheet.styles.ts`): > - Remove `container` `paddingHorizontal`. > - Remove `option` `borderRadius`. > - Keep spacing and selection colors unchanged. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 99111f7. 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 : )