Repository: MetaMask/metamask-extension
Pull request #30447: feat: nested transaction data
Author: login: matthewwalsh0
Labels: name: team-confirmations
description: Push issues to confirmations team
name: release-12.15.0
description: Issue or pull request that will be included in release 12.15.0
Created: 2025-02-19T21:52:39Z | Merged: 2025-03-12T21:58:18Z

## **Description**

Display nested transaction data in batch transaction confirmations.

Specifically:

- Add `NestedTransactionData` component.
- Replace properties of `useFourByte` hook with `data` and `to`.
- Extend `useDecodedTransactionData` hook to support optional `data` and `to` properties.
- Extend `TransactionData` component to support optional `data` and `to` properties.
- Extend `RecipientRow` to support optional `recipient` property.
- Hide root `TransactionData` if nested transactions.

[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/30447?quickstart=1)

## **Related issues**

Fixes: [#4272](https://github.com/MetaMask/MetaMask-planning/issues/4272)

## **Manual testing steps**

## **Screenshots/Recordings**

### **Before**

### **After**

<img width="200" alt="Confirmation" src="https://github.com/user-attachments/assets/82032221-2c8a-45ed-b66f-fd03c0b87329" />

<img width="200" alt="Collapsed" src="https://github.com/user-attachments/assets/0c4d5392-0e58-4fc6-8b15-5c172ea2182e" />

<img width="200" alt="Expanded" src="https://github.com/user-attachments/assets/4ececad9-28ef-444b-95eb-7894d49680de" />

## **Pre-merge author checklist**

- [x] 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).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable
- [x] 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/_locales/en/messages.json b/app/_locales/en/messages.json
index dd6c13afc7f2..67dfa1aceaa7 100644
--- a/app/_locales/en/messages.json
+++ b/app/_locales/en/messages.json
@@ -1033,6 +1033,9 @@
   "confirmFieldTooltipPaymaster": {
     "message": "The fee for this transaction will be paid by the paymaster smart contract."
   },
+  "confirmNestedTransactionTitle": {
+    "message": "Transaction $1"
+  },
   "confirmPassword": {
     "message": "Confirm password"
   },
diff --git a/app/_locales/en_GB/messages.json b/app/_locales/en_GB/messages.json
index dd6c13afc7f2..67dfa1aceaa7 100644
--- a/app/_locales/en_GB/messages.json
+++ b/app/_locales/en_GB/messages.json
@@ -1033,6 +1033,9 @@
   "confirmFieldTooltipPaymaster": {
     "message": "The fee for this transaction will be paid by the paymaster smart contract."
   },
+  "confirmNestedTransactionTitle": {
+    "message": "Transaction $1"
+  },
   "confirmPassword": {
     "message": "Confirm password"
   },
diff --git a/test/data/confirmations/contract-interaction.ts b/test/data/confirmations/contract-interaction.ts
index b5339679d920..7d1bef702f38 100644
--- a/test/data/confirmations/contract-interaction.ts
+++ b/test/data/confirmations/contract-interaction.ts
@@ -1,5 +1,6 @@
 import {
   AuthorizationList,
+  BatchTransactionParams,
   CHAIN_IDS,
   SimulationData,
   TransactionMeta,
@@ -27,12 +28,14 @@ export const genUnapprovedContractInteractionConfirmation = ({
   authorizationList = undefined,
   txData = DEPOSIT_METHOD_DATA,
   chainId = CHAIN_ID,
+  nestedTransactions,
   simulationData,
 }: {
   address?: Hex;
   authorizationList?: AuthorizationList;
   txData?: Hex;
   chainId?: string;
+  nestedTransactions?: BatchTransactionParams[];
   simulationData?: SimulationData;
 } = {}): Confirmation => {
   const confirmation: Confirmation = {
@@ -138,6 +141,7 @@ export const genUnapprovedContractInteractionConfirmation = ({
       ],
     ],
     id: '1d7c08c0-fe54-11ee-9243-91b1e533746a',
+    nestedTransactions,
     origin: 'https://metamask.github.io',
     securityAlertResponse: {
       features: [],
diff --git a/test/data/confirmations/transaction-decode.ts b/test/data/confirmations/transaction-decode.ts
index e9700ababff3..be8798eb3fdb 100644
--- a/test/data/confirmations/transaction-decode.ts
+++ b/test/data/confirmations/transaction-decode.ts
@@ -1,8 +1,13 @@
 import { DecodedTransactionDataSource } from '../../../shared/types/transaction-decode';
 
-export const CONTRACT_ADDRESS_UNISWAP = '0x1';
-export const CONTRACT_ADDRESS_SOURCIFY = '0x2';
-export const CONTRACT_ADDRESS_FOUR_BYTE = '0x3';
+export const CONTRACT_ADDRESS_UNISWAP =
+  '0x1111111111111111111111111111111111111111';
+
+export const CONTRACT_ADDRESS_SOURCIFY =
+  '0x2222222222222222222222222222222222222222';
+
+export const CONTRACT_ADDRESS_FOUR_BYTE =
+  '0x3333333333333333333333333333333333333333';
 
 export const TRANSACTION_DATA_UNISWAP =
   '0x3593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000006679b4bb00000000000000000000000000000000000000000000000000000000000000040b000604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000005af3107a40000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000005af3107a4000000000000000000000000000000000000000000000000000000000000004c41800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f4a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000027213e28d7fda5c57fe9e5dd923818dbccf71c4700000000000000000000000000000000000000000000000000000000000000190000000000000000000000000000000000000000000000000000000000000060000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000004c418';
diff --git a/ui/pages/confirmations/components/confirm/info/batch/nested-transaction-data/index.ts b/ui/pages/confirmations/components/confirm/info/batch/nested-transaction-data/index.ts
new file mode 100644
index 000000000000..368d41ed2500
--- /dev/null
+++ b/ui/pages/confirmations/components/confirm/info/batch/nested-transaction-data/index.ts
@@ -0,0 +1 @@
+export { NestedTransactionData } from './nested-transaction-data';
diff --git a/ui/pages/confirmations/components/confirm/info/batch/nested-transaction-data/nested-transaction-data.stories.tsx b/ui/pages/confirmations/components/confirm/info/batch/nested-transaction-data/nested-transaction-data.stories.tsx
new file mode 100644
index 000000000000..c8ee28add727
--- /dev/null
+++ b/ui/pages/confirmations/components/confirm/info/batch/nested-transaction-data/nested-transaction-data.stories.tsx
@@ -0,0 +1,72 @@
+import React from 'react';
+import { Provider } from 'react-redux';
+
+import configureStore from '../../../../../../../store/store';
+import { NestedTransactionData } from './nested-transaction-data';
+import { ConfirmContextProvider } from '../../../../../context/confirm';
+import { genUnapprovedContractInteractionConfirmation } from '../../../../../../../../test/data/confirmations/contract-interaction';
+import { getMockConfirmStateForTransaction } from '../../../../../../../../test/data/confirmations/helper';
+
+import {
+  CONTRACT_ADDRESS_FOUR_BYTE,
+  CONTRACT_ADDRESS_SOURCIFY,
+  TRANSACTION_DATA_FOUR_BYTE,
+} from '../../../../../../../../test/data/confirmations/transaction-decode';
+
+const FOUR_BYTE_DATA = '0xabcdefab';
+const SOURCIFY_DATA = '0x98765432';
+
+const TRANSACTION_MOCK = genUnapprovedContractInteractionConfirmation({
+  nestedTransactions: [
+    {
+      data: '0x12345678',
+      to: '0x1234567890123456789012345678901234567890',
+      value: '0x123',
+    },
+    {
+      data: FOUR_BYTE_DATA,
+      to: CONTRACT_ADDRESS_FOUR_BYTE,
+      value: '0xabc',
+    },
+    {
+      data: SOURCIFY_DATA,
+      to: CONTRACT_ADDRESS_SOURCIFY,
+      value: '0xabc',
+    },
+  ],
+});
+
+const STATE_MOCK = getMockConfirmStateForTransaction(TRANSACTION_MOCK, {
+  metamask: {
+    knownMethodData: {
+      [FOUR_BYTE_DATA]: {
+        name: 'Some Function',
+      },
+      [SOURCIFY_DATA]: {
+        name: 'Cancel Authorization',
+      },
+    },
+  },
+});
+
+const store = configureStore(STATE_MOCK);
+
+const Story = {
+  title: 'Confirmations/Components/Confirm/NestedTransactionData',
+  component: NestedTransactionData,
+  decorators: [
+    (story) => {
+      return (
+        <Provider store={store}>
+          <ConfirmContextProvider>{story()}</ConfirmContextProvider>
+        </Provider>
+      );
+    },
+  ],
+};
+
+export default Story;
+
+export const DefaultStory = () => <NestedTransactionData />;
+
+DefaultStory.storyName = 'Default';
diff --git a/ui/pages/confirmations/components/confirm/info/batch/nested-transaction-data/nested-transaction-data.test.tsx b/ui/pages/confirmations/components/confirm/info/batch/nested-transaction-data/nested-transaction-data.test.tsx
new file mode 100644
index 000000000000..acbd56282bac
--- /dev/null
+++ b/ui/pages/confirmations/components/confirm/info/batch/nested-transaction-data/nested-transaction-data.test.tsx
@@ -0,0 +1,118 @@
+import React from 'react';
+import { BatchTransactionParams } from '@metamask/transaction-controller';
+import { renderWithConfirmContextProvider } from '../../../../../../../../test/lib/confirmations/render-helpers';
+import configureStore from '../../../../../../../store/store';
+import { getMockConfirmStateForTransaction } from '../../../../../../../../test/data/confirmations/helper';
+import { genUnapprovedContractInteractionConfirmation } from '../../../../../../../../test/data/confirmations/contract-interaction';
+import { useFourByte } from '../../hooks/useFourByte';
+import { useDecodedTransactionData } from '../../hooks/useDecodedTransactionData';
+import { NestedTransactionData } from './nested-transaction-data';
+
+jest.mock('../../hooks/useFourByte', () => ({
+  useFourByte: jest.fn(),
+}));
+
+jest.mock('../../hooks/useDecodedTransactionData', () => ({
+  useDecodedTransactionData: jest.fn(),
+}));
+
+jest.mock(
+  '../../../../../../../components/app/alert-system/contexts/alertMetricsContext',
+  () => ({
+    useAlertMetrics: () => ({
+      trackAlertMetrics: jest.fn(),
+    }),
+  }),
+);
+
+const FUNCTION_NAME_MOCK = 'TestFunction';
+
+const BATCH_TRANSACTION_PARAMS_MOCK: BatchTransactionParams = {
+  data: '0x12345',
+  to: '0x1234567890123456789012345678901234567890',
+  value: '0xabc',
+};
+
+function render({
+  nestedTransactions,
+}: {
+  nestedTransactions?: BatchTransactionParams[];
+}) {
+  const store = configureStore(
+    getMockConfirmStateForTransaction(
+      genUnapprovedContractInteractionConfirmation({
+        nestedTransactions,
+      }),
+    ),
+  );
+
+  return renderWithConfirmContextProvider(<NestedTransactionData />, store);
+}
+
+describe('NestedTransaction', () => {
+  const useFourByteMock = jest.mocked(useFourByte);
+  const useDecodedTransactionDataMock = jest.mocked(useDecodedTransactionData);
+
+  beforeEach(() => {
+    jest.resetAllMocks();
+
+    useFourByteMock.mockReturnValue(undefined);
+    useDecodedTransactionDataMock.mockReturnValue({
+      value: undefined,
+      pending: false,
+    });
+  });
+
+  it('renders label as transaction index', () => {
+    const { getByText } = render({
+      nestedTransactions: [BATCH_TRANSACTION_PARAMS_MOCK],
+    });
+
+    expect(getByText('Transaction 1')).toBeInTheDocument();
+  });
+
+  it('renders label as function name', () => {
+    useFourByteMock.mockReturnValue({ name: FUNCTION_NAME_MOCK });
+
+    const { getByText } = render({
+      nestedTransactions: [BATCH_TRANSACTION_PARAMS_MOCK],
+    });
+
+    expect(getByText(FUNCTION_NAME_MOCK)).toBeInTheDocument();
+  });
+
+  it('renders recipient', () => {
+    const { getByText } = render({
+      nestedTransactions: [BATCH_TRANSACTION_PARAMS_MOCK],
+    });
+
+    expect(getByText('0x12345...67890')).toBeInTheDocument();
+  });
+
+  it('renders transaction data', () => {
+    const { getByText } = render({
+      nestedTransactions: [BATCH_TRANSACTION_PARAMS_MOCK],
+    });
+
+    expect(
+      getByText(BATCH_TRANSACTION_PARAMS_MOCK.data as string),
+    ).toBeInTheDocument();
+  });
+
+  it('renders multiple nested transactions', () => {
+    const { getByText } = render({
+      nestedTransactions: [
+        BATCH_TRANSACTION_PARAMS_MOCK,
+        BATCH_TRANSACTION_PARAMS_MOCK,
+      ],
+    });
+
+    expect(getByText('Transaction 1')).toBeInTheDocument();
+    expect(getByText('Transaction 2')).toBeInTheDocument();
+  });
+
+  it('does not render if no nested transactions', () => {
+    const { container } = render({});
+    expect(container).toBeEmptyDOMElement();
+  });
+});
diff --git a/ui/pages/confirmations/components/confirm/info/batch/nested-transaction-data/nested-transaction-data.tsx b/ui/pages/confirmations/components/confirm/info/batch/nested-transaction-data/nested-transaction-data.tsx
new file mode 100644
index 000000000000..cd98fd1309f2
--- /dev/null
+++ b/ui/pages/confirmations/components/confirm/info/batch/nested-transaction-data/nested-transaction-data.tsx
@@ -0,0 +1,68 @@
+import React from 'react';
+import {
+  BatchTransactionParams,
+  TransactionMeta,
+} from '@metamask/transaction-controller';
+import { useConfirmContext } from '../../../../../context/confirm';
+import { Box } from '../../../../../../../components/component-library';
+import { useFourByte } from '../../hooks/useFourByte';
+import { ConfirmInfoSection } from '../../../../../../../components/app/confirm/info/row/section';
+import { ConfirmInfoExpandableRow } from '../../../../../../../components/app/confirm/info/row/expandable-row';
+import { RecipientRow } from '../../shared/transaction-details/transaction-details';
+import { TransactionData } from '../../shared/transaction-data/transaction-data';
+import { ConfirmInfoRowText } from '../../../../../../../components/app/confirm/info/row';
+import { useI18nContext } from '../../../../../../../hooks/useI18nContext';
+
+export function NestedTransactionData() {
+  const { currentConfirmation } = useConfirmContext<TransactionMeta>();
+  const { nestedTransactions } = currentConfirmation ?? {};
+
+  if (!nestedTransactions?.length) {
+    return null;
+  }
+
+  return (
+    <Box>
+      {nestedTransactions.map((nestedTransaction, index) => (
+        <NestedTransaction
+          key={index}
+          index={index}
+          nestedTransaction={nestedTransaction}
+        />
+      ))}
+    </Box>
+  );
+}
+
+function NestedTransaction({
+  index,
+  nestedTransaction,
+}: {
+  index: number;
+  nestedTransaction: BatchTransactionParams;
+}) {
+  const t = useI18nContext();
+  const { data, to } = nestedTransaction;
+  const methodData = useFourByte({ data, to });
+
+  const functionName = methodData?.name;
+
+  const label =
+    functionName ?? t('confirmNestedTransactionTitle', [String(index + 1)]);
+
+  return (
+    <ConfirmInfoSection>
+      <ConfirmInfoExpandableRow
+        label={label}
+        content={
+          <>
+            {to && <RecipientRow recipient={to} />}
+            {data && to && <TransactionData data={data} to={to} noPadding />}
+          </>
+        }
+      >
+        <ConfirmInfoRowText text="" />
+      </ConfirmInfoExpandableRow>
+    </ConfirmInfoSection>
+  );
+}
diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useDecodedTransactionData.test.ts b/ui/pages/confirmations/components/confirm/info/hooks/useDecodedTransactionData.test.ts
index c12ce7025cb5..5d2a9f0170a0 100644
--- a/ui/pages/confirmations/components/confirm/info/hooks/useDecodedTransactionData.test.ts
+++ b/ui/pages/confirmations/components/confirm/info/hooks/useDecodedTransactionData.test.ts
@@ -5,7 +5,9 @@ import {
   TransactionType,
 } from '@metamask/transaction-controller';
 
+import { Hex } from '@metamask/utils';
 import {
+  TRANSACTION_DATA_FOUR_BYTE,
   TRANSACTION_DATA_UNISWAP,
   TRANSACTION_DECODE_SOURCIFY,
 } from '../../../../../../../test/data/confirmations/transaction-decode';
@@ -22,9 +24,12 @@ jest.mock('../../../../../../store/actions', () => ({
 const CONTRACT_ADDRESS_MOCK = '0x123';
 const CHAIN_ID_MOCK = '0x5';
 
-async function runHook(state: Record<string, unknown>) {
+async function runHook(
+  state: Record<string, unknown>,
+  { data, to }: { data?: Hex; to?: Hex } = {},
+) {
   const response = renderHookWithConfirmContextProvider(
-    useDecodedTransactionData,
+    () => useDecodedTransactionData({ data, to }),
     state,
   );
 
@@ -38,6 +43,10 @@ async function runHook(state: Record<string, unknown>) {
 describe('useDecodedTransactionData', () => {
   const decodeTransactionDataMock = jest.mocked(decodeTransactionData);
 
+  beforeEach(() => {
+    jest.resetAllMocks();
+  });
+
   // @ts-expect-error This is missing from the Mocha type definitions
   it.each([undefined, null, '', '0x', '0X'])(
     'returns undefined if transaction data is %s',
@@ -156,4 +165,31 @@ describe('useDecodedTransactionData', () => {
       }
     `);
   });
+
+  it('decodes data using data and to overrides', async () => {
+    decodeTransactionDataMock.mockResolvedValue(TRANSACTION_DECODE_SOURCIFY);
+
+    await runHook(
+      getMockConfirmStateForTransaction({
+        id: '123',
+        chainId: CHAIN_ID_MOCK,
+        type: TransactionType.contractInteraction,
+        status: TransactionStatus.unapproved,
+        txParams: {
+          data: TRANSACTION_DATA_FOUR_BYTE,
+          to: '0x1234',
+        } as TransactionParams,
+      }),
+      {
+        data: TRANSACTION_DATA_UNISWAP,
+        to: CONTRACT_ADDRESS_MOCK,
+      },
+    );
+
+    expect(decodeTransactionDataMock).toHaveBeenCalledWith({
+      chainId: CHAIN_ID_MOCK,
+      contractAddress: CONTRACT_ADDRESS_MOCK,
+      transactionData: TRANSACTION_DATA_UNISWAP,
+    });
+  });
 });
diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useDecodedTransactionData.ts b/ui/pages/confirmations/components/confirm/info/hooks/useDecodedTransactionData.ts
index 3486f16ed864..d650bb012a3c 100644
--- a/ui/pages/confirmations/components/confirm/info/hooks/useDecodedTransactionData.ts
+++ b/ui/pages/confirmations/components/confirm/info/hooks/useDecodedTransactionData.ts
@@ -12,17 +12,24 @@ import { useConfirmContext } from '../../../../context/confirm';
 import { hasTransactionData } from '../../../../../../../shared/modules/transaction.utils';
 import { use4ByteResolutionSelector } from '../../../../../../selectors';
 
-export function useDecodedTransactionData(
-  transactionTypeFilter?: string,
-): AsyncResult<DecodedTransactionDataResponse | undefined> {
+export function useDecodedTransactionData({
+  data,
+  to,
+  transactionTypeFilter,
+}: {
+  data?: Hex;
+  to?: Hex;
+  transactionTypeFilter?: string;
+} = {}): AsyncResult<DecodedTransactionDataResponse | undefined> {
   const { currentConfirmation } = useConfirmContext<TransactionMeta>();
   const isDecodeEnabled = useSelector(use4ByteResolutionSelector);
 
   const currentTransactionType = currentConfirmation?.type;
   const chainId = currentConfirmation?.chainId as Hex;
-  const contractAddress = currentConfirmation?.txParams?.to as Hex;
-  const transactionData = currentConfirmation?.txParams?.data as Hex;
-  const transactionTo = currentConfirmation?.txParams?.to as Hex;
+  const currentTransactionData = currentConfirmation?.txParams?.data as Hex;
+  const currentTransactionTo = currentConfirmation?.txParams?.to as Hex;
+  const transactionData = data ?? currentTransactionData;
+  const transactionTo = to ?? currentTransactionTo;
 
   return useAsyncResult(async () => {
     if (
@@ -38,13 +45,7 @@ export function useDecodedTransactionData(
     return await decodeTransactionData({
       transactionData,
       chainId,
-      contractAddress,
+      contractAddress: transactionTo,
     });
-  }, [
-    isDecodeEnabled,
-    transactionData,
-    transactionTo,
-    chainId,
-    contractAddress,
-  ]);
+  }, [isDecodeEnabled, transactionData, transactionTo, chainId]);
 }
diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.test.ts b/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.test.ts
index 9f1a848a96cd..dd986ed1b4dd 100644
--- a/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.test.ts
+++ b/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.test.ts
@@ -1,30 +1,21 @@
-import { TransactionMeta } from '@metamask/transaction-controller';
-import {
-  CONTRACT_INTERACTION_SENDER_ADDRESS,
-  genUnapprovedContractInteractionConfirmation,
-} from '../../../../../../../test/data/confirmations/contract-interaction';
 import mockState from '../../../../../../../test/data/mock-state.json';
 import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers';
 import { useFourByte } from './useFourByte';
 
-describe('useFourByte', () => {
-  const depositHexData = '0xd0e30db0';
+const DATA_MOCK = '0xd0e30db0';
+const TO_MOCK = '0x1234567890123456789012345678901234567890';
 
+describe('useFourByte', () => {
   it('returns the method name and params', () => {
-    const currentConfirmation = genUnapprovedContractInteractionConfirmation({
-      address: CONTRACT_INTERACTION_SENDER_ADDRESS,
-      txData: depositHexData,
-    }) as TransactionMeta;
-
     const { result } = renderHookWithProvider(
-      () => useFourByte(currentConfirmation),
+      () => useFourByte({ data: DATA_MOCK, to: TO_MOCK }),
       {
         ...mockState,
         metamask: {
           ...mockState.metamask,
           use4ByteResolution: true,
           knownMethodData: {
-            [depositHexData]: { name: 'Deposit', params: [] },
+            [DATA_MOCK]: { name: 'Deposit', params: [] },
           },
         },
       },
@@ -35,20 +26,15 @@ describe('useFourByte', () => {
   });
 
   it('returns null if resolution disabled', () => {
-    const currentConfirmation = genUnapprovedContractInteractionConfirmation({
-      address: CONTRACT_INTERACTION_SENDER_ADDRESS,
-      txData: depositHexData,
-    }) as TransactionMeta;
-
     const { result } = renderHookWithProvider(
-      () => useFourByte(currentConfirmation),
+      () => useFourByte({ data: DATA_MOCK, to: TO_MOCK }),
       {
         ...mockState,
         metamask: {
           ...mockState.metamask,
           use4ByteResolution: false,
           knownMethodData: {
-            [depositHexData]: { name: 'Deposit', params: [] },
+            [DATA_MOCK]: { name: 'Deposit', params: [] },
           },
         },
       },
@@ -58,13 +44,8 @@ describe('useFourByte', () => {
   });
 
   it('returns null if not known even if resolution enabled', () => {
-    const currentConfirmation = genUnapprovedContractInteractionConfirmation({
-      address: CONTRACT_INTERACTION_SENDER_ADDRESS,
-      txData: depositHexData,
-    }) as TransactionMeta;
-
     const { result } = renderHookWithProvider(
-      () => useFourByte(currentConfirmation),
+      () => useFourByte({ data: DATA_MOCK, to: TO_MOCK }),
       {
         ...mockState,
         metamask: {
@@ -79,22 +60,15 @@ describe('useFourByte', () => {
   });
 
   it('returns null if no transaction to', () => {
-    const currentConfirmation = genUnapprovedContractInteractionConfirmation({
-      address: CONTRACT_INTERACTION_SENDER_ADDRESS,
-      txData: depositHexData,
-    }) as TransactionMeta;
-
-    currentConfirmation.txParams.to = undefined;
-
     const { result } = renderHookWithProvider(
-      () => useFourByte(currentConfirmation),
+      () => useFourByte({ data: DATA_MOCK }),
       {
         ...mockState,
         metamask: {
           ...mockState.metamask,
           use4ByteResolution: true,
           knownMethodData: {
-            [depositHexData]: { name: 'Deposit', params: [] },
+            [DATA_MOCK]: { name: 'Deposit', params: [] },
           },
         },
       },
diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.ts b/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.ts
index 7fece13fb417..32f4a778f94d 100644
--- a/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.ts
+++ b/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.ts
@@ -1,4 +1,3 @@
-import { TransactionMeta } from '@metamask/transaction-controller';
 import { useDispatch, useSelector } from 'react-redux';
 import { useEffect } from 'react';
 import { Hex } from '@metamask/utils';
@@ -9,13 +8,11 @@ import {
 import { getContractMethodData } from '../../../../../../store/actions';
 import { hasTransactionData } from '../../../../../../../shared/modules/transaction.utils';
 
-export const useFourByte = (currentConfirmation: TransactionMeta) => {
+export const useFourByte = ({ to, data }: { to?: Hex; data?: Hex }) => {
   const dispatch = useDispatch();
   const isFourByteEnabled = useSelector(use4ByteResolutionSelector);
-  const transactionTo = currentConfirmation?.txParams?.to;
-  const transactionData = currentConfirmation?.txParams?.data as
-    | Hex
-    | undefined;
+  const transactionTo = to as Hex | undefined;
+  const transactionData = data as Hex | undefined;
 
   useEffect(() => {
     if (
diff --git a/ui/pages/confirmations/components/confirm/info/shared/advanced-details/advanced-details.tsx b/ui/pages/confirmations/components/confirm/info/shared/advanced-details/advanced-details.tsx
index de2f702c171d..44dab2a7e4b5 100644
--- a/ui/pages/confirmations/components/confirm/info/shared/advanced-details/advanced-details.tsx
+++ b/ui/pages/confirmations/components/confirm/info/shared/advanced-details/advanced-details.tsx
@@ -21,6 +21,7 @@ import { useConfirmContext } from '../../../../../context/confirm';
 import { selectConfirmationAdvancedDetailsOpen } from '../../../../../selectors/preferences';
 import { isSignatureTransactionType } from '../../../../../utils';
 import { TransactionData } from '../transaction-data/transaction-data';
+import { NestedTransactionData } from '../../batch/nested-transaction-data/nested-transaction-data';
 
 const NonceDetails = () => {
   const { currentConfirmation } = useConfirmContext<TransactionMeta>();
@@ -92,6 +93,7 @@ export const AdvancedDetails = ({
     <>
       <NonceDetails />
       <TransactionData />
+      <NestedTransactionData />
     </>
   );
 };
diff --git a/ui/pages/confirmations/components/confirm/info/shared/transaction-data/transaction-data.test.tsx b/ui/pages/confirmations/components/confirm/info/shared/transaction-data/transaction-data.test.tsx
index 33037e75850b..efad558b08d0 100644
--- a/ui/pages/confirmations/components/confirm/info/shared/transaction-data/transaction-data.test.tsx
+++ b/ui/pages/confirmations/components/confirm/info/shared/transaction-data/transaction-data.test.tsx
@@ -1,11 +1,13 @@
 import React from 'react';
 import configureMockStore from 'redux-mock-store';
 import {
+  BatchTransactionParams,
   TransactionStatus,
   TransactionType,
 } from '@metamask/transaction-controller';
 import { act } from '@testing-library/react';
 
+import { Hex } from '@metamask/utils';
 import { getMockConfirmStateForTransaction } from '../../../../../../../../test/data/confirmations/helper';
 import { renderWithConfirmContextProvider } from '../../../../../../../../test/lib/confirmations/render-helpers';
 import { decodeTransactionData } from '../../../../../../../store/actions';
@@ -18,27 +20,42 @@ import { Confirmation } from '../../../../../types/confirm';
 import { TransactionData } from './transaction-data';
 
 const DATA_MOCK = '0x123456';
+const DATA_2_MOCK = '0xabcdef';
+const TO_MOCK = '0x1234';
+const TO_2_MOCK = '0x5678';
 
 jest.mock('../../../../../../../store/actions', () => ({
   ...jest.requireActual('../../../../../../../store/actions'),
   decodeTransactionData: jest.fn(),
 }));
 
-async function renderTransactionData(transactionData: string) {
+async function renderTransactionData({
+  currentData,
+  dataOverride,
+  nestedTransactions,
+  toOverride,
+}: {
+  currentData: string;
+  dataOverride?: Hex;
+  nestedTransactions?: BatchTransactionParams[];
+  toOverride?: Hex;
+}) {
   const state = getMockConfirmStateForTransaction({
     id: '123',
     chainId: '0x5',
     type: TransactionType.contractInteraction,
     status: TransactionStatus.unapproved,
+    nestedTransactions,
     txParams: {
-      to: '0x1234',
-      data: transactionData,
+      to: TO_MOCK,
+      data: currentData,
     },
   } as Confirmation);
 
   const mockStore = configureMockStore()(state);
-  const { container } = renderWithConfirmContextProvider(
-    <TransactionData />,
+
+  const result = renderWithConfirmContextProvider(
+    <TransactionData data={dataOverride} to={toOverride} />,
     mockStore,
   );
 
@@ -46,16 +63,22 @@ async function renderTransactionData(transactionData: string) {
     // Ignore
   });
 
-  return container;
+  return result;
 }
 
 describe('TransactionData', () => {
   const decodeTransactionDataMock = jest.mocked(decodeTransactionData);
 
+  beforeEach(() => {
+    jest.resetAllMocks();
+  });
+
   it('renders nothing if no transaction data', async () => {
     decodeTransactionDataMock.mockResolvedValue(undefined);
 
-    const container = await renderTransactionData('');
+    const { container } = await renderTransactionData({
+      currentData: '',
+    });
 
     expect(container).toMatchSnapshot();
   });
@@ -63,7 +86,9 @@ describe('TransactionData', () => {
   it('renders raw hexadecimal if no decoded data', async () => {
     decodeTransactionDataMock.mockResolvedValue(undefined);
 
-    const container = await renderTransactionData(DATA_MOCK);
+    const { container } = await renderTransactionData({
+      currentData: DATA_MOCK,
+    });
 
     expect(container).toMatchSnapshot();
   });
@@ -71,7 +96,9 @@ describe('TransactionData', () => {
   it('renders decoded data with no names', async () => {
     decodeTransactionDataMock.mockResolvedValue(TRANSACTION_DECODE_FOUR_BYTE);
 
-    const container = await renderTransactionData(DATA_MOCK);
+    const { container } = await renderTransactionData({
+      currentData: DATA_MOCK,
+    });
 
     expect(container).toMatchSnapshot();
   });
@@ -79,7 +106,9 @@ describe('TransactionData', () => {
   it('renders decoded data with names and descriptions', async () => {
     decodeTransactionDataMock.mockResolvedValue(TRANSACTION_DECODE_UNISWAP);
 
-    const container = await renderTransactionData(DATA_MOCK);
+    const { container } = await renderTransactionData({
+      currentData: DATA_MOCK,
+    });
 
     expect(container).toMatchSnapshot();
   });
@@ -87,8 +116,40 @@ describe('TransactionData', () => {
   it('renders decoded data with tuples and arrays', async () => {
     decodeTransactionDataMock.mockResolvedValue(TRANSACTION_DECODE_NESTED);
 
-    const container = await renderTransactionData(DATA_MOCK);
+    const { container } = await renderTransactionData({
+      currentData: DATA_MOCK,
+    });
 
     expect(container).toMatchSnapshot();
   });
+
+  it('renders nothing if nested transactions and no data override', async () => {
+    decodeTransactionDataMock.mockResolvedValue(undefined);
+
+    const { container } = await renderTransactionData({
+      currentData: DATA_MOCK,
+      nestedTransactions: [{}],
+    });
+
+    expect(container).toBeEmptyDOMElement();
+  });
+
+  it('uses data and to overrides if provided', async () => {
+    decodeTransactionDataMock.mockResolvedValue(undefined);
+
+    const { getByText } = await renderTransactionData({
+      currentData: DATA_MOCK,
+      dataOverride: DATA_2_MOCK,
+      toOverride: TO_2_MOCK,
+    });
+
+    expect(getByText(DATA_2_MOCK)).toBeInTheDocument();
+
+    expect(decodeTransactionDataMock).toHaveBeenCalledWith(
+      expect.objectContaining({
+        contractAddress: TO_2_MOCK,
+        transactionData: DATA_2_MOCK,
+      }),
+    );
+  });
 });
diff --git a/ui/pages/confirmations/components/confirm/info/shared/transaction-data/transaction-data.tsx b/ui/pages/confirmations/components/confirm/info/shared/transaction-data/transaction-data.tsx
index 950a9b28c967..aaa8972b2d36 100644
--- a/ui/pages/confirmations/components/confirm/info/shared/transaction-data/transaction-data.tsx
+++ b/ui/pages/confirmations/components/confirm/info/shared/transaction-data/transaction-data.tsx
@@ -31,16 +31,31 @@ import { UniswapPathPool } from '../../../../../../../../app/scripts/lib/transac
 import { useConfirmContext } from '../../../../../context/confirm';
 import { hasTransactionData } from '../../../../../../../../shared/modules/transaction.utils';
 
-export const TransactionData = () => {
+export const TransactionData = ({
+  data,
+  noPadding,
+  to,
+}: { data?: Hex; noPadding?: boolean; to?: Hex } = {}) => {
   const { currentConfirmation } = useConfirmContext<TransactionMeta>();
+  const { nestedTransactions, txParams } = currentConfirmation ?? {};
+  const { data: currentData, to: currentTo } = txParams ?? {};
+  const transactionData = data ?? (currentData as Hex);
+  const transactionTo = to ?? (currentTo as Hex);
 
-  const transactionData = currentConfirmation?.txParams?.data as Hex;
-  const decodeResponse = useDecodedTransactionData();
+  const decodeResponse = useDecodedTransactionData({
+    data: transactionData,
+    to: transactionTo,
+  });
 
   const { value, pending } = decodeResponse;
 
+  // Don't show root transaction data if this is a batch transaction
+  if (nestedTransactions?.length && !data) {
+    return null;
+  }
+
   if (pending) {
-    return <Container isLoading />;
+    return <Container isLoading noPadding={noPadding} />;
   }
 
   if (!hasTransactionData(transactionData)) {
@@ -49,20 +64,20 @@ export const TransactionData = () => {
 
   if (!value) {
     return (
-      <Container transactionData={transactionData}>
+      <Container noPadding={noPadding} transactionData={transactionData}>
         <RawDataRow transactionData={transactionData} />
       </Container>
     );
   }
 
-  const { data, source } = value;
-  const isExpandable = data.length > 1;
+  const { data: decodeData, source } = value;
+  const isExpandable = decodeData.length > 1;
   const { chainId } = currentConfirmation;
 
   return (
-    <Container transactionData={transactionData}>
+    <Container transactionData={transactionData} noPadding={noPadding}>
       <>
-        {data.map((method, index) => (
+        {decodeData.map((method, index) => (
           <React.Fragment key={index}>
             <FunctionContainer
               method={method}
@@ -70,7 +85,7 @@ export const TransactionData = () => {
               isExpandable={isExpandable}
               chainId={chainId}
             />
-            {index < data.length - 1 && <ConfirmInfoRowDivider />}
+            {index < decodeData.length - 1 && <ConfirmInfoRowDivider />}
           </React.Fragment>
         ))}
       </>
@@ -81,17 +96,22 @@ export const TransactionData = () => {
 export function Container({
   children,
   isLoading,
+  noPadding,
   transactionData,
 }: {
   children?: React.ReactNode;
   isLoading?: boolean;
+  noPadding?: boolean;
   transactionData?: string;
 }) {
   const t = useI18nContext();
 
   return (
     <>
-      <ConfirmInfoSection data-testid="advanced-details-data-section">
+      <ConfirmInfoSection
+        noPadding={noPadding}
+        data-testid="advanced-details-data-section"
+      >
         <ConfirmInfoRow
           label={t('advancedDetailsDataDesc')}
           copyEnabled={Boolean(transactionData)}
diff --git a/ui/pages/confirmations/components/confirm/info/shared/transaction-details/transaction-details.tsx b/ui/pages/confirmations/components/confirm/info/shared/transaction-details/transaction-details.tsx
index 02e90281681c..b34e52a38d3f 100644
--- a/ui/pages/confirmations/components/confirm/info/shared/transaction-details/transaction-details.tsx
+++ b/ui/pages/confirmations/components/confirm/info/shared/transaction-details/transaction-details.tsx
@@ -2,6 +2,7 @@ import { TransactionMeta } from '@metamask/transaction-controller';
 import { isValidAddress } from 'ethereumjs-util';
 import React, { useMemo } from 'react';
 import { useSelector } from 'react-redux';
+import { Hex } from '@metamask/utils';
 import {
   ConfirmInfoRow,
   ConfirmInfoRowAddress,
@@ -48,14 +49,12 @@ export const OriginRow = () => {
   );
 };
 
-export const RecipientRow = () => {
+export const RecipientRow = ({ recipient }: { recipient?: Hex } = {}) => {
   const t = useI18nContext();
   const { currentConfirmation } = useConfirmContext<TransactionMeta>();
+  const to = recipient ?? currentConfirmation?.txParams?.to;
 
-  if (
-    !currentConfirmation?.txParams?.to ||
-    !isValidAddress(currentConfirmation?.txParams?.to ?? '')
-  ) {
+  if (!to || !isValidAddress(to)) {
     return null;
   }
 
@@ -69,10 +68,7 @@ export const RecipientRow = () => {
       label={t('interactingWith')}
       tooltip={t('interactingWithTransactionDescription')}
     >
-      <ConfirmInfoRowAddress
-        address={currentConfirmation.txParams.to}
-        chainId={chainId}
-      />
+      <ConfirmInfoRowAddress address={to} chainId={chainId} />
     </ConfirmInfoAlertRow>
   );
 };
@@ -80,7 +76,10 @@ export const RecipientRow = () => {
 export const MethodDataRow = () => {
   const t = useI18nContext();
   const { currentConfirmation } = useConfirmContext<TransactionMeta>();
-  const methodData = useFourByte(currentConfirmation);
+  const { txParams } = currentConfirmation ?? {};
+  const to = txParams?.to as Hex | undefined;
+  const data = txParams?.data as Hex | undefined;
+  const methodData = useFourByte({ to, data });
 
   if (!methodData?.name) {
     return null;


Reviews:
user: login: pedronfigueiredo
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-02-24T14:28:56Z
user: login: pedronfigueiredo
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-12T11:49:05Z
user: login: OGPoyraz
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-12T11:55:19Z
user: login: matthewwalsh0
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-12T12:01:47Z

Review comments:
diff_hunk: @@ -31,16 +31,31 @@ import { UniswapPathPool } from '../../../../../../../../app/scripts/lib/transac
 import { useConfirmContext } from '../../../../../context/confirm';
 import { hasTransactionData } from '../../../../../../../../shared/modules/transaction.utils';
 
-export const TransactionData = () => {
+export const TransactionData = ({
+  data,
+  noPadding,
+  to,
+}: { data?: Hex; noPadding?: boolean; to?: Hex } = {}) => {
   const { currentConfirmation } = useConfirmContext<TransactionMeta>();
+  const { nestedTransactions, txParams } = currentConfirmation ?? {};
+  const { data: currentData, to: currentTo } = txParams ?? {};
+  const transactionData = data ?? (currentData as Hex);
+  const transactionTo = to ?? (currentTo as Hex);
 
-  const transactionData = currentConfirmation?.txParams?.data as Hex;
-  const decodeResponse = useDecodedTransactionData();
+  const decodeResponse = useDecodedTransactionData({
+    data: transactionData,
+    to: transactionTo,
+  });
 
   const { value, pending } = decodeResponse;
 
+  // Don't show root transaction data if this is a batch transaction
+  if (nestedTransactions?.length && !data) {
path: ui/pages/confirmations/components/confirm/info/shared/transaction-data/transaction-data.tsx
user: login: OGPoyraz
body: Might be my misunderstanding - if this is the condition for checking root transaction data - should it check `data` or `currentData`? 
created_at: 2025-03-12T11:54:06Z
author_association: MEMBER
diff_hunk: @@ -31,16 +31,31 @@ import { UniswapPathPool } from '../../../../../../../../app/scripts/lib/transac
 import { useConfirmContext } from '../../../../../context/confirm';
 import { hasTransactionData } from '../../../../../../../../shared/modules/transaction.utils';
 
-export const TransactionData = () => {
+export const TransactionData = ({
+  data,
+  noPadding,
+  to,
+}: { data?: Hex; noPadding?: boolean; to?: Hex } = {}) => {
   const { currentConfirmation } = useConfirmContext<TransactionMeta>();
+  const { nestedTransactions, txParams } = currentConfirmation ?? {};
+  const { data: currentData, to: currentTo } = txParams ?? {};
+  const transactionData = data ?? (currentData as Hex);
+  const transactionTo = to ?? (currentTo as Hex);
 
-  const transactionData = currentConfirmation?.txParams?.data as Hex;
-  const decodeResponse = useDecodedTransactionData();
+  const decodeResponse = useDecodedTransactionData({
+    data: transactionData,
+    to: transactionTo,
+  });
 
   const { value, pending } = decodeResponse;
 
+  // Don't show root transaction data if this is a batch transaction
+  if (nestedTransactions?.length && !data) {
path: ui/pages/confirmations/components/confirm/info/shared/transaction-data/transaction-data.tsx
user: login: matthewwalsh0
body: This should explicitly be `data` as it's saying don't show the root data if we have nested transactions and no custom data override, since each nested transaction will use this component but with their own custom data rather than the root data.
created_at: 2025-03-12T12:01:47Z
author_association: MEMBER

PR comments:
user: login: metamaskbot
created_at: 2025-02-21T02:20:45Z
body: <details><summary>Builds ready [985558f]</summary><ul><li>builds: <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/builds/metamask-chrome-12.10.1.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/builds-mv2/metamask-firefox-12.10.1.zip">firefox</a></li>
<li>builds (flask): <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/builds-flask/metamask-flask-chrome-12.10.1-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/builds-flask-mv2/metamask-flask-firefox-12.10.1-flask.0.zip">firefox</a></li>
<li>builds (MMI): <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/builds-mmi/metamask-mmi-chrome-12.10.1-mmi.0.zip">chrome</a></li>
<li>builds (test): <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/builds-test/metamask-chrome-12.10.1.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/builds-test-mv2/metamask-firefox-12.10.1.zip">firefox</a></li>
<li>builds (test-flask): <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/builds-test-flask/metamask-flask-chrome-12.10.1-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/builds-test-flask-mv2/metamask-flask-firefox-12.10.1-flask.0.zip">firefox</a></li>
<li>build viz: <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/build-viz/index.html">Build System</a></li>
<li>mv3: <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/test-artifacts/chrome/bundle_size.json">Bundle Size Stats</a></li>
<li>mv2: <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/test-artifacts/chrome/benchmark/user_actions.json">E2e Actions Stats</a></li>
<li>storybook: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/13448334149/storybook-build/index.html">Storybook</a></li>
<li>typescript migration: <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/ts-migration-dashboard/index.html">Dashboard</a></li>
<li><a href="https://circleci.com/gh/MetaMask/metamask-extension/4570669#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/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/background-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/background-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/background-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/background-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/background-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/background-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/background-6.html">6</a></li><li>common: <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/common-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/common-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/common-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/common-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/common-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/common-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/common-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/common-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/common-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/common-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/common-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/common-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/common-12.html">12</a></li><li>ui: <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/ui-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/ui-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/ui-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/ui-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/ui-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/ui-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/ui-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/ui-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/ui-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/ui-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/ui-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/ui-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/afa91b9e-642c-4c62-8222-a9c6c3d38178/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/afa91b9e-642c-4c62-8222-a9c6c3d38178/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/afa91b9e-642c-4c62-8222-a9c6c3d38178/artifacts/0/build-artifacts/source-map-explorer/offscreen-0.html">0</a></li></ul>
     </details></li></ul></details>

<details><summary>Page Load Metrics (1686 ± 83 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">308</td><td align="right">2144</td><td align="right">1628</td><td align="right">351</td><td align="right">168</td></tr><tr><td>domContentLoaded</td><td align="right">1442</td><td align="right">2075</td><td align="right">1664</td><td align="right">166</td><td align="right">80</td></tr><tr><td>load</td><td align="right">1451</td><td align="right">2120</td><td align="right">1686</td><td align="right">172</td><td align="right">83</td></tr><tr><td>domInteractive</td><td align="right">23</td><td align="right">161</td><td align="right">44</td><td align="right">31</td><td align="right">15</td></tr><tr><td>backgroundConnect</td><td align="right">8</td><td align="right">64</td><td align="right">24</td><td align="right">18</td><td align="right">9</td></tr><tr><td>firstReactRender</td><td align="right">14</td><td align="right">73</td><td align="right">39</td><td align="right">24</td><td align="right">12</td></tr><tr><td>getState</td><td align="right">3</td><td align="right">62</td><td align="right">13</td><td align="right">15</td><td align="right">7</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">1049</td><td align="right">1612</td><td align="right">1243</td><td align="right">148</td><td align="right">71</td></tr><tr><td>setupStore</td><td align="right">7</td><td align="right">58</td><td align="right">16</td><td align="right">16</td><td align="right">8</td></tr><tr><td>uiStartup</td><td align="right">1682</td><td align="right">2527</td><td align="right">1960</td><td align="right">227</td><td align="right">109</td></tr></tbody></table></details>


author_association: COLLABORATOR
user: login: socket-security[bot]
created_at: 2025-03-10T23:05:45Z
body: **No dependency changes detected.** Learn more about [Socket for GitHub ↗︎](https://socket.dev?utm_medium=gh)

👍 No dependency changes detected in pull request
author_association: NONE
user: login: metamaskbot
created_at: 2025-03-11T00:20:50Z
body: <details><summary>Builds ready [075f736]</summary><ul><li>builds: <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/builds/metamask-chrome-12.10.1.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/builds-mv2/metamask-firefox-12.10.1.zip">firefox</a></li>
<li>builds (flask): <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/builds-flask/metamask-flask-chrome-12.10.1-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/builds-flask-mv2/metamask-flask-firefox-12.10.1-flask.0.zip">firefox</a></li>
<li>builds (MMI): <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/builds-mmi/metamask-mmi-chrome-12.10.1-mmi.0.zip">chrome</a></li>
<li>builds (test): <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/builds-test/metamask-chrome-12.10.1.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/builds-test-mv2/metamask-firefox-12.10.1.zip">firefox</a></li>
<li>builds (test-flask): <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/builds-test-flask/metamask-flask-chrome-12.10.1-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/builds-test-flask-mv2/metamask-flask-firefox-12.10.1-flask.0.zip">firefox</a></li>
<li>build viz: <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/build-viz/index.html">Build System</a></li>
<li>mv3: <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/test-artifacts/chrome/bundle_size.json">Bundle Size Stats</a></li>
<li>mv2: <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/test-artifacts/chrome/benchmark/user_actions.json">E2e Actions Stats</a></li>
<li>storybook: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/13777038962/storybook-build/index.html">Storybook</a></li>
<li>typescript migration: <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/ts-migration-dashboard/index.html">Dashboard</a></li>
<li><a href="https://circleci.com/gh/MetaMask/metamask-extension/4625294#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/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/background-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/background-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/background-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/background-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/background-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/background-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/background-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/background-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/background-8.html">8</a></li><li>common: <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/common-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/common-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/common-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/common-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/common-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/common-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/common-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/common-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/common-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/common-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/common-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/common-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/common-12.html">12</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/common-13.html">13</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/common-14.html">14</a></li><li>ui: <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/ui-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/ui-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/ui-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/ui-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/ui-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/ui-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/ui-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/ui-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/ui-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/ui-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/ui-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/ui-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/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/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/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/981eaa7b-7d74-4b7f-9b50-b0722a33dc38/artifacts/0/build-artifacts/source-map-explorer/offscreen-0.html">0</a></li></ul>
     </details></li></ul></details>

<details><summary>Page Load Metrics (2230 ± 132 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">463</td><td align="right">2956</td><td align="right">2059</td><td align="right">568</td><td align="right">273</td></tr><tr><td>domContentLoaded</td><td align="right">1852</td><td align="right">2835</td><td align="right">2150</td><td align="right">212</td><td align="right">102</td></tr><tr><td>load</td><td align="right">1860</td><td align="right">2959</td><td align="right">2230</td><td align="right">274</td><td align="right">132</td></tr><tr><td>domInteractive</td><td align="right">29</td><td align="right">137</td><td align="right">61</td><td align="right">30</td><td align="right">14</td></tr><tr><td>backgroundConnect</td><td align="right">12</td><td align="right">506</td><td align="right">87</td><td align="right">122</td><td align="right">59</td></tr><tr><td>firstReactRender</td><td align="right">16</td><td align="right">183</td><td align="right">47</td><td align="right">39</td><td align="right">19</td></tr><tr><td>getState</td><td align="right">5</td><td align="right">172</td><td align="right">47</td><td align="right">43</td><td align="right">21</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">1352</td><td align="right">2197</td><td align="right">1635</td><td align="right">172</td><td align="right">83</td></tr><tr><td>setupStore</td><td align="right">9</td><td align="right">112</td><td align="right">25</td><td align="right">26</td><td align="right">12</td></tr><tr><td>uiStartup</td><td align="right">2148</td><td align="right">6524</td><td align="right">2818</td><td align="right">963</td><td align="right">462</td></tr></tbody></table></details>


author_association: COLLABORATOR
user: login: metamaskbot
created_at: 2025-03-12T20:40:28Z
body: <details><summary>Builds ready [1dd5399]</summary><ul><li>builds: <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/builds/metamask-chrome-12.10.1.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/builds-mv2/metamask-firefox-12.10.1.zip">firefox</a></li>
<li>builds (flask): <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/builds-flask/metamask-flask-chrome-12.10.1-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/builds-flask-mv2/metamask-flask-firefox-12.10.1-flask.0.zip">firefox</a></li>
<li>builds (MMI): <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/builds-mmi/metamask-mmi-chrome-12.10.1-mmi.0.zip">chrome</a></li>
<li>builds (test): <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/builds-test/metamask-chrome-12.10.1.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/builds-test-mv2/metamask-firefox-12.10.1.zip">firefox</a></li>
<li>builds (test-flask): <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/builds-test-flask/metamask-flask-chrome-12.10.1-flask.0.zip">chrome</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/builds-test-flask-mv2/metamask-flask-firefox-12.10.1-flask.0.zip">firefox</a></li>
<li>build viz: <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/build-viz/index.html">Build System</a></li>
<li>mv3: <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/test-artifacts/chrome/bundle_size.json">Bundle Size Stats</a></li>
<li>mv2: <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/test-artifacts/chrome/benchmark/user_actions.json">E2e Actions Stats</a></li>
<li>storybook: <a href="https://diuv6g5fj9pvx.cloudfront.net/metamask-extension/13820485901/storybook-build/index.html">Storybook</a></li>
<li>typescript migration: <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/ts-migration-dashboard/index.html">Dashboard</a></li>
<li><a href="https://circleci.com/gh/MetaMask/metamask-extension/4634404#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/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/background-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/background-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/background-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/background-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/background-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/background-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/background-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/background-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/background-8.html">8</a></li><li>common: <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/common-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/common-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/common-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/common-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/common-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/common-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/common-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/common-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/common-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/common-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/common-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/common-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/common-12.html">12</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/common-13.html">13</a></li><li>ui: <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/ui-0.html">0</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/ui-1.html">1</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/ui-2.html">2</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/ui-3.html">3</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/ui-4.html">4</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/ui-5.html">5</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/ui-6.html">6</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/ui-7.html">7</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/ui-8.html">8</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/ui-9.html">9</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/ui-10.html">10</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/ui-11.html">11</a>, <a href="https://output.circle-artifacts.com/output/job/f34f6b79-1386-4994-814e-446503a6d455/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/f34f6b79-1386-4994-814e-446503a6d455/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/f34f6b79-1386-4994-814e-446503a6d455/artifacts/0/build-artifacts/source-map-explorer/offscreen-0.html">0</a></li></ul>
     </details></li></ul></details>

<details><summary>Page Load Metrics (2239 ± 161 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">482</td><td align="right">2936</td><td align="right">2022</td><td align="right">581</td><td align="right">279</td></tr><tr><td>domContentLoaded</td><td align="right">1832</td><td align="right">2503</td><td align="right">2112</td><td align="right">206</td><td align="right">99</td></tr><tr><td>load</td><td align="right">1848</td><td align="right">3157</td><td align="right">2239</td><td align="right">334</td><td align="right">161</td></tr><tr><td>domInteractive</td><td align="right">28</td><td align="right">121</td><td align="right">54</td><td align="right">28</td><td align="right">13</td></tr><tr><td>backgroundConnect</td><td align="right">13</td><td align="right">617</td><td align="right">134</td><td align="right">171</td><td align="right">82</td></tr><tr><td>firstReactRender</td><td align="right">19</td><td align="right">151</td><td align="right">47</td><td align="right">38</td><td align="right">18</td></tr><tr><td>getState</td><td align="right">7</td><td align="right">292</td><td align="right">55</td><td align="right">73</td><td align="right">35</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">1362</td><td align="right">1930</td><td align="right">1609</td><td align="right">167</td><td align="right">80</td></tr><tr><td>setupStore</td><td align="right">9</td><td align="right">91</td><td align="right">32</td><td align="right">28</td><td align="right">14</td></tr><tr><td>uiStartup</td><td align="right">2091</td><td align="right">5942</td><td align="right">2865</td><td align="right">979</td><td align="right">470</td></tr></tbody></table></details>

<details><summary>Bundle size diffs [🚨 Warning! Bundle size has increased!]</summary><ul><li>background: 0 Bytes (0.00%)</li>
<li>ui: 3.37 KiB (0.04%)</li>
<li>common: 57 Bytes (0.00%)</li></ul></details>


author_association: COLLABORATOR