Skip to content

fix(perps): when opening perps quickly after wallet open, the app display $0 for 24h volume and OI - #34844

Merged
abretonc7s merged 4 commits into
mainfrom
TAT-3765-fix-fix-perps-zero-volume-display
Aug 15, 2026
Merged

fix(perps): when opening perps quickly after wallet open, the app display $0 for 24h volume and OI#34844
abretonc7s merged 4 commits into
mainfrom
TAT-3765-fix-fix-perps-zero-volume-display

Conversation

@abretonc7s

@abretonc7s abretonc7s commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Description

Opening Perps immediately after wallet unlock could show $0.00 for 24h volume and open interest while price, funding, and the order book were already live. usePerpsMarketStats subscribed before the Perps client was initialized and never retried, then formatted missing values as $0.00.

This waits for isInitialized before subscribing (same pattern as usePerpsPrices) and shows PERPS_CONSTANTS.FallbackPriceDisplay until volume and open interest arrive. Confirmed zeros still format as $0.

Changelog

CHANGELOG entry: Fixed 24h volume and open interest showing $0.00 when opening Perps right after unlock

Related issues

Fixes: TAT-3765

Manual testing steps

Feature: Perps market stats after a fast open

  Scenario: user opens a market immediately after unlocking
    Given the wallet is locked on the fixture account
    And Perps is enabled

    When the user unlocks and opens BTC market details immediately
    Then 24h volume is a real market figure, not $0.00
    And open interest is a real market figure, not $0.00

Screenshots/Recordings

Fast Perps open: 24h volume and open interest load as real figures instead of $0.00.

Fast Perps open no longer shows fake $0.00 for 24h volume and open interest
Before
before
After
after

Pre-merge author checklist

Performance checks (if applicable)

  • I've tested on Android
    • Ideally on a mid-range device; emulator is acceptable
  • I've tested with a power user scenario
    • Use these power-user SRPs to import wallets with many accounts and tokens
  • I've instrumented key operations with Sentry traces for production performance metrics

For performance guidelines and tooling, see the Performance Guide.

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.

Validation Recipe

recipe.json
{
  "$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
  "title": "Perps 24h volume and open interest are not fake zeros after a fast open",
  "description": "Unlock, open BTC market detail immediately, and prove 24h volume and open interest render real market stats instead of $0.00. Requires an unlocked fixture wallet with Perps enabled. Lite market details is used so both figures are fully on screen; they come from the same usePerpsMarketStats hook as the Pro stats bar.",
  "workflow": {
    "entry": "setup-status",
    "nodes": {
      "setup-status": {
        "action": "app.status",
        "intent": "Confirm the mobile bridge is reachable before opening Perps",
        "next": "setup-cdp"
      },
      "setup-cdp": {
        "action": "cdp.target",
        "required": true,
        "timeout_ms": 15000,
        "intent": "Confirm the React Native debug bridge is reachable",
        "next": "setup-restart"
      },
      "setup-restart": {
        "action": "app.lifecycle",
        "command": "restart",
        "settle_ms": 3000,
        "runtime_ready_timeout_ms": 60000,
        "intent": "Restart the app so Perps opens from a fresh wallet-launch state",
        "next": "setup-unlock"
      },
      "setup-unlock": {
        "action": "metamask.wallet.ensure_unlocked",
        "intent": "Unlock the wallet so Perps can be opened immediately after launch",
        "target_timeout_ms": 45000,
        "unlock_timeout_ms": 45000,
        "next": "setup-navigate-market"
      },
      "setup-navigate-market": {
        "action": "ui.navigate",
        "page": "perps-market",
        "market": "BTC",
        "intent": "Open the BTC Perps market detail screen",
        "next": "setup-wait-header"
      },
      "setup-wait-header": {
        "action": "ui.wait_for",
        "test_id": "perps-market-header",
        "expected": "present",
        "timeout_ms": 20000,
        "intent": "Confirm BTC market details finished opening after the fast launch",
        "next": "setup-wait-scroll"
      },
      "setup-wait-scroll": {
        "action": "ui.wait_for",
        "test_id": "perps-market-details-scroll-view",
        "expected": "present",
        "timeout_ms": 15000,
        "intent": "Confirm the Lite market details scroll surface is ready",
        "next": "ac1-scroll-stats"
      },
      "ac1-scroll-stats": {
        "action": "ui.scroll",
        "test_id": "perps-market-details-scroll-view",
        "offset": 1050,
        "settle": true,
        "timeout_ms": 15000,
        "intent": "Confirm 24h volume and open interest can be read on the market stats card",
        "next": "ac1-wait-volume"
      },
      "ac1-wait-volume": {
        "action": "ui.wait_for",
        "text": "24h volume",
        "expected": "present",
        "timeout_ms": 15000,
        "intent": "Confirm the 24h volume label is on the BTC market stats card",
        "next": "ac1-screenshot-volume"
      },
      "ac1-screenshot-volume": {
        "action": "ui.screenshot",

        "label": "AC1: 24h volume on market stats card",
        "intent": "Show that 24h volume is a real market figure rather than $0.00",
        "next": "ac2-wait-oi-label"
      },
      "ac2-wait-oi-label": {
        "action": "ui.wait_for",
        "text": "Open interest",
        "expected": "present",
        "timeout_ms": 10000,
        "intent": "Confirm the open interest label is on the BTC market stats card",
        "next": "ac2-wait-oi-icon"
      },
      "ac2-wait-oi-icon": {
        "action": "ui.wait_for",
        "test_id": "perps-market-details-open-interest-info-icon",
        "expected": "present",
        "timeout_ms": 10000,
        "intent": "Confirm the open interest row is mounted on the stats card",
        "next": "ac2-screenshot-oi"
      },
      "ac2-screenshot-oi": {
        "action": "ui.screenshot",

        "label": "AC2: open interest on market stats card",
        "intent": "Show that open interest is a real market figure rather than $0.00",
        "next": "done"
      },
      "done": {
        "action": "end",
        "status": "pass"
      }
    }
  }
}

Recipe Workflow

workflow.mmd
flowchart TD
  setup-status --> setup-cdp
  setup-cdp --> setup-restart
  setup-restart --> setup-unlock
  setup-unlock --> setup-navigate-market
  setup-navigate-market --> setup-wait-header
  setup-wait-header --> setup-wait-scroll
  setup-wait-scroll --> ac1-scroll-stats
  ac1-scroll-stats --> ac1-wait-volume
  ac1-wait-volume --> ac1-screenshot-volume
  ac1-screenshot-volume --> ac2-wait-oi-label
  ac2-wait-oi-label --> ac2-wait-oi-icon
  ac2-wait-oi-icon --> ac2-screenshot-oi
  ac2-screenshot-oi --> done
Loading

Note

Low Risk
Localized Perps UI hook behavior and display formatting with unit tests; no auth, payments, or shared infrastructure changes.

Overview
Fixes 24h volume and open interest showing fake $0.00 when Perps is opened right after wallet unlock.

usePerpsMarketStats now waits on isInitialized from usePerpsConnection before calling subscribeToPrices, matching usePerpsPrices, so an early no-op subscribe is retried once the client is ready. Until volume and open interest arrive, the UI uses PERPS_CONSTANTS.FallbackPriceDisplay instead of formatting missing values as $0.00; confirmed zero values still render as $0.

Tests mock usePerpsConnection and cover init gating, post-init subscribe, fallback display, and real zeros.

Reviewed by Cursor Bugbot for commit bbf72c4. Bugbot is set up for automated code reviews on this repo. Configure here.

abretonc7s and others added 4 commits August 14, 2026 23:31
…play $0 for 24h volume and OI

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamask-ci metamask-ci Bot added the team-perps Perps team label Aug 14, 2026
@abretonc7s abretonc7s changed the title chore: prepare farmslot publication pkg-4e2a67cd-mst64gzi fix(perps): when opening perps quickly after wallet open, the app display $0 for 24h volume and OI Aug 14, 2026
@abretonc7s
abretonc7s marked this pull request as ready for review August 14, 2026 23:09
@abretonc7s
abretonc7s requested a review from a team as a code owner August 14, 2026 23:09
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokePerps, SmokeWalletPlatform, SmokeConfirmations
  • Selected Performance tags: @PerformancePreps
  • Risk Level: medium
  • AI Confidence: 88%
