Skip to content

refactor: dedupe swaps quote data validation calls#29626

Open
infiniteflower wants to merge 3 commits intomainfrom
refactor/bridge-quote-data-context
Open

refactor: dedupe swaps quote data validation calls#29626
infiniteflower wants to merge 3 commits intomainfrom
refactor/bridge-quote-data-context

Conversation

@infiniteflower
Copy link
Copy Markdown
Contributor

@infiniteflower infiniteflower commented May 1, 2026

Description

This PR reduces duplicate Bridge quote data work in the main Bridge/Unified Swaps screen. Previously, multiple components in the BridgeView subtree called useBridgeQuoteData independently, which could trigger repeated Blockaid validation for the same active quote.

The main BridgeView subtree now shares a single quote-data result through BridgeQuoteDataProvider. useBridgeConfirm accepts the caller's activeQuote, modal route roots keep their local quote data, and validation is guarded by quote requestId plus validation callback identity so the same quote/account context is not validated repeatedly.

Changelog

CHANGELOG entry: null

Related issues

No issue: maintenance-only Bridge performance/refactor to reduce duplicate quote validation calls.

Manual testing steps

Feature: Bridge quote validation deduplication

  Scenario: main Bridge screen validates one active Solana quote once
    Given the app is unlocked with an account that can quote a Solana swap or bridge
    And the user is on the Bridge/Unified Swaps screen
    And network inspection or temporary local logging is available for Blockaid validation requests

    When the user selects a Solana source token and enters a swappable amount
    And the quote details, footer, and confirm button are visible for the same active quote
    Then the app should not send repeated Blockaid validation requests for the same quote requestId
    And the confirm flow should still navigate through token warning, missing price, or price impact modals when applicable

Screenshots/Recordings

Before

Screen.Recording.2026-04-30.at.5.08.56.PM.mov

After

Screen.Recording.2026-04-30.at.5.30.30.PM.mov

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.

Note

Medium Risk
Touches core Bridge/Swaps quoting and confirmation flow by centralizing useBridgeQuoteData and changing useBridgeConfirm to consume a passed-in activeQuote, which could affect when quotes/validations run and what gets submitted. Risk is mitigated by added unit tests around context usage and validation retry behavior.

Overview
Reduces duplicate quote-data work in the main BridgeView subtree by introducing BridgeQuoteDataProvider/useBridgeQuoteDataContext and switching key consumers (footer, quote details, confirm button) to read a single shared useBridgeQuoteData result.

Updates quote validation to skip repeated Blockaid validations for the same quote by caching the last validated requestId + validateBridgeTx function identity, while still retrying after a thrown validation error.

Refactors useBridgeConfirm to no longer fetch quote data internally; callers now pass activeQuote (modals fetch their own quote as needed). Includes test updates/new tests to reflect the context provider and new confirm/validation wiring.

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

@metamaskbotv2 metamaskbotv2 Bot added the team-swaps-and-bridge Swaps and Bridge team label May 1, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 1, 2026

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.

@github-actions github-actions Bot added the size-L label May 1, 2026
@infiniteflower infiniteflower changed the title Refactor/bridge quote data context chore: dedupe swaps quote data validation calls May 1, 2026
@infiniteflower infiniteflower changed the title chore: dedupe swaps quote data validation calls refactor: dedupe swaps quote data validation calls May 1, 2026
@infiniteflower infiniteflower marked this pull request as ready for review May 1, 2026 18:43
@infiniteflower infiniteflower requested a review from a team as a code owner May 1, 2026 18:43
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b1ee556. Configure here.

Comment thread app/components/UI/Bridge/hooks/useBridgeQuoteData/index.ts
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 1, 2026

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokeSwap, SmokeConfirmations
  • Selected Performance tags: None (no tests recommended)
  • Risk Level: medium
  • AI Confidence: 90%
click to see 🤖 AI reasoning details

E2E Test Selection:
All 20 changed files are within the Bridge/Swap feature area (app/components/UI/Bridge/ and app/util/bridge/). The changes are a significant refactoring of how quote data is shared across Bridge components:

  1. New Context Pattern: A new React Context (BridgeQuoteDataProvider/useBridgeQuoteDataContext) was introduced to share useBridgeQuoteData state across the Bridge component tree, replacing multiple independent hook calls. This is a structural change that affects BridgeView, BridgeViewFooter, QuoteDetailsCard, and SwapsConfirmButton.

  2. useBridgeConfirm API Change: The hook now accepts activeQuote directly instead of latestSourceBalance, which required updates to MissingPriceModal, PriceImpactModal, TokenWarningModal, and SwapsConfirmButton.

  3. Quote Validation Logic: useBridgeQuoteData now has a lastValidatedQuoteRef to prevent redundant Blockaid security validations and avoid race conditions — this is a behavioral change in the Solana bridge security flow.

  4. useLatestBalance: Refactored to use useMemo for proper React hook compliance.

  5. useValidateBridgeTx: Wrapped in useCallback for stable reference.

These changes directly affect the Bridge/Swap user flow including quote fetching, confirmation buttons, and security validation. SmokeSwap covers bridge/swap flows, and per the tag description, SmokeConfirmations should also be selected when SmokeSwap is selected since transaction confirmations are part of the flow. No other feature areas (accounts, networks, identity, snaps, browser, etc.) are affected.

Performance Test Selection:
The changes are primarily architectural refactoring (context pattern, useCallback, useMemo) within the Bridge feature. While these improve hook stability and prevent redundant re-renders, they don't introduce new performance-sensitive paths or affect account lists, login, app launch, or other performance-critical areas measured by the available performance test tags. No performance tests are warranted.

View GitHub Actions results

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 1, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size-L team-swaps-and-bridge Swaps and Bridge team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant