Repository: MetaMask/metamask-extension
Pull request #30949: feat: add Solana accountsChanged event support
Author: login: adonesky1
Labels: name: team-wallet-api-platform-deprecated
description: DEPRECATED: please use "team-wallet-integrations" instead
Created: 2025-03-12T19:49:57Z | Merged: 2025-03-25T18:49:43Z

## **Description**

Adds support for `metamask_accountChanged` notification via `wallet_notify` ([CAIP-319](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-319.md)) notification to enable our wallet-standard implementation to forward account changed events via the [wallet standard change event](https://github.com/wallet-standard/wallet-standard/blob/c6fa5fd7d58e9ea1e6762127d16585fbb56ff88a/packages/core/features/src/events.ts#L84)

This is not a pattern we want to continue since the Multichain API should not require account changing. This is a one off bespoke implementation to support a Solana wallet-standard interface.

[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/30949?quickstart=1)

E2E testing for this feature should be handled in the Wallet Standard powered test dapp one we have it cc @EdouardBougon @baptiste-marchand 

## Demo video

https://github.com/user-attachments/assets/5d5234fe-824d-4d43-9571-8178e220ad35



## **Related issues**

Fixes: https://github.com/MetaMask/MetaMask-planning/issues/4193

## **Manual testing steps**
0. Build in flask
1. Generate 2 Solana Accounts
2. Go to any site
3. Open the dev console and run the following script:
```
const extensionPort = chrome.runtime.connect(<your extension id>)

extensionPort.onMessage.addListener((msg) => {
  console.log(msg.data)
})

extensionPort.postMessage({
  type: "caip-x",
  data: {
    jsonrpc: "2.0",
    method: "wallet_createSession",
    params: {
      requiredScopes: {},
      optionalScopes: {
        "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp": {
          methods: ["getAccount"],
          notifications: [],
          accounts: ['solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp:<SOLANA_ACCOUNT_ADDRESS_1>',
          'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp:<SOLANA_ACCOUNT_ADDRESS_2>']
        }
      },
  sessionProperties: {'solana_accountChanged_notifications': true},
};,
  }
})

```
4. Switch between the two Solana accounts in the account selector in the wallet UI
5. You should see console logs in the dev console:
```
{
    "method": "wallet_notify",
    "params": {
        "scope": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
        "notification": {
            "method": "solana_accountChanged",
            "params": "<YOUR_SOLANA_WALLET_ADDRESS>"
        }
    }
}
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors.

## **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.



Diff:
diff --git a/app/scripts/controllers/permissions/differs.test.ts b/app/scripts/controllers/permissions/differs.test.ts
index 1f17ce42bc6a..80e023f2f6fa 100644
--- a/app/scripts/controllers/permissions/differs.test.ts
+++ b/app/scripts/controllers/permissions/differs.test.ts
@@ -76,6 +76,7 @@ describe('PermissionController selectors', () => {
               },
             },
             isMultichainOrigin: true,
+            sessionProperties: {},
           },
         ],
       ]);
@@ -95,6 +96,7 @@ describe('PermissionController selectors', () => {
               },
             },
             isMultichainOrigin: true,
+            sessionProperties: {},
           },
         ],
       ]);
@@ -141,6 +143,7 @@ describe('PermissionController selectors', () => {
               },
             },
             isMultichainOrigin: true,
+            sessionProperties: {},
           },
         ],
       ]);
@@ -196,6 +199,7 @@ describe('PermissionController selectors', () => {
               },
             },
             isMultichainOrigin: true,
+            sessionProperties: {},
           },
         ],
       ]);
@@ -215,6 +219,7 @@ describe('PermissionController selectors', () => {
               },
             },
             isMultichainOrigin: true,
+            sessionProperties: {},
           },
         ],
       ]);
@@ -247,6 +252,7 @@ describe('PermissionController selectors', () => {
         },
         optionalScopes: {},
         isMultichainOrigin: true,
+        sessionProperties: {},
       };
       const previousAuthorizations = new Map([
         ['foo.bar', mockAuthorization],
diff --git a/app/scripts/controllers/permissions/enums.ts b/app/scripts/controllers/permissions/enums.ts
index 53237cab9b07..97c36db9e36b 100644
--- a/app/scripts/controllers/permissions/enums.ts
+++ b/app/scripts/controllers/permissions/enums.ts
@@ -2,4 +2,5 @@ export enum NOTIFICATION_NAMES {
   accountsChanged = 'metamask_accountsChanged',
   chainChanged = 'metamask_chainChanged',
   sessionChanged = 'wallet_sessionChanged',
+  walletNotify = 'wallet_notify',
 }
diff --git a/app/scripts/controllers/permissions/selectors.js b/app/scripts/controllers/permissions/selectors.js
index 1daf4f158e0e..dc69983ffa3f 100644
--- a/app/scripts/controllers/permissions/selectors.js
+++ b/app/scripts/controllers/permissions/selectors.js
@@ -2,6 +2,7 @@ import {
   Caip25CaveatType,
   Caip25EndowmentPermissionName,
   getEthAccounts,
+  getPermittedAccountsForScopes,
   getPermittedEthChainIds,
 } from '@metamask/chain-agnostic-permission';
 import { createSelector } from 'reselect';
@@ -44,6 +45,57 @@ export const getPermittedAccountsByOrigin = createSelector(
   },
 );
 
+/**
+ * Get the permitted accounts for a given origin and scope.
+ *
+ * @param {Record<string, Record<string, unknown>>} state - The PermissionController state
+ * @param {string[]} scopes - The scopes to get the permitted accounts for
+ * @returns {Map<string, string[]>} A map of origins to permitted accounts for the given scope
+ */
+export const getPermittedAccountsForScopesByOrigin = (state, scopes) => {
+  const subjects = getSubjects(state);
+
+  return Object.values(subjects).reduce((originToAccountsMap, subject) => {
+    const caveats =
+      subject.permissions?.[Caip25EndowmentPermissionName]?.caveats || [];
+
+    const caveat = caveats.find(({ type }) => type === Caip25CaveatType);
+
+    if (caveat) {
+      const scopeAccounts = getPermittedAccountsForScopes(caveat.value, scopes);
+
+      if (scopeAccounts.length > 0) {
+        originToAccountsMap.set(subject.origin, scopeAccounts);
+      }
+    }
+    return originToAccountsMap;
+  }, new Map());
+};
+
+/**
+ * Get the origins with a given session property.
+ *
+ * @param state - The PermissionController state
+ * @param property - The property to check for
+ * @returns An object with keys of origins and values of session properties
+ */
+export const getOriginsWithSessionProperty = (state, property) => {
+  const subjects = getSubjects(state);
+  return Object.values(subjects).reduce((acc, subject) => {
+    const caveats =
+      subject.permissions?.[Caip25EndowmentPermissionName]?.caveats || [];
+
+    const caveat = caveats.find(({ type }) => type === Caip25CaveatType);
+    const sessionProperty = caveat?.value?.sessionProperties?.[property];
+    return sessionProperty
+      ? {
+          ...acc,
+          [subject.origin]: sessionProperty,
+        }
+      : acc;
+  }, {});
+};
+
 /**
  * Get the authorized CAIP-25 scopes for each subject, keyed by origin.
  * The values of the returned map are immutable values from the
diff --git a/app/scripts/lib/rpc-method-middleware/handlers/wallet-createSession/constants.ts b/app/scripts/lib/rpc-method-middleware/handlers/wallet-createSession/constants.ts
new file mode 100644
index 000000000000..4d2e29157046
--- /dev/null
+++ b/app/scripts/lib/rpc-method-middleware/handlers/wallet-createSession/constants.ts
@@ -0,0 +1,11 @@
+export enum KnownSessionProperties {
+  SolanaAccountChangedNotifications = 'solana_accountChanged_notifications',
+}
+
+export function isKnownSessionPropertyValue(
+  value: string,
+): value is KnownSessionProperties {
+  return Object.values(KnownSessionProperties).includes(
+    value as KnownSessionProperties,
+  );
+}
diff --git a/app/scripts/lib/rpc-method-middleware/handlers/wallet-createSession/handler.test.ts b/app/scripts/lib/rpc-method-middleware/handlers/wallet-createSession/handler.test.ts
index c71d2c2f5199..7dd48e865318 100644
--- a/app/scripts/lib/rpc-method-middleware/handlers/wallet-createSession/handler.test.ts
+++ b/app/scripts/lib/rpc-method-middleware/handlers/wallet-createSession/handler.test.ts
@@ -9,6 +9,7 @@ import * as Multichain from '@metamask/chain-agnostic-permission';
 import { Json, JsonRpcRequest, JsonRpcSuccess } from '@metamask/utils';
 import * as Util from '../../../util';
 import { walletCreateSession } from './handler';
+import { KnownSessionProperties } from './constants';
 
 jest.mock('../../../util', () => ({
   ...jest.requireActual('../../../util'),
@@ -387,6 +388,7 @@ describe('wallet_createSession', () => {
                 },
               },
               isMultichainOrigin: true,
+              sessionProperties: {},
             },
           },
         ],
@@ -430,7 +432,7 @@ describe('wallet_createSession', () => {
     });
   });
 
-  it('returns the session ID, properties, and session scopes', async () => {
+  it('returns the known sessionProperties and approved session scopes', async () => {
     const { handler, response } = createMockedHandler();
     MockMultichain.getSessionScopes.mockReturnValue({
       'eip155:5': {
@@ -452,10 +454,7 @@ describe('wallet_createSession', () => {
     await handler(baseRequest);
 
     expect(response.result).toStrictEqual({
-      sessionProperties: {
-        expiry: 'date',
-        foo: 'bar',
-      },
+      sessionProperties: {},
       sessionScopes: {
         'eip155:5': {
           methods: ['eth_chainId', 'net_version'],
@@ -475,4 +474,119 @@ describe('wallet_createSession', () => {
       },
     });
   });
+
+  it('filters out unknown session properties', async () => {
+    const { handler, requestPermissionsForOrigin, listAccounts } =
+      createMockedHandler();
+    listAccounts.mockReturnValue([
+      { address: '0x1' },
+      { address: '0x3' },
+      { address: '0x4' },
+    ]);
+    MockMultichain.bucketScopes
+      .mockReturnValueOnce({
+        supportedScopes: {
+          'eip155:1337': {
+            methods: [],
+            notifications: [],
+            accounts: ['eip155:1:0x1', 'eip155:1:0x2'],
+          },
+        },
+        supportableScopes: {},
+        unsupportableScopes: {},
+      })
+      .mockReturnValueOnce({
+        supportedScopes: {
+          'eip155:100': {
+            methods: [],
+            notifications: [],
+            accounts: ['eip155:2:0x1', 'eip155:2:0x3', 'eip155:2:0xdeadbeef'],
+          },
+        },
+        supportableScopes: {},
+        unsupportableScopes: {},
+      });
+    await handler(baseRequest);
+    expect(requestPermissionsForOrigin).toHaveBeenCalledWith({
+      [Caip25EndowmentPermissionName]: {
+        caveats: [
+          {
+            type: Caip25CaveatType,
+            value: {
+              requiredScopes: {
+                'eip155:1337': {
+                  accounts: ['eip155:1337:0x1', 'eip155:1337:0x3'],
+                },
+              },
+              optionalScopes: {
+                'eip155:100': {
+                  accounts: ['eip155:100:0x1', 'eip155:100:0x3'],
+                },
+              },
+              isMultichainOrigin: true,
+              sessionProperties: {},
+            },
+          },
+        ],
+      },
+    });
+  });
+
+  it('preserves known session properties', async () => {
+    const { handler, response, requestPermissionsForOrigin } =
+      createMockedHandler();
+    requestPermissionsForOrigin.mockReturnValue([
+      {
+        [Caip25EndowmentPermissionName]: {
+          caveats: [
+            {
+              type: Caip25CaveatType,
+              value: {
+                optionalScopes: {
+                  'eip155:5': {
+                    accounts: ['eip155:5:0x1', 'eip155:5:0x2'],
+                    methods: ['eth_chainId', 'net_version'],
+                    notifications: ['accountsChanged', 'chainChanged'],
+                  },
+                },
+                sessionProperties: {
+                  [KnownSessionProperties.SolanaAccountChangedNotifications]:
+                    true,
+                },
+              },
+            },
+          ],
+        },
+      },
+    ]);
+    MockMultichain.getSessionScopes.mockReturnValue({
+      'eip155:5': {
+        methods: ['eth_chainId', 'net_version'],
+        notifications: ['accountsChanged', 'chainChanged'],
+        accounts: ['eip155:5:0x1', 'eip155:5:0x2'],
+      },
+    });
+    await handler({
+      ...baseRequest,
+      params: {
+        ...baseRequest.params,
+        sessionProperties: {
+          [KnownSessionProperties.SolanaAccountChangedNotifications]: true,
+        },
+      },
+    });
+
+    expect(response.result).toStrictEqual({
+      sessionProperties: {
+        [KnownSessionProperties.SolanaAccountChangedNotifications]: true,
+      },
+      sessionScopes: {
+        'eip155:5': {
+          accounts: ['eip155:5:0x1', 'eip155:5:0x2'],
+          methods: ['eth_chainId', 'net_version'],
+          notifications: ['accountsChanged', 'chainChanged'],
+        },
+      },
+    });
+  });
 });
diff --git a/app/scripts/lib/rpc-method-middleware/handlers/wallet-createSession/handler.ts b/app/scripts/lib/rpc-method-middleware/handlers/wallet-createSession/handler.ts
index 706276d3c20e..066aef3897da 100644
--- a/app/scripts/lib/rpc-method-middleware/handlers/wallet-createSession/handler.ts
+++ b/app/scripts/lib/rpc-method-middleware/handlers/wallet-createSession/handler.ts
@@ -39,6 +39,7 @@ import {
 import { shouldEmitDappViewedEvent } from '../../../util';
 import { MESSAGE_TYPE } from '../../../../../../shared/constants/app';
 import { GrantedPermissions } from '../types';
+import { isKnownSessionPropertyValue } from './constants';
 
 /**
  * Handler for the `wallet_createSession` RPC method which is responsible
@@ -104,6 +105,12 @@ async function walletCreateSessionHandler(
     return end(new JsonRpcError(5302, 'Invalid sessionProperties requested'));
   }
 
+  const filteredSessionProperties = Object.fromEntries(
+    Object.entries(sessionProperties ?? {}).filter(([key]) =>
+      isKnownSessionPropertyValue(key),
+    ),
+  );
+
   try {
     const { normalizedRequiredScopes, normalizedOptionalScopes } =
       validateAndNormalizeScopes(requiredScopes || {}, optionalScopes || {});
@@ -162,6 +169,7 @@ async function walletCreateSessionHandler(
       requiredScopes: getInternalScopesObject(supportedRequiredScopes),
       optionalScopes: getInternalScopesObject(supportedOptionalScopes),
       isMultichainOrigin: true,
+      sessionProperties: filteredSessionProperties,
     };
 
     const requestedCaip25CaveatValueWithSupportedEthAccounts = setEthAccounts(
@@ -200,6 +208,9 @@ async function walletCreateSessionHandler(
       getNonEvmSupportedMethods: hooks.getNonEvmSupportedMethods,
     });
 
+    const { sessionProperties: approvedSessionProperties = {} } =
+      approvedCaip25CaveatValue;
+
     // TODO: Contact analytics team for how they would prefer to track this
     // first time connection to dapp will lead to no log in the permissionHistory
     // and if user has connected to dapp before, the dapp origin will be included in the permissionHistory state
@@ -227,7 +238,7 @@ async function walletCreateSessionHandler(
 
     res.result = {
       sessionScopes,
-      sessionProperties,
+      sessionProperties: approvedSessionProperties,
     };
     return end();
   } catch (err) {
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 0799f40ce408..3eada64a1264 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -136,7 +136,12 @@ import { isSnapId } from '@metamask/snaps-utils';
 import { Interface } from '@ethersproject/abi';
 import { abiERC1155, abiERC721 } from '@metamask/metamask-eth-abis';
 import { isEvmAccountType } from '@metamask/keyring-api';
-import { hasProperty, hexToBigInt, toCaipChainId } from '@metamask/utils';
+import {
+  hasProperty,
+  hexToBigInt,
+  toCaipChainId,
+  parseCaipAccountId,
+} from '@metamask/utils';
 import { normalize } from '@metamask/eth-sig-util';
 
 import {
@@ -156,6 +161,7 @@ import {
   walletGetSession,
   walletRevokeSession,
   walletInvokeMethod,
+  MultichainApiNotifications,
 } from '@metamask/multichain-api-middleware';
 
 import {
@@ -251,6 +257,7 @@ import { endTrace, trace } from '../../shared/lib/trace';
 import { BridgeStatusAction } from '../../shared/types/bridge-status';
 import { ENVIRONMENT } from '../../development/build/constants';
 import fetchWithCache from '../../shared/lib/fetch-with-cache';
+import { MultichainNetworks } from '../../shared/constants/multichain/networks';
 import {
   BridgeUserAction,
   BridgeBackgroundAction,
@@ -328,6 +335,8 @@ import {
   getRemovedAuthorizations,
   getChangedAuthorizations,
   getAuthorizedScopesByOrigin,
+  getPermittedAccountsForScopesByOrigin,
+  getOriginsWithSessionProperty,
 } from './controllers/permissions';
 import { MetaMetricsDataDeletionController } from './controllers/metametrics-data-deletion/metametrics-data-deletion';
 import { DataDeletionService } from './services/data-deletion-service';
@@ -404,6 +413,7 @@ import {
   getCapabilities,
   processSendCalls,
 } from './lib/transaction/eip5792';
+import { KnownSessionProperties } from './lib/rpc-method-middleware/handlers/wallet-createSession/constants';
 
 export const METAMASK_CONTROLLER_EVENTS = {
   // Fired after state changes that impact the extension badge (unapproved msg count)
@@ -2812,6 +2822,20 @@ export default class MetamaskController extends EventEmitter {
    */
   setupControllerEventSubscriptions() {
     let lastSelectedAddress;
+    let lastSelectedSolanaAccountAddress;
+
+    if (process.env.MULTICHAIN_API) {
+      // this throws if there is no solana account... perhaps we should handle this better at the controller level
+      try {
+        lastSelectedSolanaAccountAddress =
+          this.accountsController.getSelectedMultichainAccount(
+            MultichainNetworks.SOLANA,
+          )?.address;
+      } catch {
+        // noop
+      }
+    }
+
     this.controllerMessenger.subscribe(
       'PreferencesController:stateChange',
       previousValueComparator(async (prevState, currState) => {
@@ -2936,6 +2960,48 @@ export default class MetamaskController extends EventEmitter {
         },
         getAuthorizedScopesByOrigin,
       );
+      if (process.env.MULTICHAIN_API) {
+        this.controllerMessenger.subscribe(
+          `${this.accountsController.name}:selectedAccountChange`,
+          async (account) => {
+            if (
+              account.type === 'solana:data-account' &&
+              account.address !== lastSelectedSolanaAccountAddress
+            ) {
+              lastSelectedSolanaAccountAddress = account.address;
+
+              const originsWithSolanaAccountChangedNotifications =
+                getOriginsWithSessionProperty(
+                  this.permissionController.state,
+                  KnownSessionProperties.SolanaAccountChangedNotifications,
+                );
+
+              const solanaAccounts = getPermittedAccountsForScopesByOrigin(
+                this.permissionController.state,
+                [
+                  MultichainNetworks.SOLANA,
+                  MultichainNetworks.SOLANA_DEVNET,
+                  MultichainNetworks.SOLANA_TESTNET,
+                ],
+              );
+
+              for (const [origin, accounts] of solanaAccounts.entries()) {
+                const parsedSolanaAddresses = accounts.map((caipAccountId) => {
+                  const { address } = parseCaipAccountId(caipAccountId);
+                  return address;
+                });
+
+                if (
+                  parsedSolanaAddresses.includes(account.address) &&
+                  originsWithSolanaAccountChangedNotifications[origin]
+                ) {
+                  this._notifySolanaAccountChange(origin, account.address);
+                }
+              }
+            }
+          },
+        );
+      }
     }
 
     this.controllerMessenger.subscribe(
@@ -5478,6 +5544,7 @@ export default class MetamaskController extends EventEmitter {
       {
         requiredScopes: {},
         optionalScopes: {},
+        sessionProperties: {},
         isMultichainOrigin: false,
       },
       [chainId],
@@ -5526,6 +5593,7 @@ export default class MetamaskController extends EventEmitter {
       {
         requiredScopes: {},
         optionalScopes: {},
+        sessionProperties: {},
         isMultichainOrigin: false,
       },
       [chainId],
@@ -5606,6 +5674,7 @@ export default class MetamaskController extends EventEmitter {
           accounts: [],
         },
       },
+      sessionProperties: {},
       isMultichainOrigin: false,
     };
 
@@ -7107,7 +7176,6 @@ export default class MetamaskController extends EventEmitter {
    */
   notifyConnections(origin, payload, apiType) {
     const connections = this.connections[origin];
-
     if (connections) {
       Object.values(connections).forEach((conn) => {
         if (apiType && conn.apiType !== apiType) {
@@ -7790,7 +7858,7 @@ export default class MetamaskController extends EventEmitter {
     this.notifyConnections(
       origin,
       {
-        method: NOTIFICATION_NAMES.sessionChanged,
+        method: MultichainApiNotifications.sessionChanged,
         params: {
           sessionScopes: getSessionScopes(newAuthorization, {
             getNonEvmSupportedMethods:
@@ -7802,6 +7870,23 @@ export default class MetamaskController extends EventEmitter {
     );
   }
 
+  async _notifySolanaAccountChange(origin, accountAddress) {
+    this.notifyConnections(
+      origin,
+      {
+        method: MultichainApiNotifications.walletNotify,
+        params: {
+          scope: MultichainNetworks.SOLANA,
+          notification: {
+            method: NOTIFICATION_NAMES.accountsChanged,
+            params: [accountAddress],
+          },
+        },
+      },
+      API_TYPE.CAIP_MULTICHAIN,
+    );
+  }
+
   async _notifyChainChange() {
     this.notifyAllConnections(
       async (origin) => ({
diff --git a/app/scripts/metamask-controller.test.js b/app/scripts/metamask-controller.test.js
index 9d78ea3b17e4..892dbd48ea43 100644
--- a/app/scripts/metamask-controller.test.js
+++ b/app/scripts/metamask-controller.test.js
@@ -1070,6 +1070,7 @@ describe('MetaMaskController', () => {
                         accounts: [],
                       },
                     },
+                    sessionProperties: {},
                     isMultichainOrigin: false,
                   },
                 },
@@ -1108,6 +1109,7 @@ describe('MetaMaskController', () => {
                         accounts: ['wallet:eip155:foo'],
                       },
                     },
+                    sessionProperties: {},
                     isMultichainOrigin: false,
                   },
                 },
@@ -1149,6 +1151,7 @@ describe('MetaMaskController', () => {
                         accounts: [],
                       },
                     },
+                    sessionProperties: {},
                     isMultichainOrigin: false,
                   },
                 },
@@ -1198,6 +1201,7 @@ describe('MetaMaskController', () => {
                         accounts: ['eip155:100:foo'],
                       },
                     },
+                    sessionProperties: {},
                     isMultichainOrigin: false,
                   },
                 },
@@ -1236,6 +1240,7 @@ describe('MetaMaskController', () => {
                         accounts: ['wallet:eip155:foo'],
                       },
                     },
+                    sessionProperties: {},
                     isMultichainOrigin: false,
                   },
                 },
@@ -1274,6 +1279,7 @@ describe('MetaMaskController', () => {
                         accounts: [],
                       },
                     },
+                    sessionProperties: {},
                     isMultichainOrigin: false,
                   },
                 },
@@ -1320,6 +1326,7 @@ describe('MetaMaskController', () => {
                         accounts: ['wallet:eip155:foo'],
                       },
                     },
+                    sessionProperties: {},
                     isMultichainOrigin: false,
                   },
                 },
@@ -1372,6 +1379,7 @@ describe('MetaMaskController', () => {
                         accounts: ['eip155:5:0xdeadbeef'],
                       },
                     },
+                    sessionProperties: {},
                     isMultichainOrigin: false,
                   },
                 },
@@ -1420,6 +1428,7 @@ describe('MetaMaskController', () => {
                         accounts: ['wallet:eip155:0xdeadbeef'],
                       },
                     },
+                    sessionProperties: {},
                     isMultichainOrigin: false,
                   },
                 },
@@ -1460,6 +1469,7 @@ describe('MetaMaskController', () => {
                         accounts: [],
                       },
                     },
+                    sessionProperties: {},
                     isMultichainOrigin: false,
                   },
                 },
@@ -1509,6 +1519,7 @@ describe('MetaMaskController', () => {
                 value: {
                   requiredScopes: {},
                   optionalScopes: { 'eip155:1': { accounts: [] } },
+                  sessionProperties: {},
                   isMultichainOrigin: false,
                 },
               },
@@ -1563,6 +1574,7 @@ describe('MetaMaskController', () => {
                 value: {
                   requiredScopes: {},
                   optionalScopes: { 'eip155:1': { accounts: [] } },
+                  sessionProperties: {},
                   isMultichainOrigin: false,
                 },
               },
diff --git a/app/scripts/migrations/148.test.ts b/app/scripts/migrations/148.test.ts
new file mode 100644
index 000000000000..7cd3cdaf3ea9
--- /dev/null
+++ b/app/scripts/migrations/148.test.ts
@@ -0,0 +1,293 @@
+import { Caip25EndowmentPermissionName } from '@metamask/chain-agnostic-permission';
+import { KnownSessionProperties } from '../lib/rpc-method-middleware/handlers/wallet-createSession/constants';
+
+import { migrate, version } from './148';
+
+const oldVersion = 147;
+
+describe(`migration #${version}`, () => {
+  it('updates the version metadata', async () => {
+    const oldStorage = {
+      meta: { version: oldVersion },
+      data: {},
+    };
+    const newStorage = await migrate(oldStorage);
+    expect(newStorage.meta).toStrictEqual({ version });
+  });
+
+  it('does nothing if PermissionController is missing', async () => {
+    const oldStorage = {
+      meta: { version: oldVersion },
+      data: {
+        SomeOtherController: {},
+      },
+    };
+    const newStorage = await migrate(oldStorage);
+    expect(newStorage.data).toStrictEqual(oldStorage.data);
+  });
+
+  it('adds sessionProperties to CAIP-25 permissions that do not have it', async () => {
+    const oldStorage = {
+      meta: { version: oldVersion },
+      data: {
+        PermissionController: {
+          subjects: {
+            'example.com': {
+              origin: 'example.com',
+              permissions: {
+                [Caip25EndowmentPermissionName]: {
+                  id: '123',
+                  parentCapability: Caip25EndowmentPermissionName,
+                  invoker: 'example.com',
+                  caveats: [
+                    {
+                      type: 'authorizedScopes',
+                      value: {
+                        requiredScopes: {},
+                        optionalScopes: {
+                          'eip155:1': {
+                            accounts: ['eip155:1:0x123'],
+                          },
+                        },
+                        isMultichainOrigin: false,
+                      },
+                    },
+                  ],
+                },
+              },
+            },
+          },
+        },
+      },
+    };
+
+    const expectedData = {
+      PermissionController: {
+        subjects: {
+          'example.com': {
+            origin: 'example.com',
+            permissions: {
+              [Caip25EndowmentPermissionName]: {
+                id: '123',
+                parentCapability: Caip25EndowmentPermissionName,
+                invoker: 'example.com',
+                caveats: [
+                  {
+                    type: 'authorizedScopes',
+                    value: {
+                      requiredScopes: {},
+                      optionalScopes: {
+                        'eip155:1': {
+                          accounts: ['eip155:1:0x123'],
+                        },
+                      },
+                      isMultichainOrigin: false,
+                      sessionProperties: {},
+                    },
+                  },
+                ],
+              },
+            },
+          },
+        },
+      },
+    };
+
+    const newStorage = await migrate(oldStorage);
+    expect(newStorage.data).toStrictEqual(expectedData);
+  });
+
+  it('preserves existing sessionProperties in CAIP-25 permissions', async () => {
+    const existingSessionProperties = {
+      [KnownSessionProperties.SolanaAccountChangedNotifications]: true,
+    };
+
+    const oldStorage = {
+      meta: { version: oldVersion },
+      data: {
+        PermissionController: {
+          subjects: {
+            'example.com': {
+              origin: 'example.com',
+              permissions: {
+                [Caip25EndowmentPermissionName]: {
+                  id: '123',
+                  parentCapability: Caip25EndowmentPermissionName,
+                  invoker: 'example.com',
+                  caveats: [
+                    {
+                      type: 'authorizedScopes',
+                      value: {
+                        requiredScopes: {},
+                        optionalScopes: {
+                          'eip155:1': {
+                            accounts: ['eip155:1:0x123'],
+                          },
+                        },
+                        isMultichainOrigin: false,
+                        sessionProperties: existingSessionProperties,
+                      },
+                    },
+                  ],
+                },
+              },
+            },
+          },
+        },
+      },
+    };
+
+    const expectedData = {
+      PermissionController: {
+        subjects: {
+          'example.com': {
+            origin: 'example.com',
+            permissions: {
+              [Caip25EndowmentPermissionName]: {
+                id: '123',
+                parentCapability: Caip25EndowmentPermissionName,
+                invoker: 'example.com',
+                caveats: [
+                  {
+                    type: 'authorizedScopes',
+                    value: {
+                      requiredScopes: {},
+                      optionalScopes: {
+                        'eip155:1': {
+                          accounts: ['eip155:1:0x123'],
+                        },
+                      },
+                      isMultichainOrigin: false,
+                      sessionProperties: existingSessionProperties,
+                    },
+                  },
+                ],
+              },
+            },
+          },
+        },
+      },
+    };
+
+    const newStorage = await migrate(oldStorage);
+    expect(newStorage.data).toStrictEqual(expectedData);
+  });
+
+  it('handles multiple subjects with CAIP-25 permissions', async () => {
+    const oldStorage = {
+      meta: { version: oldVersion },
+      data: {
+        PermissionController: {
+          subjects: {
+            'example.com': {
+              origin: 'example.com',
+              permissions: {
+                [Caip25EndowmentPermissionName]: {
+                  caveats: [
+                    {
+                      type: 'authorizedScopes',
+                      value: {
+                        requiredScopes: {},
+                        optionalScopes: {},
+                        isMultichainOrigin: false,
+                      },
+                    },
+                  ],
+                },
+              },
+            },
+            'other-site.com': {
+              origin: 'other-site.com',
+              permissions: {
+                [Caip25EndowmentPermissionName]: {
+                  caveats: [
+                    {
+                      type: 'authorizedScopes',
+                      value: {
+                        requiredScopes: {},
+                        optionalScopes: {},
+                        isMultichainOrigin: true,
+                      },
+                    },
+                  ],
+                },
+              },
+            },
+          },
+        },
+      },
+    };
+
+    const expectedData = {
+      PermissionController: {
+        subjects: {
+          'example.com': {
+            origin: 'example.com',
+            permissions: {
+              [Caip25EndowmentPermissionName]: {
+                caveats: [
+                  {
+                    type: 'authorizedScopes',
+                    value: {
+                      requiredScopes: {},
+                      optionalScopes: {},
+                      isMultichainOrigin: false,
+                      sessionProperties: {},
+                    },
+                  },
+                ],
+              },
+            },
+          },
+          'other-site.com': {
+            origin: 'other-site.com',
+            permissions: {
+              [Caip25EndowmentPermissionName]: {
+                caveats: [
+                  {
+                    type: 'authorizedScopes',
+                    value: {
+                      requiredScopes: {},
+                      optionalScopes: {},
+                      isMultichainOrigin: true,
+                      sessionProperties: {},
+                    },
+                  },
+                ],
+              },
+            },
+          },
+        },
+      },
+    };
+
+    const newStorage = await migrate(oldStorage);
+    expect(newStorage.data).toStrictEqual(expectedData);
+  });
+
+  it('ignores subjects without CAIP-25 permissions', async () => {
+    const oldStorage = {
+      meta: { version: oldVersion },
+      data: {
+        PermissionController: {
+          subjects: {
+            'example.com': {
+              origin: 'example.com',
+              permissions: {
+                'other:permission': {
+                  id: '123',
+                  parentCapability: 'other:permission',
+                  invoker: 'example.com',
+                  caveats: [],
+                },
+              },
+            },
+          },
+        },
+      },
+    };
+
+    const newStorage = await migrate(oldStorage);
+    expect(newStorage.data).toStrictEqual(oldStorage.data);
+  });
+});
diff --git a/app/scripts/migrations/148.ts b/app/scripts/migrations/148.ts
new file mode 100644
index 000000000000..34e1a8b6437c
--- /dev/null
+++ b/app/scripts/migrations/148.ts
@@ -0,0 +1,91 @@
+import { cloneDeep } from 'lodash';
+import { hasProperty, isObject } from '@metamask/utils';
+import {
+  Caip25EndowmentPermissionName,
+  Caip25CaveatType,
+} from '@metamask/chain-agnostic-permission';
+
+export const version = 148;
+
+type VersionedData = {
+  meta: { version: number };
+  data: Record<string, unknown>;
+};
+/**
+ * Add sessionProperties property to CAIP-25 permission caveats
+ *
+ * @param originalVersionedData - Versioned MetaMask extension state
+ * @returns Updated versioned MetaMask extension state
+ */
+export async function migrate(originalVersionedData: VersionedData) {
+  const versionedData = cloneDeep(originalVersionedData);
+  versionedData.meta.version = version;
+  transformState(versionedData.data);
+  return versionedData;
+}
+
+/**
+ * Add sessionProperties property to CAIP-25 permission caveats
+ *
+ * @param state - The MetaMask state
+ * @returns The updated MetaMask state
+ */
+function transformState(state: VersionedData['data']) {
+  if (!hasProperty(state, 'PermissionController')) {
+    return state;
+  }
+
+  if (!isObject(state.PermissionController)) {
+    global.sentry?.captureException?.(
+      new Error(
+        `Migration ${version}: typeof state.PermissionController is ${typeof state.PermissionController}`,
+      ),
+    );
+    return state;
+  }
+
+  const { subjects } = state.PermissionController;
+
+  if (!isObject(subjects)) {
+    global.sentry?.captureException?.(
+      new Error(
+        `Migration ${version}: typeof state.PermissionController.subjects is ${typeof subjects}`,
+      ),
+    );
+    return state;
+  }
+
+  for (const subject of Object.values(subjects)) {
+    if (
+      !isObject(subject) ||
+      !hasProperty(subject, 'permissions') ||
+      !isObject(subject.permissions)
+    ) {
+      continue;
+    }
+
+    const { permissions } = subject;
+    const caip25Permission = permissions[Caip25EndowmentPermissionName];
+
+    if (
+      !isObject(caip25Permission) ||
+      !Array.isArray(caip25Permission.caveats)
+    ) {
+      continue;
+    }
+
+    const caip25Caveat = caip25Permission.caveats.find(
+      (caveat) => caveat.type === Caip25CaveatType,
+    );
+
+    if (
+      caip25Caveat &&
+      isObject(caip25Caveat.value) &&
+      !hasProperty(caip25Caveat.value, 'sessionProperties')
+    ) {
+      caip25Caveat.value.sessionProperties = {};
+    }
+  }
+
+  return state;
+}
diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js
index 601d4abd5799..1dce1de9ea6f 100644
--- a/app/scripts/migrations/index.js
+++ b/app/scripts/migrations/index.js
@@ -173,6 +173,7 @@ const migrations = [
   require('./145'),
   require('./146'),
   require('./147'),
+  require('./148'),
 ];
 
 export default migrations;
diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json
index 1a9f58699e4d..fb6d662a8af5 100644
--- a/lavamoat/browserify/beta/policy.json
+++ b/lavamoat/browserify/beta/policy.json
@@ -1381,7 +1381,7 @@
         "@metamask/eth-json-rpc-provider": true,
         "@metamask/json-rpc-engine": true,
         "@metamask/rpc-errors": true,
-        "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": true
+        "@metamask/utils": true
       }
     },
     "@metamask/eth-json-rpc-middleware": {
@@ -2495,21 +2495,6 @@
         "semver": true
       }
     },
-    "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": {
-      "globals": {
-        "TextDecoder": true,
-        "TextEncoder": true
-      },
-      "packages": {
-        "@metamask/utils>@metamask/superstruct": true,
-        "@noble/hashes": true,
-        "@metamask/utils>@scure/base": true,
-        "browserify>buffer": true,
-        "nock>debug": true,
-        "@metamask/utils>pony-cause": true,
-        "semver": true
-      }
-    },
     "@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/utils": {
       "globals": {
         "TextDecoder": true,
diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json
index 1a9f58699e4d..fb6d662a8af5 100644
--- a/lavamoat/browserify/flask/policy.json
+++ b/lavamoat/browserify/flask/policy.json
@@ -1381,7 +1381,7 @@
         "@metamask/eth-json-rpc-provider": true,
         "@metamask/json-rpc-engine": true,
         "@metamask/rpc-errors": true,
-        "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": true
+        "@metamask/utils": true
       }
     },
     "@metamask/eth-json-rpc-middleware": {
@@ -2495,21 +2495,6 @@
         "semver": true
       }
     },
-    "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": {
-      "globals": {
-        "TextDecoder": true,
-        "TextEncoder": true
-      },
-      "packages": {
-        "@metamask/utils>@metamask/superstruct": true,
-        "@noble/hashes": true,
-        "@metamask/utils>@scure/base": true,
-        "browserify>buffer": true,
-        "nock>debug": true,
-        "@metamask/utils>pony-cause": true,
-        "semver": true
-      }
-    },
     "@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/utils": {
       "globals": {
         "TextDecoder": true,
diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json
index 1a9f58699e4d..fb6d662a8af5 100644
--- a/lavamoat/browserify/main/policy.json
+++ b/lavamoat/browserify/main/policy.json
@@ -1381,7 +1381,7 @@
         "@metamask/eth-json-rpc-provider": true,
         "@metamask/json-rpc-engine": true,
         "@metamask/rpc-errors": true,
-        "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": true
+        "@metamask/utils": true
       }
     },
     "@metamask/eth-json-rpc-middleware": {
@@ -2495,21 +2495,6 @@
         "semver": true
       }
     },
-    "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": {
-      "globals": {
-        "TextDecoder": true,
-        "TextEncoder": true
-      },
-      "packages": {
-        "@metamask/utils>@metamask/superstruct": true,
-        "@noble/hashes": true,
-        "@metamask/utils>@scure/base": true,
-        "browserify>buffer": true,
-        "nock>debug": true,
-        "@metamask/utils>pony-cause": true,
-        "semver": true
-      }
-    },
     "@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/utils": {
       "globals": {
         "TextDecoder": true,
diff --git a/lavamoat/browserify/mmi/policy.json b/lavamoat/browserify/mmi/policy.json
index e6f7e42f9c7c..505ab0e396e4 100644
--- a/lavamoat/browserify/mmi/policy.json
+++ b/lavamoat/browserify/mmi/policy.json
@@ -1527,7 +1527,7 @@
         "@metamask/eth-json-rpc-provider": true,
         "@metamask/json-rpc-engine": true,
         "@metamask/rpc-errors": true,
-        "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": true
+        "@metamask/utils": true
       }
     },
     "@metamask/eth-json-rpc-middleware": {
@@ -2641,21 +2641,6 @@
         "semver": true
       }
     },
-    "@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": {
-      "globals": {
-        "TextDecoder": true,
-        "TextEncoder": true
-      },
-      "packages": {
-        "@metamask/utils>@metamask/superstruct": true,
-        "@noble/hashes": true,
-        "@metamask/utils>@scure/base": true,
-        "browserify>buffer": true,
-        "nock>debug": true,
-        "@metamask/utils>pony-cause": true,
-        "semver": true
-      }
-    },
     "@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/utils": {
       "globals": {
         "TextDecoder": true,
diff --git a/package.json b/package.json
index 83c8ea92d106..2936107edeed 100644
--- a/package.json
+++ b/package.json
@@ -267,7 +267,7 @@
     "@metamask/base-controller": "^8.0.0",
     "@metamask/bitcoin-wallet-snap": "^0.9.0",
     "@metamask/browser-passworder": "^4.3.0",
-    "@metamask/chain-agnostic-permission": "^0.1.0",
+    "@metamask/chain-agnostic-permission": "^0.2.0",
     "@metamask/contract-metadata": "^2.5.0",
     "@metamask/controller-utils": "^11.4.0",
     "@metamask/design-tokens": "^5.0.0",
@@ -294,7 +294,7 @@
     "@metamask/message-manager": "^12.0.1",
     "@metamask/message-signing-snap": "^0.6.0",
     "@metamask/metamask-eth-abis": "^3.1.1",
-    "@metamask/multichain-api-middleware": "^0.1.0",
+    "@metamask/multichain-api-middleware": "^0.1.1",
     "@metamask/multichain-network-controller": "^0.1.0",
     "@metamask/multichain-transactions-controller": "^0.7.2",
     "@metamask/name-controller": "^8.0.3",
@@ -432,7 +432,7 @@
     "@lavamoat/lavadome-core": "0.0.20",
     "@lavamoat/lavapack": "^7.0.5",
     "@lydell/node-pty": "^1.0.1",
-    "@metamask/api-specs": "^0.11.0",
+    "@metamask/api-specs": "^0.12.0",
     "@metamask/auto-changelog": "^2.1.0",
     "@metamask/build-utils": "^3.0.0",
     "@metamask/eslint-config": "^9.0.0",
diff --git a/ui/pages/permissions-connect/connect-page/connect-page.test.tsx b/ui/pages/permissions-connect/connect-page/connect-page.test.tsx
index e00c52f4cab8..b3f66f61b882 100644
--- a/ui/pages/permissions-connect/connect-page/connect-page.test.tsx
+++ b/ui/pages/permissions-connect/connect-page/connect-page.test.tsx
@@ -247,6 +247,7 @@ describe('ConnectPage', () => {
                       },
                     },
                     isMultichainOrigin: false,
+                    sessionProperties: {},
                   },
                 },
               ],
diff --git a/ui/pages/permissions-connect/connect-page/utils.test.ts b/ui/pages/permissions-connect/connect-page/utils.test.ts
index 14283e5d5346..0bba05980a5e 100644
--- a/ui/pages/permissions-connect/connect-page/utils.test.ts
+++ b/ui/pages/permissions-connect/connect-page/utils.test.ts
@@ -14,6 +14,7 @@ const baseCaip25CaveatValue = {
     },
   },
   isMultichainOrigin: false,
+  sessionProperties: {},
 };
 
 describe('getCaip25PermissionsResponse', () => {
@@ -38,6 +39,7 @@ describe('getCaip25PermissionsResponse', () => {
                   },
                 },
                 isMultichainOrigin: false,
+                sessionProperties: {},
               },
             },
           ],
@@ -71,6 +73,7 @@ describe('getCaip25PermissionsResponse', () => {
                   },
                 },
                 isMultichainOrigin: false,
+                sessionProperties: {},
               },
             },
           ],
@@ -104,6 +107,7 @@ describe('getCaip25PermissionsResponse', () => {
                   },
                 },
                 isMultichainOrigin: false,
+                sessionProperties: {},
               },
             },
           ],
@@ -148,6 +152,7 @@ describe('getCaip25PermissionsResponse', () => {
                   },
                 },
                 isMultichainOrigin: false,
+                sessionProperties: {},
               },
             },
           ],
@@ -198,6 +203,7 @@ describe('getCaip25PermissionsResponse', () => {
                   },
                 },
                 isMultichainOrigin: false,
+                sessionProperties: {},
               },
             },
           ],
diff --git a/ui/pages/permissions-connect/connect-page/utils.ts b/ui/pages/permissions-connect/connect-page/utils.ts
index f4cea5374c69..516c4fb7c6d2 100644
--- a/ui/pages/permissions-connect/connect-page/utils.ts
+++ b/ui/pages/permissions-connect/connect-page/utils.ts
@@ -27,6 +27,7 @@ export function getRequestedCaip25CaveatValue(
     )?.value ?? {
       optionalScopes: {},
       requiredScopes: {},
+      sessionProperties: {},
       isMultichainOrigin: false,
     }
   );
diff --git a/yarn.lock b/yarn.lock
index e013a8edfbeb..e89991494167 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4896,10 +4896,10 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@metamask/api-specs@npm:^0.11.0":
-  version: 0.11.0
-  resolution: "@metamask/api-specs@npm:0.11.0"
-  checksum: 10/1b86535966e3675cb53df51d631869c11beec2c39c53a0707672984309185f2a5ef3ab0a4ab629fcd86910eb21faaf096282053e2d50af84338d6ede9f205467
+"@metamask/api-specs@npm:^0.12.0":
+  version: 0.12.0
+  resolution: "@metamask/api-specs@npm:0.12.0"
+  checksum: 10/53314f07fb4fcc64ff5ca5392a187e57eb0070241efbbc56bdcdc22dd7c0f684f7ff3bae118d865971c8f0572564c36b5fc31d40f680ea2b6f08ece3cd4b76a6
   languageName: node
   linkType: hard
 
@@ -5065,18 +5065,18 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@metamask/chain-agnostic-permission@npm:^0.1.0":
-  version: 0.1.0
-  resolution: "@metamask/chain-agnostic-permission@npm:0.1.0"
+"@metamask/chain-agnostic-permission@npm:^0.2.0":
+  version: 0.2.0
+  resolution: "@metamask/chain-agnostic-permission@npm:0.2.0"
   dependencies:
     "@metamask/api-specs": "npm:^0.10.12"
     "@metamask/controller-utils": "npm:^11.6.0"
-    "@metamask/network-controller": "npm:^22.2.1"
+    "@metamask/network-controller": "npm:^23.1.0"
     "@metamask/permission-controller": "npm:^11.0.6"
     "@metamask/rpc-errors": "npm:^7.0.2"
     "@metamask/utils": "npm:^11.2.0"
     lodash: "npm:^4.17.21"
-  checksum: 10/e5b833ebe8e3537872d959a7363965d3bf6d4e2d4d427fd8c8efc31dd3966af8090a1497ff00750acf61306ebd85b309500a9eb45c920110cdad344b2ffaaf48
+  checksum: 10/b3121bdbcc2a14d44802ad1799045b4a01c99047fa2675a639b3ebed51a1b30eba071b5a8d8cbf5a045204670a4ef159c44560036013f54a368a6e80071dd5df
   languageName: node
   linkType: hard
 
@@ -5254,19 +5254,19 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@metamask/eth-json-rpc-infura@npm:^10.0.0":
-  version: 10.0.0
-  resolution: "@metamask/eth-json-rpc-infura@npm:10.0.0"
+"@metamask/eth-json-rpc-infura@npm:^10.0.0, @metamask/eth-json-rpc-infura@npm:^10.1.0":
+  version: 10.1.0
+  resolution: "@metamask/eth-json-rpc-infura@npm:10.1.0"
   dependencies:
-    "@metamask/eth-json-rpc-provider": "npm:^4.1.5"
-    "@metamask/json-rpc-engine": "npm:^10.0.0"
-    "@metamask/rpc-errors": "npm:^7.0.0"
-    "@metamask/utils": "npm:^9.1.0"
-  checksum: 10/17e0147ff86c48107983035e9bda4d16fba321ee0e29733347e9338a4c795c506a2ffd643c44c9d5334886696412cf288f852d06311fed0d76edc8847ee6b8de
+    "@metamask/eth-json-rpc-provider": "npm:^4.1.7"
+    "@metamask/json-rpc-engine": "npm:^10.0.2"
+    "@metamask/rpc-errors": "npm:^7.0.2"
+    "@metamask/utils": "npm:^11.0.1"
+  checksum: 10/e3305d8a2535c3dd0e4b127fb6d01e70245f394b05c6fe81030a9043ad6fd4b8d904e00830236f88cb80b09fa6490ea22e7abaa8230a4fd4912436d0738ee702
   languageName: node
   linkType: hard
 
-"@metamask/eth-json-rpc-middleware@npm:^15.0.1":
+"@metamask/eth-json-rpc-middleware@npm:^15.0.1, @metamask/eth-json-rpc-middleware@npm:^15.1.0":
   version: 15.3.0
   resolution: "@metamask/eth-json-rpc-middleware@npm:15.3.0"
   dependencies:
@@ -5767,21 +5767,21 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@metamask/multichain-api-middleware@npm:^0.1.0":
-  version: 0.1.0
-  resolution: "@metamask/multichain-api-middleware@npm:0.1.0"
+"@metamask/multichain-api-middleware@npm:^0.1.1":
+  version: 0.1.1
+  resolution: "@metamask/multichain-api-middleware@npm:0.1.1"
   dependencies:
     "@metamask/api-specs": "npm:^0.10.12"
-    "@metamask/chain-agnostic-permission": "npm:^0.1.0"
+    "@metamask/chain-agnostic-permission": "npm:^0.2.0"
     "@metamask/json-rpc-engine": "npm:^10.0.3"
-    "@metamask/network-controller": "npm:^22.2.1"
+    "@metamask/network-controller": "npm:^23.1.0"
     "@metamask/permission-controller": "npm:^11.0.6"
     "@metamask/rpc-errors": "npm:^7.0.2"
     "@metamask/utils": "npm:^11.2.0"
     "@open-rpc/meta-schema": "npm:^1.14.6"
     "@open-rpc/schema-utils-js": "npm:^2.0.5"
     jsonschema: "npm:^1.4.1"
-  checksum: 10/d0d304471e05deba336fab9fd765b92875d58fcb83afd2cab09ade2b95b6f533e5ad40d3ca1e6650956798c6d3609302523fa872c0d7cb9e6373a0da0dc69615
+  checksum: 10/f4f18243c2133f7eb5827a80583f378727c460255f95f723d88b664705b8b0e8f12428b6bf16975cc2cbfec35c21797c84ab96a09317412c37135f4afd697f2f
   languageName: node
   linkType: hard
 
@@ -5886,6 +5886,32 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@metamask/network-controller@npm:^23.1.0":
+  version: 23.1.0
+  resolution: "@metamask/network-controller@npm:23.1.0"
+  dependencies:
+    "@metamask/base-controller": "npm:^8.0.0"
+    "@metamask/controller-utils": "npm:^11.6.0"
+    "@metamask/eth-block-tracker": "npm:^11.0.3"
+    "@metamask/eth-json-rpc-infura": "npm:^10.1.0"
+    "@metamask/eth-json-rpc-middleware": "npm:^15.1.0"
+    "@metamask/eth-json-rpc-provider": "npm:^4.1.8"
+    "@metamask/eth-query": "npm:^4.0.0"
+    "@metamask/json-rpc-engine": "npm:^10.0.3"
+    "@metamask/rpc-errors": "npm:^7.0.2"
+    "@metamask/swappable-obj-proxy": "npm:^2.3.0"
+    "@metamask/utils": "npm:^11.2.0"
+    async-mutex: "npm:^0.5.0"
+    fast-deep-equal: "npm:^3.1.3"
+    immer: "npm:^9.0.6"
+    loglevel: "npm:^1.8.1"
+    reselect: "npm:^5.1.1"
+    uri-js: "npm:^4.4.1"
+    uuid: "npm:^8.3.2"
+  checksum: 10/078b6b566916777649ce30c5972c79cf00eb0309499b43151e477dc641a7e7fdbfc2b2d237e7d5f5b59801a1a09f69da6996a397b8e4461af3e42e1da8918cf3
+  languageName: node
+  linkType: hard
+
 "@metamask/network-controller@patch:@metamask/network-controller@npm%3A22.1.1#~/.yarn/patches/@metamask-network-controller-npm-22.1.1-09b6510f1e.patch":
   version: 22.1.1
   resolution: "@metamask/network-controller@patch:@metamask/network-controller@npm%3A22.1.1#~/.yarn/patches/@metamask-network-controller-npm-22.1.1-09b6510f1e.patch::version=22.1.1&hash=64b409"
@@ -6628,7 +6654,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@metamask/utils@npm:^9.0.0, @metamask/utils@npm:^9.1.0, @metamask/utils@npm:^9.2.1":
+"@metamask/utils@npm:^9.0.0, @metamask/utils@npm:^9.2.1":
   version: 9.3.0
   resolution: "@metamask/utils@npm:9.3.0"
   dependencies:
@@ -27254,7 +27280,7 @@ __metadata:
     "@metamask/accounts-controller": "npm:^26.0.0"
     "@metamask/address-book-controller": "npm:^6.0.3"
     "@metamask/announcement-controller": "npm:^7.0.3"
-    "@metamask/api-specs": "npm:^0.11.0"
+    "@metamask/api-specs": "npm:^0.12.0"
     "@metamask/approval-controller": "npm:^7.0.0"
     "@metamask/assets-controllers": "patch:@metamask/assets-controllers@npm%3A53.1.1#~/.yarn/patches/@metamask-assets-controllers-npm-53.1.1-644979f986.patch"
     "@metamask/auto-changelog": "npm:^2.1.0"
@@ -27262,7 +27288,7 @@ __metadata:
     "@metamask/bitcoin-wallet-snap": "npm:^0.9.0"
     "@metamask/browser-passworder": "npm:^4.3.0"
     "@metamask/build-utils": "npm:^3.0.0"
-    "@metamask/chain-agnostic-permission": "npm:^0.1.0"
+    "@metamask/chain-agnostic-permission": "npm:^0.2.0"
     "@metamask/contract-metadata": "npm:^2.5.0"
     "@metamask/controller-utils": "npm:^11.4.0"
     "@metamask/design-tokens": "npm:^5.0.0"
@@ -27297,7 +27323,7 @@ __metadata:
     "@metamask/message-manager": "npm:^12.0.1"
     "@metamask/message-signing-snap": "npm:^0.6.0"
     "@metamask/metamask-eth-abis": "npm:^3.1.1"
-    "@metamask/multichain-api-middleware": "npm:^0.1.0"
+    "@metamask/multichain-api-middleware": "npm:^0.1.1"
     "@metamask/multichain-network-controller": "npm:^0.1.0"
     "@metamask/multichain-transactions-controller": "npm:^0.7.2"
     "@metamask/name-controller": "npm:^8.0.3"


Reviews:
user: login: adonesky1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T15:21:14Z
user: login: adonesky1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T18:57:22Z
user: login: adonesky1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T19:16:59Z
user: login: adonesky1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T19:17:39Z
user: login: adonesky1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T19:52:17Z
user: login: adonesky1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T21:22:33Z
user: login: adonesky1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T22:00:43Z
user: login: adonesky1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-21T19:25:27Z
user: login: jiexi
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-24T16:51:02Z
user: login: jiexi
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-24T17:01:07Z
user: login: jiexi
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-24T17:56:42Z
user: login: jiexi
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-24T17:57:20Z
user: login: jiexi
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-24T17:59:10Z
user: login: jiexi
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-24T18:01:33Z
user: login: jiexi
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-24T18:03:03Z
user: login: jiexi
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-24T18:08:27Z
user: login: adonesky1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T17:50:10Z
user: login: adonesky1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T17:56:55Z
user: login: adonesky1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T17:57:55Z
user: login: adonesky1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T18:07:45Z
user: login: adonesky1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T18:07:49Z
user: login: adonesky1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T18:07:54Z
user: login: adonesky1
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T18:08:12Z
user: login: jiexi
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-25T18:11:11Z
user: login: jiexi
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-25T18:16:05Z
user: login: jiexi
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-25T18:45:46Z

