Skip to content

feat(perps): consume perps controller analytics contract in MetaMask Extension#44324

Open
abretonc7s wants to merge 36 commits into
mainfrom
MANUAL-000001-feat-consume-perps-controller-analy
Open

feat(perps): consume perps controller analytics contract in MetaMask Extension#44324
abretonc7s wants to merge 36 commits into
mainfrom
MANUAL-000001-feat-consume-perps-controller-analy

Conversation

@abretonc7s

@abretonc7s abretonc7s commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Description

Adopts the controller-owned perps analytics contract (@metamask/perps-controller) and completes the assigned analytics tickets.

Beyond the initial contract adoption (re-export controller event/property/value defs, attribution APIs incl. mergeAttributionContext, trackingData/hlFeeRate on place/close/cancel/flip, removal of duplicate client-side transaction emissions so the controller TradingService owns submitted+terminal analytics, LavaMoat policy updates), this now also wires:

  • UTM merged onto all client-emitted PERPS_SCREEN_VIEWED () and source=deeplink
  • watchlisted on the asset_detail screen only
  • screen_type=error + error_type + screen_name on every displayed-error path
  • button_clicked (close/reduce_exposure) + button_location on position_close
  • sort_applied / filter_applied with sort_field/sort_direction/filter_category
  • PERPS_TRANSACTION_CONSIDERED (debounced, gated to genuine user size edits) + trading-screen defaults
  • screen_type=add_margin/remove_margin on margin modal open
  • no-swallowed-exception cleanup (captureException instead of empty catch / log-and-continue)

Hyperliquid SDK / patch

perps-controller@9.2.1's published CommonJS build is broken: @nktkas/hyperliquid ships .d.ts with an amd-module directive hardcoding an absolute CI path, which ts-bridge turns into require("file:///home/runner/.../mod.ts")Cannot find module. This PR carries a temporary yarn patch rewriting it to the bare specifier. Fixed upstream in core 9.2.2 (MetaMask/core#9471, root resolutions patch); this patch is removed once 9.2.2 is published. Upstream report: nktkas/hyperliquid#165

Deferred / N/A

  • order_execution_latency_ms and per-session environment_type on background (controller-emitted) tx events land with the 9.2.2 bump (client-emitted events already carry correct environment_type).
  • N/A in the extension: PERPS_TRADE_QUOTE_RECEIVED (no async pay-with-token quote — fee calc is synchronous), payment-token-selector-dismissed (no such selector).

Changelog

CHANGELOG entry: null

Related issues

Refs: MetaMask/core#9311, MetaMask/core#9471

Manual testing steps

  1. Build/start the Extension with the bumped @metamask/perps-controller.
  2. Open Perps (home → market list → market detail → order entry) and confirm screens still load and trade/close/cancel/TP-SL flows still work.
  3. With analytics enabled, confirm Segment receives controller-emitted Perp Trade / Close / Cancel / Risk events (including status: submitted then terminal) and that the UI no longer double-fires the same transaction event names for those flows.
  4. Open a Perps deep link / URL with utm_* or source= query params and confirm subsequent order lifecycle events include attribution fields when present.

Screenshots/Recordings

Non-visual analytics contract migration — no UI screenshots; recipe proves package/API/source assertions.

Pre-merge author checklist

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

artifacts/recipe.json
{
  "schema_version": 1,
  "title": "MANUAL-000001 perps controller analytics contract",
  "description": "Validate Extension consumes @metamask/perps-controller >=9.1 analytics contract (/ core#9311): package version, controller re-exports, attribution API wiring, and no duplicate client transaction analytics emissions.",
  "validate": {
    "workflow": {
      "entry": "gate-repo-root",
      "nodes": {
        "gate-repo-root": {
          "action": "assert_file",
          "path": "package.json",
          "contains": "@metamask/perps-controller",
          "intent": "Ensure recipe runs from the extension repo root",
          "next": "ac1-assert-package-version"
        },
        "ac1-assert-package-version": {
          "action": "command",
          "cmd": "node -e \"const v=require('./node_modules/@metamask/perps-controller/package.json').version; if(!/^9\\\\.(?:[1-9]|\\\\d{2,})\\\\./.test(v) && !/^9\\\\.(?:[1-9]|\\\\d{2,})$/.test(v)) { console.error('unexpected version', v); process.exit(1);} const c=require('@metamask/perps-controller/constants/eventNames'); if(!c.PERPS_EVENT_PROPERTY.ENTRY_POINT || !c.PERPS_EVENT_PROPERTY.HL_FEE_RATE || !c.PERPS_EVENT_PROPERTY.BULK_ACTION_ID || c.PERPS_EVENT_VALUE.STATUS.SUBMITTED!=='submitted'){ console.error('missing contract keys'); process.exit(1);} console.log('perps-controller', v);\"",
          "intent": "AC1: Extension depends on perps-controller >=9.1 with analytics contract exports",
          "next": "ac2-assert-controller-reexports"
        },
        "ac2-assert-controller-reexports": {
          "action": "assert_file",
          "path": "shared/constants/perps-events.ts",
          "contains": "from '@metamask/perps-controller'",
          "intent": "AC2: perps-events.ts imports controller analytics constants (no divergent hand-maintained mirror)",
          "next": "ac2-assert-no-local-timestamp-mirror"
        },
        "ac2-assert-no-local-timestamp-mirror": {
          "action": "command",
          "cmd": "node -e \"const fs=require('fs'); const t=fs.readFileSync('shared/constants/perps-events.ts','utf8'); if(t.includes(\\\"TIMESTAMP: 'perps_timestamp'\\\")){ console.error('local TIMESTAMP mirror still present'); process.exit(1);} if(!t.includes(\\\"from '@metamask/perps-controller'\\\")){ console.error('missing controller import'); process.exit(1);} console.log('re-export ok');\"",
          "intent": "AC2: Confirm TIMESTAMP is not locally mirrored as perps_timestamp",
          "next": "ac3-assert-attribution-api-wiring"
        },
        "ac3-assert-attribution-api-wiring": {
          "action": "assert_file",
          "path": "app/scripts/messenger-client-init/perps-controller-init.ts",
          "contains": "perpsSetAttributionContext",
          "intent": "AC3: Background API exposes controller setAttributionContext",
          "next": "ac3-assert-attribution-provider"
        },
        "ac3-assert-attribution-provider": {
          "action": "assert_file",
          "path": "ui/providers/perps/PerpsAttributionContext.tsx",
          "contains": "perpsSetAttributionContext",
          "intent": "AC3: UI attribution provider syncs UTM/entry context into controller",
          "next": "ac3-assert-layout-provider"
        },
        "ac3-assert-layout-provider": {
          "action": "assert_file",
          "path": "ui/pages/perps/perps-layout.tsx",
          "contains": "PerpsAttributionProvider",
          "intent": "AC3: Perps layout mounts attribution provider for entry/discovery/UTM propagation",
          "next": "ac3-assert-metrics-merge-utm"
        },
        "ac3-assert-metrics-merge-utm": {
          "action": "command",
          "cmd": "node -e \"const fs=require('fs'); const infra=fs.readFileSync('app/scripts/controllers/perps/infrastructure.ts','utf8'); const init=fs.readFileSync('app/scripts/messenger-client-init/perps-controller-init.ts','utf8'); if(!infra.includes('mergeAttributionContext')){ console.error('infrastructure trackPerpsEvent missing mergeAttributionContext'); process.exit(1);} if(!init.includes('mergeAttributionContext:')){ console.error('init missing mergeAttributionContext wiring'); process.exit(1);} console.log('utm merge wired');\"",
          "intent": "AC3: trackPerpsEvent merges controller UTM attribution before MetaMetrics emission",
          "next": "ac4-assert-tracking-data-builder"
        },
        "ac4-assert-tracking-data-builder": {
          "action": "assert_file",
          "path": "ui/hooks/perps/usePerpsAttribution.ts",
          "contains": "entryPoint",
          "intent": "AC4: trackingData builder attaches entryPoint/discoverySource for controller submitted+terminal events",
          "next": "ac4-assert-cancel-tracking-data"
        },
        "ac4-assert-cancel-tracking-data": {
          "action": "command",
          "cmd": "node -e \"const fs=require('fs'); const t=fs.readFileSync('ui/components/app/perps/cancel-order/cancel-order-modal.tsx','utf8'); if(!t.includes('trackingData: buildTrackingData')){ console.error('cancel missing trackingData'); process.exit(1);} console.log('cancel trackingData ok');\"",
          "intent": "AC4: Cancel passes trackingData so controller cancel events keep entry/discovery",
          "next": "ac4-assert-place-hl-fee-rate"
        },
        "ac4-assert-place-hl-fee-rate": {
          "action": "command",
          "cmd": "node -e \"const fs=require('fs'); const order=fs.readFileSync('ui/pages/perps/perps-order-entry-page.tsx','utf8'); const flip=fs.readFileSync('ui/components/app/perps/reverse-position/reverse-position-modal.tsx','utf8'); const hlCount=(order.match(/hlFeeRate: closeFeeRate/g)||[]).length; if(hlCount<3){ console.error('expected hlFeeRate on close+place+modify paths, found', hlCount); process.exit(1);} if(!flip.includes('hlFeeRate: feeRate')){ console.error('flip missing hlFeeRate'); process.exit(1);} console.log('hlFeeRate parity ok', hlCount);\"",
          "intent": "AC4: Place/modify and flip trackingData include optional hlFeeRate",
          "next": "ac5-assert-no-duplicate-order-entry-close"
        },
        "ac5-assert-no-duplicate-order-entry-close": {
          "action": "command",
          "cmd": "node -e \"const fs=require('fs'); const t=fs.readFileSync('ui/pages/perps/perps-order-entry-page.tsx','utf8'); if(t.includes('MetaMetricsEventName.PerpsPositionCloseTransaction') || t.includes('MetaMetricsEventName.PerpsTradeTransaction') || t.includes('MetaMetricsEventName.PerpsRiskManagement')){ console.error('order-entry still emits duplicate transaction analytics'); process.exit(1);} console.log('order-entry deduped');\"",
          "intent": "AC5: Order-entry no longer emits client Trade/Close/Risk transaction events",
          "next": "ac5-assert-no-duplicate-cancel"
        },
        "ac5-assert-no-duplicate-cancel": {
          "action": "command",
          "cmd": "node -e \"const fs=require('fs'); const t=fs.readFileSync('ui/components/app/perps/cancel-order/cancel-order-modal.tsx','utf8'); if(t.includes('PerpsOrderCancelTransaction')){ console.error('cancel modal still emits duplicate cancel analytics'); process.exit(1);} console.log('cancel deduped');\"",
          "intent": "AC5: Cancel modal does not emit duplicate PerpsOrderCancelTransaction",
          "next": "ac5-assert-no-duplicate-close-modal"
        },
        "ac5-assert-no-duplicate-close-modal": {
          "action": "command",
          "cmd": "node -e \"const fs=require('fs'); const t=fs.readFileSync('ui/components/app/perps/close-position/close-position-modal.tsx','utf8'); if(t.includes('PerpsPositionCloseTransaction')){ console.error('close modal still emits duplicate close analytics'); process.exit(1);} console.log('close modal deduped');\"",
          "intent": "AC5: Close modal does not emit duplicate PerpsPositionCloseTransaction",
          "next": "teardown-end"
        },
        "teardown-end": {
          "action": "end",
          "status": "pass",
          "intent": "Recipe complete"
        }
      }
    }
  }
}

Note

Medium Risk
Touches perps trading analytics and background metrics wiring across many UI flows; incorrect deduping or attribution could skew Segment data, though trade execution still goes through the controller.

Overview
Adopts @metamask/perps-controller@9.2.1 (with a temporary Yarn patch fixing broken require("file:///…/mod.ts") for @nktkas/hyperliquid in the published CJS build) and aligns Extension perps analytics with the controller-owned contract.

Contract & background: shared/constants/perps-events.ts now re-exports controller property/value enums (plus Extension compatibility aliases). Background trackPerpsEvent merges controller UTM via optional mergeAttributionContext, wired from perps-controller-init together with new perpsSet/Get/Clear/MergeAttributionContext APIs.

Attribution end-to-end: Deeplink handlers stamp source=deeplink and forward utm_* (including on signed links via handlerSearchParams: 'original'). UI adds PerpsAttributionProvider / usePerpsAttribution to sync UTM and build trackingData (entry/discovery, VIP, hlFeeRate, tradeAction) on place/close/cancel/flip/TP-SL.

Deduped analytics: Client modals and close-all flows stop emitting trade/close/cancel/risk transaction events where the controller already emits submitted+terminal events; UI keeps PerpsError and adds trackPerpsErrorScreenViewed on displayed-error paths. LavaMoat policies and Jest metamask-perps-controller mocks are expanded to match.

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

@github-actions

github-actions Bot commented Jul 9, 2026

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.

@abretonc7s

Copy link
Copy Markdown
Contributor Author

Automated dev run — MANUAL-000001

Metric Value
Run bda2ae18
Duration ?
Model cursor/grok-4.5-fast-xhigh
Nudges 0
Worker report

Description

Consume the TAT-3463 perps analytics contract from @metamask/perps-controller (≥9.1 / shipped in 9.2.1 via MetaMask/core#9311). Extension now imports controller event/property/value definitions, wires attribution APIs for entry/discovery/UTM context (including mergeAttributionContext in trackPerpsEvent), passes trackingData/hlFeeRate on place/close/cancel/flip, stops emitting duplicate client-side trade/close/cancel/risk transaction events so the controller TradingService owns submitted + terminal analytics, and updates LavaMoat policies for hyperliquid’s new decimal.js dependency.

Changelog

CHANGELOG entry: null

Related issues

Fixes: MANUAL-000001

Manual testing steps

  1. Build/start the Extension with the bumped @metamask/perps-controller.
  2. Open Perps (home → market list → market detail → order entry) and confirm screens still load and trade/close/cancel/TP-SL flows still work.
  3. With analytics enabled, confirm Segment receives controller-emitted Perp Trade / Close / Cancel / Risk events (including status: submitted then terminal) and that the UI no longer double-fires the same transaction event names for those flows.
  4. Open a Perps deep link / URL with utm_* or source= query params and confirm subsequent order lifecycle events include attribution fields when present.

Screenshots/Recordings

Evidence will be added after upload.

Before

N/A — non-visual analytics contract consumption.

After

N/A — non-visual analytics contract consumption.

Pre-merge author checklist

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

artifacts/recipe.json
{
  "schema_version": 1,
  "title": "MANUAL-000001 perps controller analytics contract",
  "description": "Validate Extension consumes @metamask/perps-controller >=9.1 analytics contract (TAT-3463 / core#9311): package version, controller re-exports, attribution API wiring, and no duplicate client transaction analytics emissions.",
  "validate": {
    "workflow": {
      "entry": "gate-repo-root",
      "nodes": {
        "gate-repo-root": {
          "action": "assert_file",
          "path": "package.json",
          "contains": "@metamask/perps-controller",
          "intent": "Ensure recipe runs from the extension repo root",
          "next": "ac1-assert-package-version"
        },
        "ac1-assert-package-version": {
          "action": "command",
          "cmd": "node -e \"const v=require('./node_modules/@metamask/perps-controller/package.json').version; if(!/^9\\\\.(?:[1-9]|\\\\d{2,})\\\\./.test(v) && !/^9\\\\.(?:[1-9]|\\\\d{2,})$/.test(v)) { console.error('unexpected version', v); process.exit(1);} const c=require('@metamask/perps-controller/constants/eventNames'); if(!c.PERPS_EVENT_PROPERTY.ENTRY_POINT || !c.PERPS_EVENT_PROPERTY.HL_FEE_RATE || !c.PERPS_EVENT_PROPERTY.BULK_ACTION_ID || c.PERPS_EVENT_VALUE.STATUS.SUBMITTED!=='submitted'){ console.error('missing TAT-3463 contract keys'); process.exit(1);} console.log('perps-controller', v);\"",
          "intent": "AC1: Extension depends on perps-controller >=9.1 with TAT-3463 analytics contract exports",
          "next": "ac2-assert-controller-reexports"
        },
        "ac2-assert-controller-reexports": {
          "action": "assert_file",
          "path": "shared/constants/perps-events.ts",
          "contains": "from '@metamask/perps-controller'",
          "intent": "AC2: perps-events.ts imports controller analytics constants (no divergent hand-maintained mirror)",
          "next": "ac2-assert-no-local-timestamp-mirror"
        },
        "ac2-assert-no-local-timestamp-mirror": {
          "action": "command",
          "cmd": "node -e \"const fs=require('fs'); const t=fs.readFileSync('shared/constants/perps-events.ts','utf8'); if(t.includes(\\\"TIMESTAMP: 'perps_timestamp'\\\")){ console.error('local TIMESTAMP mirror still present'); process.exit(1);} if(!t.includes(\\\"from '@metamask/perps-controller'\\\")){ console.error('missing controller import'); process.exit(1);} console.log('re-export ok');\"",
          "intent": "AC2: Confirm TIMESTAMP is not locally mirrored as perps_timestamp",
          "next": "ac3-assert-attribution-api-wiring"
        },
        "ac3-assert-attribution-api-wiring": {
          "action": "assert_file",
          "path": "app/scripts/messenger-client-init/perps-controller-init.ts",
          "contains": "perpsSetAttributionContext",
          "intent": "AC3: Background API exposes controller setAttributionContext",
          "next": "ac3-assert-attribution-provider"
        },
        "ac3-assert-attribution-provider": {
          "action": "assert_file",
          "path": "ui/providers/perps/PerpsAttributionContext.tsx",
          "contains": "perpsSetAttributionContext",
          "intent": "AC3: UI attribution provider syncs UTM/entry context into controller",
          "next": "ac3-assert-layout-provider"
        },
        "ac3-assert-layout-provider": {
          "action": "assert_file",
          "path": "ui/pages/perps/perps-layout.tsx",
          "contains": "PerpsAttributionProvider",
          "intent": "AC3: Perps layout mounts attribution provider for entry/discovery/UTM propagation",
          "next": "ac3-assert-metrics-merge-utm"
        },
        "ac3-assert-metrics-merge-utm": {
          "action": "command",
          "cmd": "node -e \"const fs=require('fs'); const infra=fs.readFileSync('app/scripts/controllers/perps/infrastructure.ts','utf8'); const init=fs.readFileSync('app/scripts/messenger-client-init/perps-controller-init.ts','utf8'); if(!infra.includes('mergeAttributionContext')){ console.error('infrastructure trackPerpsEvent missing mergeAttributionContext'); process.exit(1);} if(!init.includes('mergeAttributionContext:')){ console.error('init missing mergeAttributionContext wiring'); process.exit(1);} console.log('utm merge wired');\"",
          "intent": "AC3: trackPerpsEvent merges controller UTM attribution before MetaMetrics emission",
          "next": "ac4-assert-tracking-data-builder"
        },
        "ac4-assert-tracking-data-builder": {
          "action": "assert_file",
          "path": "ui/hooks/perps/usePerpsAttribution.ts",
          "contains": "entryPoint",
          "intent": "AC4: trackingData builder attaches entryPoint/discoverySource for controller submitted+terminal events",
          "next": "ac4-assert-cancel-tracking-data"
        },
        "ac4-assert-cancel-tracking-data": {
          "action": "command",
          "cmd": "node -e \"const fs=require('fs'); const t=fs.readFileSync('ui/components/app/perps/cancel-order/cancel-order-modal.tsx','utf8'); if(!t.includes('trackingData: buildTrackingData')){ console.error('cancel missing trackingData'); process.exit(1);} console.log('cancel trackingData ok');\"",
          "intent": "AC4: Cancel passes trackingData so controller cancel events keep entry/discovery",
          "next": "ac4-assert-place-hl-fee-rate"
        },
        "ac4-assert-place-hl-fee-rate": {
          "action": "command",
          "cmd": "node -e \"const fs=require('fs'); const order=fs.readFileSync('ui/pages/perps/perps-order-entry-page.tsx','utf8'); const flip=fs.readFileSync('ui/components/app/perps/reverse-position/reverse-position-modal.tsx','utf8'); const hlCount=(order.match(/hlFeeRate: closeFeeRate/g)||[]).length; if(hlCount<3){ console.error('expected hlFeeRate on close+place+modify paths, found', hlCount); process.exit(1);} if(!flip.includes('hlFeeRate: feeRate')){ console.error('flip missing hlFeeRate'); process.exit(1);} console.log('hlFeeRate parity ok', hlCount);\"",
          "intent": "AC4: Place/modify and flip trackingData include optional hlFeeRate",
          "next": "ac5-assert-no-duplicate-order-entry-close"
        },
        "ac5-assert-no-duplicate-order-entry-close": {
          "action": "command",
          "cmd": "node -e \"const fs=require('fs'); const t=fs.readFileSync('ui/pages/perps/perps-order-entry-page.tsx','utf8'); if(t.includes('MetaMetricsEventName.PerpsPositionCloseTransaction') || t.includes('MetaMetricsEventName.PerpsTradeTransaction') || t.includes('MetaMetricsEventName.PerpsRiskManagement')){ console.error('order-entry still emits duplicate transaction analytics'); process.exit(1);} console.log('order-entry deduped');\"",
          "intent": "AC5: Order-entry no longer emits client Trade/Close/Risk transaction events",
          "next": "ac5-assert-no-duplicate-cancel"
        },
        "ac5-assert-no-duplicate-cancel": {
          "action": "command",
          "cmd": "node -e \"const fs=require('fs'); const t=fs.readFileSync('ui/components/app/perps/cancel-order/cancel-order-modal.tsx','utf8'); if(t.includes('PerpsOrderCancelTransaction')){ console.error('cancel modal still emits duplicate cancel analytics'); process.exit(1);} console.log('cancel deduped');\"",
          "intent": "AC5: Cancel modal does not emit duplicate PerpsOrderCancelTransaction",
          "next": "ac5-assert-no-duplicate-close-modal"
        },
        "ac5-assert-no-duplicate-close-modal": {
          "action": "command",
          "cmd": "node -e \"const fs=require('fs'); const t=fs.readFileSync('ui/components/app/perps/close-position/close-position-modal.tsx','utf8'); if(t.includes('PerpsPositionCloseTransaction')){ console.error('close modal still emits duplicate close analytics'); process.exit(1);} console.log('close modal deduped');\"",
          "intent": "AC5: Close modal does not emit duplicate PerpsPositionCloseTransaction",
          "next": "teardown-end"
        },
        "teardown-end": {
          "action": "end",
          "status": "pass",
          "intent": "Recipe complete"
        }
      }
    }
  }
}

@abretonc7s abretonc7s changed the title chore: prepare farmslot publication pkg-bda2ae18-mrdsa9ot feat(perps): consume perps controller analytics contract in MetaMask Extension Jul 9, 2026
@abretonc7s abretonc7s marked this pull request as ready for review July 9, 2026 22:18
@abretonc7s abretonc7s requested review from a team as code owners July 9, 2026 22:18
@mm-token-exchange-service mm-token-exchange-service Bot added the team-perps Perps team label Jul 9, 2026
@mm-token-exchange-service

mm-token-exchange-service Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

✨ Files requiring CODEOWNER review ✨

🕵️ @MetaMask/extension-privacy-reviewers (1 files, +4 -0)
  • 📁 test/
    • 📁 e2e/
      • 📁 tests/
        • 📁 settings/
          • 📄 state-logs.json +4 -0

👨‍🔧 @MetaMask/perps (44 files, +2982 -588)
  • 📁 app/
    • 📁 scripts/
      • 📁 controllers/
        • 📁 perps/
          • 📄 infrastructure.test.ts +49 -12
          • 📄 infrastructure.ts +30 -3
  • 📁 shared/
    • 📁 lib/
      • 📁 deep-links/
        • 📁 routes/
          • 📄 perps.ts +14 -3
  • 📁 ui/
    • 📁 __mocks__/
      • 📁 perps/
        • 📁 perps-controller/
          • 📄 index.ts +2 -0
    • 📁 components/
      • 📁 app/
        • 📁 perps/
          • 📁 cancel-order/
            • 📄 cancel-order-modal.test.tsx +46 -30
            • 📄 cancel-order-modal.tsx +42 -13
          • 📁 close-position/
            • 📄 close-position-modal.test.tsx +84 -0
            • 📄 close-position-modal.tsx +36 -37
          • 📁 edit-margin/
            • 📄 edit-margin-modal-content.test.tsx +50 -0
            • 📄 edit-margin-modal-content.tsx +41 -26
          • 📁 order-entry/
            • 📁 components/
              • 📁 amount-input/
                • 📄 amount-input.tsx +16 -1
              • 📄 order-entry.tsx +3 -0
              • 📄 order-entry.types.ts +8 -0
          • 📁 perps-market-recent-activity/
            • 📄 perps-market-recent-activity.tsx +1 -1
          • 📁 perps-recent-activity/
            • 📄 perps-recent-activity.tsx +1 -1
          • 📁 reverse-position/
            • 📄 reverse-position-modal.test.tsx +20 -1
            • 📄 reverse-position-modal.tsx +31 -3
          • 📁 update-tpsl/
            • 📄 update-tpsl-modal-content.test.tsx +30 -6
            • 📄 update-tpsl-modal-content.tsx +29 -27
          • 📁 utils/
            • 📄 deriveTradeAction.test.ts +34 -0
            • 📄 deriveTradeAction.ts +38 -0
            • 📄 index.ts +0 -2
            • 📄 track-perps-error-screen.test.ts +41 -0
            • 📄 track-perps-error-screen.ts +28 -0
            • 📄 trackingData.test.ts +0 -100
            • 📄 trackingData.ts +0 -26
            • 📄 perps-tab.tsx +17 -10
            • 📄 perps-view.test.tsx +3 -19
            • 📄 perps-view.tsx +13 -21
            • 📄 utils.ts +0 -33
    • 📁 hooks/
      • 📁 perps/
        • 📄 index.ts +1 -0
        • 📄 usePerpsAttribution.test.ts +92 -0
        • 📄 usePerpsAttribution.ts +97 -0
        • 📄 usePerpsEventTracking.test.tsx +358 -0
        • 📄 usePerpsEventTracking.ts +39 -6
    • 📁 pages/
      • 📁 perps/
        • 📁 market-list/
          • 📄 index.test.tsx +52 -0
          • 📄 index.tsx +21 -2
          • 📄 perps-layout.tsx +8 -5
          • 📄 perps-market-detail-page.test.tsx +133 -3
          • 📄 perps-market-detail-page.tsx +69 -16
          • 📄 perps-order-entry-page.test.tsx +478 -1
          • 📄 perps-order-entry-page.tsx +295 -180
    • 📁 providers/
      • 📁 perps/
        • 📄 PerpsAttributionContext.test.tsx +268 -0
        • 📄 PerpsAttributionContext.tsx +364 -0

📜 @MetaMask/policy-reviewers (12 files, +96 -24)
  • 📁 lavamoat/
    • 📁 browserify/
      • 📁 beta/
        • 📄 policy.json +8 -2
      • 📁 experimental/
        • 📄 policy.json +8 -2
      • 📁 flask/
        • 📄 policy.json +8 -2
      • 📁 main/
        • 📄 policy.json +8 -2
    • 📁 webpack/
      • 📁 mv2/
        • 📁 beta/
          • 📄 policy.json +8 -2
        • 📁 experimental/
          • 📄 policy.json +8 -2
        • 📁 flask/
          • 📄 policy.json +8 -2
        • 📁 main/
          • 📄 policy.json +8 -2
      • 📁 mv3/
        • 📁 beta/
          • 📄 policy.json +8 -2
        • 📁 experimental/
          • 📄 policy.json +8 -2
        • 📁 flask/
          • 📄 policy.json +8 -2
        • 📁 main/
          • 📄 policy.json +8 -2

Tip

Follow the policy review process outlined in the LavaMoat Policy Review Process doc before expecting an approval from Policy Reviewers.


🧪 @MetaMask/qa (1 files, +4 -0)
  • 📁 test/
    • 📁 e2e/
      • 📁 tests/
        • 📁 settings/
          • 📄 state-logs.json +4 -0

@socket-security

socket-security Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updated@​metamask/​perps-controller@​9.0.0 ⏵ 9.2.180 +110083 +199 +1100

View full report

Comment thread ui/pages/perps/perps-order-entry-page.tsx
@abretonc7s abretonc7s changed the title feat(perps): consume perps controller analytics contract in MetaMask Extension feat(perps): consume perps controller analytics contract in MetaMask Extension [DO-NOT-MERGE] Jul 9, 2026
@abretonc7s abretonc7s changed the title feat(perps): consume perps controller analytics contract in MetaMask Extension [DO-NOT-MERGE] feat(perps): consume perps controller analytics contract in MetaMask Extension [NOT-READY] Jul 9, 2026
@abretonc7s abretonc7s added the DO-NOT-MERGE Pull requests that should not be merged label Jul 9, 2026
abretonc7s added a commit that referenced this pull request Jul 9, 2026
Co-authored-by: Cursor <cursoragent@cursor.com>
@abretonc7s abretonc7s force-pushed the MANUAL-000001-feat-consume-perps-controller-analy branch from aed93b5 to cf70bb7 Compare July 9, 2026 22:49
Comment thread ui/components/app/perps/cancel-order/cancel-order-modal.tsx
abretonc7s added a commit that referenced this pull request Jul 9, 2026
Co-authored-by: Cursor <cursoragent@cursor.com>
abretonc7s added a commit that referenced this pull request Jul 9, 2026
Co-authored-by: Cursor <cursoragent@cursor.com>
abretonc7s added a commit that referenced this pull request Jul 9, 2026
Co-authored-by: Cursor <cursoragent@cursor.com>
abretonc7s added a commit that referenced this pull request Jul 9, 2026
Co-authored-by: Cursor <cursoragent@cursor.com>
@abretonc7s abretonc7s force-pushed the MANUAL-000001-feat-consume-perps-controller-analy branch from 58b0939 to d09d491 Compare July 9, 2026 23:41
Comment thread ui/components/app/perps/close-position/close-position-modal.tsx
Comment thread ui/components/app/perps/edit-margin/edit-margin-modal-content.tsx
abretonc7s added a commit that referenced this pull request Jul 10, 2026
Co-authored-by: Cursor <cursoragent@cursor.com>
Signed deeplinks list only routing params in `sig_params`, so `parse`
canonicalizes the URL down to those before the route handler runs.
Campaign `utm_*` are appended unsigned and were dropped by that step, so
`withDeeplinkAttribution` forwarded `source=deeplink` but never the utm
params, and the client `PERPS_SCREEN_VIEWED` carried source without utm.

Set `handlerSearchParams: 'original'` on the perps deeplink routes so the
handler reads the full incoming params. These routes only open read-only
screens, so honoring unsigned routing params is safe (matches the
trending/predict/batch-sell routes). Adds a parse-level regression test
proving utm survives a signed link whose sig_params omit them.
@mm-token-exchange-service

Copy link
Copy Markdown
Contributor
Builds ready [ab89a58]
Deprecated Browserify fallback builds
⚡ Performance Benchmarks (Total: 🟢 8 pass · 🟡 16 warn · 🔴 0 fail)

Baseline (latest main): 1716549 | Date: 6/29/2026 | Pipeline: 29111239066 | Baseline logs

Interaction Benchmarks · Samples: 5
Benchmarkchrome-webpackfirefox-webpack
loadNewAccount
[Sentry log · main/release]
🟡 [CI log]🟢 [CI log]
🔴 load_new_account
confirmTx
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
bridgeUserActions
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • loadNewAccount/load_new_account: -22%
  • loadNewAccount/total: -22%
  • loadNewAccount/inp: -18%
  • loadNewAccount/fcp: +12%
  • loadNewAccount/lcp: -11%
  • bridgeUserActions/bridge_load_page: -28%
  • bridgeUserActions/bridge_load_asset_picker: +13%
  • bridgeUserActions/longTaskCount: -17%
  • bridgeUserActions/tbt: +16%
  • bridgeUserActions/inp: -14%
  • loadNewAccount/load_new_account: +636%
  • loadNewAccount/total: +636%
  • loadNewAccount/inp: -18%
  • loadNewAccount/fcp: -51%
  • loadNewAccount/lcp: +1054%
  • confirmTx/confirm_tx: +10%
  • confirmTx/longTaskCount: -100%
  • confirmTx/longTaskTotalDuration: -100%
  • confirmTx/longTaskMaxDuration: -100%
  • confirmTx/tbt: -100%
  • confirmTx/total: +10%
  • confirmTx/lcp: +1159%
  • bridgeUserActions/bridge_load_page: +154%
  • bridgeUserActions/bridge_load_asset_picker: +133%
  • bridgeUserActions/longTaskCount: -100%
  • bridgeUserActions/longTaskTotalDuration: -100%
  • bridgeUserActions/longTaskMaxDuration: -100%
  • bridgeUserActions/tbt: -100%
  • bridgeUserActions/total: +34%
  • bridgeUserActions/inp: -22%
  • bridgeUserActions/lcp: +1200%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 loadNewAccount/FCP: p75 2.1s
  • 🟡 bridgeUserActions/FCP: p75 1.8s
  • 🟡 confirmTx/FCP: p75 1.8s
  • 🟡 bridgeUserActions/FCP: p75 1.8s
Startup Benchmarks · Samples: 100
Benchmarkchrome-webpackfirefox-webpack
startupStandardHome
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
startupPowerUserHome
[Sentry log · main/release]
🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • startupStandardHome/uiStartup: +22%
  • startupStandardHome/backgroundConnect: +14%
  • startupStandardHome/firstReactRender: +205%
  • startupStandardHome/numNetworkReqs: +50%
  • startupStandardHome/domInteractive: -27%
  • startupStandardHome/firstReactRender: +287%
  • startupStandardHome/initialActions: -50%
  • startupStandardHome/setupStore: +30%
  • startupStandardHome/fcp: -26%
  • startupPowerUserHome/uiStartup: -24%
  • startupPowerUserHome/load: -26%
  • startupPowerUserHome/domContentLoaded: -26%
  • startupPowerUserHome/domInteractive: -51%
  • startupPowerUserHome/backgroundConnect: -46%
  • startupPowerUserHome/firstReactRender: +454%
  • startupPowerUserHome/loadScripts: -25%
  • startupPowerUserHome/setupStore: -24%
  • startupPowerUserHome/inp: -23%
  • startupPowerUserHome/fcp: -50%
  • startupPowerUserHome/lcp: -29%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 startupPowerUserHome/LCP: p75 2.6s
User Journey Benchmarks · Samples: 5 · mock API
Benchmarkchrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
onboardingNewWallet
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
🟡 total
assetDetails
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]
solanaAssetDetails
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]
importSrpHome
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]
sendTransactions
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]
swap
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • onboardingImportWallet/srpButtonToSrpForm: -21%
  • onboardingImportWallet/confirmSrpToPwForm: -23%
  • onboardingImportWallet/pwFormToMetricsScreen: -17%
  • onboardingImportWallet/metricsToWalletReadyScreen: -28%
  • onboardingImportWallet/doneButtonToHomeScreen: -86%
  • onboardingImportWallet/openAccountMenuToAccountListLoaded: -98%
  • onboardingImportWallet/longTaskCount: -100%
  • onboardingImportWallet/longTaskTotalDuration: -100%
  • onboardingImportWallet/longTaskMaxDuration: -100%
  • onboardingImportWallet/tbt: -100%
  • onboardingImportWallet/total: -85%
  • onboardingNewWallet/doneButtonToAssetList: -16%
  • onboardingNewWallet/longTaskCount: -50%
  • onboardingNewWallet/longTaskTotalDuration: -67%
  • onboardingNewWallet/longTaskMaxDuration: -42%
  • onboardingNewWallet/tbt: -86%
  • onboardingNewWallet/total: -14%
  • solanaAssetDetails/assetClickToPriceChart: -67%
  • solanaAssetDetails/total: -67%
  • solanaAssetDetails/inp: -24%
  • importSrpHome/loginToHomeScreen: -14%
  • importSrpHome/longTaskCount: -35%
  • importSrpHome/longTaskTotalDuration: -41%
  • importSrpHome/longTaskMaxDuration: +14%
  • importSrpHome/tbt: -45%
  • importSrpHome/lcp: -55%
  • importSrpHome/cls: -47%
  • sendTransactions/openSendPageFromHome: -24%
  • sendTransactions/selectTokenToSendFormLoaded: -53%
  • sendTransactions/longTaskCount: -20%
  • sendTransactions/longTaskTotalDuration: -26%
  • sendTransactions/longTaskMaxDuration: -10%
  • sendTransactions/tbt: -55%
  • sendTransactions/inp: -19%
  • sendTransactions/cls: -40%
  • swap/openSwapPageFromHome: -22%
  • swap/fetchAndDisplaySwapQuotes: +127%
  • swap/longTaskTotalDuration: -17%
  • swap/tbt: -67%
  • swap/total: +125%
  • swap/inp: +15%
  • swap/fcp: +11%
  • swap/cls: -63%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 assetDetails/FCP: p75 1.8s
  • 🟡 solanaAssetDetails/FCP: p75 1.8s
  • 🟡 importSrpHome/INP: p75 240ms
  • 🟡 sendTransactions/FCP: p75 1.8s
  • 🟡 swap/FCP: p75 1.9s
  • 🟡 assetDetails/FCP: p75 1.9s
  • 🟡 solanaAssetDetails/FCP: p75 1.9s
  • 🟡 importSrpHome/FCP: p75 2.0s
  • 🟡 sendTransactions/FCP: p75 1.9s
  • 🟡 swap/FCP: p75 1.9s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-webpack
