Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement transaction details component #24228

Merged
merged 9 commits into from
May 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 12 additions & 0 deletions app/_locales/en/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 15 additions & 6 deletions test/data/confirmations/contract-interaction.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import { TransactionStatus, TransactionType } from "@metamask/transaction-controller";
import { Confirmation } from "../../../ui/pages/confirmations/types/confirm";
import {
TransactionStatus,
TransactionType,
} from '@metamask/transaction-controller';
import { Confirmation } from '../../../ui/pages/confirmations/types/confirm';

export const CONTRACT_INTERACTION_SENDER_ADDRESS = '0x2e0d7e8c45221fca00d74a3609a0f7097035d09b';
export const CONTRACT_INTERACTION_SENDER_ADDRESS =
'0x2e0d7e8c45221fca00d74a3609a0f7097035d09b';

export const DEPOSIT_METHOD_DATA = '0xd0e30db0';

export const genUnapprovedContractInteractionConfirmation = (
{ address } = { address: CONTRACT_INTERACTION_SENDER_ADDRESS }
{ address, txData } = {
address: CONTRACT_INTERACTION_SENDER_ADDRESS,
txData: DEPOSIT_METHOD_DATA,
},
): Confirmation => ({
actionId: String(400855682),
chainId: '0xaa36a7',
Expand Down Expand Up @@ -41,7 +50,7 @@ export const genUnapprovedContractInteractionConfirmation = (
status: TransactionStatus.unapproved,
time: 1713534772044,
txParams: {
data: '0xd0e30db0',
data: txData,
from: address,
gas: '0xab77',
maxFeePerGas: '0xaa350353',
Expand Down Expand Up @@ -126,7 +135,7 @@ export const genUnapprovedContractInteractionConfirmation = (
status: TransactionStatus.unapproved,
time: 1713534772044,
txParams: {
data: '0xd0e30db0',
data: txData,
from: address,
gas: '0xab77',
maxFeePerGas: '0xaa350353',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { fireEvent, waitFor } from '@testing-library/react';
import React from 'react';
import { genUnapprovedContractInteractionConfirmation } from '../../../../../../test/data/confirmations/contract-interaction';
import {
DEPOSIT_METHOD_DATA,
genUnapprovedContractInteractionConfirmation,
} from '../../../../../../test/data/confirmations/contract-interaction';
import { unapprovedPersonalSignMsg } from '../../../../../../test/data/confirmations/personal_sign';
import mockState from '../../../../../../test/data/mock-state.json';
import { renderWithProvider } from '../../../../../../test/jest';
Expand Down Expand Up @@ -39,6 +42,7 @@ describe('Header', () => {
confirm: {
currentConfirmation: genUnapprovedContractInteractionConfirmation({
address: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
txData: DEPOSIT_METHOD_DATA,
}),
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,96 @@ exports[`<ContractInteractionInfo /> does not render if required data is not pre

exports[`<ContractInteractionInfo /> renders component for contract interaction request 1`] = `
<div>
<div
class="mm-box mm-box--margin-bottom-4 mm-box--background-color-background-default mm-box--rounded-md"
>
<div
class="mm-box simulation-details-layout mm-box--padding-3 mm-box--display-flex mm-box--gap-3 mm-box--flex-direction-column mm-box--rounded-md mm-box--border-color-transparent box--border-style-solid box--border-width-1"
data-testid="simulation-details-layout"
>
<div
class="mm-box mm-box--display-flex mm-box--flex-direction-row mm-box--justify-content-space-between mm-box--align-items-center"
>
<div
class="mm-box mm-box--display-flex mm-box--gap-1 mm-box--flex-direction-row mm-box--align-items-center"
>
<p
class="mm-box mm-text mm-text--body-md-medium mm-box--color-text-default"
>
Estimated changes
</p>
<div
class="info-tooltip"
data-testid="info-tooltip"
>
<div>
<div
aria-describedby="tippy-tooltip-1"
class="info-tooltip__tooltip-container"
data-original-title="null"
data-tooltipped=""
style="display: inline;"
tabindex="0"
>
<svg
viewBox="0 0 10 10"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M5 0C2.2 0 0 2.2 0 5s2.2 5 5 5 5-2.2 5-5-2.2-5-5-5zm0 2c.4 0 .7.3.7.7s-.3.7-.7.7-.7-.2-.7-.6.3-.8.7-.8zm.7 6H4.3V4.3h1.5V8z"
fill="var(--color-icon-muted)"
/>
</svg>
</div>
</div>
</div>
</div>
<div
role="progressbar"
>
<svg
class="preloader__icon"
fill="none"
height="20"
viewBox="0 0 16 16"
width="20"
xmlns="http://www.w3.org/2000/svg"
>
<path
clip-rule="evenodd"
d="M8 13.7143C4.84409 13.7143 2.28571 11.1559 2.28571 8C2.28571 4.84409 4.84409 2.28571 8 2.28571C11.1559 2.28571 13.7143 4.84409 13.7143 8C13.7143 11.1559 11.1559 13.7143 8 13.7143ZM8 16C3.58172 16 0 12.4183 0 8C0 3.58172 3.58172 0 8 0C12.4183 0 16 3.58172 16 8C16 12.4183 12.4183 16 8 16Z"
fill="var(--color-primary-muted)"
fill-rule="evenodd"
/>
<mask
height="16"
id="mask0"
mask-type="alpha"
maskUnits="userSpaceOnUse"
width="16"
x="0"
y="0"
>
<path
clip-rule="evenodd"
d="M8 13.7143C4.84409 13.7143 2.28571 11.1559 2.28571 8C2.28571 4.84409 4.84409 2.28571 8 2.28571C11.1559 2.28571 13.7143 4.84409 13.7143 8C13.7143 11.1559 11.1559 13.7143 8 13.7143ZM8 16C3.58172 16 0 12.4183 0 8C0 3.58172 3.58172 0 8 0C12.4183 0 16 3.58172 16 8C16 12.4183 12.4183 16 8 16Z"
fill="var(--color-primary-default)"
fill-rule="evenodd"
/>
</mask>
<g
mask="url(#mask0)"
>
<path
d="M6.85718 17.9999V11.4285V8.28564H-4.85711V17.9999H6.85718Z"
fill="var(--color-primary-default)"
/>
</g>
</svg>
</div>
</div>
</div>
</div>
<div
class="mm-box mm-box--margin-bottom-4 mm-box--padding-2 mm-box--background-color-background-default mm-box--rounded-md"
>
Expand All @@ -21,9 +111,9 @@ exports[`<ContractInteractionInfo /> renders component for contract interaction
</p>
<div>
<div
aria-describedby="tippy-tooltip-1"
aria-describedby="tippy-tooltip-2"
class=""
data-original-title="This is the site asking for your signature."
data-original-title="This is the site asking for your confirmation."
data-tooltipped=""
style="display: flex;"
tabindex="0"
Expand All @@ -41,8 +131,94 @@ exports[`<ContractInteractionInfo /> renders component for contract interaction
<p
class="mm-box mm-text mm-text--body-md mm-box--color-inherit"
>
0x2e0d7e8c45221fca00d74a3609a0f7097035d09b
metamask.github.io
</p>
</div>
</div>
<div
class="mm-box confirm-info-row mm-box--margin-top-2 mm-box--margin-bottom-2 mm-box--padding-right-2 mm-box--padding-left-2 mm-box--display-flex mm-box--flex-direction-row mm-box--flex-wrap-wrap mm-box--justify-content-space-between mm-box--color-text-default mm-box--rounded-lg"
style="overflow-wrap: anywhere; min-height: 24px;"
>
<div
class="mm-box mm-box--display-flex mm-box--flex-direction-row mm-box--justify-content-center mm-box--align-items-center"
>
<p
class="mm-box mm-text mm-text--body-md-medium mm-box--color-inherit"
>
Interacting with
</p>
<div>
<div
aria-describedby="tippy-tooltip-3"
class=""
data-original-title="This is the contract you're interacting with. Protect yourself from scammers by verifying the details."
data-tooltipped=""
style="display: flex;"
tabindex="0"
>
<span
class="mm-box mm-icon mm-icon--size-sm mm-box--margin-left-1 mm-box--display-inline-block mm-box--color-icon-muted"
style="mask-image: url('./images/icons/question.svg');"
/>
</div>
</div>
</div>
<div
class="mm-box mm-box--display-flex mm-box--flex-direction-row mm-box--align-items-center"
>
<div
class="mm-box mm-box--display-flex mm-box--flex-direction-row mm-box--align-items-center"
>
<div
class="mm-box mm-text mm-avatar-base mm-avatar-base--size-xs mm-avatar-account mm-text--body-xs mm-text--text-transform-uppercase mm-box--display-flex mm-box--justify-content-center mm-box--align-items-center mm-box--color-text-default mm-box--background-color-background-alternative mm-box--rounded-full mm-box--border-color-transparent box--border-style-solid box--border-width-1"
>
<div
class="mm-avatar-account__jazzicon"
>
<div
style="border-radius: 50px; overflow: hidden; padding: 0px; margin: 0px; width: 16px; height: 16px; display: inline-block; background: rgb(200, 20, 98);"
>
<svg
height="16"
width="16"
x="0"
y="0"
>
<rect
fill="#018E82"
height="16"
transform="translate(0.09338133124744565 -0.04490608666778058) rotate(456.7 8 8)"
width="16"
x="0"
y="0"
/>
<rect
fill="#FB187B"
height="16"
transform="translate(-6.3240369287990985 -1.0053822898747908) rotate(305.5 8 8)"
width="16"
x="0"
y="0"
/>
<rect
fill="#237CE1"
height="16"
transform="translate(4.0809955633515935 -14.427164334848008) rotate(395.8 8 8)"
width="16"
x="0"
y="0"
/>
</svg>
</div>
</div>
</div>
<p
class="mm-box mm-text mm-text--body-md mm-box--margin-left-2 mm-box--color-inherit"
data-testid="confirm-info-row-display-name"
>
0x88AA6...A5125
</p>
</div>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Meta } from '@storybook/react';
import React from 'react';
import { Provider } from 'react-redux';
import { genUnapprovedContractInteractionConfirmation } from '../../../../../../../test/data/confirmations/contract-interaction';
Expand All @@ -6,15 +7,22 @@ import configureStore from '../../../../../../store/store';
import ContractInteractionInfo from './contract-interaction';

const store = configureStore({
metamask: { ...mockState.metamask },
confirm: { currentConfirmation: genUnapprovedContractInteractionConfirmation() },
...mockState,
metamask: {
...mockState.metamask,
},
confirm: {
currentConfirmation: genUnapprovedContractInteractionConfirmation(),
},
});

const Story = {
title: 'Components/App/Confirm/info/ContractInteractionInfo',
component: ContractInteractionInfo,
decorators: [
(story: () => any) => <Provider store={store}>{story()}</Provider>,
(story: () => Meta<typeof ContractInteractionInfo>) => (
<Provider store={store}>{story()}</Provider>
),
],
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import React from 'react';
import thunk from 'redux-thunk';
import configureMockStore from 'redux-mock-store';
import { genUnapprovedContractInteractionConfirmation } from '../../../../../../../test/data/confirmations/contract-interaction';
import mockState from '../../../../../../../test/data/mock-state.json';
import { renderWithProvider } from '../../../../../../../test/lib/render-helpers';
import ContractInteractionInfo from './contract-interaction';

describe('<ContractInteractionInfo />', () => {
const middleware = [thunk];

Copy link
Contributor

Choose a reason for hiding this comment

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

just curious - why is thunk middleware required here ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because useKnownMethodDataInTransaction, which is further down the component chain needs to be able to dispatch actions.

it('renders component for contract interaction request', () => {
const state = {
...mockState,
confirm: {
currentConfirmation: genUnapprovedContractInteractionConfirmation(),
},
};
const mockStore = configureMockStore([])(state);
const mockStore = configureMockStore(middleware)(state);
const { container } = renderWithProvider(
<ContractInteractionInfo />,
mockStore,
Expand All @@ -33,7 +36,7 @@ describe('<ContractInteractionInfo />', () => {
},
},
};
const mockStore = configureMockStore([])(state);
const mockStore = configureMockStore(middleware)(state);
const { container } = renderWithProvider(
<ContractInteractionInfo />,
mockStore,
Expand Down