From c5a4eef074982682e30c892441e7345ac3e8b786 Mon Sep 17 00:00:00 2001 From: Max Alekseenko Date: Thu, 1 Aug 2024 20:06:50 +0200 Subject: [PATCH 1/3] display ens in tx interpretation --- .../tx/interpretation/TxInterpretation.tsx | 20 +++++++++++++++---- ui/tx/TxSubHeading.tsx | 10 +++++++++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/ui/shared/tx/interpretation/TxInterpretation.tsx b/ui/shared/tx/interpretation/TxInterpretation.tsx index 3f71f9f3e5..cc708fda36 100644 --- a/ui/shared/tx/interpretation/TxInterpretation.tsx +++ b/ui/shared/tx/interpretation/TxInterpretation.tsx @@ -23,12 +23,15 @@ import { extractVariables, getStringChunks, fillStringVariables, checkSummary, N type Props = { summary?: TxInterpretationSummary; isLoading?: boolean; + ensDomainNames?: Record; className?: string; } type NonStringTxInterpretationVariable = Exclude -const TxInterpretationElementByType = ({ variable }: { variable?: NonStringTxInterpretationVariable }) => { +const TxInterpretationElementByType = ( + { variable, ensDomainNames }: { variable?: NonStringTxInterpretationVariable; ensDomainNames?: Record }, +) => { const onAddressClick = React.useCallback(() => { mixpanel.logEvent(mixpanel.EventTypes.TX_INTERPRETATION_INTERACTION, { Type: 'Address click' }); }, []); @@ -48,10 +51,14 @@ const TxInterpretationElementByType = ({ variable }: { variable?: NonStringTxInt const { type, value } = variable; switch (type) { case 'address': { + let address = value; + if (!address.ens_domain_name && ensDomainNames?.[address.hash]) { + address = { ...address, ens_domain_name: ensDomainNames[address.hash] }; + } return ( { +const TxInterpretation = ({ summary, isLoading, ensDomainNames, className }: Props) => { if (!summary) { return null; } @@ -151,7 +158,12 @@ const TxInterpretation = ({ summary, isLoading, className }: Props) => { { index < variablesNames.length && ( variablesNames[index] === NATIVE_COIN_SYMBOL_VAR_NAME ? { currencyUnits.ether + ' ' } : - + ( + + ) ) } ); diff --git a/ui/tx/TxSubHeading.tsx b/ui/tx/TxSubHeading.tsx index dcfcf76837..4d41690bd5 100644 --- a/ui/tx/TxSubHeading.tsx +++ b/ui/tx/TxSubHeading.tsx @@ -59,14 +59,21 @@ const TxSubHeading = ({ hash, hasTag, txQuery }: Props) => { (hasNovesInterpretation && novesInterpretationQuery.data && !novesInterpretationQuery.isPlaceholderData) || (hasInternalInterpretation && !txInterpretationQuery.isPlaceholderData); + const ensDomainNames: Record = {}; + [ txQuery.data?.from, txQuery.data?.to ].forEach(data => { + if (data?.hash && data?.ens_domain_name) { + ensDomainNames[data.hash] = data.ens_domain_name; + } + }); + const content = (() => { if (hasNovesInterpretation && novesInterpretationQuery.data) { const novesSummary = createNovesSummaryObject(novesInterpretationQuery.data); - return ( @@ -77,6 +84,7 @@ const TxSubHeading = ({ hash, hasTag, txQuery }: Props) => { From 291210def0ac77df85b0ea35db46a269ac10bf73 Mon Sep 17 00:00:00 2001 From: Max Alekseenko Date: Tue, 6 Aug 2024 15:10:08 +0200 Subject: [PATCH 2/3] improve loading --- ui/tx/TxSubHeading.tsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ui/tx/TxSubHeading.tsx b/ui/tx/TxSubHeading.tsx index 4d41690bd5..68424a833a 100644 --- a/ui/tx/TxSubHeading.tsx +++ b/ui/tx/TxSubHeading.tsx @@ -72,7 +72,7 @@ const TxSubHeading = ({ hash, hasTag, txQuery }: Props) => { return ( { { } })(); + const isLoading = + txQuery.isPlaceholderData || + (hasNovesInterpretation && novesInterpretationQuery.isPlaceholderData) || + (hasInternalInterpretation && txInterpretationQuery.isPlaceholderData); + return ( { content } @@ -132,7 +137,7 @@ const TxSubHeading = ({ hash, hasTag, txQuery }: Props) => { gap={ 3 } mt={{ base: 3, lg: 0 }} > - { !hasTag && } + { !hasTag && } { (appActionData && hasAnyInterpretation) && ( ) } From 9fb08da342c5c0503ae583a1dbf5862b39014969 Mon Sep 17 00:00:00 2001 From: Max Alekseenko Date: Tue, 6 Aug 2024 17:03:01 +0200 Subject: [PATCH 3/3] add test --- ui/tx/TxSubHeading.pw.tsx | 20 ++++++++++++++++++ ...erpretation-and-recipient-ENS-domain-1.png | Bin 0 -> 9801 bytes 2 files changed, 20 insertions(+) create mode 100644 ui/tx/__screenshots__/TxSubHeading.pw.tsx_default_blockscout-provider-with-interpretation-and-recipient-ENS-domain-1.png diff --git a/ui/tx/TxSubHeading.pw.tsx b/ui/tx/TxSubHeading.pw.tsx index f6f6fedb89..bc85ff183a 100644 --- a/ui/tx/TxSubHeading.pw.tsx +++ b/ui/tx/TxSubHeading.pw.tsx @@ -1,6 +1,7 @@ import React from 'react'; import type { AddressMetadataInfo, AddressMetadataTagApi } from 'types/api/addressMetadata'; +import type { AddressParam } from 'types/api/addressParams'; import config from 'configs/app'; import { protocolTagWithMeta } from 'mocks/metadata/address'; @@ -64,6 +65,25 @@ test.describe('blockscout provider', () => { await expect(component).toHaveScreenshot(); }); + test('with interpretation and recipient ENS domain', async({ render, mockApiResponse }) => { + const txData = { + ...txMock.base, + to: { + ...txMock.base.to, + hash: (txInterpretation.data.summaries[0].summary_template_variables.to_address.value as AddressParam).hash, + ens_domain_name: 'duckduck.eth', + }, + }; + const txWithEnsQuery = { + data: txData, + isPlaceholderData: false, + isError: false, + } as TxQuery; + await mockApiResponse('tx_interpretation', txInterpretation, { pathParams: { hash } }); + const component = await render(); + await expect(component).toHaveScreenshot(); + }); + test('with interpretation and view all link +@mobile', async({ render, mockApiResponse }) => { await mockApiResponse( 'tx_interpretation', diff --git a/ui/tx/__screenshots__/TxSubHeading.pw.tsx_default_blockscout-provider-with-interpretation-and-recipient-ENS-domain-1.png b/ui/tx/__screenshots__/TxSubHeading.pw.tsx_default_blockscout-provider-with-interpretation-and-recipient-ENS-domain-1.png new file mode 100644 index 0000000000000000000000000000000000000000..bfc91a9f8cc685c06e0fbd1d7abb0bb5c20bd559 GIT binary patch literal 9801 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 literal 0 HcmV?d00001