dappPageLoad
[Sentry log · main/release]
🟢 [CI log]
Bundle sizes
  • background: 11.13 MiB
  • ui: 17.02 MiB
  • common: 0 Bytes
  • other: 998.07 KiB
  • contentScripts: 1.79 MiB
  • zip: 26.36 MiB
No matching bundle-size baseline was found in the history data, so diff values are omitted.

The deeplink PERPS_SCREEN_VIEWED fired before the provider's UTM-sync
effect back-filled utmAttribution state (React runs effects after render,
and warm markets make the fire-once screen view eligible immediately), so
the fire-once guard blocked the enriched re-fire and the event carried
source=deeplink but no utm_*. Derive UTM and the deeplink source from the
current locationSearch at render time in screenViewedAttribution so they
are available synchronously on the first emit; the sticky store still
covers later in-app navigations whose search no longer carries utm. Adds a
race regression test that seeds the utm-bearing search after mount.

Also clears the Test lint job (jsdoc @param, import-x/no-duplicates,
snake_case naming-convention headers on analytics/URL test literals,
jest/no-if) and updates the Sentry UI-state and state-logs e2e fixtures
for the controller's new recentlyViewedMarkets state.
Adds a router-driven regression matching the real interstitial flow: the
attribution provider is already mounted at a non-utm perps route when the
deeplink Continue navigates to the utm-bearing market route. The provider's
locationSearch updates in place (no remount) and the fire-once screen view
fires immediately, so the first emit must get UTM from the render-time
derivation of the current search rather than the effect-back-filled state.
Proven non-vacuous: without the render-time union the first emit drops utm.
The entry PERPS_SCREEN_VIEWED fires fire-once on the first eligible render,
but react-router applies the destination useLocation().search one render
AFTER window.location.hash is already correct — so deriving utm from the
provider's locationSearch (render or state) still reads empty at that
instant and the enriched re-fire is blocked. Read utm and the deeplink
source directly from the current hash query at emit time in
usePerpsEventTracking, winning over the provider store; the sticky store
still covers later in-app navigations whose hash no longer carries utm.
Adds a regression that seeds window.location.hash with utm while the
provider search is empty, asserting the first emit carries utm + source.
Make the emit-time window.location.hash read the authoritative UTM source
for every PERPS_SCREEN_VIEWED, not just when a provider store is present.
A stale or absent provider context (the emitting instance's locationSearch
may never carry the perps-route search, and the fire-once guard blocks any
enriched re-fire) must not drop UTM — the hash is always current at emit.
Adds a regression proving the declarative fire-once emit stamps utm from
the hash even with no provider wrapping the call site.
@mm-token-exchange-service