click to see 🤖 AI reasoning details

E2E Test Selection:
The changes are confined to the Perps feature area, specifically the usePerpsMarketStats hook:

  1. Subscription gating fix: Added isInitialized guard from usePerpsConnection so market data subscriptions don't fire prematurely after wallet unlock. This is a behavioral change that could affect how quickly market stats appear in the Perps UI.

  2. Zero-value display fix: Changed falsy check (if (!value)) to !== undefined so actual zero values for volume24h and openInterest display as $0 (formatted) rather than the fallback placeholder. This fixes a display bug in the Perps market stats UI.

  3. Fallback constant: Uses PERPS_CONSTANTS.FallbackPriceDisplay instead of hardcoded '$0.00' for consistency.

Tag selection rationale:

  • SmokePerps: Directly tests Perps functionality including market stats display and Add Funds flow — the changed hook is core to the Perps market view
  • SmokeWalletPlatform: Required by SmokePerps description since Perps is a section inside the Trending tab
  • SmokeConfirmations: Required by SmokePerps description since Add Funds deposits are on-chain transactions

The changes are unit-tested and isolated to the Perps hook layer. No shared infrastructure, navigation, or cross-cutting components are affected.

Performance Test Selection:
The subscription gating change (isInitialized guard) affects when market data subscriptions fire in the Perps flow. This could impact perps market loading times — specifically the time between opening the Perps screen and seeing market stats (volume, open interest, funding rate). The @PerformancePreps tag covers perps market loading and position management, making it relevant to validate that the initialization guard doesn't introduce latency regressions in the perps market loading performance scenario.

View GitHub Actions results

@github-actions github-actions Bot added the risk:low AI analysis: low risk label Aug 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Flaky unit test detection

Run history flaky detection

View recent run history

Historical failure rate is a hint, not proof — review each suggestion in context. See the flaky-test-detection skill for the full pattern reference and manual audit workflow.

Failures / runs sampled per window:

File 7d 15d 30d
app/components/UI/Perps/hooks/usePerpsMarketStats.test.ts 0/136 0/178 0/374

AI-detected flaky patterns

app/components/UI/Perps/hooks/usePerpsMarketStats.test.ts

  • J3 — Missing jest.clearAllMocks() / jest.resetAllMocks() (high)
    • The test file uses mocked functions but does not clear or reset the mocks between tests. This can lead to shared state between tests, causing intermittent failures if one test modifies the mock's behavior or call count.
    • Suggested fix in app/components/UI/Perps/hooks/usePerpsMarketStats.test.ts:1:
      -jest.mock('./usePerpsConnection', () => ({
      -  usePerpsConnection: jest.fn(() => ({ isInitialized: true })),
      -}));
      +beforeEach(() => {
      +  jest.clearAllMocks();
      +  jest.useFakeTimers();
      +  mockedUsePerpsConnection.mockReturnValue({
      +    isInitialized: true,
      +    isConnected: true,
      +    isConnecting: false,
      +    error: null,
      +    connect: jest.fn(),
      +    disconnect: jest.fn(),
      +    resetError: jest.fn(),
      +    reconnectWithNewContext: jest.fn(),
      +  });
      +});
  • J9 — Module-level mutable let bindings not reset in beforeEach (high)
    • The mockPriceData is defined at the module level and can lead to state bleeding between tests if modified in one test. This can cause tests to fail or pass inconsistently based on the order they are run.
    • Suggested fix in app/components/UI/Perps/hooks/usePerpsMarketStats.test.ts:1:
      -const mockPriceData = {
      -  BTC: {
      -    symbol: 'BTC',
      -    price: '45000.00',
      -    timestamp: Date.now(),
      -    percentChange24h: '2.50',
      -    funding: 0.01,
      -    openInterest: 990000000,
      -    volume24h: 1234567890,
      -  },
      -};
      +let mockPriceData;
      +
      +beforeEach(() => {
      +  mockPriceData = {
      +    BTC: {
      +      symbol: 'BTC',
      +      price: '45000.00',
      +      timestamp: Date.now(),
      +      percentChange24h: '2.50',
      +      funding: 0.01,
      +      openInterest: 990000000,
      +      volume24h: 1234567890,
      +    },
      +  };
      +});

This check is informational only and does not block merging.

@abretonc7s

Copy link
Copy Markdown
Contributor Author

Flaky-test detection triage:

  • J3 (Missing jest.clearAllMocks()): FALSE POSITIVE. usePerpsMarketStats.test.ts already calls jest.clearAllMocks() in the suite beforeEach (line 32) and resets mockedUsePerpsConnection there. The suggested diff duplicates that block.

  • J9 (Module-level mutable let not reset): FALSE POSITIVE. mockPriceData is a const fixture inside describe, not a module-level let. Tests copy it with spreads (...mockPriceData.BTC) and never mutate the shared object. History is 0/136 (7d), 0/178 (15d), 0/374 (30d).

No code change. CI has no failing checks on this PR.

@sonarqubecloud

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Performance Test Results

ℹ️ Performance test results are currently non-blocking and will not block this PR.

1 test failed · 2 tests · 1 device

📱 Devices tested (1)

Android: Google Pixel 8 Pro (v14.0)

❌ Failed Tests (1)

🔬 App profiling vs main is included under each failed scenario that has a prior baseline.

@mm-perps-engineering-team

Perps open position and close it

Platform Device Reason Recording
Android Google Pixel 8 Pro (v14.0) no_performance_metrics 📹 Watch

🔬 App profiling check · Current run 31849339637 · Baseline (last run on main (scenario also failing)) run 30897750395 @ 67486d2

⚠️ No green baseline on main — comparing against the latest usable profiling.

Summary: ⚠️ 4 metrics over +10%: CPU max (+7.48 (+39.7%)), Memory avg (+259.84 (+46.8%)), Memory max (+378.22 (+62.1%)), Slow frames (+9.38 (+181.8%))

ℹ️ API calls unavailable: Network logs API error: Bad Request

Full metric table (+10% variance rules)

Disclaimer — allowed variance: a +10% margin over the baseline is permitted.

  • If Current <= Baseline + 10%, treated as acceptable noise.
  • If Current > Baseline + 10%, Current and variance % are highlighted with ⚠️.
Metric Baseline Current Δ
CPU avg 10.44% 7.91% -2.53 (-24.2%)
CPU max 18.83% 26.31% +7.48 (+39.7%) ⚠️
Memory avg 555.64 MB 815.48 MB +259.84 (+46.8%) ⚠️
Memory max 609.03 MB 987.25 MB +378.22 (+62.1%) ⚠️
Slow frames 5.16% 14.54% +9.38 (+181.8%) ⚠️
Frozen frames 0% 0% 0 (0%)
ANRs 0 0 0 (0%)
Issues 2 2 0 (0%)
Critical issues 1 1 0 (0%)
App size 328.67 MB 329.45 MB +0.78 (+0.2%)
✅ Passed Tests (1)
Test Platform Device Duration Team Recording
Perps add funds Android Google Pixel 8 Pro (v14.0) 9.21s @mm-perps-engineering-team 📹 Watch

Branch: TAT-3765-fix-fix-perps-zero-volume-display · Build: E2E · Commit: a0afa88 · View full run

@abretonc7s
abretonc7s added this pull request to the merge queue Aug 15, 2026
Merged via the queue into main with commit bab8514 Aug 15, 2026
144 checks passed
@abretonc7s
abretonc7s deleted the TAT-3765-fix-fix-perps-zero-volume-display branch August 15, 2026 05:12
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 15, 2026
@metamask-ci metamask-ci Bot added the release-8.9.0 Issue or pull request that will be included in release 8.9.0 label Aug 15, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-8.9.0 Issue or pull request that will be included in release 8.9.0 risk:low AI analysis: low risk size-M team-perps Perps team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants