1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-22 09:23:21 +01:00

Extract out confirm-data and confirm-hex-data components from confirm-transaction-base.component.js (#17822)

This commit is contained in:
Jyoti Puri 2023-03-09 10:38:37 +05:30 committed by GitHub
parent 2c2505be06
commit 0ac54e40ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 628 additions and 178 deletions

View File

@ -308,11 +308,10 @@ describe('MetaMask', function () {
await driver.clickElement({ text: 'Hex', tag: 'button' });
await driver.delay(regularDelayMs);
const functionType = await driver.findElement(
'.confirm-page-container-content__function-type',
);
const functionTypeText = await functionType.getText();
assert(functionTypeText.match('Transfer'));
await driver.findElement({
tag: 'span',
text: 'Transfer',
});
const tokenAmount = await driver.findElement(
'.confirm-page-container-summary__title-text',
@ -320,17 +319,10 @@ describe('MetaMask', function () {
const tokenAmountText = await tokenAmount.getText();
assert.equal(tokenAmountText, '1 TST');
const confirmDataDiv = await driver.findElement(
'.confirm-page-container-content__data-box',
);
const confirmDataText = await confirmDataDiv.getText();
await driver.delay(regularDelayMs);
assert(
confirmDataText.match(
/0xa9059cbb0000000000000000000000002f318c334780961fb129d2a6c30d0763d9a5c97/u,
),
);
await driver.waitForSelector({
tag: 'p',
text: '0xa9059cbb0000000000000000000000002f318c334780961fb129d2a6c30d0763d9a5c97',
});
await driver.clickElement({ text: 'Details', tag: 'button' });
await driver.delay(regularDelayMs);

View File

@ -1,10 +1,12 @@
import React, { useMemo, useState } from 'react';
import { Provider } from 'react-redux';
import { render } from '@testing-library/react';
import { renderHook } from '@testing-library/react-hooks';
import userEvent from '@testing-library/user-event';
import { Router } from 'react-router-dom';
import PropTypes from 'prop-types';
import { createMemoryHistory } from 'history';
import configureStore from '../../ui/store/store';
import { I18nContext, LegacyI18nProvider } from '../../ui/contexts/i18n';
import { LegacyMetaMetricsProvider } from '../../ui/contexts/metametrics';
import { getMessage } from '../../ui/helpers/utils/i18n-helper';
@ -35,7 +37,7 @@ I18nProvider.defaultProps = {
children: undefined,
};
export function renderWithProvider(component, store, pathname = '/') {
const createProviderWrapper = (store, pathname = '/') => {
const history = createMemoryHistory({ initialEntries: [pathname] });
const Wrapper = ({ children }) =>
store ? (
@ -59,12 +61,29 @@ export function renderWithProvider(component, store, pathname = '/') {
Wrapper.propTypes = {
children: PropTypes.node,
};
return {
Wrapper,
history,
};
};
export function renderWithProvider(component, store, pathname = '/') {
const { history, Wrapper } = createProviderWrapper(store, pathname);
return {
...render(component, { wrapper: Wrapper }),
history,
};
}
export function renderHookWithProvider(hook, state, pathname = '/') {
const store = state ? configureStore(state) : undefined;
const { history, Wrapper } = createProviderWrapper(store, pathname);
return {
...renderHook(hook, { wrapper: Wrapper }),
history,
};
}
export function renderWithLocalization(component) {
const Wrapper = ({ children }) => (
<I18nProvider currentLocale="en" current={en} en={en}>

View File

@ -12,6 +12,7 @@
@import 'beta-header/index';
@import 'cancel-speedup-popover/index';
@import 'confirm-page-container/index';
@import 'confirm-data/index';
@import 'confirmation-warning-modal/index';
@import 'nfts-items/index';
@import 'nfts-tab/index';

View File

@ -0,0 +1,10 @@
import { Story, Canvas, ArgsTable } from '@storybook/addon-docs';
import { ConfirmData } from '.';
# Confirm Data
Confirm Data is used on confirmation screen to display transaction data.
<Canvas>
<Story id="components-app-ConfirmData--default-story" />
</Canvas>

View File

@ -0,0 +1,72 @@
import React from 'react';
import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
import {
Color,
TextVariant,
TEXT_TRANSFORM,
} from '../../../helpers/constants/design-system';
import { getKnownMethodData } from '../../../selectors';
import { useI18nContext } from '../../../hooks/useI18nContext';
import { useTransactionFunctionType } from '../../../hooks/useTransactionFunctionType';
import Box from '../../ui/box/box';
import Disclosure from '../../ui/disclosure';
import TransactionDecoding from '../transaction-decoding';
import { Text } from '../../component-library';
const ConfirmData = ({ txData, dataComponent }) => {
const t = useI18nContext();
const { txParams = {} } = txData;
const methodData = useSelector(
(state) => getKnownMethodData(state, txParams.data) || {},
);
const { functionType } = useTransactionFunctionType(txData);
if (dataComponent) {
return dataComponent;
}
if (!txParams.data) {
return null;
}
const { params } = methodData;
const functionParams = params?.length
? `(${params.map(({ type }) => type).join(', ')})`
: '';
return (
<Box color={Color.textAlternative} className="confirm-data" padding={4}>
<Box paddingBottom={3} paddingTop={2}>
<Text
as="span"
textTransform={TEXT_TRANSFORM.UPPERCASE}
variant={TextVariant.bodySm}
>
{`${t('functionType')}:`}
</Text>
<Text
as="span"
color={Color.textDefault}
paddingLeft={1}
textTransform={TEXT_TRANSFORM.CAPITALIZE}
variant={TextVariant.bodySmBold}
>
{`${functionType} ${functionParams}`}
</Text>
</Box>
<Disclosure>
<TransactionDecoding to={txParams?.to} inputData={txParams?.data} />
</Disclosure>
</Box>
);
};
ConfirmData.propTypes = {
txData: PropTypes.object,
dataComponent: PropTypes.element,
};
export default ConfirmData;

View File

@ -0,0 +1,46 @@
import React from 'react';
import README from './README.mdx';
import ConfirmData from './confirm-data';
export default {
title: 'Components/App/ConfirmData',
component: ConfirmData,
parameters: {
docs: {
page: README,
},
},
argTypes: {
txData: {
control: 'object',
},
dataHexComponent: {
control: 'element',
},
},
args: {
txData: {
txParams: {
data: '0xa9059cbb000000000000000000000000b19ac54efa18cc3a14a5b821bfec73d284bf0c5e0000000000000000000000000000000000000000000000003782dace9d900000',
},
origin: 'https://metamask.github.io',
type: 'transfer',
},
},
};
export const DefaultStory = (args) => {
return <ConfirmData {...args} />;
};
DefaultStory.storyName = 'Default';
export const DataComponentStory = (args) => {
return <ConfirmData {...args} />;
};
DataComponentStory.storyName = 'DataComponent';
DataComponentStory.args = {
dataComponent: <div>Any custom component passed in props</div>,
};

View File

@ -0,0 +1,58 @@
import React from 'react';
import mockState from '../../../../test/data/mock-state.json';
import { renderWithProvider } from '../../../../test/jest';
import configureStore from '../../../store/store';
import ConfirmData from './confirm-data';
jest.mock('../../../../shared/lib/fetch-with-cache');
describe('ConfirmData', () => {
const store = configureStore(mockState);
it('should render function type', async () => {
const { findByText } = renderWithProvider(
<ConfirmData
txData={{
txParams: {
data: '0x608060405234801',
},
origin: 'https://metamask.github.io',
type: 'transfer',
}}
/>,
store,
);
expect(await findByText('Transfer')).toBeInTheDocument();
});
it('should return null if transaction has no data', () => {
const { container } = renderWithProvider(
<ConfirmData
txData={{
txParams: {},
origin: 'https://metamask.github.io',
type: 'transfer',
}}
/>,
store,
);
expect(container.firstChild).toStrictEqual(null);
});
it('should render dataComponent if passed', () => {
const { getByText } = renderWithProvider(
<ConfirmData
txData={{
txParams: {},
origin: 'https://metamask.github.io',
type: 'transfer',
}}
dataComponent={<span>Data Component</span>}
/>,
store,
);
expect(getByText('Data Component')).toBeInTheDocument();
});
});

View File

@ -0,0 +1 @@
export { default as ConfirmData } from './confirm-data';

View File

@ -0,0 +1,5 @@
.confirm-data {
& > .disclosure {
margin-top: 0;
}
}

View File

@ -0,0 +1,10 @@
import { Story, Canvas, ArgsTable } from '@storybook/addon-docs';
import { ConfirmHexData } from '.';
# Confirm Data
Confirm Hex Data is used on confirmation screen to display transaction data.
<Canvas>
<Story id="components-app-ConfirmHexData--default-story" />
</Canvas>

View File

@ -0,0 +1,106 @@
import React from 'react';
import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
import { toBuffer } from '../../../../shared/modules/buffer-utils';
import { getKnownMethodData } from '../../../selectors';
import { useI18nContext } from '../../../hooks/useI18nContext';
import { useTransactionFunctionType } from '../../../hooks/useTransactionFunctionType';
import {
Color,
OVERFLOW_WRAP,
TextVariant,
TEXT_TRANSFORM,
} from '../../../helpers/constants/design-system';
import Box from '../../ui/box';
import { Text } from '../../component-library';
import CopyRawData from '../transaction-decoding/components/ui/copy-raw-data';
const ConfirmHexData = ({ txData, dataHexComponent }) => {
const t = useI18nContext();
const { txParams = {} } = txData;
const methodData = useSelector(
(state) => getKnownMethodData(state, txParams.data) || {},
);
const { functionType } = useTransactionFunctionType(txData);
if (dataHexComponent) {
return dataHexComponent;
}
if (!txParams.data || !txParams.to) {
return null;
}
const { params } = methodData;
const functionParams = params?.length
? `(${params.map(({ type }) => type).join(', ')})`
: '';
return (
<Box padding={4}>
<Box paddingBottom={3} paddingTop={2}>
<Text
as="span"
textTransform={TEXT_TRANSFORM.UPPERCASE}
variant={TextVariant.bodySm}
>
{`${t('functionType')}:`}
</Text>
<Text
as="span"
color={Color.textDefault}
paddingLeft={1}
textTransform={TEXT_TRANSFORM.CAPITALIZE}
variant={TextVariant.bodySmBold}
>
{`${functionType} ${functionParams}`}
</Text>
</Box>
{params && (
<Box backgroundColor={Color.backgroundAlternative} padding={4}>
<Text
as="h3"
paddingBottom={3}
paddingTop={2}
textTransform={TEXT_TRANSFORM.UPPERCASE}
variant={TextVariant.bodySm}
>
{`${t('parameters')}:`}
</Text>
<Text
overflowWrap={OVERFLOW_WRAP.BREAK_WORD}
variant={TextVariant.bodySm}
>
<pre>{JSON.stringify(params, null, 2)}</pre>
</Text>
</Box>
)}
<Text
as="h3"
paddingBottom={3}
paddingTop={2}
textTransform={TEXT_TRANSFORM.UPPERCASE}
variant={TextVariant.bodySm}
>
{`${t('hexData')}: ${toBuffer(txParams?.data).length} bytes`}
</Text>
<Text
backgroundColor={Color.backgroundAlternative}
overflowWrap={OVERFLOW_WRAP.BREAK_WORD}
padding={4}
variant={TextVariant.bodySm}
>
{txParams?.data}
</Text>
<CopyRawData data={txParams?.data} />
</Box>
);
};
ConfirmHexData.propTypes = {
txData: PropTypes.object,
dataHexComponent: PropTypes.element,
};
export default ConfirmHexData;

View File

@ -0,0 +1,47 @@
import React from 'react';
import README from './README.mdx';
import ConfirmHexData from './confirm-hexdata';
export default {
title: 'Components/App/ConfirmHexData',
component: ConfirmHexData,
parameters: {
docs: {
page: README,
},
},
argTypes: {
txData: {
control: 'object',
},
dataHexComponent: {
control: 'element',
},
},
args: {
txData: {
txParams: {
data: '0xa9059cbb000000000000000000000000b19ac54efa18cc3a14a5b821bfec73d284bf0c5e0000000000000000000000000000000000000000000000003782dace9d900000',
to: '0x0',
},
origin: 'https://metamask.github.io',
type: 'transfer',
},
},
};
export const DefaultStory = (args) => {
return <ConfirmHexData {...args} />;
};
DefaultStory.storyName = 'Default';
export const DataHexComponentStory = (args) => {
return <ConfirmHexData {...args} />;
};
DataHexComponentStory.storyName = 'DataHexComponent';
DataHexComponentStory.args = {
dataHexComponent: <div>Any custom component passed in props</div>,
};

View File

@ -0,0 +1,77 @@
import React from 'react';
import mockState from '../../../../test/data/mock-state.json';
import { renderWithProvider } from '../../../../test/jest';
import configureStore from '../../../store/store';
import ConfirmHexData from './confirm-hexdata';
jest.mock('../../../../shared/lib/fetch-with-cache');
describe('ConfirmHexData', () => {
const store = configureStore(mockState);
it('should render function type', async () => {
const { findByText } = renderWithProvider(
<ConfirmHexData
txData={{
txParams: {
to: '0x8eeee1781fd885ff5ddef7789486676961873d12',
data: '0x608060405234801',
},
origin: 'https://metamask.github.io',
type: 'transfer',
}}
/>,
store,
);
expect(await findByText('Transfer')).toBeInTheDocument();
});
it('should return null if transaction has no data', () => {
const { container } = renderWithProvider(
<ConfirmHexData
txData={{
txParams: {
data: '0x608060405234801',
},
origin: 'https://metamask.github.io',
type: 'transfer',
}}
/>,
store,
);
expect(container.firstChild).toStrictEqual(null);
});
it('should return null if transaction has no to address', () => {
const { container } = renderWithProvider(
<ConfirmHexData
txData={{
txParams: {
data: '0x608060405234801',
},
origin: 'https://metamask.github.io',
type: 'transfer',
}}
/>,
store,
);
expect(container.firstChild).toStrictEqual(null);
});
it('should render dataHexComponent if passed', () => {
const { getByText } = renderWithProvider(
<ConfirmHexData
txData={{
txParams: {},
origin: 'https://metamask.github.io',
type: 'transfer',
}}
dataHexComponent={<span>Data Hex Component</span>}
/>,
store,
);
expect(getByText('Data Hex Component')).toBeInTheDocument();
});
});

View File

@ -0,0 +1 @@
export { default as ConfirmHexData } from './confirm-hexdata';

View File

@ -21,45 +21,6 @@
padding: 0 24px;
}
&__data {
padding: 16px;
color: var(--color-text-alternative);
& > .disclosure {
margin-top: 0;
}
}
&__data-box {
@include H7;
background-color: var(--color-background-alternative);
padding: 12px;
word-wrap: break-word;
overflow-y: auto;
&-label {
@include H7;
text-transform: uppercase;
padding: 8px 0 12px;
}
}
&__data-field {
display: flex;
flex-direction: row;
&-label {
font-weight: 500;
padding-right: 16px;
}
&:not(:last-child) {
margin-bottom: 5px;
}
}
&__gas-fee {
border-bottom: 1px solid var(--color-border-muted);
@ -68,15 +29,6 @@
}
}
&__function-type {
@include H6;
font-weight: 500;
text-transform: capitalize;
color: var(--color-text-default);
padding-left: 5px;
}
&__tab {
@include H7;

View File

@ -0,0 +1,46 @@
import { useSelector } from 'react-redux';
import { ORIGIN_METAMASK } from '../../shared/constants/app';
import { TransactionType } from '../../shared/constants/transaction';
import { getKnownMethodData } from '../selectors';
import { getNativeCurrency } from '../ducks/metamask/metamask';
import { getTransactionTypeTitle } from '../helpers/utils/transactions.util';
import { getMethodName } from '../helpers/utils/metrics';
import { useI18nContext } from './useI18nContext';
export const useTransactionFunctionType = (txData = {}) => {
const t = useI18nContext();
const nativeCurrency = useSelector(getNativeCurrency);
const { txParams } = txData;
const methodData = useSelector(
(state) => getKnownMethodData(state, txParams?.data) || {},
);
if (!txParams) {
return {};
}
const isTokenApproval =
txData.type === TransactionType.tokenMethodSetApprovalForAll ||
txData.type === TransactionType.tokenMethodApprove;
const isContractInteraction =
txData.type === TransactionType.contractInteraction;
const isTransactionFromDapp =
(isTokenApproval || isContractInteraction) &&
txData.origin !== ORIGIN_METAMASK;
let functionType = isTransactionFromDapp
? getMethodName(methodData?.name)
: undefined;
if (!functionType) {
functionType = txData.type
? getTransactionTypeTitle(t, txData.type, nativeCurrency)
: t('contractInteraction');
}
return { functionType };
};

View File

@ -0,0 +1,48 @@
import { TransactionType } from '../../shared/constants/transaction';
import { renderHookWithProvider } from '../../test/lib/render-helpers';
import mockState from '../../test/data/mock-state.json';
import { useTransactionFunctionType } from './useTransactionFunctionType';
describe('useTransactionFunctionType', () => {
it('should return functionType depending on transaction data if present', () => {
const { result } = renderHookWithProvider(
() =>
useTransactionFunctionType({
txParams: {
data: '0x095ea7b30000000000000000000000002f318c334780961fb129d2a6c30d0763d9a5c9700000000000000000000000000000000000000000000000000000000000011170',
},
type: TransactionType.tokenMethodApprove,
}),
mockState,
);
expect(result.current.functionType).toStrictEqual('Approve spend limit');
});
it('should return functionType depending on transaction type if method not present in transaction data', () => {
const { result } = renderHookWithProvider(
() =>
useTransactionFunctionType({
txParams: {},
type: TransactionType.tokenMethodTransfer,
}),
mockState,
);
expect(result.current.functionType).toStrictEqual('Transfer');
});
it('should return functionType Contract interaction by default', () => {
const { result } = renderHookWithProvider(
() =>
useTransactionFunctionType({
txParams: {},
}),
mockState,
);
expect(result.current.functionType).toStrictEqual('Contract interaction');
});
it('should return undefined is txData is not present', () => {
const { result } = renderHookWithProvider(
() => useTransactionFunctionType(),
mockState,
);
expect(result.current.functionType).toBeUndefined();
});
});

View File

@ -2,6 +2,15 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ConfirmTransactionBase from '../confirm-transaction-base';
import { toBuffer } from '../../../shared/modules/buffer-utils';
import Box from '../../components/ui/box';
import { Text } from '../../components/component-library';
import {
Color,
DISPLAY,
OVERFLOW_WRAP,
TextVariant,
TEXT_TRANSFORM,
} from '../../helpers/constants/design-system';
export default class ConfirmDeployContract extends Component {
static contextTypes = {
@ -17,26 +26,55 @@ export default class ConfirmDeployContract extends Component {
const { txData: { origin, txParams: { data } = {} } = {} } = this.props;
return (
<div className="confirm-page-container-content__data">
<div className="confirm-page-container-content__data-box">
<div className="confirm-page-container-content__data-field">
<div className="confirm-page-container-content__data-field-label">
<Box color={Color.textAlternative} padding={4}>
<Box
backgroundColor={Color.backgroundAlternative}
padding={4}
variant={TextVariant.bodySm}
>
<Box display={DISPLAY.FLEX}>
<Text
backgroundColor={Color.backgroundAlternative}
marginBottom={1}
paddingRight={4}
variant={TextVariant.bodySmBold}
>
{`${t('origin')}:`}
</div>
<div>{origin}</div>
</div>
<div className="confirm-page-container-content__data-field">
<div className="confirm-page-container-content__data-field-label">
</Text>
<Text
overflowWrap={OVERFLOW_WRAP.BREAK_WORD}
variant={TextVariant.bodySm}
>
{origin}
</Text>
</Box>
<Box display={DISPLAY.FLEX}>
<Text
backgroundColor={Color.backgroundAlternative}
paddingRight={4}
variant={TextVariant.bodySmBold}
>
{`${t('bytes')}:`}
</div>
<div>{toBuffer(data).length}</div>
</div>
</div>
<div className="confirm-page-container-content__data-box-label">
{`${t('hexData')}:`}
</div>
<div className="confirm-page-container-content__data-box">{data}</div>
</div>
</Text>
<Text variant={TextVariant.bodySm}>{toBuffer(data).length}</Text>
</Box>
</Box>
<Text
as="h3"
paddingBottom={3}
paddingTop={2}
textTransform={TEXT_TRANSFORM.UPPERCASE}
variant={TextVariant.bodySm}
>{`${t('hexData')}:`}</Text>
<Text
backgroundColor={Color.backgroundAlternative}
overflowWrap={OVERFLOW_WRAP.BREAK_WORD}
padding={4}
variant={TextVariant.bodySm}
>
{data}
</Text>
</Box>
);
}

View File

@ -11,7 +11,6 @@ export default class ConfirmSendEther extends Component {
static propTypes = {
editTransaction: PropTypes.func,
history: PropTypes.object,
txParams: PropTypes.object,
};
handleEdit({ txData }) {
@ -21,18 +20,10 @@ export default class ConfirmSendEther extends Component {
});
}
shouldHideData() {
const { txParams = {} } = this.props;
return !txParams.data;
}
render() {
const hideData = this.shouldHideData();
return (
<ConfirmTransactionBase
actionKey="confirm"
hideData={hideData}
onEdit={(confirmTransactionData) =>
this.handleEdit(confirmTransactionData)
}

View File

@ -6,16 +6,6 @@ import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm
import { AssetType } from '../../../shared/constants/transaction';
import ConfirmSendEther from './confirm-send-ether.component';
const mapStateToProps = (state) => {
const {
confirmTransaction: { txData: { txParams } = {} },
} = state;
return {
txParams,
};
};
const mapDispatchToProps = (dispatch) => {
return {
editTransaction: async (txData) => {
@ -28,5 +18,5 @@ const mapDispatchToProps = (dispatch) => {
export default compose(
withRouter,
connect(mapStateToProps, mapDispatchToProps),
connect(undefined, mapDispatchToProps),
)(ConfirmSendEther);

View File

@ -1,7 +1,6 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ConfirmPageContainer from '../../components/app/confirm-page-container';
import TransactionDecoding from '../../components/app/transaction-decoding';
import { isBalanceSufficient } from '../send/send.utils';
import { DEFAULT_ROUTE } from '../../helpers/constants/routes';
import {
@ -11,12 +10,10 @@ import {
GAS_PRICE_FETCH_FAILURE_ERROR_KEY,
} from '../../helpers/constants/error-keys';
import UserPreferencedCurrencyDisplay from '../../components/app/user-preferenced-currency-display';
import CopyRawData from '../../components/app/transaction-decoding/components/ui/copy-raw-data';
import { PRIMARY, SECONDARY } from '../../helpers/constants/common';
import TextField from '../../components/ui/text-field';
import SimulationErrorMessage from '../../components/ui/simulation-error-message';
import Disclosure from '../../components/ui/disclosure';
import { EVENT } from '../../../shared/constants/metametrics';
import {
TransactionType,
@ -27,7 +24,6 @@ import {
getTransactionTypeTitle,
isLegacyTransaction,
} from '../../helpers/utils/transactions.util';
import { toBuffer } from '../../../shared/modules/buffer-utils';
import { TransactionModalContextProvider } from '../../contexts/transaction-modal';
import TransactionDetail from '../../components/app/transaction-detail/transaction-detail.component';
@ -60,6 +56,8 @@ import {
hexWEIToDecGWEI,
} from '../../../shared/modules/conversion.utils';
import TransactionAlerts from '../../components/app/transaction-alerts';
import { ConfirmHexData } from '../../components/app/confirm-hexdata';
import { ConfirmData } from '../../components/app/confirm-data';
const renderHeartBeatIfNotInTest = () =>
process.env.IN_TEST ? null : <LoadingHeartBeat />;
@ -110,7 +108,6 @@ export default class ConfirmTransactionBase extends Component {
contentComponent: PropTypes.node,
dataComponent: PropTypes.node,
dataHexComponent: PropTypes.node,
hideData: PropTypes.bool,
hideSubtitle: PropTypes.bool,
tokenAddress: PropTypes.string,
customTokenAmount: PropTypes.string,
@ -638,85 +635,27 @@ export default class ConfirmTransactionBase extends Component {
);
}
renderData(functionType) {
const { t } = this.context;
renderData() {
const { txData, dataComponent } = this.props;
const {
txData: { txParams } = {},
methodData: { params } = {},
hideData,
dataComponent,
} = this.props;
if (hideData) {
txParams: { data },
} = txData;
if (!data) {
return null;
}
const functionParams = params?.length
? `(${params.map(({ type }) => type).join(', ')})`
: '';
return (
dataComponent || (
<div className="confirm-page-container-content__data">
<div className="confirm-page-container-content__data-box-label">
{`${t('functionType')}:`}
<span className="confirm-page-container-content__function-type">
{`${functionType} ${functionParams}`}
</span>
</div>
<Disclosure>
<TransactionDecoding to={txParams?.to} inputData={txParams?.data} />
</Disclosure>
</div>
)
);
return <ConfirmData txData={txData} dataComponent={dataComponent} />;
}
renderDataHex(functionType) {
const { t } = this.context;
renderDataHex() {
const { txData, dataHexComponent } = this.props;
const {
txData: { txParams } = {},
methodData: { params } = {},
hideData,
dataHexComponent,
} = this.props;
if (hideData || !txParams.to) {
txParams: { data, to },
} = txData;
if (!data || !to) {
return null;
}
const functionParams = params?.length
? `(${params.map(({ type }) => type).join(', ')})`
: '';
return (
dataHexComponent || (
<div className="confirm-page-container-content__data">
<div className="confirm-page-container-content__data-box-label">
{`${t('functionType')}:`}
<span className="confirm-page-container-content__function-type">
{`${functionType} ${functionParams}`}
</span>
</div>
{params && (
<div className="confirm-page-container-content__data-box">
<div className="confirm-page-container-content__data-field-label">
{`${t('parameters')}:`}
</div>
<div>
<pre>{JSON.stringify(params, null, 2)}</pre>
</div>
</div>
)}
<div className="confirm-page-container-content__data-box-label">
{`${t('hexData')}: ${toBuffer(txParams?.data).length} bytes`}
</div>
<div className="confirm-page-container-content__data-box">
{txParams?.data}
</div>
<CopyRawData data={txParams?.data} />
</div>
)
<ConfirmHexData txData={txData} dataHexComponent={dataHexComponent} />
);
}
@ -1049,6 +988,7 @@ export default class ConfirmTransactionBase extends Component {
// component, which in turn returns this `<ConfirmTransactionBase />` component. We meed to prevent
// the user from editing the transaction in those cases.
// as this component is made functional, useTransactionFunctionType can be used to get functionType
const isTokenApproval =
txData.type === TransactionType.tokenMethodSetApprovalForAll ||
txData.type === TransactionType.tokenMethodApprove;