Skip to content

fix: add location property to unified swap bridge events#7931

Open
sahar-fehri wants to merge 7 commits intomainfrom
fix/add-location-to-unified-swapbridge-events
Open

fix: add location property to unified swap bridge events#7931
sahar-fehri wants to merge 7 commits intomainfrom
fix/add-location-to-unified-swapbridge-events

Conversation

@sahar-fehri
Copy link
Contributor

@sahar-fehri sahar-fehri commented Feb 13, 2026

Explanation

Adds the location property (entry point) to every Unified SwapBridge event, enabling analytics to trace a user's origin regardless of where they are in the swap/bridge flow.

How to test locally

Add this console log in bridge-controller.ts inside trackUnifiedSwapBridgeEvent, right before the this.#trackMetaMetricsFn call:

console.log(`[SwapBridgeEvent] ${eventName} | location: ${(combinedPropertiesForEvent as Record<string, unknown>)?.location}`);

Then go through a swap flow and check the console for [SwapBridgeEvent] lines. Every event should show the correct location.

References

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Medium Risk
Introduces a new required analytics field and changes public types/method signatures (RequiredEventContextFromClient, submitTx, submitIntent), which may break downstream consumers or alter event payloads if not adopted correctly.

Overview
All Unified SwapBridge analytics events now carry a required location (entry point) for consistent attribution across the entire swap/bridge flow, including internally-fired events and post-submission status events.

In bridge-controller, a default/stored #location is introduced with setLocation() and is also captured from the initial ButtonClicked event; #getEventProperties falls back to this stored value when the client doesn’t provide one, and the MetaMetricsSwapsEventSource enum gains TrendingExplore and is exported publicly.

In bridge-status-controller, location is persisted on BridgeHistoryItem, accepted in StartPollingForBridgeTxStatusArgs, and plumbed through submitTx/submitIntent so Submitted/Completed/Failed/PollingStatusUpdated/StatusValidationFailed events include the originating location; snapshots/changelogs are updated accordingly.

Written by Cursor Bugbot for commit 774dc90. This will update automatically on new commits. Configure here.

@sahar-fehri
Copy link
Contributor Author

@metamaskbot publish-preview

@github-actions
Copy link
Contributor