Review comments:
diff_hunk: @@ -2,4 +2,6 @@ export enum NOTIFICATION_NAMES {
   accountsChanged = 'metamask_accountsChanged',
   chainChanged = 'metamask_chainChanged',
   sessionChanged = 'wallet_sessionChanged',
+  walletNotify = 'wallet_notify',
+  solanaAccountChanged = 'solana_accountChanged',
path: app/scripts/controllers/permissions/enums.ts
user: login: adonesky1
body: moving these into the `@metamask/chain-agnostic-permission` package
created_at: 2025-03-17T15:21:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2790,6 +2796,10 @@ export default class MetamaskController extends EventEmitter {
    */
   setupControllerEventSubscriptions() {
     let lastSelectedAddress;
+    let lastSelectedSolanaAccountAddress =
+      this.accountsController.getSelectedMultichainAccount(
+        MultichainNetworks.SOLANA,
path: app/scripts/metamask-controller.js
user: login: adonesky1
body: should this also extend to testnet/devnet solana?

created_at: 2025-03-17T18:57:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2,4 +2,6 @@ export enum NOTIFICATION_NAMES {
   accountsChanged = 'metamask_accountsChanged',
   chainChanged = 'metamask_chainChanged',
   sessionChanged = 'wallet_sessionChanged',
+  walletNotify = 'wallet_notify',
+  solanaAccountChanged = 'solana_accountChanged',
path: app/scripts/controllers/permissions/enums.ts
user: login: adonesky1
body: Here: https://github.com/MetaMask/core/pull/5491/files#diff-d4264b93bc87ab9ed17b687adfd862b58f089ff5a2430628205cb798aca271ddR127
created_at: 2025-03-17T19:16:59Z
author_association: CONTRIBUTOR
diff_hunk: @@ -44,6 +44,57 @@ export const getPermittedAccountsByOrigin = createSelector(
   },
 );
 
+// This will be moved to the @metamask/chain-agnostic-permission package
+/**
+ * Get the permitted accounts for a given scope.
+ *
+ * @param {Pick<Caip25CaveatValue, 'requiredScopes' | 'optionalScopes'>} caip25CaveatValue - The CAIP-25 CaveatValue to get the permitted accounts for
+ * @param {string[]} scopes - The scopes to get the permitted accounts for
+ * @returns {string[]} An array of permitted accounts
+ */
+export const getPermittedAccountsForScopes = (caip25CaveatValue, scopes) => {
+  const scopeAccounts = [];
+
+  scopes.forEach((scope) => {
+    const requiredScope = caip25CaveatValue.requiredScopes[scope];
+    const optionalScope = caip25CaveatValue.optionalScopes[scope];
+    if (requiredScope) {
+      scopeAccounts.push(...requiredScope.accounts);
+    }
+
+    if (optionalScope) {
+      scopeAccounts.push(...optionalScope.accounts);
+    }
+  });
+  return scopeAccounts;
+};
path: app/scripts/controllers/permissions/selectors.js
user: login: adonesky1
body: Moved [here](https://github.com/MetaMask/core/pull/5491/files#diff-3e05548aa13d4e9cc180b8fea8084b3c627294ba7fecd1cdf84156b7b269de5fR138), will replace with reference to this package when available.
created_at: 2025-03-17T19:17:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2,4 +2,5 @@ export enum NOTIFICATION_NAMES {
   accountsChanged = 'metamask_accountsChanged',
   chainChanged = 'metamask_chainChanged',
   sessionChanged = 'wallet_sessionChanged',
+  walletNotify = 'wallet_notify',
path: app/scripts/controllers/permissions/enums.ts
user: login: adonesky1
body: Will add `wallet_sessionChanged` and `wallet_notify` to `@metamask/multichain-api-middleware` package
created_at: 2025-03-17T19:52:17Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2,4 +2,5 @@ export enum NOTIFICATION_NAMES {
   accountsChanged = 'metamask_accountsChanged',
   chainChanged = 'metamask_chainChanged',
   sessionChanged = 'wallet_sessionChanged',
+  walletNotify = 'wallet_notify',
path: app/scripts/controllers/permissions/enums.ts
user: login: adonesky1
body: Will do here: https://github.com/MetaMask/core/pull/5491/files
created_at: 2025-03-17T21:22:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -7742,6 +7795,23 @@ export default class MetamaskController extends EventEmitter {
     );
   }
 
+  async _notifySolanaAccountChange(origin, accountAddress) {
+    this.notifyConnections(
+      origin,
+      {
+        method: NOTIFICATION_NAMES.walletNotify,
+        params: {
+          scope: MultichainNetworks.SOLANA,
+          notification: {
+            method: NOTIFICATION_NAMES.accountsChanged,
path: app/scripts/metamask-controller.js
user: login: adonesky1
body: I think we just use the `metamask_accountsChanged` event since this really bespoke and specific to our wallet's Wallet Standard interface needs 🤷 ?
created_at: 2025-03-17T22:00:43Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,11 @@
+export enum KnownSessionProperties {
path: app/scripts/lib/rpc-method-middleware/handlers/wallet-createSession/constants.ts
user: login: adonesky1
body: Forgot to export this from the `@metamask/chain-agnostic-permission` package, can do as a fast follow: https://github.com/MetaMask/core/pull/5522
created_at: 2025-03-21T19:25:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -44,6 +45,56 @@ export const getPermittedAccountsByOrigin = createSelector(
   },
 );
 
+/**
+ * Get the permitted accounts for a given origin and scope.
+ *
+ * @param {Record<string, Record<string, unknown>>} state - The PermissionController state
+ * @param {string[]} scopes - The scopes to get the permitted accounts for
+ * @returns {Map<string, string[]>} A map of origins to permitted accounts for the given scope
+ */
+export const getPermittedAccountsForScopesByOrigin = (state, scopes) => {
+  const subjects = getSubjects(state);
+
+  return Object.values(subjects).reduce((originToAccountsMap, subject) => {
+    const caveats =
+      subject.permissions?.[Caip25EndowmentPermissionName]?.caveats || [];
+
+    const caveat = caveats.find(({ type }) => type === Caip25CaveatType);
+
+    if (caveat) {
+      const scopeAccounts = getPermittedAccountsForScopes(caveat.value, scopes);
+
+      if (scopeAccounts.length > 0) {
+        originToAccountsMap.set(subject.origin, scopeAccounts);
+      }
+    }
+    return originToAccountsMap;
+  }, new Map());
+};
+
+/**
+ * Get the origins with a given session property.
+ *
+ * @param state - The PermissionController state
+ * @param property - The property to check for
+ * @returns An object with keys of origins and values of session properties
+ */
+export const getOriginsWithSessionProperty = (state, property) => {
+  const subjects = getSubjects(state);
+  return Object.values(subjects).reduce((acc, subject) => {
+    const caveats =
+      subject.permissions?.[Caip25EndowmentPermissionName]?.caveats || [];
+
+    const caveat = caveats.find(({ type }) => type === Caip25CaveatType);
+    return caveat?.value?.sessionProperties?.[property]
+      ? {
+          ...acc,
+          [subject.origin]: caveat?.value?.sessionProperties?.[property],
path: app/scripts/controllers/permissions/selectors.js
user: login: jiexi
body: nit. okay if we assign `caveat?.value?.sessionProperties?.[property]` to a variable and DRY both usages here?
created_at: 2025-03-24T16:51:02Z
author_association: MEMBER
diff_hunk: @@ -104,6 +105,15 @@ async function walletCreateSessionHandler(
     return end(new JsonRpcError(5302, 'Invalid sessionProperties requested'));
   }
 
+  let filteredSessionProperties = {};
+  if (sessionProperties && Object.keys(sessionProperties).length > 0) {
path: app/scripts/lib/rpc-method-middleware/handlers/wallet-createSession/handler.ts
user: login: jiexi
body: length check necessary given the check on line 104?, or even dropping these guards and doing something like
```
  const filteredSessionProperties = Object.fromEntries(
      Object.entries(sessionProperties ?? {}).filter(([key]) =>
        isKnownSessionPropertyValue(key),
      ),
    );
created_at: 2025-03-24T17:01:07Z
author_association: MEMBER
diff_hunk: @@ -2812,6 +2821,20 @@ export default class MetamaskController extends EventEmitter {
    */
   setupControllerEventSubscriptions() {
     let lastSelectedAddress;
+    let lastSelectedSolanaAccountAddress;
path: app/scripts/metamask-controller.js
user: login: jiexi
body: thoughts on using `previousValueComparator` instead of keeping track of the previous value in this var?
created_at: 2025-03-24T17:56:42Z
author_association: MEMBER
diff_hunk: @@ -2936,6 +2959,48 @@ export default class MetamaskController extends EventEmitter {
         },
         getAuthorizedScopesByOrigin,
       );
+      if (process.env.MULTICHAIN_API) {
+        this.controllerMessenger.subscribe(
+          `${this.accountsController.name}:selectedAccountChange`,
+          async (account) => {
+            if (
+              account.type === 'solana:data-account' &&
+              account.address !== lastSelectedSolanaAccountAddress
+            ) {
+              lastSelectedSolanaAccountAddress = account.address;
+
+              const originsWithSolanaAccountChangedNotifications =
+                getOriginsWithSessionProperty(
+                  this.permissionController.state,
+                  'solana_accountChanged_notifications',
path: app/scripts/metamask-controller.js
user: login: jiexi
body: do we have a constant for this?
created_at: 2025-03-24T17:57:20Z
author_association: MEMBER
diff_hunk: @@ -2936,6 +2959,48 @@ export default class MetamaskController extends EventEmitter {
         },
         getAuthorizedScopesByOrigin,
       );
+      if (process.env.MULTICHAIN_API) {
+        this.controllerMessenger.subscribe(
+          `${this.accountsController.name}:selectedAccountChange`,
+          async (account) => {
+            if (
+              account.type === 'solana:data-account' &&
+              account.address !== lastSelectedSolanaAccountAddress
+            ) {
+              lastSelectedSolanaAccountAddress = account.address;
+
+              const originsWithSolanaAccountChangedNotifications =
+                getOriginsWithSessionProperty(
+                  this.permissionController.state,
+                  'solana_accountChanged_notifications',
+                );
+
+              const solanaAccounts = getPermittedAccountsForScopesByOrigin(
+                this.permissionController.state,
+                [
+                  MultichainNetworks.SOLANA,
+                  MultichainNetworks.SOLANA_DEVNET,
+                  MultichainNetworks.SOLANA_TESTNET,
path: app/scripts/metamask-controller.js
user: login: jiexi
body: thoughts on targeting by namespace? Not saying we necessarily make that change, but it might be more aligned with what we're trying to achieve here
created_at: 2025-03-24T17:59:10Z
author_association: MEMBER
diff_hunk: @@ -2936,6 +2959,48 @@ export default class MetamaskController extends EventEmitter {
         },
         getAuthorizedScopesByOrigin,
       );
+      if (process.env.MULTICHAIN_API) {
+        this.controllerMessenger.subscribe(
+          `${this.accountsController.name}:selectedAccountChange`,
+          async (account) => {
+            if (
+              account.type === 'solana:data-account' &&
+              account.address !== lastSelectedSolanaAccountAddress
+            ) {
+              lastSelectedSolanaAccountAddress = account.address;
+
+              const originsWithSolanaAccountChangedNotifications =
+                getOriginsWithSessionProperty(
+                  this.permissionController.state,
+                  'solana_accountChanged_notifications',
+                );
+
+              const solanaAccounts = getPermittedAccountsForScopesByOrigin(
+                this.permissionController.state,
+                [
+                  MultichainNetworks.SOLANA,
+                  MultichainNetworks.SOLANA_DEVNET,
+                  MultichainNetworks.SOLANA_TESTNET,
+                ],
+              );
+
+              for (const [origin, accounts] of solanaAccounts.entries()) {
+                const parsedSolanaAddresses = accounts.map((caipAccountId) => {
+                  const { address } = parseCaipAccountId(caipAccountId);
+                  return address;
+                });
+
+                if (
+                  parsedSolanaAddresses.includes(account.address) &&
+                  originsWithSolanaAccountChangedNotifications[origin]
path: app/scripts/metamask-controller.js
user: login: jiexi
body: minor performance optimization if we move this check to the top of this loop
created_at: 2025-03-24T18:01:33Z
author_association: MEMBER
diff_hunk: @@ -7742,6 +7795,23 @@ export default class MetamaskController extends EventEmitter {
     );
   }
 
+  async _notifySolanaAccountChange(origin, accountAddress) {
+    this.notifyConnections(
+      origin,
+      {
+        method: NOTIFICATION_NAMES.walletNotify,
+        params: {
+          scope: MultichainNetworks.SOLANA,
+          notification: {
+            method: NOTIFICATION_NAMES.accountsChanged,
path: app/scripts/metamask-controller.js
user: login: jiexi
body: yeah. makes sense
created_at: 2025-03-24T18:03:03Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,87 @@
+import { cloneDeep } from 'lodash';
+import { hasProperty, isObject } from '@metamask/utils';
+import {
+  Caip25EndowmentPermissionName,
+  Caip25CaveatType,
+} from '@metamask/chain-agnostic-permission';
+
+export const version = 148;
+
+type VersionedData = {
+  meta: { version: number };
+  data: Record<string, unknown>;
+};
+/**
+ * Add sessionProperties property to CAIP-25 permission caveats
+ *
+ * @param originalVersionedData - Versioned MetaMask extension state
+ * @returns Updated versioned MetaMask extension state
+ */
+export async function migrate(originalVersionedData: VersionedData) {
+  const versionedData = cloneDeep(originalVersionedData);
+  versionedData.meta.version = version;
+  transformState(versionedData.data);
+  return versionedData;
+}
+
+/**
+ * Add sessionProperties property to CAIP-25 permission caveats
+ *
+ * @param state - The MetaMask state
+ * @returns The updated MetaMask state
+ */
+function transformState(state: VersionedData['data']) {
+  if (!hasProperty(state, 'PermissionController')) {
+    return state;
+  }
+
+  if (!isObject(state.PermissionController)) {
+    global.sentry?.captureException?.(
+      new Error(
+        `Migration ${version}: typeof state.PermissionController is ${typeof state.PermissionController}`,
+      ),
+    );
+    return state;
+  }
+
+  const { subjects } = state.PermissionController;
+
+  if (!isObject(subjects)) {
+    global.sentry?.captureException?.(
+      new Error(
+        `Migration ${version}: typeof state.PermissionController.subjects is ${typeof subjects}`,
+      ),
+    );
+    return state;
+  }
+
+  for (const subject of Object.values(subjects)) {
+    if (
+      !isObject(subject) ||
+      !hasProperty(subject, 'permissions') ||
+      !isObject(subject.permissions)
+    ) {
+      continue;
+    }
+
+    const { permissions } = subject;
+    const caip25Permission = permissions[Caip25EndowmentPermissionName];
+
+    if (
+      !isObject(caip25Permission) ||
+      !Array.isArray(caip25Permission.caveats)
+    ) {
+      continue;
+    }
+
+    for (const caveat of caip25Permission.caveats) {
+      if (caveat.type === Caip25CaveatType && isObject(caveat.value)) {
+        if (!hasProperty(caveat.value, 'sessionProperties')) {
+          caveat.value.sessionProperties = {};
+        }
+      }
path: app/scripts/migrations/148.ts
user: login: jiexi
body: okay if we add a `break` in here? or use `find` instead of the for loop? definitely a nit
created_at: 2025-03-24T18:08:26Z
author_association: MEMBER
diff_hunk: @@ -2812,6 +2821,20 @@ export default class MetamaskController extends EventEmitter {
    */
   setupControllerEventSubscriptions() {
     let lastSelectedAddress;
+    let lastSelectedSolanaAccountAddress;
path: app/scripts/metamask-controller.js
user: login: adonesky1
body: I'm not sure if its possible given the conditions under which we want to emit the event. If for example the account is changed from solana account 1 to an evm account and then back to solana account 1 we don't want to emit the event... I think we need this piece of state since a single step backwards looking state comparison won't give us the flexibility we need for this logic
created_at: 2025-03-25T17:50:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2936,6 +2959,48 @@ export default class MetamaskController extends EventEmitter {
         },
         getAuthorizedScopesByOrigin,
       );
+      if (process.env.MULTICHAIN_API) {
+        this.controllerMessenger.subscribe(
+          `${this.accountsController.name}:selectedAccountChange`,
+          async (account) => {
+            if (
+              account.type === 'solana:data-account' &&
+              account.address !== lastSelectedSolanaAccountAddress
+            ) {
+              lastSelectedSolanaAccountAddress = account.address;
+
+              const originsWithSolanaAccountChangedNotifications =
+                getOriginsWithSessionProperty(
+                  this.permissionController.state,
+                  'solana_accountChanged_notifications',
+                );
+
+              const solanaAccounts = getPermittedAccountsForScopesByOrigin(
+                this.permissionController.state,
+                [
+                  MultichainNetworks.SOLANA,
+                  MultichainNetworks.SOLANA_DEVNET,
+                  MultichainNetworks.SOLANA_TESTNET,
path: app/scripts/metamask-controller.js
user: login: adonesky1
body: agreed. Unfortunately this will require a change to (or a new helper in core called `getPermittedAccountsForNamespace`) Perhaps we could leave this for a followup?
created_at: 2025-03-25T17:56:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2936,6 +2959,48 @@ export default class MetamaskController extends EventEmitter {
         },
         getAuthorizedScopesByOrigin,
       );
+      if (process.env.MULTICHAIN_API) {
+        this.controllerMessenger.subscribe(
+          `${this.accountsController.name}:selectedAccountChange`,
+          async (account) => {
+            if (
+              account.type === 'solana:data-account' &&
+              account.address !== lastSelectedSolanaAccountAddress
+            ) {
+              lastSelectedSolanaAccountAddress = account.address;
+
+              const originsWithSolanaAccountChangedNotifications =
+                getOriginsWithSessionProperty(
+                  this.permissionController.state,
+                  'solana_accountChanged_notifications',
+                );
+
+              const solanaAccounts = getPermittedAccountsForScopesByOrigin(
+                this.permissionController.state,
+                [
+                  MultichainNetworks.SOLANA,
+                  MultichainNetworks.SOLANA_DEVNET,
+                  MultichainNetworks.SOLANA_TESTNET,
+                ],
+              );
+
+              for (const [origin, accounts] of solanaAccounts.entries()) {
+                const parsedSolanaAddresses = accounts.map((caipAccountId) => {
+                  const { address } = parseCaipAccountId(caipAccountId);
+                  return address;
+                });
+
+                if (
+                  parsedSolanaAddresses.includes(account.address) &&
+                  originsWithSolanaAccountChangedNotifications[origin]
path: app/scripts/metamask-controller.js
user: login: adonesky1
body: 🤔 we need the `parsedSolanaAddresses` to be parsed first though?
created_at: 2025-03-25T17:57:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -44,6 +45,56 @@ export const getPermittedAccountsByOrigin = createSelector(
   },
 );
 
+/**
+ * Get the permitted accounts for a given origin and scope.
+ *
+ * @param {Record<string, Record<string, unknown>>} state - The PermissionController state
+ * @param {string[]} scopes - The scopes to get the permitted accounts for
+ * @returns {Map<string, string[]>} A map of origins to permitted accounts for the given scope
+ */
+export const getPermittedAccountsForScopesByOrigin = (state, scopes) => {
+  const subjects = getSubjects(state);
+
+  return Object.values(subjects).reduce((originToAccountsMap, subject) => {
+    const caveats =
+      subject.permissions?.[Caip25EndowmentPermissionName]?.caveats || [];
+
+    const caveat = caveats.find(({ type }) => type === Caip25CaveatType);
+
+    if (caveat) {
+      const scopeAccounts = getPermittedAccountsForScopes(caveat.value, scopes);
+
+      if (scopeAccounts.length > 0) {
+        originToAccountsMap.set(subject.origin, scopeAccounts);
+      }
+    }
+    return originToAccountsMap;
+  }, new Map());
+};
+
+/**
+ * Get the origins with a given session property.
+ *
+ * @param state - The PermissionController state
+ * @param property - The property to check for
+ * @returns An object with keys of origins and values of session properties
+ */
+export const getOriginsWithSessionProperty = (state, property) => {
+  const subjects = getSubjects(state);
+  return Object.values(subjects).reduce((acc, subject) => {
+    const caveats =
+      subject.permissions?.[Caip25EndowmentPermissionName]?.caveats || [];
+
+    const caveat = caveats.find(({ type }) => type === Caip25CaveatType);
+    return caveat?.value?.sessionProperties?.[property]
+      ? {
+          ...acc,
+          [subject.origin]: caveat?.value?.sessionProperties?.[property],
path: app/scripts/controllers/permissions/selectors.js
user: login: adonesky1
body: done here: https://github.com/MetaMask/metamask-extension/pull/30949/commits/2ea1fcdcee5b15741ceaa19030caf1a8290a1c31
created_at: 2025-03-25T18:07:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -104,6 +105,15 @@ async function walletCreateSessionHandler(
     return end(new JsonRpcError(5302, 'Invalid sessionProperties requested'));
   }
 
+  let filteredSessionProperties = {};
+  if (sessionProperties && Object.keys(sessionProperties).length > 0) {
path: app/scripts/lib/rpc-method-middleware/handlers/wallet-createSession/handler.ts
user: login: adonesky1
body: done here: https://github.com/MetaMask/metamask-extension/pull/30949/commits/2ea1fcdcee5b15741ceaa19030caf1a8290a1c31
created_at: 2025-03-25T18:07:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2936,6 +2959,48 @@ export default class MetamaskController extends EventEmitter {
         },
         getAuthorizedScopesByOrigin,
       );
+      if (process.env.MULTICHAIN_API) {
+        this.controllerMessenger.subscribe(
+          `${this.accountsController.name}:selectedAccountChange`,
+          async (account) => {
+            if (
+              account.type === 'solana:data-account' &&
+              account.address !== lastSelectedSolanaAccountAddress
+            ) {
+              lastSelectedSolanaAccountAddress = account.address;
+
+              const originsWithSolanaAccountChangedNotifications =
+                getOriginsWithSessionProperty(
+                  this.permissionController.state,
+                  'solana_accountChanged_notifications',
path: app/scripts/metamask-controller.js
user: login: adonesky1
body: done here: https://github.com/MetaMask/metamask-extension/pull/30949/commits/2ea1fcdcee5b15741ceaa19030caf1a8290a1c31
created_at: 2025-03-25T18:07:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,87 @@
+import { cloneDeep } from 'lodash';
+import { hasProperty, isObject } from '@metamask/utils';
+import {
+  Caip25EndowmentPermissionName,
+  Caip25CaveatType,
+} from '@metamask/chain-agnostic-permission';
+
+export const version = 148;
+
+type VersionedData = {
+  meta: { version: number };
+  data: Record<string, unknown>;
+};
+/**
+ * Add sessionProperties property to CAIP-25 permission caveats
+ *
+ * @param originalVersionedData - Versioned MetaMask extension state
+ * @returns Updated versioned MetaMask extension state
+ */
+export async function migrate(originalVersionedData: VersionedData) {
+  const versionedData = cloneDeep(originalVersionedData);
+  versionedData.meta.version = version;
+  transformState(versionedData.data);
+  return versionedData;
+}
+
+/**
+ * Add sessionProperties property to CAIP-25 permission caveats
+ *
+ * @param state - The MetaMask state
+ * @returns The updated MetaMask state
+ */
+function transformState(state: VersionedData['data']) {
+  if (!hasProperty(state, 'PermissionController')) {
+    return state;
+  }
+
+  if (!isObject(state.PermissionController)) {
+    global.sentry?.captureException?.(
+      new Error(
+        `Migration ${version}: typeof state.PermissionController is ${typeof state.PermissionController}`,
+      ),
+    );
+    return state;
+  }
+
+  const { subjects } = state.PermissionController;
+
+  if (!isObject(subjects)) {
+    global.sentry?.captureException?.(
+      new Error(
+        `Migration ${version}: typeof state.PermissionController.subjects is ${typeof subjects}`,
+      ),
+    );
+    return state;
+  }
+
+  for (const subject of Object.values(subjects)) {
+    if (
+      !isObject(subject) ||
+      !hasProperty(subject, 'permissions') ||
+      !isObject(subject.permissions)
+    ) {
+      continue;
+    }
+
+    const { permissions } = subject;
+    const caip25Permission = permissions[Caip25EndowmentPermissionName];
+
+    if (
+      !isObject(caip25Permission) ||
+      !Array.isArray(caip25Permission.caveats)
+    ) {
+      continue;
+    }
+
+    for (const caveat of caip25Permission.caveats) {
+      if (caveat.type === Caip25CaveatType && isObject(caveat.value)) {
+        if (!hasProperty(caveat.value, 'sessionProperties')) {
+          caveat.value.sessionProperties = {};
+        }
+      }
path: app/scripts/migrations/148.ts
user: login: adonesky1
body: done here: https://github.com/MetaMask/metamask-extension/pull/30949/commits/2ea1fcdcee5b15741ceaa19030caf1a8290a1c31 & here https://github.com/MetaMask/metamask-extension/pull/30949/commits/4450c7e31d3859cb4d2b0ab9964640008a38a655
created_at: 2025-03-25T18:08:12Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2812,6 +2821,20 @@ export default class MetamaskController extends EventEmitter {
    */
   setupControllerEventSubscriptions() {
     let lastSelectedAddress;
+    let lastSelectedSolanaAccountAddress;
path: app/scripts/metamask-controller.js
user: login: jiexi
body: yup. you right
created_at: 2025-03-25T18:11:11Z
author_association: MEMBER
diff_hunk: @@ -2936,6 +2959,48 @@ export default class MetamaskController extends EventEmitter {
         },
         getAuthorizedScopesByOrigin,
       );
+      if (process.env.MULTICHAIN_API) {
+        this.controllerMessenger.subscribe(
+          `${this.accountsController.name}:selectedAccountChange`,
+          async (account) => {
+            if (
+              account.type === 'solana:data-account' &&
+              account.address !== lastSelectedSolanaAccountAddress
+            ) {
+              lastSelectedSolanaAccountAddress = account.address;
+
+              const originsWithSolanaAccountChangedNotifications =
+                getOriginsWithSessionProperty(
+                  this.permissionController.state,
+                  'solana_accountChanged_notifications',
+                );
+
+              const solanaAccounts = getPermittedAccountsForScopesByOrigin(
+                this.permissionController.state,
+                [
+                  MultichainNetworks.SOLANA,
+                  MultichainNetworks.SOLANA_DEVNET,
+                  MultichainNetworks.SOLANA_TESTNET,
+                ],
+              );
+
+              for (const [origin, accounts] of solanaAccounts.entries()) {
+                const parsedSolanaAddresses = accounts.map((caipAccountId) => {
+                  const { address } = parseCaipAccountId(caipAccountId);
+                  return address;
+                });
+
+                if (
+                  parsedSolanaAddresses.includes(account.address) &&
+                  originsWithSolanaAccountChangedNotifications[origin]
path: app/scripts/metamask-controller.js
user: login: jiexi
body: if `originsWithSolanaAccountChangedNotifications[origin]` is false, then we don't need to do `parsedSolanaAddresses` and its includes checks in the first place
created_at: 2025-03-25T18:16:04Z
author_association: MEMBER

PR comments:
user: login: github-actions[bot]
created_at: 2025-03-12T19:50:11Z
body: **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.
author_association: CONTRIBUTOR
user: login: metamaskbot
created_at: 2025-03-18T20:47:43Z
body: :x: Multichain API Spec Test Failed. View the report [here](https://output.circle-artifacts.com/output/job/95ef4668-f3b7-42c7-8e22-75caf65daf2a/artifacts/0/html-report-multichain/index.html).
author_association: COLLABORATOR
user: login: metamaskbot
created_at: 2025-03-19T17:12:53Z
body: :x: Multichain API Spec Test Failed. View the report [here](https://output.circle-artifacts.com/output/job/f8daf6fb-2277-46a4-8e22-9985fdc380e6/artifacts/0/html-report-multichain/index.html).
author_association: COLLABORATOR
user: login: metamaskbot
created_at: 2025-03-19T17:48:32Z
body: :x: Multichain API Spec Test Failed. View the report [here](https://output.circle-artifacts.com/output/job/93ca3277-5b3e-4787-98eb-4eda657ec3b2/artifacts/0/html-report-multichain/index.html).
author_association: COLLABORATOR
user: login: metamaskbot
created_at: 2025-03-19T18:30:10Z
body: <details><summary>Builds ready [27cc99c]</summary><ul><li>builds: <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/builds/metamask-chrome-12.14.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/builds-mv2/metamask-firefox-12.14.0.zip">firefox</a></li>
<li>builds (flask): <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/builds-flask/metamask-flask-chrome-12.14.0-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/builds-flask-mv2/metamask-flask-firefox-12.14.0-flask.0.zip">firefox</a></li>
<li>builds (MMI): <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/builds-mmi/metamask-mmi-chrome-12.14.0-mmi.0.zip">chrome</a></li>
<li>builds (test): <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/builds-test/metamask-chrome-12.14.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/builds-test-mv2/metamask-firefox-12.14.0.zip">firefox</a></li>
<li>builds (test-flask): <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/builds-test-flask/metamask-flask-chrome-12.14.0-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/builds-test-flask-mv2/metamask-flask-firefox-12.14.0-flask.0.zip">firefox</a></li>
<li>build viz: <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/build-viz/index.html">Build System</a></li>
<li>mv3: <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/test-artifacts/chrome/bundle_size.json">Bundle Size Stats</a></li>
<li>mv2: <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/test-artifacts/chrome/benchmark/user_actions.json">E2e Actions Stats</a></li>
<li>storybook: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/13953344192/storybook-build/index.html">Storybook</a></li>
<li>typescript migration: <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/ts-migration-dashboard/index.html">Dashboard</a></li>
<li><a href="https://circleci.com/gh/MetaMask/metamask-extension/4660670#artifacts/containers/0">all artifacts</a></li>
<li><details>
       <summary>bundle viz:</summary>
       <ul><li>background: <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/background-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/background-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/background-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/background-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/background-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/background-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/background-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/background-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/background-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/background-9.html">9</a></li><li>common: <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/common-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/common-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/common-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/common-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/common-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/common-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/common-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/common-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/common-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/common-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/common-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/common-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/common-12.html">12</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/common-13.html">13</a></li><li>ui: <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/ui-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/ui-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/ui-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/ui-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/ui-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/ui-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/ui-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/ui-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/ui-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/ui-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/ui-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/ui-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/ui-12.html">12</a></li><li>content-script: <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/content-script-0.html">0</a></li><li>offscreen: <a href="https://output.circle-artifacts.com/output/job/26a76c1e-cbeb-459c-8081-d9d873fdd91f/artifacts/0/build-artifacts/source-map-explorer/offscreen-0.html">0</a></li></ul>
     </details></li></ul></details>

<details><summary>Page Load Metrics (3345 ± 1591 ms)</summary><table><thead><tr><th>Platform</th><th>Page</th><th>Metric</th><th>Min (ms)</th><th>Max (ms)</th><th>Average (ms)</th><th>StandardDeviation (ms)</th><th>MarginOfError (ms)</th></tr></thead><tbody><tr><td rowspan="11">Chrome</td><td rowspan="11">Home</td><td>firstPaint</td><td align="right">856</td><td align="right">10424</td><td align="right">2488</td><td align="right">1902</td><td align="right">913</td></tr><tr><td>domContentLoaded</td><td align="right">1531</td><td align="right">13950</td><td align="right">2936</td><td align="right">3021</td><td align="right">1451</td></tr><tr><td>load</td><td align="right">1600</td><td align="right">14832</td><td align="right">3345</td><td align="right">3314</td><td align="right">1591</td></tr><tr><td>domInteractive</td><td align="right">17</td><td align="right">251</td><td align="right">69</td><td align="right">62</td><td align="right">30</td></tr><tr><td>backgroundConnect</td><td align="right">38</td><td align="right">1662</td><td align="right">410</td><td align="right">482</td><td align="right">231</td></tr><tr><td>firstReactRender</td><td align="right">18</td><td align="right">275</td><td align="right">79</td><td align="right">81</td><td align="right">39</td></tr><tr><td>getState</td><td align="right">14</td><td align="right">739</td><td align="right">174</td><td align="right">219</td><td align="right">105</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">1</td><td align="right">0</td><td align="right">0</td><td align="right">0</td></tr><tr><td>loadScripts</td><td align="right">1142</td><td align="right">11501</td><td align="right">2276</td><td align="right">2600</td><td align="right">1248</td></tr><tr><td>setupStore</td><td align="right">9</td><td align="right">704</td><td align="right">110</td><td align="right">174</td><td align="right">83</td></tr><tr><td>uiStartup</td><td align="right">1753</td><td align="right">20801</td><td align="right">5095</td><td align="right">5031</td><td align="right">2416</td></tr></tbody></table></details>


author_association: COLLABORATOR
user: login: metamaskbot
created_at: 2025-03-19T19:02:47Z
body: :x: Multichain API Spec Test Failed. View the report [here](https://output.circle-artifacts.com/output/job/ed03a14e-7638-48c8-b63b-8de48dd99990/artifacts/0/html-report-multichain/index.html).
author_association: COLLABORATOR
user: login: metamaskbot
created_at: 2025-03-19T22:35:16Z
body: <details><summary>Builds ready [10b079d]</summary><ul><li>builds: <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/builds/metamask-chrome-12.14.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/builds-mv2/metamask-firefox-12.14.0.zip">firefox</a></li>
<li>builds (flask): <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/builds-flask/metamask-flask-chrome-12.14.0-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/builds-flask-mv2/metamask-flask-firefox-12.14.0-flask.0.zip">firefox</a></li>
<li>builds (MMI): <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/builds-mmi/metamask-mmi-chrome-12.14.0-mmi.0.zip">chrome</a></li>
<li>builds (test): <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/builds-test/metamask-chrome-12.14.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/builds-test-mv2/metamask-firefox-12.14.0.zip">firefox</a></li>
<li>builds (test-flask): <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/builds-test-flask/metamask-flask-chrome-12.14.0-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/builds-test-flask-mv2/metamask-flask-firefox-12.14.0-flask.0.zip">firefox</a></li>
<li>build viz: <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/build-viz/index.html">Build System</a></li>
<li>mv3: <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/test-artifacts/chrome/bundle_size.json">Bundle Size Stats</a></li>
<li>mv2: <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/test-artifacts/chrome/benchmark/user_actions.json">E2e Actions Stats</a></li>
<li>storybook: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/13957465808/storybook-build/index.html">Storybook</a></li>
<li>typescript migration: <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/ts-migration-dashboard/index.html">Dashboard</a></li>
<li><a href="https://circleci.com/gh/MetaMask/metamask-extension/4661884#artifacts/containers/0">all artifacts</a></li>
<li><details>
       <summary>bundle viz:</summary>
       <ul><li>background: <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/background-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/background-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/background-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/background-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/background-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/background-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/background-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/background-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/background-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/background-9.html">9</a></li><li>common: <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/common-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/common-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/common-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/common-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/common-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/common-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/common-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/common-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/common-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/common-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/common-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/common-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/common-12.html">12</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/common-13.html">13</a></li><li>ui: <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/ui-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/ui-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/ui-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/ui-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/ui-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/ui-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/ui-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/ui-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/ui-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/ui-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/ui-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/ui-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/ui-12.html">12</a></li><li>content-script: <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/content-script-0.html">0</a></li><li>offscreen: <a href="https://output.circle-artifacts.com/output/job/6ad232bb-8d03-43d4-836b-c7980adafe44/artifacts/0/build-artifacts/source-map-explorer/offscreen-0.html">0</a></li></ul>
     </details></li></ul></details>

<details><summary>Page Load Metrics (6128 ± 3591 ms)</summary><table><thead><tr><th>Platform</th><th>Page</th><th>Metric</th><th>Min (ms)</th><th>Max (ms)</th><th>Average (ms)</th><th>StandardDeviation (ms)</th><th>MarginOfError (ms)</th></tr></thead><tbody><tr><td rowspan="11">Chrome</td><td rowspan="11">Home</td><td>firstPaint</td><td align="right">1718</td><td align="right">27723</td><td align="right">5877</td><td align="right">7439</td><td align="right">3572</td></tr><tr><td>domContentLoaded</td><td align="right">1599</td><td align="right">27580</td><td align="right">5421</td><td align="right">7212</td><td align="right">3463</td></tr><tr><td>load</td><td align="right">1730</td><td align="right">27985</td><td align="right">6128</td><td align="right">7478</td><td align="right">3591</td></tr><tr><td>domInteractive</td><td align="right">26</td><td align="right">2215</td><td align="right">248</td><td align="right">507</td><td align="right">243</td></tr><tr><td>backgroundConnect</td><td align="right">103</td><td align="right">2419</td><td align="right">670</td><td align="right">680</td><td align="right">327</td></tr><tr><td>firstReactRender</td><td align="right">28</td><td align="right">237</td><td align="right">109</td><td align="right">59</td><td align="right">29</td></tr><tr><td>getState</td><td align="right">40</td><td align="right">1199</td><td align="right">282</td><td align="right">328</td><td align="right">157</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">1</td><td align="right">0</td><td align="right">0</td><td align="right">0</td></tr><tr><td>loadScripts</td><td align="right">1198</td><td align="right">27114</td><td align="right">4508</td><td align="right">6730</td><td align="right">3232</td></tr><tr><td>setupStore</td><td align="right">10</td><td align="right">528</td><td align="right">123</td><td align="right">144</td><td align="right">69</td></tr><tr><td>uiStartup</td><td align="right">2100</td><td align="right">28811</td><td align="right">8657</td><td align="right">7454</td><td align="right">3579</td></tr></tbody></table></details>


author_association: COLLABORATOR
user: login: metamaskbot
created_at: 2025-03-20T18:16:17Z
body: <details><summary>Builds ready [be78511]</summary><ul><li>builds: <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/builds/metamask-chrome-12.14.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/builds-mv2/metamask-firefox-12.14.0.zip">firefox</a></li>
<li>builds (flask): <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/builds-flask/metamask-flask-chrome-12.14.0-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/builds-flask-mv2/metamask-flask-firefox-12.14.0-flask.0.zip">firefox</a></li>
<li>builds (MMI): <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/builds-mmi/metamask-mmi-chrome-12.14.0-mmi.0.zip">chrome</a></li>
<li>builds (test): <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/builds-test/metamask-chrome-12.14.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/builds-test-mv2/metamask-firefox-12.14.0.zip">firefox</a></li>
<li>builds (test-flask): <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/builds-test-flask/metamask-flask-chrome-12.14.0-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/builds-test-flask-mv2/metamask-flask-firefox-12.14.0-flask.0.zip">firefox</a></li>
<li>build viz: <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/build-viz/index.html">Build System</a></li>
<li>mv3: <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/test-artifacts/chrome/bundle_size.json">Bundle Size Stats</a></li>
<li>mv2: <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/test-artifacts/chrome/benchmark/user_actions.json">E2e Actions Stats</a></li>
<li>storybook: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/13975816833/storybook-build/index.html">Storybook</a></li>
<li>typescript migration: <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/ts-migration-dashboard/index.html">Dashboard</a></li>
<li><a href="https://circleci.com/gh/MetaMask/metamask-extension/4665204#artifacts/containers/0">all artifacts</a></li>
<li><details>
       <summary>bundle viz:</summary>
       <ul><li>background: <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/background-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/background-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/background-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/background-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/background-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/background-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/background-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/background-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/background-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/background-9.html">9</a></li><li>common: <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/common-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/common-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/common-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/common-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/common-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/common-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/common-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/common-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/common-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/common-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/common-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/common-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/common-12.html">12</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/common-13.html">13</a></li><li>ui: <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/ui-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/ui-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/ui-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/ui-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/ui-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/ui-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/ui-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/ui-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/ui-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/ui-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/ui-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/ui-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/ui-12.html">12</a></li><li>content-script: <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/content-script-0.html">0</a></li><li>offscreen: <a href="https://output.circle-artifacts.com/output/job/57241d52-79a3-4e08-85df-b870048e58fe/artifacts/0/build-artifacts/source-map-explorer/offscreen-0.html">0</a></li></ul>
     </details></li></ul></details>

<details><summary>Page Load Metrics (4086 ± 1607 ms)</summary><table><thead><tr><th>Platform</th><th>Page</th><th>Metric</th><th>Min (ms)</th><th>Max (ms)</th><th>Average (ms)</th><th>StandardDeviation (ms)</th><th>MarginOfError (ms)</th></tr></thead><tbody><tr><td rowspan="11">Chrome</td><td rowspan="11">Home</td><td>firstPaint</td><td align="right">1868</td><td align="right">17231</td><td align="right">3713</td><td align="right">3235</td><td align="right">1554</td></tr><tr><td>domContentLoaded</td><td align="right">1672</td><td align="right">16549</td><td align="right">3224</td><td align="right">3160</td><td align="right">1517</td></tr><tr><td>load</td><td align="right">1936</td><td align="right">17828</td><td align="right">4086</td><td align="right">3347</td><td align="right">1607</td></tr><tr><td>domInteractive</td><td align="right">28</td><td align="right">451</td><td align="right">92</td><td align="right">99</td><td align="right">47</td></tr><tr><td>backgroundConnect</td><td align="right">174</td><td align="right">1556</td><td align="right">789</td><td align="right">457</td><td align="right">219</td></tr><tr><td>firstReactRender</td><td align="right">34</td><td align="right">324</td><td align="right">136</td><td align="right">64</td><td align="right">31</td></tr><tr><td>getState</td><td align="right">53</td><td align="right">937</td><td align="right">341</td><td align="right">251</td><td align="right">121</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">1</td><td align="right">0</td><td align="right">0</td><td align="right">0</td></tr><tr><td>loadScripts</td><td align="right">1177</td><td align="right">15031</td><td align="right">2393</td><td align="right">2925</td><td align="right">1405</td></tr><tr><td>setupStore</td><td align="right">8</td><td align="right">904</td><td align="right">210</td><td align="right">200</td><td align="right">96</td></tr><tr><td>uiStartup</td><td align="right">2441</td><td align="right">24567</td><td align="right">8582</td><td align="right">5715</td><td align="right">2744</td></tr></tbody></table></details>


author_association: COLLABORATOR
user: login: socket-security[bot]
created_at: 2025-03-20T21:12:00Z
body: **New and updated dependencies detected.** Learn more about [Socket for GitHub ↗︎](https://socket.dev?utm_medium=gh)


| Package | New capabilities | Transitives | Size | Publisher |
|:--- |:--- |:--- |:--- |:--- |
| [npm/@metamask/chain-agnostic-permission@0.1.0](https://socket.dev/npm/package/@metamask/chain-agnostic-permission/overview/0.1.0) ➜ [0.2.0](https://socket.dev/npm/package/@metamask/chain-agnostic-permission/overview/0.2.0) | None | <a href="https://socket.dev/npm/package/@metamask/chain-agnostic-permission/dependencies/0.2.0">`0`</a> | 444 kB | <a href="https://socket.dev/npm/user/metamaskbot">metamaskbot</a> |
| [npm/@metamask/eth-json-rpc-infura@10.0.0](https://socket.dev/npm/package/@metamask/eth-json-rpc-infura/overview/10.0.0) ➜ [10.1.0](https://socket.dev/npm/package/@metamask/eth-json-rpc-infura/overview/10.1.0) | None | <a href="https://socket.dev/npm/package/@metamask/eth-json-rpc-infura/dependencies/10.1.0">`+1`</a> | 236 kB | <a href="https://socket.dev/npm/user/mcmire">mcmire</a> |
| [npm/@metamask/multichain-api-middleware@0.1.0](https://socket.dev/npm/package/@metamask/multichain-api-middleware/overview/0.1.0) ➜ [0.1.1](https://socket.dev/npm/package/@metamask/multichain-api-middleware/overview/0.1.1) | None | <a href="https://socket.dev/npm/package/@metamask/multichain-api-middleware/dependencies/0.1.1">`0`</a> | 168 kB | <a href="https://socket.dev/npm/user/metamaskbot">metamaskbot</a> |



[**View full report↗︎**](https://socket.dev/dashboard/org/MetaMask/diff/90aa87d2-c120-43dc-8270-f15eb76fd73d/fa8c17c5-5c20-4ae9-b84d-cee5f2dfce8d)

<!-- overview-comment -->
author_association: NONE
user: login: adonesky1
created_at: 2025-03-20T22:06:07Z
body: @metamaskbot update-policies
author_association: CONTRIBUTOR
user: login: metamaskbot
created_at: 2025-03-20T22:13:08Z
body: Policy update failed. You can [review the logs or retry the policy update here](https://github.com/MetaMask/metamask-extension/actions/runs/13980264486)
author_association: COLLABORATOR
user: login: metamaskbot
created_at: 2025-03-21T01:00:56Z
body: <details><summary>Builds ready [aa94501]</summary><ul><li>builds: <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/builds/metamask-chrome-12.14.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/builds-mv2/metamask-firefox-12.14.0.zip">firefox</a></li>
<li>builds (flask): <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/builds-flask/metamask-flask-chrome-12.14.0-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/builds-flask-mv2/metamask-flask-firefox-12.14.0-flask.0.zip">firefox</a></li>
<li>builds (MMI): <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/builds-mmi/metamask-mmi-chrome-12.14.0-mmi.0.zip">chrome</a></li>
<li>builds (test): <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/builds-test/metamask-chrome-12.14.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/builds-test-mv2/metamask-firefox-12.14.0.zip">firefox</a></li>
<li>builds (test-flask): <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/builds-test-flask/metamask-flask-chrome-12.14.0-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/builds-test-flask-mv2/metamask-flask-firefox-12.14.0-flask.0.zip">firefox</a></li>
<li>build viz: <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/build-viz/index.html">Build System</a></li>
<li>mv3: <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/test-artifacts/chrome/bundle_size.json">Bundle Size Stats</a></li>
<li>mv2: <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/test-artifacts/chrome/benchmark/user_actions.json">E2e Actions Stats</a></li>
<li>storybook: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/13981919719/storybook-build/index.html">Storybook</a></li>
<li>typescript migration: <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/ts-migration-dashboard/index.html">Dashboard</a></li>
<li><a href="https://circleci.com/gh/MetaMask/metamask-extension/4666295#artifacts/containers/0">all artifacts</a></li>
<li><details>
       <summary>bundle viz:</summary>
       <ul><li>background: <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/background-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/background-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/background-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/background-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/background-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/background-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/background-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/background-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/background-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/background-9.html">9</a></li><li>common: <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/common-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/common-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/common-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/common-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/common-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/common-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/common-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/common-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/common-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/common-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/common-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/common-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/common-12.html">12</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/common-13.html">13</a></li><li>ui: <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/ui-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/ui-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/ui-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/ui-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/ui-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/ui-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/ui-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/ui-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/ui-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/ui-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/ui-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/ui-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/ui-12.html">12</a></li><li>content-script: <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/content-script-0.html">0</a></li><li>offscreen: <a href="https://output.circle-artifacts.com/output/job/8d5c1eb9-5937-4d0f-8eb4-75c893758a3f/artifacts/0/build-artifacts/source-map-explorer/offscreen-0.html">0</a></li></ul>
     </details></li></ul></details>

<details><summary>Page Load Metrics (3312 ± 1087 ms)</summary><table><thead><tr><th>Platform</th><th>Page</th><th>Metric</th><th>Min (ms)</th><th>Max (ms)</th><th>Average (ms)</th><th>StandardDeviation (ms)</th><th>MarginOfError (ms)</th></tr></thead><tbody><tr><td rowspan="11">Chrome</td><td rowspan="11">Home</td><td>firstPaint</td><td align="right">1768</td><td align="right">10194</td><td align="right">3036</td><td align="right">2078</td><td align="right">998</td></tr><tr><td>domContentLoaded</td><td align="right">1565</td><td align="right">9756</td><td align="right">2695</td><td align="right">1991</td><td align="right">956</td></tr><tr><td>load</td><td align="right">1794</td><td align="right">10812</td><td align="right">3312</td><td align="right">2263</td><td align="right">1087</td></tr><tr><td>domInteractive</td><td align="right">25</td><td align="right">456</td><td align="right">112</td><td align="right">103</td><td align="right">50</td></tr><tr><td>backgroundConnect</td><td align="right">217</td><td align="right">1142</td><td align="right">554</td><td align="right">310</td><td align="right">149</td></tr><tr><td>firstReactRender</td><td align="right">58</td><td align="right">213</td><td align="right">114</td><td align="right">43</td><td align="right">21</td></tr><tr><td>getState</td><td align="right">81</td><td align="right">711</td><td align="right">291</td><td align="right">208</td><td align="right">100</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">1</td><td align="right">0</td><td align="right">0</td><td align="right">0</td></tr><tr><td>loadScripts</td><td align="right">1152</td><td align="right">9182</td><td align="right">2019</td><td align="right">1841</td><td align="right">884</td></tr><tr><td>setupStore</td><td align="right">37</td><td align="right">491</td><td align="right">169</td><td align="right">117</td><td align="right">56</td></tr><tr><td>uiStartup</td><td align="right">2735</td><td align="right">16150</td><td align="right">6073</td><td align="right">3469</td><td align="right">1666</td></tr></tbody></table></details>


author_association: COLLABORATOR
user: login: metamaskbot
created_at: 2025-03-21T14:58:15Z
body: <details><summary>Builds ready [775d45c]</summary><ul><li>builds: <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/builds/metamask-chrome-12.14.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/builds-mv2/metamask-firefox-12.14.0.zip">firefox</a></li>
<li>builds (flask): <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/builds-flask/metamask-flask-chrome-12.14.0-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/builds-flask-mv2/metamask-flask-firefox-12.14.0-flask.0.zip">firefox</a></li>
<li>builds (MMI): <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/builds-mmi/metamask-mmi-chrome-12.14.0-mmi.0.zip">chrome</a></li>
<li>builds (test): <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/builds-test/metamask-chrome-12.14.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/builds-test-mv2/metamask-firefox-12.14.0.zip">firefox</a></li>
<li>builds (test-flask): <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/builds-test-flask/metamask-flask-chrome-12.14.0-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/builds-test-flask-mv2/metamask-flask-firefox-12.14.0-flask.0.zip">firefox</a></li>
<li>build viz: <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/build-viz/index.html">Build System</a></li>
<li>mv3: <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/test-artifacts/chrome/bundle_size.json">Bundle Size Stats</a></li>
<li>mv2: <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/test-artifacts/chrome/benchmark/user_actions.json">E2e Actions Stats</a></li>
<li>storybook: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/13993849472/storybook-build/index.html">Storybook</a></li>
<li>typescript migration: <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/ts-migration-dashboard/index.html">Dashboard</a></li>
<li><a href="https://circleci.com/gh/MetaMask/metamask-extension/4668647#artifacts/containers/0">all artifacts</a></li>
<li><details>
       <summary>bundle viz:</summary>
       <ul><li>background: <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/background-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/background-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/background-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/background-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/background-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/background-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/background-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/background-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/background-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/background-9.html">9</a></li><li>common: <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/common-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/common-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/common-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/common-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/common-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/common-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/common-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/common-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/common-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/common-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/common-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/common-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/common-12.html">12</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/common-13.html">13</a></li><li>ui: <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/ui-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/ui-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/ui-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/ui-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/ui-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/ui-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/ui-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/ui-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/ui-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/ui-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/ui-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/ui-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/ui-12.html">12</a></li><li>content-script: <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/content-script-0.html">0</a></li><li>offscreen: <a href="https://output.circle-artifacts.com/output/job/9aa732d3-9a89-4d0b-a223-393735a9ee99/artifacts/0/build-artifacts/source-map-explorer/offscreen-0.html">0</a></li></ul>
     </details></li></ul></details>

<details><summary>Page Load Metrics (3902 ± 1231 ms)</summary><table><thead><tr><th>Platform</th><th>Page</th><th>Metric</th><th>Min (ms)</th><th>Max (ms)</th><th>Average (ms)</th><th>StandardDeviation (ms)</th><th>MarginOfError (ms)</th></tr></thead><tbody><tr><td rowspan="11">Chrome</td><td rowspan="11">Home</td><td>firstPaint</td><td align="right">1850</td><td align="right">12847</td><td align="right">3482</td><td align="right">2327</td><td align="right">1117</td></tr><tr><td>domContentLoaded</td><td align="right">1708</td><td align="right">11788</td><td align="right">3058</td><td align="right">2138</td><td align="right">1027</td></tr><tr><td>load</td><td align="right">1863</td><td align="right">13893</td><td align="right">3902</td><td align="right">2563</td><td align="right">1231</td></tr><tr><td>domInteractive</td><td align="right">30</td><td align="right">289</td><td align="right">96</td><td align="right">78</td><td align="right">37</td></tr><tr><td>backgroundConnect</td><td align="right">108</td><td align="right">2266</td><td align="right">755</td><td align="right">563</td><td align="right">270</td></tr><tr><td>firstReactRender</td><td align="right">23</td><td align="right">367</td><td align="right">126</td><td align="right">70</td><td align="right">34</td></tr><tr><td>getState</td><td align="right">40</td><td align="right">1820</td><td align="right">421</td><td align="right">485</td><td align="right">233</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">0</td><td align="right">0</td><td align="right">0</td><td align="right">0</td></tr><tr><td>loadScripts</td><td align="right">1226</td><td align="right">10279</td><td align="right">2265</td><td align="right">1898</td><td align="right">911</td></tr><tr><td>setupStore</td><td align="right">10</td><td align="right">1179</td><td align="right">192</td><td align="right">249</td><td align="right">119</td></tr><tr><td>uiStartup</td><td align="right">2187</td><td align="right">19222</td><td align="right">8103</td><td align="right">4888</td><td align="right">2347</td></tr></tbody></table></details>


author_association: COLLABORATOR
user: login: metamaskbot
created_at: 2025-03-21T16:53:00Z
body: <details><summary>Builds ready [10b9cc5]</summary><ul><li>builds: <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/builds/metamask-chrome-12.14.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/builds-mv2/metamask-firefox-12.14.0.zip">firefox</a></li>
<li>builds (flask): <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/builds-flask/metamask-flask-chrome-12.14.0-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/builds-flask-mv2/metamask-flask-firefox-12.14.0-flask.0.zip">firefox</a></li>
<li>builds (MMI): <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/builds-mmi/metamask-mmi-chrome-12.14.0-mmi.0.zip">chrome</a></li>
<li>builds (test): <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/builds-test/metamask-chrome-12.14.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/builds-test-mv2/metamask-firefox-12.14.0.zip">firefox</a></li>
<li>builds (test-flask): <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/builds-test-flask/metamask-flask-chrome-12.14.0-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/builds-test-flask-mv2/metamask-flask-firefox-12.14.0-flask.0.zip">firefox</a></li>
<li>build viz: <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/build-viz/index.html">Build System</a></li>
<li>mv3: <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/test-artifacts/chrome/bundle_size.json">Bundle Size Stats</a></li>
<li>mv2: <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/test-artifacts/chrome/benchmark/user_actions.json">E2e Actions Stats</a></li>
<li>storybook: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/13996127615/storybook-build/index.html">Storybook</a></li>
<li>typescript migration: <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/ts-migration-dashboard/index.html">Dashboard</a></li>
<li><a href="https://circleci.com/gh/MetaMask/metamask-extension/4669170#artifacts/containers/0">all artifacts</a></li>
<li><details>
       <summary>bundle viz:</summary>
       <ul><li>background: <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/background-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/background-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/background-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/background-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/background-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/background-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/background-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/background-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/background-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/background-9.html">9</a></li><li>common: <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/common-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/common-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/common-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/common-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/common-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/common-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/common-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/common-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/common-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/common-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/common-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/common-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/common-12.html">12</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/common-13.html">13</a></li><li>ui: <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/ui-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/ui-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/ui-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/ui-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/ui-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/ui-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/ui-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/ui-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/ui-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/ui-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/ui-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/ui-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/ui-12.html">12</a></li><li>content-script: <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/content-script-0.html">0</a></li><li>offscreen: <a href="https://output.circle-artifacts.com/output/job/6d19d13d-4497-43f9-93a6-51ab5b32bee7/artifacts/0/build-artifacts/source-map-explorer/offscreen-0.html">0</a></li></ul>
     </details></li></ul></details>

<details><summary>Page Load Metrics (4146 ± 1668 ms)</summary><table><thead><tr><th>Platform</th><th>Page</th><th>Metric</th><th>Min (ms)</th><th>Max (ms)</th><th>Average (ms)</th><th>StandardDeviation (ms)</th><th>MarginOfError (ms)</th></tr></thead><tbody><tr><td rowspan="11">Chrome</td><td rowspan="11">Home</td><td>firstPaint</td><td align="right">1874</td><td align="right">16727</td><td align="right">3701</td><td align="right">3213</td><td align="right">1543</td></tr><tr><td>domContentLoaded</td><td align="right">1743</td><td align="right">13333</td><td align="right">3092</td><td align="right">2555</td><td align="right">1227</td></tr><tr><td>load</td><td align="right">1921</td><td align="right">18030</td><td align="right">4146</td><td align="right">3474</td><td align="right">1668</td></tr><tr><td>domInteractive</td><td align="right">28</td><td align="right">393</td><td align="right">99</td><td align="right">104</td><td align="right">50</td></tr><tr><td>backgroundConnect</td><td align="right">217</td><td align="right">3374</td><td align="right">911</td><td align="right">715</td><td align="right">343</td></tr><tr><td>firstReactRender</td><td align="right">59</td><td align="right">245</td><td align="right">134</td><td align="right">43</td><td align="right">21</td></tr><tr><td>getState</td><td align="right">82</td><td align="right">2001</td><td align="right">442</td><td align="right">423</td><td align="right">203</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">1</td><td align="right">0</td><td align="right">0</td><td align="right">0</td></tr><tr><td>loadScripts</td><td align="right">1298</td><td align="right">10558</td><td align="right">2241</td><td align="right">2077</td><td align="right">997</td></tr><tr><td>setupStore</td><td align="right">35</td><td align="right">463</td><td align="right">183</td><td align="right">127</td><td align="right">61</td></tr><tr><td>uiStartup</td><td align="right">3187</td><td align="right">22467</td><td align="right">8578</td><td align="right">5297</td><td align="right">2544</td></tr></tbody></table></details>


author_association: COLLABORATOR
user: login: metamaskbot
created_at: 2025-03-21T20:27:56Z
body: <details><summary>Builds ready [6317531]</summary><ul><li>builds: <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/builds/metamask-chrome-12.14.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/builds-mv2/metamask-firefox-12.14.0.zip">firefox</a></li>
<li>builds (flask): <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/builds-flask/metamask-flask-chrome-12.14.0-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/builds-flask-mv2/metamask-flask-firefox-12.14.0-flask.0.zip">firefox</a></li>
<li>builds (MMI): <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/builds-mmi/metamask-mmi-chrome-12.14.0-mmi.0.zip">chrome</a></li>
<li>builds (test): <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/builds-test/metamask-chrome-12.14.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/builds-test-mv2/metamask-firefox-12.14.0.zip">firefox</a></li>
<li>builds (test-flask): <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/builds-test-flask/metamask-flask-chrome-12.14.0-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/builds-test-flask-mv2/metamask-flask-firefox-12.14.0-flask.0.zip">firefox</a></li>
<li>build viz: <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/build-viz/index.html">Build System</a></li>
<li>mv3: <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/test-artifacts/chrome/bundle_size.json">Bundle Size Stats</a></li>
<li>mv2: <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/test-artifacts/chrome/benchmark/user_actions.json">E2e Actions Stats</a></li>
<li>storybook: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/13999779706/storybook-build/index.html">Storybook</a></li>
<li>typescript migration: <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/ts-migration-dashboard/index.html">Dashboard</a></li>
<li><a href="https://circleci.com/gh/MetaMask/metamask-extension/4669748#artifacts/containers/0">all artifacts</a></li>
<li><details>
       <summary>bundle viz:</summary>
       <ul><li>background: <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/background-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/background-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/background-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/background-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/background-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/background-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/background-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/background-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/background-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/background-9.html">9</a></li><li>common: <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/common-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/common-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/common-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/common-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/common-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/common-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/common-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/common-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/common-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/common-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/common-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/common-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/common-12.html">12</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/common-13.html">13</a></li><li>ui: <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/ui-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/ui-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/ui-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/ui-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/ui-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/ui-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/ui-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/ui-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/ui-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/ui-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/ui-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/ui-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/ui-12.html">12</a></li><li>content-script: <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/content-script-0.html">0</a></li><li>offscreen: <a href="https://output.circle-artifacts.com/output/job/04a423f4-1153-43ed-8049-ddcc114573c9/artifacts/0/build-artifacts/source-map-explorer/offscreen-0.html">0</a></li></ul>
     </details></li></ul></details>

<details><summary>Page Load Metrics (3735 ± 2074 ms)</summary><table><thead><tr><th>Platform</th><th>Page</th><th>Metric</th><th>Min (ms)</th><th>Max (ms)</th><th>Average (ms)</th><th>StandardDeviation (ms)</th><th>MarginOfError (ms)</th></tr></thead><tbody><tr><td rowspan="11">Chrome</td><td rowspan="11">Home</td><td>firstPaint</td><td align="right">1694</td><td align="right">20198</td><td align="right">3602</td><td align="right">4336</td><td align="right">2082</td></tr><tr><td>domContentLoaded</td><td align="right">1586</td><td align="right">20063</td><td align="right">3393</td><td align="right">4335</td><td align="right">2082</td></tr><tr><td>load</td><td align="right">1743</td><td align="right">20189</td><td align="right">3735</td><td align="right">4319</td><td align="right">2074</td></tr><tr><td>domInteractive</td><td align="right">25</td><td align="right">1300</td><td align="right">135</td><td align="right">272</td><td align="right">131</td></tr><tr><td>backgroundConnect</td><td align="right">78</td><td align="right">810</td><td align="right">324</td><td align="right">201</td><td align="right">97</td></tr><tr><td>firstReactRender</td><td align="right">23</td><td align="right">113</td><td align="right">65</td><td align="right">26</td><td align="right">13</td></tr><tr><td>getState</td><td align="right">26</td><td align="right">396</td><td align="right">157</td><td align="right">100</td><td align="right">48</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">1</td><td align="right">0</td><td align="right">0</td><td align="right">0</td></tr><tr><td>loadScripts</td><td align="right">1118</td><td align="right">19596</td><td align="right">2766</td><td align="right">4257</td><td align="right">2044</td></tr><tr><td>setupStore</td><td align="right">9</td><td align="right">221</td><td align="right">84</td><td align="right">71</td><td align="right">34</td></tr><tr><td>uiStartup</td><td align="right">1932</td><td align="right">20423</td><td align="right">5066</td><td align="right">4234</td><td align="right">2033</td></tr></tbody></table></details>


author_association: COLLABORATOR
user: login: jiexi
created_at: 2025-03-25T18:46:01Z
body: tested manually. looks great
author_association: MEMBER
user: login: metamaskbot
created_at: 2025-03-25T18:50:53Z
body: <details><summary>Builds ready [bbcfb23]</summary><ul><li>builds: <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/builds/metamask-chrome-12.14.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/builds-mv2/metamask-firefox-12.14.0.zip">firefox</a></li>
<li>builds (flask): <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/builds-flask/metamask-flask-chrome-12.14.0-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/builds-flask-mv2/metamask-flask-firefox-12.14.0-flask.0.zip">firefox</a></li>
<li>builds (MMI): <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/builds-mmi/metamask-mmi-chrome-12.14.0-mmi.0.zip">chrome</a></li>
<li>builds (test): <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/builds-test/metamask-chrome-12.14.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/builds-test-mv2/metamask-firefox-12.14.0.zip">firefox</a></li>
<li>builds (test-flask): <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/builds-test-flask/metamask-flask-chrome-12.14.0-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/builds-test-flask-mv2/metamask-flask-firefox-12.14.0-flask.0.zip">firefox</a></li>
<li>build viz: <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/build-viz/index.html">Build System</a></li>
<li>mv3: <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/test-artifacts/chrome/bundle_size.json">Bundle Size Stats</a></li>
<li>mv2: <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/test-artifacts/chrome/benchmark/user_actions.json">E2e Actions Stats</a></li>
<li>storybook: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/14067156539/storybook-build/index.html">Storybook</a></li>
<li>typescript migration: <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/ts-migration-dashboard/index.html">Dashboard</a></li>
<li><a href="https://circleci.com/gh/MetaMask/metamask-extension/4681916#artifacts/containers/0">all artifacts</a></li>
<li><details>
       <summary>bundle viz:</summary>
       <ul><li>background: <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/background-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/background-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/background-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/background-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/background-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/background-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/background-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/background-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/background-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/background-9.html">9</a></li><li>common: <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/common-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/common-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/common-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/common-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/common-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/common-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/common-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/common-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/common-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/common-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/common-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/common-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/common-12.html">12</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/common-13.html">13</a></li><li>ui: <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/ui-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/ui-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/ui-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/ui-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/ui-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/ui-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/ui-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/ui-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/ui-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/ui-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/ui-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/ui-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/ui-12.html">12</a></li><li>content-script: <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/content-script-0.html">0</a></li><li>offscreen: <a href="https://output.circle-artifacts.com/output/job/91f25c12-3375-4b76-aa83-4780f40fb56a/artifacts/0/build-artifacts/source-map-explorer/offscreen-0.html">0</a></li></ul>
     </details></li></ul></details>

<details><summary>Page Load Metrics (3297 ± 852 ms)</summary><table><thead><tr><th>Platform</th><th>Page</th><th>Metric</th><th>Min (ms)</th><th>Max (ms)</th><th>Average (ms)</th><th>StandardDeviation (ms)</th><th>MarginOfError (ms)</th></tr></thead><tbody><tr><td rowspan="11">Chrome</td><td rowspan="11">Home</td><td>firstPaint</td><td align="right">1970</td><td align="right">10387</td><td align="right">3026</td><td align="right">1777</td><td align="right">853</td></tr><tr><td>domContentLoaded</td><td align="right">1584</td><td align="right">10296</td><td align="right">2615</td><td align="right">1812</td><td align="right">870</td></tr><tr><td>load</td><td align="right">2070</td><td align="right">10383</td><td align="right">3297</td><td align="right">1775</td><td align="right">852</td></tr><tr><td>domInteractive</td><td align="right">26</td><td align="right">463</td><td align="right">117</td><td align="right">105</td><td align="right">50</td></tr><tr><td>backgroundConnect</td><td align="right">87</td><td align="right">1106</td><td align="right">595</td><td align="right">344</td><td align="right">165</td></tr><tr><td>firstReactRender</td><td align="right">18</td><td align="right">249</td><td align="right">116</td><td align="right">53</td><td align="right">26</td></tr><tr><td>getState</td><td align="right">35</td><td align="right">791</td><td align="right">306</td><td align="right">241</td><td align="right">116</td></tr><tr><td>initialActions</td><td align="right">0</td><td align="right">1</td><td align="right">0</td><td align="right">0</td><td align="right">0</td></tr><tr><td>loadScripts</td><td align="right">1146</td><td align="right">9898</td><td align="right">1977</td><td align="right">1835</td><td align="right">881</td></tr><tr><td>setupStore</td><td align="right">18</td><td align="right">377</td><td align="right">164</td><td align="right">119</td><td align="right">57</td></tr><tr><td>uiStartup</td><td align="right">2909</td><td align="right">14101</td><td align="right">6151</td><td align="right">3082</td><td align="right">1480</td></tr></tbody></table></details>


author_association: COLLABORATOR