-
+
+
-
+
+
-
- metamask.github.io
-
-
+ metamask.github.io
+
diff --git a/ui/pages/confirmations/confirm/stories/signatures/personal-sign.stories.tsx b/ui/pages/confirmations/confirm/stories/signatures/personal-sign.stories.tsx
index c43a54c5baee..1bffc1e34b3e 100644
--- a/ui/pages/confirmations/confirm/stories/signatures/personal-sign.stories.tsx
+++ b/ui/pages/confirmations/confirm/stories/signatures/personal-sign.stories.tsx
@@ -3,7 +3,7 @@ import {
ARG_TYPES_SIGNATURE,
CONFIRM_PAGE_DECORATOR,
SignatureStoryTemplate
-} from './utils';
+} from '../utils';
import { signatureRequestSIWE, unapprovedPersonalSignMsg } from '../../../../../../test/data/confirmations/personal_sign';
/**
diff --git a/ui/pages/confirmations/confirm/stories/signatures/sign-typed-data-v3-or-v4.stories.tsx b/ui/pages/confirmations/confirm/stories/signatures/sign-typed-data-v3-or-v4.stories.tsx
index 1c8fe17d9c46..80c86a41137c 100644
--- a/ui/pages/confirmations/confirm/stories/signatures/sign-typed-data-v3-or-v4.stories.tsx
+++ b/ui/pages/confirmations/confirm/stories/signatures/sign-typed-data-v3-or-v4.stories.tsx
@@ -3,7 +3,7 @@ import {
ARG_TYPES_SIGNATURE,
CONFIRM_PAGE_DECORATOR,
SignatureStoryTemplate
-} from './utils';
+} from '../utils';
import { permitSignatureMsg, unapprovedTypedSignMsgV3, unapprovedTypedSignMsgV4 } from '../../../../../../test/data/confirmations/typed_sign';
/**
diff --git a/ui/pages/confirmations/confirm/stories/signatures/sign-typed-data.stories.tsx b/ui/pages/confirmations/confirm/stories/signatures/sign-typed-data.stories.tsx
index 3268fcde5a8b..89c46695f60c 100644
--- a/ui/pages/confirmations/confirm/stories/signatures/sign-typed-data.stories.tsx
+++ b/ui/pages/confirmations/confirm/stories/signatures/sign-typed-data.stories.tsx
@@ -3,7 +3,7 @@ import {
ARG_TYPES_SIGNATURE,
CONFIRM_PAGE_DECORATOR,
SignatureStoryTemplate
-} from './utils';
+} from '../utils';
import { unapprovedTypedSignMsgV1 } from '../../../../../../test/data/confirmations/typed_sign';
/**
diff --git a/ui/pages/confirmations/confirm/stories/transactions/contract-interaction.stories.tsx b/ui/pages/confirmations/confirm/stories/transactions/contract-interaction.stories.tsx
new file mode 100644
index 000000000000..278501e1baf6
--- /dev/null
+++ b/ui/pages/confirmations/confirm/stories/transactions/contract-interaction.stories.tsx
@@ -0,0 +1,53 @@
+import ConfirmPage from '../../confirm';
+import { CONFIRM_PAGE_DECORATOR, ConfirmStoryTemplate } from '../utils';
+import {
+ DEPOSIT_METHOD_DATA,
+ PAYMASTER_AND_DATA,
+ genUnapprovedContractInteractionConfirmation,
+} from '../../../../../../test/data/confirmations/contract-interaction';
+import mockState from '../../../../../../test/data/mock-state.json';
+
+const FROM = '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc';
+
+export default {
+ title: 'Pages/Confirmations/Confirm/Transactions/ContractInteraction',
+ component: ConfirmPage,
+ decorators: CONFIRM_PAGE_DECORATOR,
+};
+
+export const DefaultStory = () => {
+ const confirmation = genUnapprovedContractInteractionConfirmation({
+ address: FROM,
+ txData: DEPOSIT_METHOD_DATA,
+ });
+
+ return ConfirmStoryTemplate(confirmation);
+};
+
+DefaultStory.storyName = 'Default';
+
+export const UserOperationStory = () => {
+ const confirmation = {
+ ...genUnapprovedContractInteractionConfirmation({
+ address: FROM,
+ txData: DEPOSIT_METHOD_DATA,
+ }),
+ isUserOperation: true,
+ };
+
+ return ConfirmStoryTemplate(confirmation, {
+ preferences: {
+ ...mockState.metamask.preferences,
+ petnamesEnabled: true,
+ },
+ userOperations: {
+ [confirmation.id]: {
+ userOperation: {
+ paymasterAndData: PAYMASTER_AND_DATA,
+ },
+ },
+ },
+ });
+};
+
+UserOperationStory.storyName = 'User Operation';
diff --git a/ui/pages/confirmations/confirm/stories/signatures/utils.tsx b/ui/pages/confirmations/confirm/stories/utils.tsx
similarity index 68%
rename from ui/pages/confirmations/confirm/stories/signatures/utils.tsx
rename to ui/pages/confirmations/confirm/stories/utils.tsx
index 918f30820abb..1bbff2f6e851 100644
--- a/ui/pages/confirmations/confirm/stories/signatures/utils.tsx
+++ b/ui/pages/confirmations/confirm/stories/utils.tsx
@@ -2,10 +2,16 @@ import React from 'react';
import { Provider } from 'react-redux';
import { MemoryRouter, Route } from 'react-router-dom';
import { cloneDeep } from 'lodash';
-import mockState from '../../../../../../test/data/mock-state.json';
-import configureStore from '../../../../../store/store';
-import ConfirmPage from '../../confirm';
-import { SignatureRequestType } from '../../../types/confirm';
+import mockState from '../../../../../test/data/mock-state.json';
+import configureStore from '../../../../store/store';
+import ConfirmPage from '../confirm';
+import { SignatureRequestType } from '../../types/confirm';
+
+export const CONFIRM_PAGE_DECORATOR = [
+ (story: () => React.ReactFragment) => {
+ return
{story()}
;
+ },
+];
export const ARG_TYPES_SIGNATURE = {
msgParams: {
@@ -14,24 +20,17 @@ export const ARG_TYPES_SIGNATURE = {
},
};
-export const CONFIRM_PAGE_DECORATOR = [
- (story: () => React.ReactFragment) => {
- return
{story()}
;
- },
-];
-
-export function SignatureStoryTemplate(
- args: { msgParams: SignatureRequestType['msgParams'] },
- confirmation: SignatureRequestType,
+export function ConfirmStoryTemplate(
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ currentConfirmation: any,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ metamaskState: any = {},
): JSX.Element {
- const mockConfirmation = cloneDeep(confirmation) as SignatureRequestType;
- mockConfirmation.msgParams = args.msgParams;
-
const store = configureStore({
confirm: {
- currentConfirmation: mockConfirmation,
+ currentConfirmation,
},
- metamask: { ...mockState.metamask },
+ metamask: { ...mockState.metamask, ...metamaskState },
});
return (
@@ -45,3 +44,13 @@ export function SignatureStoryTemplate(
);
}
+
+export function SignatureStoryTemplate(
+ args: { msgParams: SignatureRequestType['msgParams'] },
+ confirmation: SignatureRequestType,
+): JSX.Element {
+ const mockConfirmation = cloneDeep(confirmation) as SignatureRequestType;
+ mockConfirmation.msgParams = args.msgParams;
+
+ return ConfirmStoryTemplate(mockConfirmation);
+}
diff --git a/ui/selectors/account-abstraction.ts b/ui/selectors/account-abstraction.ts
index a8f420fd7fed..179f4665bfd6 100644
--- a/ui/selectors/account-abstraction.ts
+++ b/ui/selectors/account-abstraction.ts
@@ -1,5 +1,6 @@
import { TransactionMeta } from '@metamask/transaction-controller';
import { UserOperationControllerState } from '@metamask/user-operation-controller';
+import { createSelector } from 'reselect';
export type AccountAbstractionState = {
confirmTransaction?: { txData?: TransactionMeta };
@@ -10,6 +11,12 @@ export function getUserOperations(state: AccountAbstractionState) {
return state.metamask.userOperations || {};
}
+export const selectUserOperationMetadata = createSelector(
+ getUserOperations,
+ (_state: AccountAbstractionState, userOperationId: string) => userOperationId,
+ (userOperations, userOperationId) => userOperations[userOperationId],
+);
+
export function getUserOperation(state: AccountAbstractionState) {
const currentTransaction = state.confirmTransaction?.txData;
@@ -39,3 +46,20 @@ export function getIsUsingPaymaster(state: AccountAbstractionState) {
return Boolean(paymasterData?.length) && paymasterData !== '0x';
}
+
+export const selectPaymasterData = createSelector(
+ selectUserOperationMetadata,
+ (userOperationMetadata) => {
+ const paymasterAndData =
+ userOperationMetadata?.userOperation?.paymasterAndData;
+
+ return paymasterAndData === '0x' ? undefined : paymasterAndData;
+ },
+);
+
+export const selectPaymasterAddress = createSelector(
+ selectPaymasterData,
+ (paymasterData) => {
+ return paymasterData?.slice(0, 42);
+ },
+);