Skip to content

feat: add batch sell metrics#9272

Merged
infiniteflower merged 8 commits into
mainfrom
feat/batchSell-metrics
Jun 29, 2026
Merged

feat: add batch sell metrics#9272
infiniteflower merged 8 commits into
mainfrom
feat/batchSell-metrics

Conversation

@infiniteflower

@infiniteflower infiniteflower commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Explanation

This PR revises Batch Sell analytics in @metamask/bridge-controller.

It narrows the Batch Sell metrics surface to the five supported events, updates the event payload types and controller assembly to emit the exact Batch Sell property schema, and removes legacy Batch Sell event names that are no longer used. Batch Sell chain IDs are now supplied by the client for these events so metrics can be emitted before quote request state exists.

It also fixes Batch Sell quote metadata so sentAmount.usd is calculated with each quote's own source token exchange rate. Previously, selectBridgeQuotesWithMetadata derived one source token rate from the first quote request and applied it to every quote, which made later Batch Sell source tokens incorrect when their prices differed from the first token.

Tests cover the revised Batch Sell event payloads and the per-source-token USD regression for selectBatchSellQuotes.

References

Related to: MetaMask/metamask-mobile#32439, https://github.com/Consensys/segment-schema/pull/639

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
Touches shared metrics typing and quote USD calculation used by Batch Sell UI; consumers must adopt new event names and client chain/location fields, but scope is analytics and display metadata rather than transaction execution.

Overview
Adds five Batch Sell analytics events (BatchSellMetricsEventName) with dedicated payload types, BatchSellMetricsLocation, and wiring through trackUnifiedSwapBridgeEvent / #getEventProperties. Batch Sell events use client-supplied chain IDs and their own location enum (not unified feature_id / swap-bridge context). setLocation / getLocation and metrics typing now use the broader BridgeControllerMetricsEventName and BridgeControllerMetricsLocation unions.

Fixes Batch Sell quote metadata: selectBridgeQuotesWithMetadata resolves each quote’s source token exchange rate from that quote’s srcAsset instead of reusing the first quote request’s source rate, so sentAmount.usd is correct when multiple source tokens differ in price.

Exports new constants/types from the package index; tests cover Batch Sell event payloads and per-token USD in selectBatchSellQuotes.

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

@infiniteflower

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-previews

@github-actions

Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/account-tree-controller@7.5.3-preview-bdb5ec714
@metamask-previews/accounts-controller@39.0.3-preview-bdb5ec714
@metamask-previews/address-book-controller@7.1.2-preview-bdb5ec714
@metamask-previews/ai-controllers@0.7.0-preview-bdb5ec714
@metamask-previews/analytics-controller@1.2.0-preview-bdb5ec714
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-bdb5ec714
@metamask-previews/announcement-controller@8.1.0-preview-bdb5ec714
@metamask-previews/app-metadata-controller@2.0.1-preview-bdb5ec714
@metamask-previews/approval-controller@9.0.2-preview-bdb5ec714
@metamask-previews/assets-controller@9.1.0-preview-bdb5ec714
@metamask-previews/assets-controllers@109.2.2-preview-bdb5ec714
@metamask-previews/authenticated-user-storage@2.1.0-preview-bdb5ec714
@metamask-previews/base-controller@9.1.0-preview-bdb5ec714
@metamask-previews/base-data-service@0.1.3-preview-bdb5ec714
@metamask-previews/bitcoin-regtest-up@0.0.0-preview-bdb5ec714
@metamask-previews/bridge-controller@77.0.0-preview-bdb5ec714
@metamask-previews/bridge-status-controller@73.0.0-preview-bdb5ec714
@metamask-previews/build-utils@3.0.4-preview-bdb5ec714
@metamask-previews/chain-agnostic-permission@1.6.2-preview-bdb5ec714
@metamask-previews/chomp-api-service@3.1.0-preview-bdb5ec714
@metamask-previews/claims-controller@0.5.3-preview-bdb5ec714
@metamask-previews/client-controller@1.0.1-preview-bdb5ec714
@metamask-previews/compliance-controller@2.1.0-preview-bdb5ec714
@metamask-previews/composable-controller@12.0.1-preview-bdb5ec714
@metamask-previews/config-registry-controller@0.4.1-preview-bdb5ec714
@metamask-previews/connectivity-controller@0.2.0-preview-bdb5ec714
@metamask-previews/controller-utils@12.3.0-preview-bdb5ec714
@metamask-previews/core-backend@6.3.3-preview-bdb5ec714
@metamask-previews/delegation-controller@3.0.2-preview-bdb5ec714
@metamask-previews/earn-controller@12.2.1-preview-bdb5ec714
@metamask-previews/eip-5792-middleware@3.0.4-preview-bdb5ec714
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.1-preview-bdb5ec714
@metamask-previews/eip1193-permission-middleware@2.0.1-preview-bdb5ec714
@metamask-previews/ens-controller@19.1.4-preview-bdb5ec714
@metamask-previews/eth-block-tracker@15.0.1-preview-bdb5ec714
@metamask-previews/eth-json-rpc-middleware@23.1.3-preview-bdb5ec714
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-bdb5ec714
@metamask-previews/foundryup@1.0.1-preview-bdb5ec714
@metamask-previews/gas-fee-controller@26.2.3-preview-bdb5ec714
@metamask-previews/gator-permissions-controller@4.2.1-preview-bdb5ec714
@metamask-previews/geolocation-controller@0.1.3-preview-bdb5ec714
@metamask-previews/java-tron-up@0.0.0-preview-bdb5ec714
@metamask-previews/json-rpc-engine@10.5.0-preview-bdb5ec714
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-bdb5ec714
@metamask-previews/keyring-controller@27.1.0-preview-bdb5ec714
@metamask-previews/local-node-utils@0.0.0-preview-bdb5ec714
@metamask-previews/logging-controller@8.0.2-preview-bdb5ec714
@metamask-previews/message-manager@14.1.2-preview-bdb5ec714
@metamask-previews/messenger@1.2.0-preview-bdb5ec714
@metamask-previews/messenger-cli@0.2.0-preview-bdb5ec714
@metamask-previews/money-account-balance-service@2.1.1-preview-bdb5ec714
@metamask-previews/money-account-controller@0.3.3-preview-bdb5ec714
@metamask-previews/money-account-upgrade-controller@2.1.0-preview-bdb5ec714
@metamask-previews/multichain-account-service@11.1.0-preview-bdb5ec714
@metamask-previews/multichain-api-middleware@3.1.5-preview-bdb5ec714
@metamask-previews/multichain-network-controller@3.2.0-preview-bdb5ec714
@metamask-previews/multichain-transactions-controller@7.1.1-preview-bdb5ec714
@metamask-previews/name-controller@9.1.2-preview-bdb5ec714
@metamask-previews/network-controller@33.0.0-preview-bdb5ec714
@metamask-previews/network-enablement-controller@5.4.0-preview-bdb5ec714
@metamask-previews/notification-services-controller@24.2.0-preview-bdb5ec714
@metamask-previews/passkey-controller@2.0.1-preview-bdb5ec714
@metamask-previews/permission-controller@13.1.1-preview-bdb5ec714
@metamask-previews/permission-log-controller@5.1.0-preview-bdb5ec714
@metamask-previews/perps-controller@9.0.0-preview-bdb5ec714
@metamask-previews/phishing-controller@17.2.0-preview-bdb5ec714
@metamask-previews/polling-controller@16.0.7-preview-bdb5ec714
@metamask-previews/preferences-controller@23.1.0-preview-bdb5ec714
@metamask-previews/profile-metrics-controller@4.0.0-preview-bdb5ec714
@metamask-previews/profile-sync-controller@28.2.0-preview-bdb5ec714
@metamask-previews/ramps-controller@15.0.0-preview-bdb5ec714
@metamask-previews/rate-limit-controller@7.0.1-preview-bdb5ec714
@metamask-previews/react-data-query@0.2.1-preview-bdb5ec714
@metamask-previews/remote-feature-flag-controller@4.2.2-preview-bdb5ec714
@metamask-previews/sample-controllers@5.0.2-preview-bdb5ec714
@metamask-previews/seedless-onboarding-controller@10.0.3-preview-bdb5ec714
@metamask-previews/selected-network-controller@26.1.4-preview-bdb5ec714
@metamask-previews/shield-controller@5.1.2-preview-bdb5ec714
@metamask-previews/signature-controller@39.2.6-preview-bdb5ec714
@metamask-previews/smart-transactions-controller@24.2.3-preview-bdb5ec714
@metamask-previews/snap-account-service@1.0.0-preview-bdb5ec714
@metamask-previews/social-controllers@2.3.1-preview-bdb5ec714
@metamask-previews/solana-test-validator-up@0.0.0-preview-bdb5ec714
@metamask-previews/storage-service@1.0.2-preview-bdb5ec714
@metamask-previews/subscription-controller@6.2.0-preview-bdb5ec714
@metamask-previews/transaction-controller@68.2.0-preview-bdb5ec714
@metamask-previews/transaction-pay-controller@23.16.1-preview-bdb5ec714
@metamask-previews/user-operation-controller@41.2.5-preview-bdb5ec714
@metamask-previews/wallet@5.0.0-preview-bdb5ec714
@metamask-previews/wallet-cli@0.0.0-preview-bdb5ec714

@infiniteflower

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-previews

@github-actions

Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/account-tree-controller@7.5.3-preview-d5fd8101f
@metamask-previews/accounts-controller@39.0.3-preview-d5fd8101f
@metamask-previews/address-book-controller@7.1.2-preview-d5fd8101f
@metamask-previews/ai-controllers@0.7.0-preview-d5fd8101f
@metamask-previews/analytics-controller@1.2.0-preview-d5fd8101f
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-d5fd8101f
@metamask-previews/announcement-controller@8.1.0-preview-d5fd8101f
@metamask-previews/app-metadata-controller@2.0.1-preview-d5fd8101f
@metamask-previews/approval-controller@9.0.2-preview-d5fd8101f
@metamask-previews/assets-controller@9.1.0-preview-d5fd8101f
@metamask-previews/assets-controllers@109.2.2-preview-d5fd8101f
@metamask-previews/authenticated-user-storage@2.1.0-preview-d5fd8101f
@metamask-previews/base-controller@9.1.0-preview-d5fd8101f
@metamask-previews/base-data-service@0.1.3-preview-d5fd8101f
@metamask-previews/bitcoin-regtest-up@0.0.0-preview-d5fd8101f
@metamask-previews/bridge-controller@77.0.0-preview-d5fd8101f
@metamask-previews/bridge-status-controller@73.0.0-preview-d5fd8101f
@metamask-previews/build-utils@3.0.4-preview-d5fd8101f
@metamask-previews/chain-agnostic-permission@1.6.2-preview-d5fd8101f
@metamask-previews/chomp-api-service@3.1.0-preview-d5fd8101f
@metamask-previews/claims-controller@0.5.3-preview-d5fd8101f
@metamask-previews/client-controller@1.0.1-preview-d5fd8101f
@metamask-previews/compliance-controller@2.1.0-preview-d5fd8101f
@metamask-previews/composable-controller@12.0.1-preview-d5fd8101f
@metamask-previews/config-registry-controller@0.4.1-preview-d5fd8101f
@metamask-previews/connectivity-controller@0.2.0-preview-d5fd8101f
@metamask-previews/controller-utils@12.3.0-preview-d5fd8101f
@metamask-previews/core-backend@6.3.3-preview-d5fd8101f
@metamask-previews/delegation-controller@3.0.2-preview-d5fd8101f
@metamask-previews/earn-controller@12.2.1-preview-d5fd8101f
@metamask-previews/eip-5792-middleware@3.0.4-preview-d5fd8101f
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.1-preview-d5fd8101f
@metamask-previews/eip1193-permission-middleware@2.0.1-preview-d5fd8101f
@metamask-previews/ens-controller@19.1.4-preview-d5fd8101f
@metamask-previews/eth-block-tracker@15.0.1-preview-d5fd8101f
@metamask-previews/eth-json-rpc-middleware@23.1.3-preview-d5fd8101f
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-d5fd8101f
@metamask-previews/foundryup@1.0.1-preview-d5fd8101f
@metamask-previews/gas-fee-controller@26.2.3-preview-d5fd8101f
@metamask-previews/gator-permissions-controller@4.2.1-preview-d5fd8101f
@metamask-previews/geolocation-controller@0.1.3-preview-d5fd8101f
@metamask-previews/java-tron-up@0.0.0-preview-d5fd8101f
@metamask-previews/json-rpc-engine@10.5.0-preview-d5fd8101f
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-d5fd8101f
@metamask-previews/keyring-controller@27.1.0-preview-d5fd8101f
@metamask-previews/local-node-utils@0.0.0-preview-d5fd8101f
@metamask-previews/logging-controller@8.0.2-preview-d5fd8101f
@metamask-previews/message-manager@14.1.2-preview-d5fd8101f
@metamask-previews/messenger@1.2.0-preview-d5fd8101f
@metamask-previews/messenger-cli@0.2.0-preview-d5fd8101f
@metamask-previews/money-account-balance-service@2.1.1-preview-d5fd8101f
@metamask-previews/money-account-controller@0.3.3-preview-d5fd8101f
@metamask-previews/money-account-upgrade-controller@2.1.0-preview-d5fd8101f
@metamask-previews/multichain-account-service@11.1.0-preview-d5fd8101f
@metamask-previews/multichain-api-middleware@3.1.5-preview-d5fd8101f
@metamask-previews/multichain-network-controller@3.2.0-preview-d5fd8101f
@metamask-previews/multichain-transactions-controller@7.1.1-preview-d5fd8101f
@metamask-previews/name-controller@9.1.2-preview-d5fd8101f
@metamask-previews/network-controller@33.0.0-preview-d5fd8101f
@metamask-previews/network-enablement-controller@5.4.0-preview-d5fd8101f
@metamask-previews/notification-services-controller@24.2.0-preview-d5fd8101f
@metamask-previews/passkey-controller@2.0.1-preview-d5fd8101f
@metamask-previews/permission-controller@13.1.1-preview-d5fd8101f
@metamask-previews/permission-log-controller@5.1.0-preview-d5fd8101f
@metamask-previews/perps-controller@9.0.0-preview-d5fd8101f
@metamask-previews/phishing-controller@17.2.0-preview-d5fd8101f
@metamask-previews/polling-controller@16.0.7-preview-d5fd8101f
@metamask-previews/preferences-controller@23.1.0-preview-d5fd8101f
@metamask-previews/profile-metrics-controller@4.0.0-preview-d5fd8101f
@metamask-previews/profile-sync-controller@28.2.0-preview-d5fd8101f
@metamask-previews/ramps-controller@15.0.0-preview-d5fd8101f
@metamask-previews/rate-limit-controller@7.0.1-preview-d5fd8101f
@metamask-previews/react-data-query@0.2.1-preview-d5fd8101f
@metamask-previews/remote-feature-flag-controller@4.2.2-preview-d5fd8101f
@metamask-previews/sample-controllers@5.0.2-preview-d5fd8101f
@metamask-previews/seedless-onboarding-controller@10.0.3-preview-d5fd8101f
@metamask-previews/selected-network-controller@26.1.4-preview-d5fd8101f
@metamask-previews/shield-controller@5.1.2-preview-d5fd8101f
@metamask-previews/signature-controller@39.2.6-preview-d5fd8101f
@metamask-previews/smart-transactions-controller@24.2.3-preview-d5fd8101f
@metamask-previews/snap-account-service@1.0.0-preview-d5fd8101f
@metamask-previews/social-controllers@2.3.1-preview-d5fd8101f
@metamask-previews/solana-test-validator-up@0.0.0-preview-d5fd8101f
@metamask-previews/storage-service@1.0.2-preview-d5fd8101f
@metamask-previews/subscription-controller@6.2.0-preview-d5fd8101f
@metamask-previews/transaction-controller@68.2.0-preview-d5fd8101f
@metamask-previews/transaction-pay-controller@23.16.1-preview-d5fd8101f
@metamask-previews/user-operation-controller@41.2.5-preview-d5fd8101f
@metamask-previews/wallet@5.0.0-preview-d5fd8101f
@metamask-previews/wallet-cli@0.0.0-preview-d5fd8101f

@infiniteflower

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-previews

@infiniteflower infiniteflower marked this pull request as ready for review June 26, 2026 21:12
@infiniteflower infiniteflower requested review from a team as code owners June 26, 2026 21:12
@github-actions

Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/account-tree-controller@7.5.3-preview-6e8c113e9
@metamask-previews/accounts-controller@39.0.3-preview-6e8c113e9
@metamask-previews/address-book-controller@7.1.2-preview-6e8c113e9
@metamask-previews/ai-controllers@0.7.0-preview-6e8c113e9
@metamask-previews/analytics-controller@1.2.0-preview-6e8c113e9
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-6e8c113e9
@metamask-previews/announcement-controller@8.1.0-preview-6e8c113e9
@metamask-previews/app-metadata-controller@2.0.1-preview-6e8c113e9
@metamask-previews/approval-controller@9.0.2-preview-6e8c113e9
@metamask-previews/assets-controller@9.1.0-preview-6e8c113e9
@metamask-previews/assets-controllers@109.2.2-preview-6e8c113e9
@metamask-previews/authenticated-user-storage@2.1.0-preview-6e8c113e9
@metamask-previews/base-controller@9.1.0-preview-6e8c113e9
@metamask-previews/base-data-service@0.1.3-preview-6e8c113e9
@metamask-previews/bitcoin-regtest-up@0.0.0-preview-6e8c113e9
@metamask-previews/bridge-controller@77.0.0-preview-6e8c113e9
@metamask-previews/bridge-status-controller@73.0.0-preview-6e8c113e9
@metamask-previews/build-utils@3.0.4-preview-6e8c113e9
@metamask-previews/chain-agnostic-permission@1.6.2-preview-6e8c113e9
@metamask-previews/chomp-api-service@3.1.0-preview-6e8c113e9
@metamask-previews/claims-controller@0.5.3-preview-6e8c113e9
@metamask-previews/client-controller@1.0.1-preview-6e8c113e9
@metamask-previews/compliance-controller@2.1.0-preview-6e8c113e9
@metamask-previews/composable-controller@12.0.1-preview-6e8c113e9
@metamask-previews/config-registry-controller@0.4.1-preview-6e8c113e9
@metamask-previews/connectivity-controller@0.2.0-preview-6e8c113e9
@metamask-previews/controller-utils@12.3.0-preview-6e8c113e9
@metamask-previews/core-backend@6.3.3-preview-6e8c113e9
@metamask-previews/delegation-controller@3.0.2-preview-6e8c113e9
@metamask-previews/earn-controller@12.2.1-preview-6e8c113e9
@metamask-previews/eip-5792-middleware@3.0.4-preview-6e8c113e9
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.1-preview-6e8c113e9
@metamask-previews/eip1193-permission-middleware@2.0.1-preview-6e8c113e9
@metamask-previews/ens-controller@19.1.4-preview-6e8c113e9
@metamask-previews/eth-block-tracker@15.0.1-preview-6e8c113e9
@metamask-previews/eth-json-rpc-middleware@23.1.3-preview-6e8c113e9
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-6e8c113e9
@metamask-previews/foundryup@1.0.1-preview-6e8c113e9
@metamask-previews/gas-fee-controller@26.2.3-preview-6e8c113e9
@metamask-previews/gator-permissions-controller@4.2.1-preview-6e8c113e9
@metamask-previews/geolocation-controller@0.1.3-preview-6e8c113e9
@metamask-previews/java-tron-up@0.0.0-preview-6e8c113e9
@metamask-previews/json-rpc-engine@10.5.0-preview-6e8c113e9
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-6e8c113e9
@metamask-previews/keyring-controller@27.1.0-preview-6e8c113e9
@metamask-previews/local-node-utils@0.0.0-preview-6e8c113e9
@metamask-previews/logging-controller@8.0.2-preview-6e8c113e9
@metamask-previews/message-manager@14.1.2-preview-6e8c113e9
@metamask-previews/messenger@1.2.0-preview-6e8c113e9
@metamask-previews/messenger-cli@0.2.0-preview-6e8c113e9
@metamask-previews/money-account-balance-service@2.1.1-preview-6e8c113e9
@metamask-previews/money-account-controller@0.3.3-preview-6e8c113e9
@metamask-previews/money-account-upgrade-controller@2.1.0-preview-6e8c113e9
@metamask-previews/multichain-account-service@11.1.0-preview-6e8c113e9
@metamask-previews/multichain-api-middleware@3.1.5-preview-6e8c113e9
@metamask-previews/multichain-network-controller@3.2.0-preview-6e8c113e9
@metamask-previews/multichain-transactions-controller@7.1.1-preview-6e8c113e9
@metamask-previews/name-controller@9.1.2-preview-6e8c113e9
@metamask-previews/network-controller@33.0.0-preview-6e8c113e9
@metamask-previews/network-enablement-controller@5.4.0-preview-6e8c113e9
@metamask-previews/notification-services-controller@24.2.0-preview-6e8c113e9
@metamask-previews/passkey-controller@2.0.1-preview-6e8c113e9
@metamask-previews/permission-controller@13.1.1-preview-6e8c113e9
@metamask-previews/permission-log-controller@5.1.0-preview-6e8c113e9
@metamask-previews/perps-controller@9.0.0-preview-6e8c113e9
@metamask-previews/phishing-controller@17.2.0-preview-6e8c113e9
@metamask-previews/polling-controller@16.0.7-preview-6e8c113e9
@metamask-previews/preferences-controller@23.1.0-preview-6e8c113e9
@metamask-previews/profile-metrics-controller@4.0.0-preview-6e8c113e9
@metamask-previews/profile-sync-controller@28.2.0-preview-6e8c113e9
@metamask-previews/ramps-controller@15.0.0-preview-6e8c113e9
@metamask-previews/rate-limit-controller@7.0.1-preview-6e8c113e9
@metamask-previews/react-data-query@0.2.1-preview-6e8c113e9
@metamask-previews/remote-feature-flag-controller@4.2.2-preview-6e8c113e9
@metamask-previews/sample-controllers@5.0.2-preview-6e8c113e9
@metamask-previews/seedless-onboarding-controller@10.0.3-preview-6e8c113e9
@metamask-previews/selected-network-controller@26.1.4-preview-6e8c113e9
@metamask-previews/shield-controller@5.1.2-preview-6e8c113e9
@metamask-previews/signature-controller@39.2.6-preview-6e8c113e9
@metamask-previews/smart-transactions-controller@24.2.3-preview-6e8c113e9
@metamask-previews/snap-account-service@1.0.0-preview-6e8c113e9
@metamask-previews/social-controllers@2.3.1-preview-6e8c113e9
@metamask-previews/solana-test-validator-up@0.0.0-preview-6e8c113e9
@metamask-previews/storage-service@1.0.2-preview-6e8c113e9
@metamask-previews/subscription-controller@6.2.0-preview-6e8c113e9
@metamask-previews/transaction-controller@68.2.0-preview-6e8c113e9
@metamask-previews/transaction-pay-controller@23.16.1-preview-6e8c113e9
@metamask-previews/user-operation-controller@41.2.5-preview-6e8c113e9
@metamask-previews/wallet@5.0.0-preview-6e8c113e9
@metamask-previews/wallet-cli@0.0.0-preview-6e8c113e9

@infiniteflower infiniteflower enabled auto-merge June 26, 2026 21:19
@infiniteflower infiniteflower added this pull request to the merge queue Jun 29, 2026
Merged via the queue into main with commit 1c9969a Jun 29, 2026
396 checks passed
@infiniteflower infiniteflower deleted the feat/batchSell-metrics branch June 29, 2026 08:33
pull Bot pushed a commit to Dustin4444/metamask-mobile that referenced this pull request Jun 30, 2026
<!--
Please submit this PR as a draft initially.

Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.

In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.

  type=text           Section must contain non-placeholder prose.
  type=changelog      Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
                      comment but do not block the PR.

Sections without a directive are checked for structural presence only.
-->

## **Description**

<!-- mms-check: type=text required=true -->

<!--
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?
-->

Adds Batch Sell analytics coverage for token selection, quote review,
review CTA, and final submit milestones. The Batch Sell token selector
now tracks page views and valid Continue clicks with source-chain and
selected-token context, including Trade menu and deeplink entry
locations.

The Batch Sell quote review flow now tracks quote page views, Review CTA
clicks, and final review modal submissions using aligned source token
arrays. Missing per-token quotes stay aligned with selected tokens by
emitting placeholder source USD values, while the bridge-controller
derives `source_token_count` from `source_token_addresses`.

This also carries raw recommended quote data through
`useBatchSellQuoteData.tokenData` so metric hooks and downstream
consumers can look up the quote attached to each selected source token.

## **Changelog**

<!-- mms-check: type=changelog required=true blocking=true -->

<!--
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**

<!-- mms-check: type=issue-link required=true -->

Refs: MetaMask/core#9272,
Consensys/segment-schema#639

## **Manual testing steps**

<!-- mms-check: type=manual-testing required=true -->

```gherkin
Feature: Batch Sell analytics metrics

  Scenario: user opens Batch Sell from the Trade menu
    Given the wallet has eligible Batch Sell source tokens
    When the user opens Batch Sell from the Trade menu
    Then the "Batch Sell Token Page Viewed" event includes source chain, destination chain, and location

  Scenario: user continues from Batch Sell token selection
    Given the user has selected one or more eligible source tokens
    When the user taps Continue
    Then the "Batch Sell Token Page Continue Clicked" event includes source token symbols, source token addresses, and location

  Scenario: user reviews Batch Sell quotes
    Given the Batch Sell quote review page has loaded at least one quote
    When the quote review page is shown
    Then the "Batch Sell Quote Page Viewed" event includes aligned source token arrays, destination token details, source token slippages, source USD values, and location

  Scenario: user opens the final Batch Sell review modal
    Given the Batch Sell quote review page has reviewable quotes
    When the user taps Review
    Then the "Batch Sell Quote Page Review Clicked" event includes the same quote-page metric properties

  Scenario: user submits Batch Sell
    Given the final review modal is ready to submit
    When the user taps Sell all
    Then the "Batch Sell Review Modal Submitted" event includes the quote-page metric properties plus quoted gas and quoted return
```