Preview builds have been published. See these instructions for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/account-tree-controller": "4.1.1-preview-b32f1a3ca",
  "@metamask-previews/accounts-controller": "36.0.0-preview-b32f1a3ca",
  "@metamask-previews/address-book-controller": "7.0.1-preview-b32f1a3ca",
  "@metamask-previews/ai-controllers": "0.0.0-preview-b32f1a3ca",
  "@metamask-previews/analytics-controller": "1.0.0-preview-b32f1a3ca",
  "@metamask-previews/analytics-data-regulation-controller": "0.0.0-preview-b32f1a3ca",
  "@metamask-previews/announcement-controller": "8.0.0-preview-b32f1a3ca",
  "@metamask-previews/app-metadata-controller": "2.0.0-preview-b32f1a3ca",
  "@metamask-previews/approval-controller": "8.0.0-preview-b32f1a3ca",
  "@metamask-previews/assets-controller": "1.0.0-preview-b32f1a3ca",
  "@metamask-previews/assets-controllers": "99.3.2-preview-b32f1a3ca",
  "@metamask-previews/base-controller": "9.0.0-preview-b32f1a3ca",
  "@metamask-previews/bridge-controller": "66.1.1-preview-b32f1a3ca",
  "@metamask-previews/bridge-status-controller": "66.0.2-preview-b32f1a3ca",
  "@metamask-previews/build-utils": "3.0.4-preview-b32f1a3ca",
  "@metamask-previews/chain-agnostic-permission": "1.4.0-preview-b32f1a3ca",
  "@metamask-previews/claims-controller": "0.4.2-preview-b32f1a3ca",
  "@metamask-previews/composable-controller": "12.0.0-preview-b32f1a3ca",
  "@metamask-previews/connectivity-controller": "0.1.0-preview-b32f1a3ca",
  "@metamask-previews/controller-utils": "11.18.0-preview-b32f1a3ca",
  "@metamask-previews/core-backend": "5.1.1-preview-b32f1a3ca",
  "@metamask-previews/delegation-controller": "2.0.1-preview-b32f1a3ca",
  "@metamask-previews/earn-controller": "11.1.0-preview-b32f1a3ca",
  "@metamask-previews/eip-5792-middleware": "2.1.0-preview-b32f1a3ca",
  "@metamask-previews/eip-7702-internal-rpc-middleware": "0.1.0-preview-b32f1a3ca",
  "@metamask-previews/eip1193-permission-middleware": "1.0.3-preview-b32f1a3ca",
  "@metamask-previews/ens-controller": "19.0.2-preview-b32f1a3ca",
  "@metamask-previews/error-reporting-service": "3.0.1-preview-b32f1a3ca",
  "@metamask-previews/eth-block-tracker": "15.0.1-preview-b32f1a3ca",
  "@metamask-previews/eth-json-rpc-middleware": "23.1.0-preview-b32f1a3ca",
  "@metamask-previews/eth-json-rpc-provider": "6.0.0-preview-b32f1a3ca",
  "@metamask-previews/foundryup": "1.0.1-preview-b32f1a3ca",
  "@metamask-previews/gas-fee-controller": "26.0.2-preview-b32f1a3ca",
  "@metamask-previews/gator-permissions-controller": "1.1.2-preview-b32f1a3ca",
  "@metamask-previews/json-rpc-engine": "10.2.2-preview-b32f1a3ca",
  "@metamask-previews/json-rpc-middleware-stream": "8.0.8-preview-b32f1a3ca",
  "@metamask-previews/keyring-controller": "25.1.0-preview-b32f1a3ca",
  "@metamask-previews/logging-controller": "7.0.1-preview-b32f1a3ca",
  "@metamask-previews/message-manager": "14.1.0-preview-b32f1a3ca",
  "@metamask-previews/messenger": "0.3.0-preview-b32f1a3ca",
  "@metamask-previews/multichain-account-service": "7.0.0-preview-b32f1a3ca",
  "@metamask-previews/multichain-api-middleware": "1.2.6-preview-b32f1a3ca",
  "@metamask-previews/multichain-network-controller": "3.0.3-preview-b32f1a3ca",
  "@metamask-previews/multichain-transactions-controller": "7.0.1-preview-b32f1a3ca",
  "@metamask-previews/name-controller": "9.0.0-preview-b32f1a3ca",
  "@metamask-previews/network-controller": "29.0.0-preview-b32f1a3ca",
  "@metamask-previews/network-enablement-controller": "4.1.0-preview-b32f1a3ca",
  "@metamask-previews/notification-services-controller": "22.0.0-preview-b32f1a3ca",
  "@metamask-previews/permission-controller": "12.2.0-preview-b32f1a3ca",
  "@metamask-previews/permission-log-controller": "5.0.0-preview-b32f1a3ca",
  "@metamask-previews/perps-controller": "0.0.0-preview-b32f1a3ca",
  "@metamask-previews/phishing-controller": "16.2.0-preview-b32f1a3ca",
  "@metamask-previews/polling-controller": "16.0.2-preview-b32f1a3ca",
  "@metamask-previews/preferences-controller": "22.1.0-preview-b32f1a3ca",
  "@metamask-previews/profile-metrics-controller": "3.0.1-preview-b32f1a3ca",
  "@metamask-previews/profile-sync-controller": "27.1.0-preview-b32f1a3ca",
  "@metamask-previews/ramps-controller": "8.0.0-preview-b32f1a3ca",
  "@metamask-previews/rate-limit-controller": "7.0.0-preview-b32f1a3ca",
  "@metamask-previews/remote-feature-flag-controller": "4.0.0-preview-b32f1a3ca",
  "@metamask-previews/sample-controllers": "4.0.2-preview-b32f1a3ca",
  "@metamask-previews/seedless-onboarding-controller": "8.0.0-preview-b32f1a3ca",
  "@metamask-previews/selected-network-controller": "26.0.2-preview-b32f1a3ca",
  "@metamask-previews/shield-controller": "5.0.1-preview-b32f1a3ca",
  "@metamask-previews/signature-controller": "39.0.2-preview-b32f1a3ca",
  "@metamask-previews/storage-service": "1.0.0-preview-b32f1a3ca",
  "@metamask-previews/subscription-controller": "6.0.0-preview-b32f1a3ca",
  "@metamask-previews/transaction-controller": "62.17.0-preview-b32f1a3ca",
  "@metamask-previews/transaction-pay-controller": "14.0.0-preview-b32f1a3ca",
  "@metamask-previews/user-operation-controller": "41.0.2-preview-b32f1a3ca"
}

Copy link

@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.

propertiesFromClient.location
) {
this.#location = propertiesFromClient.location;
}
Copy link

Choose a reason for hiding this comment

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

Location state can leak between flows

Medium Severity

#location is only persisted when the event is ButtonClicked. Internal events like InputChanged and QuotesValidationFailed read this.#location, and resetState does not clear it. Flows that start without ButtonClicked or without calling setLocation can inherit a stale location from a previous flow, causing incorrect attribution.

Additional Locations (1)

Fix in Cursor Fix in Web

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant