[pull] main from MetaMask:main#318
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 adds analytics tracking for social login failures to help identify where and why failures occur during the OAuth login flow. The implementation tracks failures at three stages: 1. **Provider login failures** - When users cancel or encounter errors during the OAuth provider authentication step 2. **Token exchange failures** - When errors occur during the authorization code to JWT token exchange 3. **Seedless authentication failures** - When errors occur during the seedless authentication step Each failure event includes contextual metadata: - `account_type` - The type of account being created (e.g., `default_google`, `default_apple`) - `is_rehydration` - Whether this is a rehydration flow (existing user returning) - `failure_type` - Whether the failure was due to user cancellation or an error - `error_category` - The specific stage where the failure occurred ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/SL-257 ## **Manual testing steps** 1. Start a social login flow (Google or Apple) 2. Cancel the OAuth provider authentication dialog 3. Verify that a `SocialLoginFailed` event is tracked with `failure_type: 'user_cancelled'` and `error_category: 'provider_login'` 4. Attempt a social login and simulate a network error during token exchange 5. Verify that a `SocialLoginFailed` event is tracked with `failure_type: 'error'` and `error_category: 'get_auth_tokens'` 6. Attempt a social login and simulate an error during seedless authentication 7. Verify that a `SocialLoginFailed` event is tracked with `failure_type: 'error'` and `error_category: 'seedless_auth'` ## **Screenshots/Recordings** <!-- Not applicable - this is an analytics-only change with no UI changes --> ### **Before** <!-- N/A --> ### **After** <!-- N/A --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [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] > Adds SOCIAL_LOGIN_FAILED tracking with rehydration context across provider login, token exchange, and seedless auth; updates OAuth login API and tests accordingly. > > - **Analytics**: > - Add `SOCIAL_LOGIN_FAILED` event in `core/Analytics/MetaMetrics.events.ts` and export mapping. > - **OAuth** (`core/OAuthService/OAuthService.ts`): > - Add `userClickedRehydration` to local state and `#trackSocialLoginFailure` to emit `SOCIAL_LOGIN_FAILED` with `account_type`, `is_rehydration`, `failure_type`, and `error_category`. > - Invoke tracking on failures in `provider_login`, `get_auth_tokens`, and `seedless_auth` stages; validate `id_token` earlier. > - Change `handleOAuthLogin(loginHandler, userClickedRehydration)` signature and wire usage. > - **Onboarding** (`components/Views/Onboarding/index.js`): > - Pass rehydration flag to `handleOAuthLogin` (`!createWallet`). > - **Tests**: > - Update unit tests in `OAuthService.test.ts` and `Onboarding/index.test.tsx` to reflect new `handleOAuthLogin` param and event behavior. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 37e8b08. 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 fixes styling for "unconfirmed" transaction status <!-- 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: Fixed styling for "unconfirmed" transaction status ## **Related issues** Fixes: #21574 https://consensyssoftware.atlassian.net/browse/TMCU-158 ## **Manual testing steps** ```gherkin Feature: Send BTC Scenario: user sends BTC Given BTC is enabled When user initiates BTC transaction and navigates to Activity tab Then unconfirmed transaction with yellow/orange "Pending" status should appear ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <img width="395" height="835" alt="Screenshot 2025-11-07 at 13 53 14" src="https://github.com/user-attachments/assets/e74b1b50-be28-4800-a1cc-6be00665d119" /> <!-- [screenshots/recordings] --> ### **After** <img width="396" height="833" alt="Screenshot 2025-11-07 at 13 52 51" src="https://github.com/user-attachments/assets/431a522f-0338-4b22-b39a-29d51d03dfca" /> <!-- [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] > Maps `Unconfirmed` statuses to pending and enables overriding styles on status text components; updates i18n and snapshots. > > - **UI**: > - `app/components/Base/StatusText.js`: > - `ConfirmedText`, `PendingText`, `FailedText` now accept optional `style` prop merged with base styles. > - Treat `"Unconfirmed"/"unconfirmed"` as pending in `StatusText` switch. > - **i18n**: > - `locales/languages/en.json`: add `"transaction.unconfirmed": "Pending"`. > - **Tests**: > - Update `TransactionDetails` snapshots to reflect array-based `style` merging. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit fa44247. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description**
PR to add trending tokens card. This should be under a feature flag(
selector `selectAssetsTrendingTokensEnabled`)
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: No functional changes, this is still under a feature
flag.
## **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] -->
<img width="425" height="858" alt="Screenshot 2025-11-11 at 18 09 58"
src="https://github.com/user-attachments/assets/ff394cf2-fbc8-4965-a2d1-e048eb1990ad"
/>
## **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]
> Introduces a Trending Tokens UI section integrated into TrendingView
with a shared token logo hook, updates the trending fetch hook to
default to popular networks, and adds comprehensive tests and i18n.
>
> - **UI (Trending)**:
> - **Trending Tokens Section**: New `TrendingTokensSection` with
`TrendingTokensList`, `TrendingTokenRowItem`, `TrendingTokenLogo`, and
`TrendingTokensSkeleton`, integrated into `TrendingView` (header tweak,
scroll container).
> - **Hooks**:
> - **New**: `useTokenLogo` for shared image loading/error/background
logic; refactors `PerpsTokenLogo` to use it.
> - **Updated**: `useTrendingRequest` now accepts optional `chainIds`,
defaults to popular networks via
`useNetworksByNamespace`/`useNetworksToUse`, sets initial loading to
true, and fixes debounce dependencies.
> - **Utils**:
> - Add formatting helpers `formatCompactUSD` and `formatMarketStats`
for market cap/volume.
> - **Tests**:
> - Add extensive unit tests and snapshots for new components/hooks and
updated trending request behavior.
> - **Localization**:
> - Update `en.json` with `trending.title`, `trending.view_all`, and
`trending.tokens` strings.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
49ddd1a. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description** Ensure the Predict withdraw confirmation uses the entire balance if the `Max` button is used. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: [#6156](MetaMask/MetaMask-planning#6156) #22190 ## **Manual testing steps** ## **Screenshots/Recordings** ### **Before** ### **After** ## **Pre-merge author checklist** - [x] I’ve followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Ensure Predict withdraw Max uses the full balance converted to USD and add a fixed 1:1 USD rate for Polygon USDCE. > > - **Confirmations / Amounts**: > - Convert Predict balance to USD via `tokenFiatRate` for withdraw calculations and `Max` behavior; default rate falls back to `1`. > - Refine max-percentage logic when pay token is missing or matches the first required token. > - **Token Fiat Rates**: > - Return fixed `1` rate for `POLYGON_USDCE` on `POLYGON` when currency is USD (alongside `ARBITRUM_USDC`). > - Minor refactor for USD checks and token matches. > - **Alerts**: > - Use human Predict balance in `useInsufficientPredictBalanceAlert` comparison. > - **Tests**: > - Update and add tests for USDCE fixed rate and Predict withdraw USD conversion/max behavior. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit f179f68. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Adjusted the funding tooltip copy in the position component to display position-specific information. Previously, both the position card's "Funding Cost" and the market statistics "Funding Rate" used the same generic tooltip explaining funding rates. This change adds a dedicated tooltip for funding payments that clarifies it represents the cumulative amount paid/received since the position opened. **Changes:** - Added new `funding_payments` tooltip type - Updated position card to use the new tooltip - Market statistics continues to use the existing `funding_rate` tooltip ## **Changelog** CHANGELOG entry: Updated funding tooltip in position component to show position-specific information ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TAT-1880 ## **Manual testing steps** ```gherkin Feature: Funding payments tooltip in position component Scenario: user views funding tooltip in position card Given user has an open perp position And the position card displays the "Funding" field with an info icon When user taps the info icon next to "Funding" in the position card Then the tooltip displays title "Funding payments" And the tooltip content reads "This is the amount you've paid in funding fees since the position was opened. Funding is paid or received every hour to keep the perp price close to the actual token price." Scenario: user views funding rate tooltip in market statistics Given user is viewing market statistics for a perp When user taps the info icon next to "Funding rate" Then the tooltip displays title "Funding rate" And the tooltip content describes the general funding rate concept ``` ## **Screenshots/Recordings** ### **Before** Position card showed generic funding rate tooltip (same as market statistics) ### **After** Position card shows position-specific funding payments tooltip with cumulative payment context https://github.com/user-attachments/assets/65db42a1-68fc-4758-950f-ad1dd79e1030 ## **Pre-merge author checklist** - [x] I've followed MetaMask Contributor Docs and MetaMask Mobile Coding Standards - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable (N/A - localization change only) - [x] I've documented my code using JSDoc format if applicable (N/A) - [x] I've applied the right labels on the PR ## **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 a new `funding_payments` tooltip and switches the position card’s funding info icon to use it, with corresponding registry and locale updates. > > - **Perps Tooltips**: > - Add new content key `funding_payments` to `PerpsTooltipContentKey` and register in `contentRegistry`. > - **Position Card**: > - Change funding info icon handler from `funding_rate` to `funding_payments` in `PerpsPositionCard`. > - **Localization**: > - Add `perps.tooltips.funding_payments` strings (title and content) in `en.json`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 2149df2. 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 enables back native token send. As it stated in the previous automated flaky test thread [here](https://consensys.slack.com/archives/C02U025CVU4/p1762243312142959) and the [logs](https://github.com/MetaMask/metamask-mobile/actions/runs/19055429448/job/54425009493), send native spec was failing. However if you look at the logs - this is not entirely related as there is a detox crash. I ran these tests over and over on local but I couldn't encoutner the issue once, hence we are enabling it back. https://github.com/user-attachments/assets/042fdb4f-c846-4e7c-92d9-6985798e3de0 **Update 1** We still encounter the issues in the CI - Ola [had a look but no chance](https://consensys.slack.com/archives/C01U65ZUS2E/p1762787121323169?thread_ts=1762776032.589089&cid=C01U65ZUS2E). Hence we are disabling this `50%` test rest looks good. **Update 2** It appears the issues are because of `%` text. I changed e2e test to lookup component test ids instead of text and it worked. ## **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: #22135 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [X] I’ve followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [X] I've completed the PR template to the best of my ability - [X] I’ve included tests if applicable - [X] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [X] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds testIDs to percentage buttons and updates send flow e2e selectors to target them by ID. > > - **UI**: > - Add `testID` to percentage buttons in `app/components/Views/confirmations/components/edit-amount-keyboard/edit-amount-keyboard.tsx` as `percentage-button-<value>`. > - **E2E Tests**: > - Update `e2e/pages/Send/RedesignedSendView.ts` to select `50%` and `Max` via `getElementByID('percentage-button-50'|'percentage-button-100')` instead of text. > - Keep send native token spec logic the same while interacting with the new IDs. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 505718b. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…tion cp-7.59.0 (#22252) ## **Description** This PR implements a major refactor of the Perps order handling system to address precision and validation issues. The changes establish USD as the primary source of truth for order amounts, replacing the complex `findOptimalAmount` optimization logic with a simpler, more robust approach that recalculates position sizes at execution time using fresh market prices. ### Key Changes #### 1. Migration from `findOptimalAmount` to USD-as-Source-of-Truth **Previous Approach:** - Used `findOptimalAmount` function to find the "optimal" USD amount that maximized value while maintaining the same position size - Performed complex calculations with position size increments and rounding - Optimized order amounts on every input change (percentage, slider, keypad, etc.) - Position size was calculated once in the UI and used directly for order placement **New Approach:** - **USD amount is now the primary source of truth** - stored and validated as entered by user - Position size is recalculated at execution time with the freshest available price - Eliminates complex optimization logic (~150 lines removed from `orderCalculations.ts`) - Simplified order form handling (~71 lines removed from `usePerpsOrderForm.ts`) **Benefits:** - Eliminates edge cases where optimization could produce invalid orders - Reduces computational overhead on every input change - More predictable behavior - what user enters is what gets validated and executed - Better handling of price volatility during order placement #### 2. Standardized Slippage Management **New Configuration:** ```typescript export const ORDER_SLIPPAGE_CONFIG = { DEFAULT_SLIPPAGE_BPS: 100, // 100 basis points = 1% } as const; ``` **Improvements:** - Unified slippage configuration using basis points for consistency - Added price staleness validation to prevent execution with stale prices - New `priceAtCalculation` and `maxSlippageBps` fields in `OrderParams` - Provider validates price hasn't moved beyond tolerance before execution - Standardized slippage across market orders, position closing, and TP/SL orders **Slippage Validation Example:** ```typescript // Provider checks price delta before order execution const priceDeltaBps = Math.abs( ((currentPrice - priceAtCalculation) / priceAtCalculation) * 10000 ); if (priceDeltaBps > maxSlippageBps) { throw new Error(`Price moved too much: ${priceDeltaBps} bps`); } ``` #### 3. Enhanced Order Validation **Validation Improvements:** - **USD as source of truth for minimum validation** - validates user's exact USD input without recalculation - Example: User enters $10 → validates $10 directly (no rounding errors) - For full position closes (e.g., Close All), minimum validation is skipped - Added `skipValidation` flag to prevent validation flash during keypad input - Enhanced limit order validation to require price parameter **Type System Updates:** ```typescript export type OrderParams = { // Existing fields... size: string; // Now derived, provider recalculates from usdAmount // New hybrid approach fields usdAmount?: string; // Primary source of truth priceAtCalculation?: number; // For slippage validation maxSlippageBps?: number; // Slippage tolerance (e.g., 100 = 1%) // Updated documentation slippage?: number; // Now defaults to ORDER_SLIPPAGE_CONFIG.DEFAULT_SLIPPAGE_BPS / 10000 }; ``` #### 4. Close Position Validation & Precision **Problem Addressed:** - Close positions were failing with "Minimum order size is $10" even when closing 100% of small positions (e.g., closing a $5.23 position) - Close position calculations used hardcoded decimal precision (6 decimals) instead of asset-specific `szDecimals` - As part of the USD-as-source-of-truth refactor, close position calculations needed the same precision improvements as order placement **Solution - Full vs Partial Close Distinction:** **Full Position Close (100%):** - Added `isFullClose` flag to `OrderParams` type - Set automatically when `size` parameter is omitted: `isFullClose: !params.size` - Skips USD validation and $10 minimum entirely - Allows closing positions of any size (e.g., $5.23 position) **Partial Position Close:** - Still enforces $10 minimum validation - Uses same USD validation logic as new orders - Requires `currentPrice` or `usdAmount` for validation **Close Amount Calculation Refactor:** - Migrated `calculateCloseAmountFromPercentage` to USD as source of truth - Added required `szDecimals` parameter (removed dangerous defaults) - Implemented post-rounding USD validation: ```typescript const actualUsd = tokenAmount * currentPrice; if (actualUsd < usdValue) { tokenAmount += 1 / multiplier; // Add 1 minimum increment } ``` - Now matches `calculatePositionSize` logic for consistency **Type Changes:** ```typescript export type OrderParams = { // ... existing fields isFullClose?: boolean; // Indicates closing 100% of position (skips validation) }; // calculateCloseAmountFromPercentage now requires szDecimals interface CloseAmountFromPercentageParams { percentage: number; positionSize: number; currentPrice: number; szDecimals: number; // REQUIRED - no longer optional } ``` **Files Changed:** - `controllers/types/index.ts` - Added `isFullClose` flag - `utils/positionCalculations.ts` - Refactored to use USD as source of truth with asset-specific precision - `Views/PerpsClosePositionView/PerpsClosePositionView.tsx` - Added `szDecimals` handling with loading state - `controllers/providers/HyperLiquidProvider.ts` - Updated validation to skip minimum for full closes #### 5. Position Size Calculation Changes **Rounding Behavior:** - Changed from `Math.floor` to `Math.round` in `calculatePositionSize` - More accurate position size calculation that rounds to nearest value - Aligned with provider's recalculation logic for consistency **Provider-Side Recalculation:** ```typescript // In HyperLiquidProvider.placeOrder() if (params.usdAmount && parseFloat(params.usdAmount) > 0) { const usdAmount = parseFloat(params.usdAmount); // Recalculate with fresh price finalPositionSize = usdAmount / currentPrice; // Apply same rounding as UI const multiplier = Math.pow(10, assetInfo.szDecimals); finalPositionSize = Math.round(finalPositionSize * multiplier) / multiplier; } ``` #### 6. User Experience Improvements **Input Handling:** - Removed optimization calls from percentage/slider/max buttons - Fixed input clamping to only apply for keypad input (not percentage/slider/max) - Reduced unnecessary re-renders and calculations - Skip validation during active input to prevent flickering error messages **Code Cleanup:** - Removed FinalizationRegistry polyfill from `shim.js` (no longer needed by updated dependencies) - Removed unused `findOptimalAmount` and `findHighestAmountForPositionSize` functions - Cleaned up debounced optimization logic from form handlers ### Migration Path **Backward Compatibility:** - `size` field still present in `OrderParams` for backward compatibility - Provider falls back to legacy size calculation if `usdAmount` is not provided - Existing orders and integrations continue to work **Hybrid Approach:** Orders now pass both `usdAmount` (primary) and `size` (derived): ```typescript const orderParams: OrderParams = { coin: 'BTC', isBuy: true, size: positionSize, // Kept for compatibility, recalculated by provider usdAmount: orderForm.amount, // USD as source of truth priceAtCalculation: assetData.price, // For validation maxSlippageBps: 100, // 1% tolerance // ... other fields }; ``` ### Files Changed **Core Logic (276 additions, 290 deletions):** - `app/components/UI/Perps/controllers/providers/HyperLiquidProvider.ts` (+148 lines) - Hybrid USD-based order placement with price validation - Standardized slippage across all order types - Position size recalculation at execution time - `app/components/UI/Perps/utils/orderCalculations.ts` (-149 lines) - Removed `findOptimalAmount` and `findHighestAmountForPositionSize` - Changed `Math.floor` to `Math.round` for position size calculation - `app/components/UI/Perps/hooks/usePerpsOrderForm.ts` (-71 lines) - Removed `optimizeOrderAmount` function and related logic - Simplified amount initialization - `app/components/UI/Perps/hooks/usePerpsOrderValidation.ts` (+28 lines) - Added `skipValidation` and `originalUsdAmount` parameters - Improved minimum order size validation with original USD input **UI Components:** - `app/components/UI/Perps/Views/PerpsOrderView/PerpsOrderView.tsx` (+/-54 lines) - Removed optimization calls from input handlers - Added `skipValidation` flag during input focus - Pass `usdAmount` and price validation params to provider - Fixed input clamping behavior **Configuration:** - `app/components/UI/Perps/constants/perpsConfig.ts` (+10 lines) - Added `ORDER_SLIPPAGE_CONFIG` constant - `app/components/UI/Perps/constants/hyperLiquidConfig.ts` (-1 line) - Removed legacy slippage configuration **Types & Validation:** - `app/components/UI/Perps/controllers/types/index.ts` (+9 lines) - Updated `OrderParams` type with USD-based fields - `app/components/UI/Perps/utils/hyperLiquidValidation.ts` (+9 lines) - Enhanced validation for limit orders - Added minimum order size tolerance - `app/components/UI/Perps/utils/hyperLiquidValidation.test.ts` (+29 lines) - Added tests for limit order price validation **Cleanup:** - `shim.js` (-18 lines) - Removed FinalizationRegistry polyfill ## **Changelog** CHANGELOG entry: Improved Perps order precision and validation by using USD amounts as source of truth and standardizing slippage management ## **Related issues** Fixes: [TAT-1902](https://consensyssoftware.atlassian.net/browse/TAT-1902) - Investigate and resolve order placement issue for specific token pairs **How this PR fixes TAT-1902:** The USD-as-source-of-truth refactor directly addresses order placement failures for specific token pairs by: - Recalculating position size at execution time with fresh market prices instead of using stale UI calculations - Using asset-specific `szDecimals` precision throughout (no more hardcoded 6 decimals) - Eliminating optimization logic that could produce invalid amounts near precision boundaries - Validating orders with the exact USD amount entered by the user, preventing precision loss from multiple conversions This ensures orders are calculated with the most current price and correct precision for each token pair, preventing the placement failures that occurred with the previous approach. ## **Manual testing steps** ```gherkin Feature: Perps Order Placement with USD as Source of Truth Scenario: User places a market order with precise USD amount Given user is on the Perps trading screen And user has sufficient balance When user enters "$100" USD amount via keypad And user selects "Market" order type And user taps "Place Order" Then order is placed with position size calculated from fresh market price And order execution succeeds without "insufficient margin" errors And no validation flickering occurs during input Scenario: User places order near minimum amount threshold Given user is on the Perps trading screen And market price causes calculated value to be near $10 minimum When user enters an amount that rounds to ~$9.99-$10.01 And user places the order Then validation passes with 1% tolerance And no flickering validation errors appear Scenario: Price moves during order placement Given user has entered order details And calculated position size at price $50,000 When market price moves to $50,500 (>1% move) And user places the order Then order is rejected with "Price moved too much" error And user is prompted to review and resubmit Scenario: User places limit order without price Given user is on the Perps trading screen And user selects "Limit" order type And user does not enter a limit price When user attempts to place order Then validation error displays "Price is required for limit orders" Scenario: User uses percentage buttons Given user is on the Perps trading screen And user has $1000 available balance When user taps "25%" button Then amount field shows "$250" And no optimization is triggered And position size is calculated correctly Scenario: User adjusts amount with slider Given user is on the Perps trading screen When user drags the amount slider Then amount updates in real-time And validation is skipped during interaction And validation applies after slider is released Scenario: User enters amount exceeding maximum Given user has $1000 available balance at 10x leverage And maximum possible order is $10,000 When user enters "$15,000" via keypad And user dismisses the keypad Then amount is automatically clamped to "$10,000" And validation message explains the limit Scenario: User closes 100% of a position worth less than minimum Given user has an open position worth $5.23 And minimum order size is $10 When user taps "Close Position" button And selects "100%" (full close) And confirms the close Then position closes successfully And no minimum order size error appears And full position value is returned Scenario: User closes partial position below minimum Given user has an open position worth $100 And minimum order size is $10 When user attempts to close $8 worth of the position And confirms the close Then validation error displays "Minimum order size is $10" And close operation is prevented ``` ## **Screenshots/Recordings** ### **Before** - Orders occasionally failed with "insufficient margin" despite UI showing valid amounts - Validation messages flickered during input on low-priced tokens - Complex optimization logic ran on every input change - Position size calculated once in UI, potentially stale at execution ### **After** - Consistent order execution with USD as source of truth - No validation flickering with 1% tolerance on minimum amounts - Simplified input handling without optimization overhead - Position size recalculated with fresh price at execution time - Price staleness validation prevents execution with stale prices <!-- Add screenshots/recordings here if available --> ## **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. --- ## **Technical Notes for Reviewers** ### Critical Changes to Review 1. **Rounding Change in `calculatePositionSize`** - Changed from `Math.floor` to `Math.round` - Verify this doesn't cause issues with existing positions or orders - Check that rounding behavior matches exchange requirements 2. **Backward Compatibility** - `OrderParams.size` still present but recalculated by provider - Verify existing integrations continue to work - Test with and without `usdAmount` parameter 3. **Slippage Validation** - Price staleness check may reject valid orders in volatile markets - Default 1% tolerance (100 bps) - verify this is appropriate - Check error messages are clear to users 4. **Minimum Order Size Validation** - USD as source of truth - validates exact user input ($10 ≥ $10) - No tolerance needed when using usdAmount parameter - **Full position closes (100%)** skip validation entirely via `isFullClose` flag - **Partial position closes** enforce $10 minimum validation - **New positions** enforce $10 minimum validation - Close position calculations use same USD validation logic as order placement 5. **Input Clamping Logic** - Now only clamps for keypad input, not percentage/slider/max - Verify this doesn't break max amount validation - Test with various input methods ### Testing Recommendations - Test with various token prices (low, medium, high) - Test near minimum order size ($10) with price fluctuations - Test with high leverage where rounding matters more - Test order placement during price volatility - Test limit orders with missing/invalid prices - Verify no "insufficient margin" errors for valid amounts - Check validation doesn't flicker during keypad input [TAT-1902]: https://consensyssoftware.atlassian.net/browse/TAT-1902?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Switches order/close flows to USD-as-source-of-truth with provider-side size recalculation and unified slippage, improves validation/precision, removes optimization logic, and updates hooks/tests/docs. > > - **Core trading/provider**: > - Use USD as source of truth; provider recalculates size at execution with fresh price and asset `szDecimals` (`HyperLiquidProvider.ts`). > - Add slippage config via `ORDER_SLIPPAGE_CONFIG` (default 100 bps) and price-staleness validation; pass `usdAmount`, `priceAtCalculation`, `maxSlippageBps` through `OrderParams`. > - Refactor order build/format helpers into `orderCalculations` (`calculateFinalPositionSize`, `calculateOrderPriceAndSize`, `buildOrdersArray`). > - Support full-close bypass of $10 minimum via `isFullClose`; propagate slippage params in close flows. > - **Validation & precision**: > - `calculatePositionSize`/close calculations use asset precision, round to nearest, and ensure post-rounding USD meets target. > - `validateOrder` now validates minimums from USD, requires price for limit orders, and tolerates full closes. > - Remove `findOptimalAmount`/related logic and old slippage from `hyperLiquidConfig`. > - **UI/hooks**: > - `PerpsOrderView`/`PerpsClosePositionView`: pass USD + slippage params; skip validation during input; clamp only for keypad; use market data with fallback decimals. > - `usePerpsMarketData` accepts `{ asset, showErrorToast }` and auto-toasts on errors; expose loading. > - `usePerpsOrderValidation`/`usePerpsClosePositionValidation`: add `skipValidation`, use original USD for min checks. > - **Types/constants**: > - Extend `OrderParams`/`ClosePositionParams` with USD/slippage/full-close fields; add `DECIMAL_PRECISION_CONFIG.FALLBACK_SIZE_DECIMALS` and `ORDER_SLIPPAGE_CONFIG`. > - **Tests & docs**: > - Update extensive tests to new params, rounding, and hook signatures; adjust provider tests for price-required errors. > - Refresh trading guide (market order/slippage sections) and fix reference paths. > - **Cleanup**: > - Remove FinalizationRegistry polyfill from `shim.js`; simplify order form by dropping optimization APIs. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit fda1210. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: dylanbutler1 <99672693+dylanbutler1@users.noreply.github.com>
…22392) <!-- 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 aims to fix recipient input to show multiline for selected address in send flow ## **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 recipient to be shown multi-line in send flow ## **Related issues** Fixes: #22207 ## **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** <img width="568" height="1084" alt="Screenshot 2025-11-10 at 12 03 50" src="https://github.com/user-attachments/assets/f8f0da96-2505-4c76-b77c-f904fcab3d6d" /> ### **After** <img width="568" height="1084" alt="Screenshot 2025-11-10 at 12 03 43" src="https://github.com/user-attachments/assets/56c76b7c-a0c9-4640-9f02-bc3b446eed68" /> ## **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] > Replaces direct TextField props with a custom Input element to force single-line recipient addresses and prevent multiline behavior. > > - **Confirmations › RecipientInput (`app/components/Views/confirmations/components/recipient-input/recipient-input.tsx`)** > - Use `TextField` `inputElement` with `foundation/Input` to control behavior. > - Configure single-line input: `multiline={false}`, `numberOfLines={1}`, `scrollEnabled={false}`, `textAlignVertical="center"`, `textBreakStrategy="simple"`. > - Move input props (value, change handlers, autocorrect/spellcheck/autocomplete/capitalize, placeholder, autofocus, testID) onto `Input`. > - Apply `INPUT_STYLE_OVERRIDE` to remove height/lineHeight and pad adjustments; disable state styles; set `textVariant` via `TOKEN_TEXTFIELD_INPUT_TEXT_VARIANT`. > - Keep start/end accessories (To label, Clear/Paste buttons) unchanged. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e06f20c. 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 aims to add PPOM validation requests for deeplinks. ## **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: MetaMask/mobile-planning#2370 Fixes: #17358 ## **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] > Integrates PPOM validation into deeplink transfer/approve flows, generating a securityAlertId and passing it to addTransaction, with refactors and tests. > > - **Deeplink handling (`app/components/Views/confirmations/utils/deeplink.ts`)**: > - Add `validateWithPPOM` to build a PPOM request (with uuid-based `securityAlertId`) and call `ppomUtil.validateRequest`. > - Pass returned `securityAlertResponse` to `addTransaction` for both native and ERC20 transfers. > - Refactor tx construction to derive `txParams` and `transactionType`; downgrade duplicate-request log from error to log. > - **Approve flow (`app/core/DeeplinkManager/TransactionManager/approveTransaction.ts`)**: > - Compute `chainId`/`networkClientId`, call `validateWithPPOM`, and include `securityAlertResponse` in `addTransaction`. > - **Tests**: > - Extend deeplink and approve tests to mock PPOM and UUID, assert PPOM validation payload, `securityAlertResponse`, and `networkClientId` wiring. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit daa4941. 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 : )