Focused automated tests run:

- `yarn jest
app/components/UI/Bridge/hooks/useTrackBatchSellTokenPageContinueClicked/index.test.ts
app/components/UI/Bridge/Views/BatchSellTokenSelect/BatchSellTokenSelect.test.tsx
app/components/UI/Bridge/hooks/useTrackBatchSellTokenPageViewed/index.test.ts`
- `yarn jest
app/components/UI/Bridge/hooks/useTrackBatchSellQuotePageReviewClicked/index.test.ts
app/components/UI/Bridge/hooks/useTrackBatchSellQuotePageViewed/index.test.ts
app/components/UI/Bridge/Views/BatchSellReview/BatchSellReview.test.tsx`
- `yarn jest
app/components/UI/Bridge/hooks/useTrackBatchSellReviewModalSubmitted/index.test.ts
app/components/UI/Bridge/components/BatchSellFinalReviewModal/BatchSellFinalReviewModal.test.tsx
app/components/UI/Bridge/hooks/useTrackBatchSellQuotePageReviewClicked/index.test.ts
app/components/UI/Bridge/hooks/useTrackBatchSellQuotePageViewed/index.test.ts`

## **Screenshots/Recordings**

<!-- mms-check: type=screenshot required=true -->

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->


### **Before**

<!-- [screenshots/recordings] -->

N/A

### **After**

<!-- [screenshots/recordings] -->

<img width="737" height="117" alt="Screenshot 2026-06-26 at 4 58 58 PM"
src="https://github.com/user-attachments/assets/17d3c74e-0638-4abb-9430-44ec9e42c669"
/>
<img width="974" height="175" alt="Screenshot 2026-06-26 at 4 59 20 PM"
src="https://github.com/user-attachments/assets/01b2abe0-f564-4029-989c-ddf7fb1a9fae"
/>
<img width="969" height="250" alt="Screenshot 2026-06-26 at 4 59 35 PM"
src="https://github.com/user-attachments/assets/9b9f4a00-ec16-4211-9f51-e19a27c7f6a3"
/>
<img width="964" height="257" alt="Screenshot 2026-06-26 at 4 59 58 PM"
src="https://github.com/user-attachments/assets/ecf7654d-1c08-4148-8b4a-053e554d7f6d"
/>
<img width="951" height="282" alt="Screenshot 2026-06-26 at 5 00 07 PM"
src="https://github.com/user-attachments/assets/cb3d01e6-1e8d-492c-a3f9-15204a09597f"
/>


## **Pre-merge author checklist**

<!-- mms-check: type=checklist required=true -->

<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.

Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->

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

#### Performance checks (if applicable)

- [x] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- N/A: analytics-only changes; focused Jest coverage was run instead of
device performance testing.
- [x] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- N/A: no performance-sensitive rendering or data loading behavior was
changed.
- [x] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
  - N/A: this PR adds analytics events, not performance traces.

For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).

## **Pre-merge reviewer checklist**

<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->

- [ ] 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]
> **Low Risk**
> Changes are analytics instrumentation and dependency bump only; submit
and navigation behavior is unchanged aside from firing events before
existing actions.
> 
> **Overview**
> This PR wires **Batch Sell** funnel analytics through
`BridgeController.trackUnifiedSwapBridgeEvent`, using new hooks for
token page view/continue, quote page view, Review click, and final
**Sell all** submit (including quoted gas and return USD).
> 
> **Entry location** is passed via `batchSellLocation` route params
(`TradeMenu` from trade actions, `Deeplink` from batch-sell URLs) and
synced with `BridgeController.setLocation` on the token select screen so
later events share the same `location`.
> 
> **Quote data** for metrics is extended: `useBatchSellQuoteData`
attaches each row’s recommended `quote` and exposes network fee `usd`,
reused by shared `getBatchSellQuotePageMetricProperties` (with `0`
placeholders when a selected token lacks a quote). Review tracking is
skipped when the Review button triggers **Get new quote** instead of
opening final review.
> 
> `@metamask/bridge-controller` is bumped to **77.1.0**; test fixtures
and navigation types are updated accordingly.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
d5b8c8b. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
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.

2 participants