diff --git a/test/e2e/metamask-ui.spec.js b/test/e2e/metamask-ui.spec.js index 8794d47bb958..c1fa2a4a1de4 100644 --- a/test/e2e/metamask-ui.spec.js +++ b/test/e2e/metamask-ui.spec.js @@ -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); diff --git a/test/lib/render-helpers.js b/test/lib/render-helpers.js index 36b907037f10..ff5e97006c4d 100644 --- a/test/lib/render-helpers.js +++ b/test/lib/render-helpers.js @@ -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 }) => ( diff --git a/ui/components/app/app-components.scss b/ui/components/app/app-components.scss index 7dea635f3a39..7cf61bbcf8f0 100644 --- a/ui/components/app/app-components.scss +++ b/ui/components/app/app-components.scss @@ -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'; diff --git a/ui/components/app/confirm-data/README.mdx b/ui/components/app/confirm-data/README.mdx new file mode 100644 index 000000000000..b7863325173d --- /dev/null +++ b/ui/components/app/confirm-data/README.mdx @@ -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. + + + + diff --git a/ui/components/app/confirm-data/confirm-data.js b/ui/components/app/confirm-data/confirm-data.js new file mode 100644 index 000000000000..a82e715101ae --- /dev/null +++ b/ui/components/app/confirm-data/confirm-data.js @@ -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 ( + + + + {`${t('functionType')}:`} + + + {`${functionType} ${functionParams}`} + + + + + + + ); +}; + +ConfirmData.propTypes = { + txData: PropTypes.object, + dataComponent: PropTypes.element, +}; + +export default ConfirmData; diff --git a/ui/components/app/confirm-data/confirm-data.stories.js b/ui/components/app/confirm-data/confirm-data.stories.js new file mode 100644 index 000000000000..89fa877e7f8c --- /dev/null +++ b/ui/components/app/confirm-data/confirm-data.stories.js @@ -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 ; +}; + +DefaultStory.storyName = 'Default'; + +export const DataComponentStory = (args) => { + return ; +}; + +DataComponentStory.storyName = 'DataComponent'; +DataComponentStory.args = { + dataComponent:
Any custom component passed in props
, +}; diff --git a/ui/components/app/confirm-data/confirm-data.test.js b/ui/components/app/confirm-data/confirm-data.test.js new file mode 100644 index 000000000000..72231956f300 --- /dev/null +++ b/ui/components/app/confirm-data/confirm-data.test.js @@ -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( + , + store, + ); + expect(await findByText('Transfer')).toBeInTheDocument(); + }); + + it('should return null if transaction has no data', () => { + const { container } = renderWithProvider( + , + store, + ); + expect(container.firstChild).toStrictEqual(null); + }); + + it('should render dataComponent if passed', () => { + const { getByText } = renderWithProvider( + Data Component} + />, + store, + ); + expect(getByText('Data Component')).toBeInTheDocument(); + }); +}); diff --git a/ui/components/app/confirm-data/index.js b/ui/components/app/confirm-data/index.js new file mode 100644 index 000000000000..f1870428db4d --- /dev/null +++ b/ui/components/app/confirm-data/index.js @@ -0,0 +1 @@ +export { default as ConfirmData } from './confirm-data'; diff --git a/ui/components/app/confirm-data/index.scss b/ui/components/app/confirm-data/index.scss new file mode 100644 index 000000000000..db19ef9e5f95 --- /dev/null +++ b/ui/components/app/confirm-data/index.scss @@ -0,0 +1,5 @@ +.confirm-data { + & > .disclosure { + margin-top: 0; + } +} diff --git a/ui/components/app/confirm-hexdata/README.mdx b/ui/components/app/confirm-hexdata/README.mdx new file mode 100644 index 000000000000..ac3847b96992 --- /dev/null +++ b/ui/components/app/confirm-hexdata/README.mdx @@ -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. + + + + diff --git a/ui/components/app/confirm-hexdata/confirm-hexdata.js b/ui/components/app/confirm-hexdata/confirm-hexdata.js new file mode 100644 index 000000000000..de76017edf89 --- /dev/null +++ b/ui/components/app/confirm-hexdata/confirm-hexdata.js @@ -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 ( + + + + {`${t('functionType')}:`} + + + {`${functionType} ${functionParams}`} + + + {params && ( + + + {`${t('parameters')}:`} + + +
{JSON.stringify(params, null, 2)}
+
+
+ )} + + {`${t('hexData')}: ${toBuffer(txParams?.data).length} bytes`} + + + {txParams?.data} + + +
+ ); +}; + +ConfirmHexData.propTypes = { + txData: PropTypes.object, + dataHexComponent: PropTypes.element, +}; + +export default ConfirmHexData; diff --git a/ui/components/app/confirm-hexdata/confirm-hexdata.stories.js b/ui/components/app/confirm-hexdata/confirm-hexdata.stories.js new file mode 100644 index 000000000000..6cb32621f090 --- /dev/null +++ b/ui/components/app/confirm-hexdata/confirm-hexdata.stories.js @@ -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 ; +}; + +DefaultStory.storyName = 'Default'; + +export const DataHexComponentStory = (args) => { + return ; +}; + +DataHexComponentStory.storyName = 'DataHexComponent'; +DataHexComponentStory.args = { + dataHexComponent:
Any custom component passed in props
, +}; diff --git a/ui/components/app/confirm-hexdata/confirm-hexdata.test.js b/ui/components/app/confirm-hexdata/confirm-hexdata.test.js new file mode 100644 index 000000000000..2c384b3088c1 --- /dev/null +++ b/ui/components/app/confirm-hexdata/confirm-hexdata.test.js @@ -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( + , + store, + ); + expect(await findByText('Transfer')).toBeInTheDocument(); + }); + + it('should return null if transaction has no data', () => { + const { container } = renderWithProvider( + , + store, + ); + expect(container.firstChild).toStrictEqual(null); + }); + + it('should return null if transaction has no to address', () => { + const { container } = renderWithProvider( + , + store, + ); + expect(container.firstChild).toStrictEqual(null); + }); + + it('should render dataHexComponent if passed', () => { + const { getByText } = renderWithProvider( + Data Hex Component} + />, + store, + ); + expect(getByText('Data Hex Component')).toBeInTheDocument(); + }); +}); diff --git a/ui/components/app/confirm-hexdata/index.js b/ui/components/app/confirm-hexdata/index.js new file mode 100644 index 000000000000..f2594d0eae02 --- /dev/null +++ b/ui/components/app/confirm-hexdata/index.js @@ -0,0 +1 @@ +export { default as ConfirmHexData } from './confirm-hexdata'; diff --git a/ui/components/app/confirm-page-container/confirm-page-container-content/index.scss b/ui/components/app/confirm-page-container/confirm-page-container-content/index.scss index 92395fbb1754..5b58b4a32392 100644 --- a/ui/components/app/confirm-page-container/confirm-page-container-content/index.scss +++ b/ui/components/app/confirm-page-container/confirm-page-container-content/index.scss @@ -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; diff --git a/ui/hooks/useTransactionFunctionType.js b/ui/hooks/useTransactionFunctionType.js new file mode 100644 index 000000000000..d973b724a3f2 --- /dev/null +++ b/ui/hooks/useTransactionFunctionType.js @@ -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 }; +}; diff --git a/ui/hooks/useTransactionFunctionType.test.js b/ui/hooks/useTransactionFunctionType.test.js new file mode 100644 index 000000000000..ec9f1e08ba78 --- /dev/null +++ b/ui/hooks/useTransactionFunctionType.test.js @@ -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(); + }); +}); diff --git a/ui/pages/confirm-deploy-contract/confirm-deploy-contract.component.js b/ui/pages/confirm-deploy-contract/confirm-deploy-contract.component.js index 63026bfaa22f..6c663db0be27 100644 --- a/ui/pages/confirm-deploy-contract/confirm-deploy-contract.component.js +++ b/ui/pages/confirm-deploy-contract/confirm-deploy-contract.component.js @@ -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 ( -
-
-
-
+ + + + {`${t('origin')}:`} -
-
{origin}
-
-
-
+ + + {origin} + + + + {`${t('bytes')}:`} -
-
{toBuffer(data).length}
-
-
-
- {`${t('hexData')}:`} -
-
{data}
-
+ + {toBuffer(data).length} + + + {`${t('hexData')}:`} + + {data} + + ); } diff --git a/ui/pages/confirm-send-ether/confirm-send-ether.component.js b/ui/pages/confirm-send-ether/confirm-send-ether.component.js index a1166fb03c07..02b113010fd8 100644 --- a/ui/pages/confirm-send-ether/confirm-send-ether.component.js +++ b/ui/pages/confirm-send-ether/confirm-send-ether.component.js @@ -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 ( this.handleEdit(confirmTransactionData) } diff --git a/ui/pages/confirm-send-ether/confirm-send-ether.container.js b/ui/pages/confirm-send-ether/confirm-send-ether.container.js index 83bd08126c61..9bca08091290 100644 --- a/ui/pages/confirm-send-ether/confirm-send-ether.container.js +++ b/ui/pages/confirm-send-ether/confirm-send-ether.container.js @@ -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); diff --git a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js index fdb8d8fba00a..dd025605d389 100644 --- a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -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 : ; @@ -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 || ( -
-
- {`${t('functionType')}:`} - - {`${functionType} ${functionParams}`} - -
- - - -
- ) - ); + return ; } - 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 || ( -
-
- {`${t('functionType')}:`} - - {`${functionType} ${functionParams}`} - -
- {params && ( -
-
- {`${t('parameters')}:`} -
-
-
{JSON.stringify(params, null, 2)}
-
-
- )} -
- {`${t('hexData')}: ${toBuffer(txParams?.data).length} bytes`} -
-
- {txParams?.data} -
- -
- ) + ); } @@ -1049,6 +988,7 @@ export default class ConfirmTransactionBase extends Component { // component, which in turn returns this `` 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;