[pull] main from MetaMask:main#78
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** Adds a default mocks setup for all tests. Each test now automatically includes a predefined set of default mocks. Test-specific mocks can be added on top of these defaults. When a test mocks an endpoint that is also in the default set, the test’s mock takes precedence. This ensures consistent baseline mocks across the suite while still allowing per-test customization. ## **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: [MMQA-851](https://consensyssoftware.atlassian.net/browse/MMQA-851) ## **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. [MMQA-851]: https://consensyssoftware.atlassian.net/browse/MMQA-851?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
<!--
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.
…imizations (#18430) <!-- 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 implements WebSocket-based real-time data streaming for the Perps feature, replacing the previous polling-based approach. The implementation evolved significantly from the original plan to include critical performance optimizations and architectural improvements that eliminate unnecessary re-renders and provide flexible update control. **Key improvements:** 1. **Pure WebSocket Architecture**: Migrated from hybrid REST/WebSocket to pure WebSocket for all live data (prices, positions, orders, fills) 2. **Flexible Throttling**: Made throttling optional with smart defaults - instant updates for user actions (orders/positions), throttled for high-frequency data (prices) 3. **Re-render Optimization**: Created isolated leaf components for frequently updating data to prevent parent component re-renders 4. **TP/SL Fix**: Fixed root cause of Take Profit/Stop Loss data not displaying by extracting from `triggerPx` field instead of broken `isPositionTpsl` flag 5. **WebSocket Pre-warming**: Pre-establishes positions and orders subscriptions when entering Perps environment to eliminate empty initial states ## **Changelog** CHANGELOG entry: Fixed Perps live data updates and significantly improved performance by implementing WebSocket streaming with optimized re-rendering **Latest fixes:** - Eliminated duplicate WebSocket subscriptions by implementing shared webData2 connection for positions and orders - Single WebSocket connection now provides both positions (with TP/SL) and orders data - Fixed pre-warming to create persistent subscriptions that stay alive throughout Perps session - Pre-warm subscriptions now use no-op callbacks to maintain connections and continuous caching - Fixed reference counting with separate position/order subscriber tracking to prevent premature disconnection ## **Related issues** Fixes: Implementation of PR#3 from perps_stream_architecture_v3.md plan ## **Manual testing steps** ```gherkin Feature: Perps WebSocket Streaming Scenario: User views live price updates without UI lag Given user is on the Perps Market Details view And market prices are changing rapidly When user observes the price display Then prices update smoothly every 1-2 seconds And parent components do not re-render And UI remains responsive Scenario: User places and cancels orders with instant feedback Given user has the Orders tab open in Market Details When user places a new order Then order appears instantly in the list without delay When user cancels an order Then order disappears instantly from the list Scenario: User views positions with TP/SL values Given user has open positions with Take Profit and Stop Loss set When user views the Positions tab Then TP/SL values are displayed correctly for each position And values update in real-time via WebSocket Scenario: Positions are available immediately on mount Given user navigates to Perps environment When any component requests positions data Then positions are available immediately from cache And there is no empty state for ~10 seconds And components render with data from the start Scenario: Funding countdown updates without parent re-renders Given user is viewing a market with funding payments When funding countdown timer ticks Then only the countdown text updates And parent components remain stable (no re-renders) ``` ## **Screenshots/Recordings** ### **Before** - Excessive re-renders every second from funding countdown - 30-second delay for order cancellation updates - TP/SL values not displaying (isPositionTpsl always false) - Parent components re-rendering on every price update - Empty positions array for ~10 seconds on initial mount ### **After** - Isolated countdown component - no parent re-renders - Instant order updates (0ms throttle) - TP/SL values correctly extracted and displayed - Leaf components handle updates without affecting parents - Positions and orders available immediately from pre-warmed cache ## **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. --- ## Technical Details ### Files Changed Summary **New Components (3):** - `FundingCountdown` - Isolated timer component preventing parent re-renders - `LivePriceDisplay` - Real-time price display component - `LivePriceHeader` - Market header with live price updates **New Stream Hooks (4):** - `usePerpsLiveOrders` - Real-time order updates (0ms default throttle) - `usePerpsLivePositions` - Real-time position updates (0ms default throttle) - `usePerpsLivePrices` - Real-time price updates (1000ms default throttle) - `usePerpsLiveFills` - Real-time fill updates (0ms default throttle) **Removed Polling Hooks (2):** - `usePerpsOpenOrders` - Replaced by `usePerpsLiveOrders` - `usePerpsPositions` - Replaced by `usePerpsLivePositions` **Core Infrastructure:** - `PerpsStreamManager` - Enhanced with optional throttling - `HyperLiquidSubscriptionService` - Pure WebSocket implementation ### Performance Metrics | Metric | Before | After | Improvement | |--------|--------|-------|-------------| | WebSocket Connections | N per component | 1 per data type | ~90% reduction | | Parent Re-renders | Every update | Never | 100% reduction | | Order Update Latency | 30 seconds | Instant | 30s improvement | | Price Update Frequency | Uncontrolled | 1-2 seconds | Balanced | ### Architecture Improvements 1. **Optional Throttling Pattern** ```typescript // Instant updates for user actions const orders = usePerpsLiveOrders({ throttleMs: 0 }); // default // Throttled updates for high-frequency data const prices = usePerpsLivePrices({ throttleMs: 1000 }); // default ``` 2. **Leaf Component Pattern** ```typescript // Before: Parent re-renders every second <Text>{fundingCountdown}</Text> // After: Only leaf component re-renders <FundingCountdown /> ``` 3. **TP/SL Data Extraction** ```typescript // Fixed: Extract from triggerPx instead of broken isPositionTpsl if (order.triggerPx) { if (order.orderType?.includes('Take Profit')) { existing.takeProfitPrice = order.triggerPx; } else if (order.orderType?.includes('Stop')) { existing.stopLossPrice = order.triggerPx; } } ``` 4. **Persistent Pre-warming with Single Connection** ```typescript // Pre-warm creates REAL subscriptions that persist throughout session public prewarm(): () => void { // Creates subscription with no-op callback to keep connection alive this.prewarmUnsubscribe = this.subscribe({ callback: () => {}, // Keeps connection alive for caching throttleMs: 0 }); return this.prewarmUnsubscribe; // Cleanup function for when leaving Perps } ``` 5. **Shared webData2 Subscription with Proper Reference Counting** ```typescript // Separate counters for positions and orders prevent premature disconnection private positionSubscriberCount = 0; private orderSubscriberCount = 0; // Only cleanup when BOTH have zero subscribers private cleanupSharedWebData2Subscription(): void { const totalSubscribers = this.positionSubscriberCount + this.orderSubscriberCount; if (totalSubscribers <= 0 && this.sharedWebData2Subscription) { // Safe to disconnect - no subscribers left } } ``` --------- Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.3)
Can you help keep this open source service alive? 💖 Please sponsor : )