Copy link
Copy Markdown
Contributor
Builds ready [ef0f86a]
Deprecated Browserify fallback builds
⚡ Performance Benchmarks (Total: 🟢 16 pass · 🟡 8 warn · 🔴 0 fail)

Baseline (latest main): 1716549 | Date: 6/29/2026 | Pipeline: 29115381042 | Baseline logs

Interaction Benchmarks · Samples: 5
Benchmarkchrome-webpackfirefox-webpack
loadNewAccount
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]
confirmTx
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
bridgeUserActions
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]

📈 Results compared to the previous 5 runs on main

  • loadNewAccount/load_new_account: -22%
  • loadNewAccount/total: -22%
  • loadNewAccount/inp: -26%
  • bridgeUserActions/bridge_load_page: -29%
  • bridgeUserActions/bridge_load_asset_picker: -13%
  • bridgeUserActions/longTaskCount: -17%
  • bridgeUserActions/inp: -14%
  • loadNewAccount/inp: +170%
  • loadNewAccount/fcp: -18%
  • loadNewAccount/lcp: +894%
  • confirmTx/longTaskCount: -100%
  • confirmTx/longTaskTotalDuration: -100%
  • confirmTx/longTaskMaxDuration: -100%
  • confirmTx/tbt: -100%
  • confirmTx/fcp: -72%
  • confirmTx/lcp: +987%
  • bridgeUserActions/bridge_load_page: +46%
  • bridgeUserActions/bridge_load_asset_picker: +59%
  • bridgeUserActions/longTaskCount: -100%
  • bridgeUserActions/longTaskTotalDuration: -100%
  • bridgeUserActions/longTaskMaxDuration: -100%
  • bridgeUserActions/tbt: -100%
  • bridgeUserActions/total: +15%
  • bridgeUserActions/inp: +12%
  • bridgeUserActions/fcp: -58%
  • bridgeUserActions/lcp: +991%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 loadNewAccount/FCP: p75 1.8s
  • 🟡 loadNewAccount/INP: p75 264ms
Startup Benchmarks · Samples: 100
Benchmarkchrome-webpackfirefox-webpack
startupStandardHome
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
startupPowerUserHome
[Sentry log · main/release]
🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • startupStandardHome/uiStartup: +18%
  • startupStandardHome/firstReactRender: +211%
  • startupStandardHome/numNetworkReqs: +50%
  • startupStandardHome/domInteractive: -27%
  • startupStandardHome/firstReactRender: +280%
  • startupStandardHome/setupStore: +23%
  • startupStandardHome/fcp: -26%
  • startupPowerUserHome/domInteractive: -36%
  • startupPowerUserHome/backgroundConnect: -26%
  • startupPowerUserHome/firstReactRender: +575%
  • startupPowerUserHome/inp: -20%
  • startupPowerUserHome/fcp: -36%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 startupPowerUserHome/LCP: p75 3.4s
User Journey Benchmarks · Samples: 5 · mock API
Benchmarkchrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
onboardingNewWallet
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
🟡 total
assetDetails
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
solanaAssetDetails
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
importSrpHome
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]
sendTransactions
[Sentry log · main/release]
🟡 [CI log]🟢 [CI log]
swap
[Sentry log · main/release]
🟡 [CI log]🟢 [CI log]

📈 Results compared to the previous 5 runs on main

  • onboardingImportWallet/metricsToWalletReadyScreen: -14%
  • onboardingImportWallet/doneButtonToHomeScreen: -86%
  • onboardingImportWallet/openAccountMenuToAccountListLoaded: -49%
  • onboardingImportWallet/longTaskCount: -80%
  • onboardingImportWallet/longTaskTotalDuration: -94%
  • onboardingImportWallet/longTaskMaxDuration: -91%
  • onboardingImportWallet/tbt: -100%
  • onboardingImportWallet/total: -83%
  • onboardingNewWallet/createPwToRecoveryScreen: +12%
  • onboardingNewWallet/longTaskCount: -50%
  • onboardingNewWallet/longTaskTotalDuration: -72%
  • onboardingNewWallet/longTaskMaxDuration: -51%
  • onboardingNewWallet/tbt: -100%
  • solanaAssetDetails/assetClickToPriceChart: -55%
  • solanaAssetDetails/total: -55%
  • solanaAssetDetails/inp: -38%
  • importSrpHome/loginToHomeScreen: -34%
  • importSrpHome/openAccountMenuAfterLogin: -14%
  • importSrpHome/longTaskCount: -52%
  • importSrpHome/longTaskTotalDuration: -56%
  • importSrpHome/tbt: -52%
  • importSrpHome/inp: -15%
  • importSrpHome/lcp: -60%
  • importSrpHome/cls: -47%
  • sendTransactions/openSendPageFromHome: -12%
  • sendTransactions/reviewTransactionToConfirmationPage: +16%
  • sendTransactions/longTaskCount: -20%
  • sendTransactions/longTaskTotalDuration: -29%
  • sendTransactions/longTaskMaxDuration: -14%
  • sendTransactions/tbt: -70%
  • sendTransactions/total: +15%
  • sendTransactions/inp: -19%
  • sendTransactions/cls: -40%
  • swap/openSwapPageFromHome: -31%
  • swap/fetchAndDisplaySwapQuotes: +128%
  • swap/longTaskTotalDuration: -17%
  • swap/tbt: -100%
  • swap/total: +126%
  • swap/inp: +15%
  • swap/cls: -63%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 importSrpHome/INP: p75 224ms
  • 🟡 sendTransactions/FCP: p75 1.8s
  • 🟡 swap/FCP: p75 1.8s
  • 🟡 importSrpHome/FCP: p75 1.9s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-webpack
dappPageLoad
[Sentry log · main/release]
🟢 [CI log]
Bundle sizes
  • background: 11.13 MiB
  • ui: 17.02 MiB
  • common: 0 Bytes
  • other: 998.07 KiB
  • contentScripts: 1.79 MiB
  • zip: 26.36 MiB
No matching bundle-size baseline was found in the history data, so diff values are omitted.

A deeplink to the wallet perps tab mounts one PerpsAttributionProvider;
navigating deeper into /perps/* ("See all") mounts a fresh provider on a
bare in-app URL, whose client PERPS_SCREEN_VIEWED lost the entry utm (the
hash no longer carries it and the sticky store was per-instance). Add a
module-level, session-scoped attribution store (lifetime = UI session,
mirroring the controller's global attribution): the first utm-bearing
entry seeds it and later provider instances inherit it. The emit-time hash
read still wins when a fresh deeplink is present. Adds a regression: a new
provider on a bare URL carries the entry-session utm on its screen view.
@mm-token-exchange-service

Copy link
Copy Markdown
Contributor
Builds ready [a23b47f]
Deprecated Browserify fallback builds
⚡ Performance Benchmarks (Total: 🟢 16 pass · 🟡 7 warn · 🔴 1 fail)

Baseline (latest main): 1716549 | Date: 6/29/2026 | Pipeline: 29118279509 | Baseline logs

Metricschrome-webpackfirefox-webpack
onboardingNewWallet
[Sentry log · main/release]
🟢 [CI log]🔴 [CI log]

Regressions (🔴 1 failure)

Interaction Benchmarks · Samples: 5
Benchmarkchrome-webpackfirefox-webpack
loadNewAccount
[Sentry log · main/release]
🟡 [CI log]🟢 [CI log]
confirmTx
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
bridgeUserActions
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]

📈 Results compared to the previous 5 runs on main

  • loadNewAccount/fcp: +19%
  • bridgeUserActions/bridge_load_page: +28%
  • bridgeUserActions/longTaskCount: -17%
  • bridgeUserActions/inp: -14%
  • loadNewAccount/load_new_account: +57%
  • loadNewAccount/total: +57%
  • loadNewAccount/inp: -18%
  • loadNewAccount/fcp: -52%
  • loadNewAccount/lcp: +1135%
  • confirmTx/confirm_tx: +15%
  • confirmTx/longTaskCount: -100%
  • confirmTx/longTaskTotalDuration: -100%
  • confirmTx/longTaskMaxDuration: -100%
  • confirmTx/tbt: -100%
  • confirmTx/total: +15%
  • confirmTx/fcp: -46%
  • confirmTx/lcp: +1184%
  • bridgeUserActions/bridge_load_page: +140%
  • bridgeUserActions/bridge_load_asset_picker: +106%
  • bridgeUserActions/longTaskCount: -100%
  • bridgeUserActions/longTaskTotalDuration: -100%
  • bridgeUserActions/longTaskMaxDuration: -100%
  • bridgeUserActions/tbt: -100%
  • bridgeUserActions/total: +37%
  • bridgeUserActions/inp: -14%
  • bridgeUserActions/fcp: -47%
  • bridgeUserActions/lcp: +1221%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 loadNewAccount/FCP: p75 2.2s
Startup Benchmarks · Samples: 100
Benchmarkchrome-webpackfirefox-webpack
startupStandardHome
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
startupPowerUserHome
[Sentry log · main/release]
🟢 [CI log]

📈 Results compared to the previous 5 runs on main

  • startupStandardHome/load: -18%
  • startupStandardHome/domContentLoaded: -18%
  • startupStandardHome/domInteractive: -17%
  • startupStandardHome/backgroundConnect: -16%
  • startupStandardHome/firstReactRender: +146%
  • startupStandardHome/initialActions: -33%
  • startupStandardHome/loadScripts: -18%
  • startupStandardHome/numNetworkReqs: +10%
  • startupStandardHome/longTaskCount: -33%
  • startupStandardHome/longTaskTotalDuration: -22%
  • startupStandardHome/longTaskMaxDuration: -21%
  • startupStandardHome/tbt: -19%
  • startupStandardHome/inp: -13%
  • startupStandardHome/fcp: -17%
  • startupStandardHome/lcp: -10%
  • startupStandardHome/domInteractive: -27%
  • startupStandardHome/firstReactRender: +280%
  • startupStandardHome/setupStore: +30%
  • startupStandardHome/fcp: -24%
  • startupPowerUserHome/uiStartup: -38%
  • startupPowerUserHome/load: -38%
  • startupPowerUserHome/domContentLoaded: -38%
  • startupPowerUserHome/domInteractive: -52%
  • startupPowerUserHome/backgroundConnect: -53%
  • startupPowerUserHome/firstReactRender: +381%
  • startupPowerUserHome/initialActions: -50%
  • startupPowerUserHome/loadScripts: -37%
  • startupPowerUserHome/setupStore: -95%
  • startupPowerUserHome/inp: -42%
  • startupPowerUserHome/fcp: -50%
  • startupPowerUserHome/lcp: -43%
User Journey Benchmarks · Samples: 5 · mock API 🔴 1
Benchmarkchrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
onboardingNewWallet
[Sentry log · main/release]
🟢 [CI log]🔴 [CI log]
🔴 total
assetDetails
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
solanaAssetDetails
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
importSrpHome
[Sentry log · main/release]
🟡 [CI log]🟢 [CI log]
sendTransactions
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]
swap
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • onboardingImportWallet/metricsToWalletReadyScreen: -30%
  • onboardingImportWallet/doneButtonToHomeScreen: -86%
  • onboardingImportWallet/openAccountMenuToAccountListLoaded: -50%
  • onboardingImportWallet/longTaskCount: -80%
  • onboardingImportWallet/longTaskTotalDuration: -94%
  • onboardingImportWallet/longTaskMaxDuration: -92%
  • onboardingImportWallet/tbt: -100%
  • onboardingImportWallet/total: -84%
  • onboardingNewWallet/agreeButtonToOnboardingSuccess: -30%
  • onboardingNewWallet/doneButtonToAssetList: -19%
  • onboardingNewWallet/longTaskCount: -100%
  • onboardingNewWallet/longTaskTotalDuration: -100%
  • onboardingNewWallet/longTaskMaxDuration: -100%
  • onboardingNewWallet/tbt: -100%
  • onboardingNewWallet/total: -18%
  • solanaAssetDetails/assetClickToPriceChart: -70%
  • solanaAssetDetails/total: -70%
  • solanaAssetDetails/inp: -31%
  • importSrpHome/openAccountMenuAfterLogin: +58%
  • importSrpHome/homeAfterImportWithNewWallet: -23%
  • importSrpHome/longTaskCount: -35%
  • importSrpHome/longTaskTotalDuration: -28%
  • importSrpHome/longTaskMaxDuration: +18%
  • importSrpHome/tbt: -35%
  • importSrpHome/total: -20%
  • importSrpHome/inp: +12%
  • importSrpHome/lcp: -52%
  • importSrpHome/cls: -47%
  • sendTransactions/openSendPageFromHome: -37%
  • sendTransactions/selectTokenToSendFormLoaded: -53%
  • sendTransactions/longTaskCount: -20%
  • sendTransactions/longTaskTotalDuration: -29%
  • sendTransactions/longTaskMaxDuration: -14%
  • sendTransactions/tbt: -70%
  • sendTransactions/total: +11%
  • sendTransactions/inp: -23%
  • sendTransactions/lcp: -18%
  • sendTransactions/cls: -40%
  • swap/openSwapPageFromHome: -24%
  • swap/fetchAndDisplaySwapQuotes: +154%
  • swap/tbt: -57%
  • swap/total: +150%
  • swap/cls: -63%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 importSrpHome/INP: p75 296ms
  • 🟡 sendTransactions/FCP: p75 1.8s
  • 🟡 assetDetails/FCP: p75 1.9s
  • 🟡 solanaAssetDetails/FCP: p75 1.9s
  • 🟡 sendTransactions/FCP: p75 1.9s
  • 🟡 swap/FCP: p75 1.9s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-webpack
dappPageLoad
[Sentry log · main/release]
🟢 [CI log]
Bundle sizes
  • background: 11.13 MiB
  • ui: 17.04 MiB
  • common: 0 Bytes
  • other: 998.07 KiB
  • contentScripts: 1.79 MiB
  • zip: 26.37 MiB
No matching bundle-size baseline was found in the history data, so diff values are omitted.

The controller only emits the transaction `action` property when
`trackingData.tradeAction` is set (and forwards it verbatim), so the
controller-owned trade executed/failed events were silently dropping
`action` — a regression versus the removed client emissions. Add a shared
`derivePerpsTradeAction(existingDirection, orderDirection)` helper
(create_position / increase_exposure / flip_long_to_short /
flip_short_to_long), pass its result as `trackingData.tradeAction` on all
perpsPlaceOrder paths, and use the same helper for the client
PERPS_TRANSACTION_CONSIDERED action so the considered and executed events
agree. CONSIDERED previously derived from `hasPosition` only, mislabeling
an opposite-side order against an existing position as increase_exposure
instead of a flip. The considered-debounce still gates on a stable
`positionDirection` primitive to avoid position-stream churn resets.

Tests: derivation (create/increase/both flips), buildTrackingData
passthrough, and CONSIDERED flip cases (long->short, short->long) plus a
place-order tradeAction assertion.
Comment thread ui/components/app/perps/utils/deriveTradeAction.ts
…ch intent

edit-margin: the terminal margin-risk "failed" event for the controller
`{ success: false }` branch is emitted by perps-controller from its next
release (core #9471); note it so no client fallback is added (would
double-emit once that ships).

update-tpsl: document that the delayed positions refetch is intentionally
not retained/cleared on unmount — it must run ~2.5s after the modal closes
(covered by an existing test) and only pushes into the global stream
manager, so there is no unmounted-component state update to guard.
…t scope, catch hygiene

- Emit the error screen view on the market-not-found state of both the
  market-detail and order-entry pages (screen_type=error,
  error_type=market_not_found, correct screen_name), which previously
  rendered a displayed error without any funnel event.
- Make source=deeplink PER-ENTRY: a fresh PerpsAttributionProvider mount on
  a non-deeplink URL reports its own source instead of inheriting the prior
  entry's deeplink flag. UTM stays session-sticky (last-touch), matching
  mobile.
- Re-assert the asset_details entry point on market-detail mount so
  trackingData for close/cancel/TP-SL/margin taken there reflects
  asset_details even after returning from the order-entry screen (which
  sets trade_screen on the shared provider).
- perps-view: capture the close-all refresh, close-all, and cancel-all
  catch errors via captureException instead of swallowing them.

Tests: market-not-found error views (both pages), cross-provider utm-sticky
but per-entry source, and asset_details entry-point re-assert.
Comment thread ui/pages/perps/perps-market-detail-page.tsx
The close-all summary event (number_positions_closed) is emitted by the
controller's batch-close summary from the next perps-controller release
(core #9471); document it at the success branch so no client fallback is
added (would double-count).
@mm-token-exchange-service

Copy link
Copy Markdown
Contributor
Builds ready [e924e78]
Deprecated Browserify fallback builds
⚡ Performance Benchmarks (Total: 🟢 15 pass · 🟡 7 warn · 🔴 2 fail)

Baseline (latest main): 1716549 | Date: 6/29/2026 | Pipeline: 29122008250 | Baseline logs

Metricschrome-webpackfirefox-webpack
loadNewAccount
[Sentry log · main/release]
🟢 [CI log]🔴 load_new_account(p95) [CI log]
onboardingNewWallet
[Sentry log · main/release]
🟢 [CI log]🔴 [CI log]

Regressions (🔴 2 failures)

Interaction Benchmarks · Samples: 5 🔴 1
Benchmarkchrome-webpackfirefox-webpack
loadNewAccount
[Sentry log · main/release]
🟢 [CI log]🔴 [CI log]
🔴 load_new_account
confirmTx
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
bridgeUserActions
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
🔴 bridge_search_token

📈 Results compared to the previous 5 runs on main

  • loadNewAccount/load_new_account: -26%
  • loadNewAccount/total: -26%
  • loadNewAccount/inp: -34%
  • loadNewAccount/lcp: +75%
  • confirmTx/longTaskTotalDuration: -20%
  • confirmTx/longTaskMaxDuration: -24%
  • confirmTx/tbt: -37%
  • confirmTx/inp: -18%
  • confirmTx/fcp: -11%
  • bridgeUserActions/bridge_load_page: -26%
  • bridgeUserActions/bridge_load_asset_picker: -29%
  • bridgeUserActions/longTaskCount: -17%
  • bridgeUserActions/longTaskTotalDuration: -39%
  • bridgeUserActions/longTaskMaxDuration: -32%
  • bridgeUserActions/tbt: -77%
  • bridgeUserActions/total: -10%
  • bridgeUserActions/inp: -31%
  • bridgeUserActions/fcp: -20%
  • loadNewAccount/load_new_account: +691%
  • loadNewAccount/total: +691%
  • loadNewAccount/inp: -26%
  • loadNewAccount/fcp: -49%
  • loadNewAccount/lcp: +1019%
  • confirmTx/confirm_tx: +13%
  • confirmTx/longTaskCount: -100%
  • confirmTx/longTaskTotalDuration: -100%
  • confirmTx/longTaskMaxDuration: -100%
  • confirmTx/tbt: -100%
  • confirmTx/total: +13%
  • confirmTx/inp: +53%
  • confirmTx/fcp: -47%
  • confirmTx/lcp: +1093%
  • bridgeUserActions/bridge_load_page: +65%
  • bridgeUserActions/bridge_load_asset_picker: +71%
  • bridgeUserActions/bridge_search_token: +285%
  • bridgeUserActions/longTaskCount: -100%
  • bridgeUserActions/longTaskTotalDuration: -100%
  • bridgeUserActions/longTaskMaxDuration: -100%
  • bridgeUserActions/tbt: -100%
  • bridgeUserActions/total: +233%
  • bridgeUserActions/inp: -14%
  • bridgeUserActions/fcp: -50%
  • bridgeUserActions/lcp: +1196%
Startup Benchmarks · Samples: 100
Benchmarkchrome-webpackfirefox-webpack
startupStandardHome
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
startupPowerUserHome
[Sentry log · main/release]
🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • startupStandardHome/uiStartup: +21%
  • startupStandardHome/backgroundConnect: +10%
  • startupStandardHome/firstReactRender: +209%
  • startupStandardHome/setupStore: +16%
  • startupStandardHome/numNetworkReqs: +15%
  • startupStandardHome/domInteractive: +10%
  • startupStandardHome/firstReactRender: +314%
  • startupStandardHome/setupStore: +45%
  • startupStandardHome/fcp: +10%
  • startupPowerUserHome/domInteractive: -41%
  • startupPowerUserHome/backgroundConnect: -29%
  • startupPowerUserHome/firstReactRender: +572%
  • startupPowerUserHome/fcp: -40%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 startupPowerUserHome/LCP: p75 3.3s
User Journey Benchmarks · Samples: 5 · mock API 🔴 1
Benchmarkchrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
onboardingNewWallet
[Sentry log · main/release]
🟢 [CI log]🔴 [CI log]
🔴 total
assetDetails
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
solanaAssetDetails
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
importSrpHome
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]
sendTransactions
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
swap
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • onboardingImportWallet/metricsToWalletReadyScreen: -17%
  • onboardingImportWallet/doneButtonToHomeScreen: -86%
  • onboardingImportWallet/openAccountMenuToAccountListLoaded: -64%
  • onboardingImportWallet/longTaskCount: -80%
  • onboardingImportWallet/longTaskTotalDuration: -94%
  • onboardingImportWallet/longTaskMaxDuration: -91%
  • onboardingImportWallet/tbt: -100%
  • onboardingImportWallet/total: -83%
  • onboardingNewWallet/longTaskCount: -50%
  • onboardingNewWallet/longTaskTotalDuration: -63%
  • onboardingNewWallet/longTaskMaxDuration: -43%
  • onboardingNewWallet/tbt: -77%
  • solanaAssetDetails/assetClickToPriceChart: -53%
  • solanaAssetDetails/total: -53%
  • solanaAssetDetails/inp: -38%
  • solanaAssetDetails/fcp: -20%
  • solanaAssetDetails/lcp: -21%
  • importSrpHome/loginToHomeScreen: -27%
  • importSrpHome/openAccountMenuAfterLogin: -18%
  • importSrpHome/homeAfterImportWithNewWallet: -29%
  • importSrpHome/longTaskCount: -52%
  • importSrpHome/longTaskTotalDuration: -54%
  • importSrpHome/tbt: -48%
  • importSrpHome/total: -29%
  • importSrpHome/fcp: +52%
  • importSrpHome/lcp: -58%
  • importSrpHome/cls: -47%
  • sendTransactions/openSendPageFromHome: -27%
  • sendTransactions/selectTokenToSendFormLoaded: -54%
  • sendTransactions/reviewTransactionToConfirmationPage: +17%
  • sendTransactions/longTaskCount: -20%
  • sendTransactions/longTaskTotalDuration: -30%
  • sendTransactions/longTaskMaxDuration: -15%
  • sendTransactions/tbt: -77%
  • sendTransactions/total: +16%
  • sendTransactions/inp: -28%
  • sendTransactions/lcp: -13%
  • sendTransactions/cls: -40%
  • swap/openSwapPageFromHome: -35%
  • swap/fetchAndDisplaySwapQuotes: +108%
  • swap/longTaskMaxDuration: +13%
  • swap/tbt: -13%
  • swap/total: +106%
  • swap/cls: -63%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 importSrpHome/INP: p75 248ms
  • 🟡 importSrpHome/FCP: p75 2.6s
  • 🟡 assetDetails/FCP: p75 1.8s
  • 🟡 solanaAssetDetails/FCP: p75 1.8s
  • 🟡 importSrpHome/FCP: p75 2.0s
  • 🟡 sendTransactions/FCP: p75 1.9s
  • 🟡 swap/FCP: p75 1.9s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-webpack
dappPageLoad
[Sentry log · main/release]
🟢 [CI log]

📈 Results compared to the previous 5 runs on main

  • dappPageLoad/pageLoadTime: -25%
  • dappPageLoad/domContentLoaded: -20%
Bundle sizes
  • background: 11.13 MiB
  • ui: 17.04 MiB
  • common: 0 Bytes
  • other: 998.07 KiB
  • contentScripts: 1.79 MiB
  • zip: 26.37 MiB
No matching bundle-size baseline was found in the history data, so diff values are omitted.

@geositta geositta left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I am requesting changes for two findings: direction changes can emit a considered event for a seeded amount without a new size edit, and partial UTM updates produce different attribution between client and controller events.

// Reset the considered-event gating refs when the market or order context
// changes, so a prior edit doesn't make the next market's seeded default fire
// as a user consideration (the page is reused across symbols).
useEffect(() => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Changing direction resets usePerpsOrderForm to its seeded amount, but this effect does not reset hasUserEditedSizeRef or lastInputMethodRef.

After editing size and switching Long/Short, the seeded amount can emit PERPS_TRANSACTION_CONSIDERED without another size interaction. Please reset both refs when orderDirection changes and add a timer-based regression test.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 10dc57c — the reset effect now also depends on orderDirection, so switching Long/Short clears hasUserEditedSizeRef/lastInputMethodRef and the reseeded default amount cannot emit CONSIDERED without a new size interaction. Added a fake-timer regression test (edit size → switch direction → advance 1s → no CONSIDERED until a fresh edit).

// only means controller-emitted events miss UTM enrichment; the client
// still merges the mirrored context, so log for visibility rather than
// swallow.
submitRequestToBackground('perpsSetAttributionContext', [

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The client accumulates partial UTM updates at line 264, but this call forwards only the latest utmContext. In @metamask/perps-controller, setAttributionContext stores { ...context } directly in its private attribution field, replacing the entire controller-side attribution context rather than merging it.

After utm_source=A&utm_medium=B, followed by utm_source=C, client screen-view events report C/B, while controller-emitted events report only C. After rememberSessionUtm(utmContext), forward the accumulated sessionUtmAttribution to the controller and test consecutive partial UTM updates.

This analytics only mismatch requires two partial UTM entries in one UI session; ordinary in-app navigation without UTM parameters does not trigger it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 10dc57crememberSessionUtm now returns the merged accumulated context, and we forward that (not just the latest partial) to perpsSetAttributionContext, so the controllers replace-semantics stay in sync with the client-side accumulation. Added a test asserting that after utm_source=A&utm_medium=B then utm_source=C, the second background call receives the merged { utmSource: C, utmMedium: B }.


// Market-not-found renders a displayed error state (see the `!market` branch
// below); emit the error screen view for that funnel state.
usePerpsEventTracking({

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This new error event can fire alongside the existing asset_details screen event at line 405 because that event does not require market to exist. For an unknown symbol, one rendered error screen therefore produces two screen view events. Gate the normal event on Boolean(market), add resetKey: decodedSymbol here so consecutive invalid symbols are tracked, and test that each invalid symbol produces exactly one error event.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 10dc57c — the market memo is now computed before the asset_details screen view, whose condition gains Boolean(market), and the error view gains resetKey: decodedSymbol. An unknown symbol now emits exactly one error screen view and zero asset_details views, and consecutive invalid symbols each track. Added tests covering both the single-error/no-asset-details case and the per-symbol re-arm.

… and market-not-found

- Reset considered-event refs on orderDirection change so a Long/Short switch
  does not let the reseeded default amount emit PERPS_TRANSACTION_CONSIDERED
  without a fresh size interaction.
- Forward the accumulated session UTM (not just the latest partial) to the
  controller, since setAttributionContext replaces its stored context wholesale.
- Gate the asset_details screen view on the market existing and re-arm the
  market-not-found error view per symbol, so an unknown symbol emits exactly one
  error screen view (not two).
@mm-token-exchange-service

Copy link
Copy Markdown
Contributor
Builds ready [10dc57c]
Deprecated Browserify fallback builds
⚡ Performance Benchmarks (Total: 🟢 17 pass · 🟡 7 warn · 🔴 1 fail)

Baseline (latest main): 1716549 | Date: 6/29/2026 | Pipeline: 29142234502 | Baseline logs

Metricschrome-webpackfirefox-webpack
onboardingNewWallet
[Sentry log · main/release]
🟢 [CI log]🔴 [CI log]

Regressions (🔴 1 failure)

Interaction Benchmarks · Samples: 5
Benchmarkchrome-webpackfirefox-webpack
loadNewAccount
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
confirmTx
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
bridgeUserActions
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]

📈 Results compared to the previous 5 runs on main

  • loadNewAccount/inp: -26%
  • bridgeUserActions/bridge_load_page: -27%
  • bridgeUserActions/bridge_load_asset_picker: -15%
  • bridgeUserActions/longTaskCount: -17%
  • bridgeUserActions/tbt: +14%
  • bridgeUserActions/inp: -14%
  • loadNewAccount/inp: -26%
  • loadNewAccount/fcp: -17%
  • loadNewAccount/lcp: +891%
  • confirmTx/longTaskCount: -100%
  • confirmTx/longTaskTotalDuration: -100%
  • confirmTx/longTaskMaxDuration: -100%
  • confirmTx/tbt: -100%
  • confirmTx/fcp: -55%
  • confirmTx/lcp: +948%
  • bridgeUserActions/bridge_load_page: +123%
  • bridgeUserActions/bridge_load_asset_picker: +89%
  • bridgeUserActions/longTaskCount: -100%
  • bridgeUserActions/longTaskTotalDuration: -100%
  • bridgeUserActions/longTaskMaxDuration: -100%
  • bridgeUserActions/tbt: -100%
  • bridgeUserActions/total: +132%
  • bridgeUserActions/inp: -14%
  • bridgeUserActions/fcp: -85%
  • bridgeUserActions/lcp: +1156%
Startup Benchmarks · Samples: 100
Benchmarkchrome-webpackfirefox-webpack
startupStandardHome
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
startupPowerUserHome
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • startupStandardHome/uiStartup: +18%
  • startupStandardHome/backgroundConnect: +14%
  • startupStandardHome/firstReactRender: +200%
  • startupStandardHome/numNetworkReqs: +50%
  • startupPowerUserHome/uiStartup: +174%
  • startupPowerUserHome/load: +11%
  • startupPowerUserHome/domContentLoaded: +12%
  • startupPowerUserHome/backgroundConnect: +1001%
  • startupPowerUserHome/firstReactRender: +453%
  • startupPowerUserHome/initialActions: +33%
  • startupPowerUserHome/loadScripts: +12%
  • startupPowerUserHome/setupStore: +11%
  • startupPowerUserHome/numNetworkReqs: +17%
  • startupPowerUserHome/longTaskCount: -13%
  • startupPowerUserHome/longTaskMaxDuration: +14%
  • startupPowerUserHome/fcp: +12%
  • startupPowerUserHome/lcp: +331%
  • startupStandardHome/domInteractive: -17%
  • startupStandardHome/firstReactRender: +321%
  • startupStandardHome/setupStore: +38%
  • startupStandardHome/fcp: -17%
  • startupPowerUserHome/uiStartup: +12%
  • startupPowerUserHome/domInteractive: -37%
  • startupPowerUserHome/backgroundConnect: -25%
  • startupPowerUserHome/firstReactRender: +632%
  • startupPowerUserHome/inp: -12%
  • startupPowerUserHome/fcp: -37%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🔴 startupPowerUserHome/INP: p75 536ms
  • 🟡 startupPowerUserHome/LCP: p75 3.7s
User Journey Benchmarks · Samples: 5 · mock API 🔴 1
Benchmarkchrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
onboardingNewWallet
[Sentry log · main/release]
🟢 [CI log]🔴 [CI log]
🔴 total
assetDetails
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
solanaAssetDetails
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
importSrpHome
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]
sendTransactions
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
swap
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • onboardingImportWallet/pwFormToMetricsScreen: +14%
  • onboardingImportWallet/doneButtonToHomeScreen: -86%
  • onboardingImportWallet/openAccountMenuToAccountListLoaded: -49%
  • onboardingImportWallet/longTaskCount: -80%
  • onboardingImportWallet/longTaskTotalDuration: -94%
  • onboardingImportWallet/longTaskMaxDuration: -92%
  • onboardingImportWallet/tbt: -100%
  • onboardingImportWallet/total: -83%
  • onboardingNewWallet/createPwToRecoveryScreen: +17%
  • onboardingNewWallet/agreeButtonToOnboardingSuccess: +12%
  • onboardingNewWallet/longTaskCount: -50%
  • onboardingNewWallet/longTaskTotalDuration: -66%
  • onboardingNewWallet/longTaskMaxDuration: -41%
  • onboardingNewWallet/tbt: -85%
  • solanaAssetDetails/assetClickToPriceChart: -60%
  • solanaAssetDetails/total: -60%
  • solanaAssetDetails/inp: -31%
  • importSrpHome/loginToHomeScreen: -22%
  • importSrpHome/openAccountMenuAfterLogin: +73%
  • importSrpHome/homeAfterImportWithNewWallet: -12%
  • importSrpHome/longTaskCount: -44%
  • importSrpHome/longTaskTotalDuration: -41%
  • importSrpHome/tbt: -36%
  • importSrpHome/total: -12%
  • importSrpHome/lcp: -59%
  • importSrpHome/cls: -47%
  • sendTransactions/openSendPageFromHome: -11%
  • sendTransactions/reviewTransactionToConfirmationPage: -38%
  • sendTransactions/longTaskCount: -20%
  • sendTransactions/longTaskTotalDuration: -34%
  • sendTransactions/longTaskMaxDuration: -20%
  • sendTransactions/tbt: -100%
  • sendTransactions/total: -34%
  • sendTransactions/inp: -11%
  • sendTransactions/lcp: -10%
  • sendTransactions/cls: -40%
  • swap/openSwapPageFromHome: -25%
  • swap/fetchAndDisplaySwapQuotes: +104%
  • swap/longTaskCount: -100%
  • swap/longTaskTotalDuration: -100%
  • swap/longTaskMaxDuration: -100%
  • swap/tbt: -100%
  • swap/total: +102%
  • swap/cls: -63%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 importSrpHome/INP: p75 240ms
  • 🟡 assetDetails/FCP: p75 1.9s
  • 🟡 solanaAssetDetails/FCP: p75 1.9s
  • 🟡 importSrpHome/FCP: p75 1.8s
  • 🟡 swap/FCP: p75 1.9s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-webpack
dappPageLoad
[Sentry log · main/release]
🟢 [CI log]
Bundle sizes
  • background: 14.24 MiB
  • ui: 17.08 MiB
  • common: 0 Bytes
  • other: 998.07 KiB
  • contentScripts: 1.87 MiB
  • zip: 27.04 MiB
No matching bundle-size baseline was found in the history data, so diff values are omitted.

@mm-token-exchange-service

Copy link
Copy Markdown
Contributor
Builds ready [f372672]
Deprecated Browserify fallback builds
⚡ Performance Benchmarks (Total: 🟢 15 pass · 🟡 10 warn · 🔴 0 fail)

Baseline (latest main): 1716549 | Date: 6/29/2026 | Pipeline: 29144882692 | Baseline logs

Interaction Benchmarks · Samples: 5
Benchmarkchrome-webpackfirefox-webpack
loadNewAccount
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
🔴 load_new_account
confirmTx
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
bridgeUserActions
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
🔴 bridge_load_page

📈 Results compared to the previous 5 runs on main

  • loadNewAccount/load_new_account: -20%
  • loadNewAccount/total: -20%
  • loadNewAccount/inp: -26%
  • bridgeUserActions/bridge_load_page: -25%
  • bridgeUserActions/bridge_load_asset_picker: +17%
  • bridgeUserActions/bridge_search_token: +12%
  • bridgeUserActions/longTaskCount: +67%
  • bridgeUserActions/longTaskTotalDuration: +37%
  • bridgeUserActions/longTaskMaxDuration: -12%
  • bridgeUserActions/tbt: -12%
  • bridgeUserActions/inp: -14%
  • loadNewAccount/load_new_account: +553%
  • loadNewAccount/total: +553%
  • loadNewAccount/inp: +113%
  • loadNewAccount/lcp: +1117%
  • confirmTx/confirm_tx: +11%
  • confirmTx/longTaskCount: -100%
  • confirmTx/longTaskTotalDuration: -100%
  • confirmTx/longTaskMaxDuration: -100%
  • confirmTx/tbt: -100%
  • confirmTx/total: +11%
  • confirmTx/lcp: +1123%
  • bridgeUserActions/bridge_load_page: +1224%
  • bridgeUserActions/bridge_load_asset_picker: +115%
  • bridgeUserActions/longTaskCount: -100%
  • bridgeUserActions/longTaskTotalDuration: -100%
  • bridgeUserActions/longTaskMaxDuration: -100%
  • bridgeUserActions/tbt: -100%
  • bridgeUserActions/total: +174%
  • bridgeUserActions/inp: -22%
  • bridgeUserActions/lcp: +1157%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 loadNewAccount/INP: p75 208ms
  • 🟡 loadNewAccount/FCP: p75 1.9s
  • 🟡 confirmTx/FCP: p75 1.8s
  • 🟡 bridgeUserActions/FCP: p75 1.8s
Startup Benchmarks · Samples: 100
Benchmarkchrome-webpackfirefox-webpack
startupStandardHome
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
startupPowerUserHome
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • startupStandardHome/uiStartup: +20%
  • startupStandardHome/backgroundConnect: +10%
  • startupStandardHome/firstReactRender: +213%
  • startupStandardHome/numNetworkReqs: +50%
  • startupStandardHome/lcp: -14%
  • startupPowerUserHome/uiStartup: +152%
  • startupPowerUserHome/backgroundConnect: +863%
  • startupPowerUserHome/firstReactRender: +393%
  • startupPowerUserHome/initialActions: +33%
  • startupPowerUserHome/longTaskCount: -13%
  • startupPowerUserHome/longTaskMaxDuration: +13%
  • startupPowerUserHome/tbt: +13%
  • startupPowerUserHome/lcp: +319%
  • startupStandardHome/domInteractive: +66%
  • startupStandardHome/firstReactRender: +272%
  • startupStandardHome/setupStore: +30%
  • startupStandardHome/fcp: +34%
  • startupPowerUserHome/domInteractive: -40%
  • startupPowerUserHome/backgroundConnect: -22%
  • startupPowerUserHome/firstReactRender: +569%
  • startupPowerUserHome/fcp: -38%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🔴 startupPowerUserHome/INP: p75 576ms
  • 🟡 startupPowerUserHome/INP: p75 224ms
  • 🟡 startupPowerUserHome/LCP: p75 3.3s
User Journey Benchmarks · Samples: 5 · mock API
Benchmarkchrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
onboardingNewWallet
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
🟡 total
assetDetails
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
solanaAssetDetails
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
importSrpHome
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]
sendTransactions
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
swap
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • onboardingImportWallet/srpButtonToSrpForm: -15%
  • onboardingImportWallet/confirmSrpToPwForm: -18%
  • onboardingImportWallet/pwFormToMetricsScreen: -15%
  • onboardingImportWallet/metricsToWalletReadyScreen: -29%
  • onboardingImportWallet/doneButtonToHomeScreen: -86%
  • onboardingImportWallet/openAccountMenuToAccountListLoaded: -98%
  • onboardingImportWallet/longTaskCount: -100%
  • onboardingImportWallet/longTaskTotalDuration: -100%
  • onboardingImportWallet/longTaskMaxDuration: -100%
  • onboardingImportWallet/tbt: -100%
  • onboardingImportWallet/total: -85%
  • onboardingNewWallet/doneButtonToAssetList: -29%
  • onboardingNewWallet/longTaskCount: -50%
  • onboardingNewWallet/longTaskTotalDuration: -72%
  • onboardingNewWallet/longTaskMaxDuration: -51%
  • onboardingNewWallet/tbt: -100%
  • onboardingNewWallet/total: -24%
  • solanaAssetDetails/assetClickToPriceChart: -58%
  • solanaAssetDetails/total: -58%
  • solanaAssetDetails/inp: -24%
  • importSrpHome/loginToHomeScreen: -20%
  • importSrpHome/homeAfterImportWithNewWallet: -20%
  • importSrpHome/longTaskCount: -44%
  • importSrpHome/longTaskTotalDuration: -49%
  • importSrpHome/tbt: -40%
  • importSrpHome/total: -19%
  • importSrpHome/inp: -21%
  • importSrpHome/lcp: -58%
  • importSrpHome/cls: -47%
  • sendTransactions/openSendPageFromHome: -26%
  • sendTransactions/selectTokenToSendFormLoaded: -49%
  • sendTransactions/reviewTransactionToConfirmationPage: -38%
  • sendTransactions/longTaskCount: -100%
  • sendTransactions/longTaskTotalDuration: -100%
  • sendTransactions/longTaskMaxDuration: -100%
  • sendTransactions/tbt: -100%
  • sendTransactions/total: -38%
  • sendTransactions/inp: -11%
  • sendTransactions/lcp: -12%
  • sendTransactions/cls: -40%
  • swap/openSwapPageFromHome: -28%
  • swap/fetchAndDisplaySwapQuotes: +107%
  • swap/longTaskCount: -100%
  • swap/longTaskTotalDuration: -100%
  • swap/longTaskMaxDuration: -100%
  • swap/tbt: -100%
  • swap/total: +105%
  • swap/inp: +15%
  • swap/cls: -63%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 importSrpHome/INP: p75 208ms
  • 🟡 importSrpHome/FCP: p75 1.8s
  • 🟡 sendTransactions/FCP: p75 1.9s
  • 🟡 swap/FCP: p75 1.8s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-webpack
dappPageLoad
[Sentry log · main/release]
🟢 [CI log]

📈 Results compared to the previous 5 runs on main

  • dappPageLoad/pageLoadTime: -16%
Bundle sizes
  • background: 14.24 MiB
  • ui: 17.08 MiB
  • common: 0 Bytes
  • other: 998.07 KiB
  • contentScripts: 1.87 MiB
  • zip: 27.04 MiB
No matching bundle-size baseline was found in the history data, so diff values are omitted.

…override

@nktkas/hyperliquid's HTTP transport abort helper (_abort.js) calls the bare
globals setTimeout/clearTimeout. Under the webpack MV3 LavaMoat SES sandbox the
@metamask/perps-controller compartment (and its bundled @nktkas/hyperliquid
subtree) was not granted these globals, so cancelling a request threw
"clearTimeout is not a function" — surfacing as PerpsStreamManager "Failed to
fetch account/markets" and degrading perps data loading in e2e Chrome builds.

The MV3 generated policy.json never captured the perps-controller dependency
subtree (mv2 and browserify policies do). Grant the timer/fetch globals via the
MV3 policy-override.json (merged into the runtime policy by @lavamoat/webpack's
loadPolicy -> applyOverride), mirroring the global sets the analyzer already
records for these packages in the mv2 policy. Override-only keeps the change
drift-safe: it does not alter the generated policy.json the validate job checks.
Resolve MV3 LavaMoat policy-override conflicts by keeping both intents:
main's new override entries (assets-controllers tanstack query-core,
gridplus-sdk zod) alongside our perps-controller/@nktkas/hyperliquid timer
globals. No other conflicts.
@mm-token-exchange-service

Copy link
Copy Markdown
Contributor
Builds ready [71e5e28]
Deprecated Browserify fallback builds
⚡ Performance Benchmarks (Total: 🟢 15 pass · 🟡 9 warn · 🔴 1 fail)

Baseline (latest main): 1716549 | Date: 6/29/2026 | Pipeline: 29150760429 | Baseline logs

Metricschrome-webpackfirefox-webpack
onboardingNewWallet
[Sentry log · main/release]
🟢 [CI log]🔴 [CI log]

Regressions (🔴 1 failure)

Interaction Benchmarks · Samples: 5
Benchmarkchrome-webpackfirefox-webpack
loadNewAccount
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
confirmTx
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
bridgeUserActions
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]

📈 Results compared to the previous 5 runs on main

  • loadNewAccount/load_new_account: +38%
  • loadNewAccount/total: +38%
  • loadNewAccount/inp: -18%
  • loadNewAccount/lcp: -12%
  • confirmTx/inp: +12%
  • bridgeUserActions/bridge_load_asset_picker: -13%
  • bridgeUserActions/longTaskCount: -17%
  • bridgeUserActions/longTaskTotalDuration: -11%
  • bridgeUserActions/inp: -22%
  • loadNewAccount/load_new_account: +58%
  • loadNewAccount/total: +58%
  • loadNewAccount/inp: -26%
  • loadNewAccount/fcp: -48%
  • loadNewAccount/lcp: +1139%
  • confirmTx/confirm_tx: +12%
  • confirmTx/longTaskCount: -100%
  • confirmTx/longTaskTotalDuration: -100%
  • confirmTx/longTaskMaxDuration: -100%
  • confirmTx/tbt: -100%
  • confirmTx/total: +12%
  • confirmTx/lcp: +1189%
  • bridgeUserActions/bridge_load_page: +139%
  • bridgeUserActions/bridge_load_asset_picker: +45%
  • bridgeUserActions/longTaskCount: -100%
  • bridgeUserActions/longTaskTotalDuration: -100%
  • bridgeUserActions/longTaskMaxDuration: -100%
  • bridgeUserActions/tbt: -100%
  • bridgeUserActions/total: +37%
  • bridgeUserActions/inp: -14%
  • bridgeUserActions/fcp: -47%
  • bridgeUserActions/lcp: +1238%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 confirmTx/FCP: p75 1.9s
Startup Benchmarks · Samples: 100
Benchmarkchrome-webpackfirefox-webpack
startupStandardHome
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
🟡 loadScripts
startupPowerUserHome
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • startupStandardHome/uiStartup: +18%
  • startupStandardHome/backgroundConnect: +10%
  • startupStandardHome/firstReactRender: +209%
  • startupStandardHome/numNetworkReqs: +20%
  • startupPowerUserHome/uiStartup: +180%
  • startupPowerUserHome/load: +13%
  • startupPowerUserHome/domContentLoaded: +13%
  • startupPowerUserHome/backgroundConnect: +990%
  • startupPowerUserHome/firstReactRender: +432%
  • startupPowerUserHome/initialActions: +33%
  • startupPowerUserHome/loadScripts: +13%
  • startupPowerUserHome/setupStore: +16%
  • startupPowerUserHome/numNetworkReqs: +14%
  • startupPowerUserHome/longTaskCount: -13%
  • startupPowerUserHome/longTaskMaxDuration: +13%
  • startupStandardHome/uiStartup: +11%
  • startupStandardHome/firstReactRender: +344%
  • startupStandardHome/setupStore: +45%
  • startupPowerUserHome/uiStartup: +14%
  • startupPowerUserHome/domInteractive: -33%
  • startupPowerUserHome/backgroundConnect: +16%
  • startupPowerUserHome/firstReactRender: +623%
  • startupPowerUserHome/fcp: -31%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🔴 startupPowerUserHome/INP: p75 536ms
  • 🟡 startupPowerUserHome/LCP: p75 3.7s
User Journey Benchmarks · Samples: 5 · mock API 🔴 1
Benchmarkchrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
onboardingNewWallet
[Sentry log · main/release]
🟢 [CI log]🔴 [CI log]
🔴 total
assetDetails
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
solanaAssetDetails
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
importSrpHome
[Sentry log · main/release]
🟡 [CI log]🟢 [CI log]
sendTransactions
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
swap
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • onboardingImportWallet/srpButtonToSrpForm: -20%
  • onboardingImportWallet/metricsToWalletReadyScreen: -43%
  • onboardingImportWallet/doneButtonToHomeScreen: -86%
  • onboardingImportWallet/openAccountMenuToAccountListLoaded: -98%
  • onboardingImportWallet/longTaskCount: -100%
  • onboardingImportWallet/longTaskTotalDuration: -100%
  • onboardingImportWallet/longTaskMaxDuration: -100%
  • onboardingImportWallet/tbt: -100%
  • onboardingImportWallet/total: -86%
  • onboardingNewWallet/createPwToRecoveryScreen: +17%
  • onboardingNewWallet/agreeButtonToOnboardingSuccess: +19%
  • onboardingNewWallet/doneButtonToAssetList: -33%
  • onboardingNewWallet/longTaskCount: -50%
  • onboardingNewWallet/longTaskTotalDuration: -71%
  • onboardingNewWallet/longTaskMaxDuration: -48%
  • onboardingNewWallet/tbt: -98%
  • onboardingNewWallet/total: -28%
  • solanaAssetDetails/assetClickToPriceChart: -68%
  • solanaAssetDetails/total: -68%
  • solanaAssetDetails/inp: -31%
  • importSrpHome/loginToHomeScreen: -24%
  • importSrpHome/openAccountMenuAfterLogin: -19%
  • importSrpHome/homeAfterImportWithNewWallet: -26%
  • importSrpHome/longTaskCount: -19%
  • importSrpHome/longTaskTotalDuration: -43%
  • importSrpHome/tbt: -43%
  • importSrpHome/total: -26%
  • importSrpHome/lcp: -61%
  • importSrpHome/cls: -47%
  • sendTransactions/openSendPageFromHome: -25%
  • sendTransactions/selectTokenToSendFormLoaded: -50%
  • sendTransactions/longTaskCount: -100%
  • sendTransactions/longTaskTotalDuration: -100%
  • sendTransactions/longTaskMaxDuration: -100%
  • sendTransactions/tbt: -100%
  • sendTransactions/inp: -11%
  • sendTransactions/lcp: -12%
  • sendTransactions/cls: -40%
  • swap/openSwapPageFromHome: -30%
  • swap/fetchAndDisplaySwapQuotes: +154%
  • swap/longTaskTotalDuration: -23%
  • swap/longTaskMaxDuration: -11%
  • swap/tbt: -100%
  • swap/total: +151%
  • swap/cls: -63%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 importSrpHome/INP: p75 280ms
  • 🟡 assetDetails/FCP: p75 1.8s
  • 🟡 solanaAssetDetails/FCP: p75 1.9s
  • 🟡 sendTransactions/FCP: p75 2.1s
  • 🟡 swap/FCP: p75 2.0s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-webpack
dappPageLoad
[Sentry log · main/release]
🟢 [CI log]
Bundle sizes
  • background: 14.25 MiB
  • ui: 17.08 MiB
  • common: 0 Bytes
  • other: 998.07 KiB
  • contentScripts: 1.87 MiB
  • zip: 27.04 MiB
No matching bundle-size baseline was found in the history data, so diff values are omitted.

geositta
geositta previously approved these changes Jul 11, 2026

@geositta geositta left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approve One analytics issue remains in order entry: an unknown symbol can still emit both trading and error, and the error hook does not reset between invalid symbols. This is confined to invalid or delisted market routes, but it should probably be corrected here or tracked for immediate follow-up.

The committed webpack MV3 policy.json files were stale and lacked the
@metamask/perps-controller subtree, causing the validate-lavamoat-policies
MV3 job to fail after main was merged in.

Regenerating the policy via static analysis captures the perps subtree
(including the setTimeout/clearTimeout/fetch bare-global refs the SDK's
transport layer uses), so the policy-override.json entries added earlier
to grant those timer globals are redundant. A no-override regen produces a
byte-identical policy.json across all four build types, so the perps
override entries are removed while main's zod/tanstack entries are kept.
@sonarqubecloud

Copy link
Copy Markdown

@mm-token-exchange-service

Copy link
Copy Markdown
Contributor
Builds ready [960d3aa]
Deprecated Browserify fallback builds
⚡ Performance Benchmarks (Total: 🟢 14 pass · 🟡 11 warn · 🔴 0 fail)

Baseline (latest main): 1716549 | Date: 6/29/2026 | Pipeline: 29182604370 | Baseline logs

Interaction Benchmarks · Samples: 5
Benchmarkchrome-webpackfirefox-webpack
loadNewAccount
[Sentry log · main/release]
🟡 [CI log]🟢 [CI log]
confirmTx
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
bridgeUserActions
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
🔴 bridge_load_page

📈 Results compared to the previous 5 runs on main

  • loadNewAccount/load_new_account: -24%
  • loadNewAccount/total: -24%
  • loadNewAccount/fcp: +12%
  • bridgeUserActions/bridge_load_page: +13%
  • bridgeUserActions/longTaskCount: +67%
  • bridgeUserActions/longTaskTotalDuration: +35%
  • bridgeUserActions/inp: -14%
  • loadNewAccount/load_new_account: +54%
  • loadNewAccount/total: +54%
  • loadNewAccount/fcp: -48%
  • loadNewAccount/lcp: +1109%
  • confirmTx/confirm_tx: +12%
  • confirmTx/longTaskCount: -100%
  • confirmTx/longTaskTotalDuration: -100%
  • confirmTx/longTaskMaxDuration: -100%
  • confirmTx/tbt: -100%
  • confirmTx/total: +12%
  • confirmTx/lcp: +1155%
  • bridgeUserActions/bridge_load_page: +1316%
  • bridgeUserActions/bridge_load_asset_picker: +198%
  • bridgeUserActions/longTaskCount: -100%
  • bridgeUserActions/longTaskTotalDuration: -100%
  • bridgeUserActions/longTaskMaxDuration: -100%
  • bridgeUserActions/tbt: -100%
  • bridgeUserActions/total: +207%
  • bridgeUserActions/inp: -14%
  • bridgeUserActions/fcp: -41%
  • bridgeUserActions/lcp: +1237%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 loadNewAccount/FCP: p75 2.1s
  • 🟡 confirmTx/FCP: p75 1.9s
Startup Benchmarks · Samples: 100
Benchmarkchrome-webpackfirefox-webpack
startupStandardHome
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
🟡 loadScripts
startupPowerUserHome
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • startupStandardHome/uiStartup: +18%
  • startupStandardHome/firstReactRender: +207%
  • startupStandardHome/setupStore: -15%
  • startupStandardHome/numNetworkReqs: +50%
  • startupPowerUserHome/uiStartup: +178%
  • startupPowerUserHome/load: +14%
  • startupPowerUserHome/domContentLoaded: +14%
  • startupPowerUserHome/domInteractive: +29%
  • startupPowerUserHome/backgroundConnect: +1027%
  • startupPowerUserHome/firstReactRender: +451%
  • startupPowerUserHome/initialActions: +33%
  • startupPowerUserHome/loadScripts: +14%
  • startupPowerUserHome/setupStore: +26%
  • startupPowerUserHome/numNetworkReqs: +16%
  • startupPowerUserHome/longTaskCount: -13%
  • startupPowerUserHome/longTaskMaxDuration: +16%
  • startupPowerUserHome/fcp: +14%
  • startupPowerUserHome/lcp: +348%
  • startupStandardHome/uiStartup: +11%
  • startupStandardHome/load: +10%
  • startupStandardHome/domContentLoaded: +10%
  • startupStandardHome/domInteractive: +74%
  • startupStandardHome/firstReactRender: +310%
  • startupStandardHome/loadScripts: +10%
  • startupStandardHome/setupStore: +52%
  • startupStandardHome/fcp: +70%
  • startupPowerUserHome/uiStartup: +11%
  • startupPowerUserHome/domInteractive: -31%
  • startupPowerUserHome/backgroundConnect: -14%
  • startupPowerUserHome/firstReactRender: +620%
  • startupPowerUserHome/fcp: -32%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🔴 startupPowerUserHome/INP: p75 552ms
  • 🟡 startupPowerUserHome/LCP: p75 3.7s
User Journey Benchmarks · Samples: 5 · mock API
Benchmarkchrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
onboardingNewWallet
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
🟡 total
assetDetails
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
solanaAssetDetails
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
importSrpHome
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]
sendTransactions
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
swap
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • onboardingImportWallet/metricsToWalletReadyScreen: -16%
  • onboardingImportWallet/doneButtonToHomeScreen: -86%
  • onboardingImportWallet/openAccountMenuToAccountListLoaded: -50%
  • onboardingImportWallet/longTaskCount: -80%
  • onboardingImportWallet/longTaskTotalDuration: -94%
  • onboardingImportWallet/longTaskMaxDuration: -91%
  • onboardingImportWallet/tbt: -99%
  • onboardingImportWallet/total: -83%
  • onboardingNewWallet/longTaskCount: -50%
  • onboardingNewWallet/longTaskTotalDuration: -70%
  • onboardingNewWallet/longTaskMaxDuration: -48%
  • onboardingNewWallet/tbt: -95%
  • solanaAssetDetails/assetClickToPriceChart: -75%
  • solanaAssetDetails/total: -75%
  • solanaAssetDetails/inp: -65%
  • solanaAssetDetails/fcp: -43%
  • solanaAssetDetails/lcp: -29%
  • importSrpHome/loginToHomeScreen: -16%
  • importSrpHome/openAccountMenuAfterLogin: +92%
  • importSrpHome/homeAfterImportWithNewWallet: -28%
  • importSrpHome/longTaskCount: -35%
  • importSrpHome/longTaskTotalDuration: -25%
  • importSrpHome/longTaskMaxDuration: +27%
  • importSrpHome/tbt: -18%
  • importSrpHome/total: -11%
  • importSrpHome/inp: -21%
  • importSrpHome/lcp: -50%
  • importSrpHome/cls: -47%
  • sendTransactions/openSendPageFromHome: -14%
  • sendTransactions/selectTokenToSendFormLoaded: -44%
  • sendTransactions/longTaskCount: -100%
  • sendTransactions/longTaskTotalDuration: -100%
  • sendTransactions/longTaskMaxDuration: -100%
  • sendTransactions/tbt: -100%
  • sendTransactions/inp: -11%
  • sendTransactions/fcp: -15%
  • sendTransactions/lcp: -21%
  • sendTransactions/cls: -40%
  • swap/fetchAndDisplaySwapQuotes: +135%
  • swap/longTaskCount: -100%
  • swap/longTaskTotalDuration: -100%
  • swap/longTaskMaxDuration: -100%
  • swap/tbt: -100%
  • swap/total: +133%
  • swap/cls: -63%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 importSrpHome/INP: p75 208ms
  • 🟡 importSrpHome/FCP: p75 1.8s
  • 🟡 assetDetails/FCP: p75 1.9s
  • 🟡 solanaAssetDetails/FCP: p75 1.9s
  • 🟡 importSrpHome/FCP: p75 1.8s
  • 🟡 swap/INP: p75 496ms
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-webpack
dappPageLoad
[Sentry log · main/release]
🟢 [CI log]
Bundle sizes
  • background: 14.25 MiB
  • ui: 17.08 MiB
  • common: 0 Bytes
  • other: 998.07 KiB
  • contentScripts: 1.87 MiB
  • zip: 27.04 MiB
No matching bundle-size baseline was found in the history data, so diff values are omitted.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants