Skip to content

Commit

Permalink
Fix: show known addresses in decoded tx data (#2423)
Browse files Browse the repository at this point in the history
* Fix: show known addresses in decoded tx data

* Address book priority; add more known addresses

* Default avatar size
  • Loading branch information
katspaugh authored Aug 23, 2023
1 parent d65ffea commit 500d687
Show file tree
Hide file tree
Showing 11 changed files with 55 additions and 28 deletions.
4 changes: 3 additions & 1 deletion src/components/batch/BatchSidebar/BatchTxItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ const BatchTxItem = ({

<TxDataRow title="Created:">{timestamp ? dateString(timestamp) : null}</TxDataRow>

{txDetails.txData?.dataDecoded && <MethodDetails data={txDetails.txData.dataDecoded} />}
{txDetails.txData?.dataDecoded && (
<MethodDetails data={txDetails.txData.dataDecoded} addressInfoIndex={txDetails.txData.addressInfoIndex} />
)}
</div>
</AccordionDetails>
</Accordion>
Expand Down
12 changes: 9 additions & 3 deletions src/components/common/EthHashInfo/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,15 @@ describe('EthHashInfo', () => {

describe('name', () => {
it('renders a name by default', () => {
const { queryByText } = render(<EthHashInfo address={MOCK_SAFE_ADDRESS} name="Test" />)
const { queryByText } = render(<EthHashInfo address="0x1234" name="Test name" />)

expect(queryByText('Test')).toBeInTheDocument()
expect(queryByText('Test name')).toBeInTheDocument()
})

it('renders a name from the address book even if a name is passed', () => {
const { queryByText } = render(<EthHashInfo address={MOCK_SAFE_ADDRESS} name="Fallback name" />)

expect(queryByText('Address book name')).toBeInTheDocument()
})

it('renders a name from the address book', () => {
Expand All @@ -173,7 +179,7 @@ describe('EthHashInfo', () => {

expect(container.querySelector('.icon')).toHaveAttribute(
'style',
`background-image: url(${makeBlockie(MOCK_SAFE_ADDRESS)}); width: 44px; height: 44px;`,
`background-image: url(${makeBlockie(MOCK_SAFE_ADDRESS)}); width: 40px; height: 40px;`,
)
})

Expand Down
4 changes: 2 additions & 2 deletions src/components/common/EthHashInfo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import useSafeAddress from '@/hooks/useSafeAddress'

const EthHashInfo = ({
showName = true,
avatarSize = 44,
avatarSize = 40,
...props
}: EthHashInfoProps & { showName?: boolean }): ReactElement => {
const settings = useAppSelector(selectSettings)
Expand All @@ -21,7 +21,7 @@ const EthHashInfo = ({
const chain = useAppSelector((state) => selectChainById(state, props.chainId || currentChainId))
const addressBook = useAddressBook()
const link = chain ? getBlockExplorerLink(chain, props.address) : undefined
const name = showName ? props.name || addressBook[props.address] : undefined
const name = showName ? addressBook[props.address] || props.name : undefined
const showEmoji =
settings.addressEmojis &&
props.showAvatar !== false &&
Expand Down
19 changes: 14 additions & 5 deletions src/components/transactions/TxDetails/Summary/TxDataRow/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { ReactElement, ReactNode } from 'react'
import type { AddressEx } from '@safe-global/safe-gateway-typescript-sdk'
import CopyButton from '@/components/common/CopyButton'
import { HexEncodedData } from '@/components/transactions/HexEncodedData'
import { Typography } from '@mui/material'
import { hexDataLength } from 'ethers/lib/utils'
import type { ReactElement, ReactNode } from 'react'
import css from './styles.module.css'
import valueCss from '@/components/transactions/TxDetails/TxData/DecodedData/ValueArray/styles.module.css'
import EthHashInfo from '@/components/common/EthHashInfo'

type TxDataRowProps = {
Expand All @@ -27,15 +27,24 @@ export const generateDataRowValue = (
value?: string,
type?: 'hash' | 'rawData' | 'address' | 'bytes',
hasExplorer?: boolean,
addressInfo?: AddressEx,
): ReactElement | null => {
if (value == undefined) return null

switch (type) {
case 'hash':
case 'address':
const customAvatar = addressInfo?.logoUri

return (
<div className={valueCss.address}>
<EthHashInfo address={value} hasExplorer={hasExplorer} showAvatar={false} showCopyButton />
</div>
<EthHashInfo
address={value}
name={addressInfo?.name}
customAvatar={customAvatar}
showAvatar={!!customAvatar}
hasExplorer={hasExplorer}
showCopyButton
/>
)
case 'rawData':
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import type { ReactElement } from 'react'
import { generateDataRowValue, TxDataRow } from '@/components/transactions/TxDetails/Summary/TxDataRow'
import { isAddress, isArrayParameter, isByte } from '@/utils/transaction-guards'
import type { DataDecoded } from '@safe-global/safe-gateway-typescript-sdk'
import type { AddressEx, DataDecoded } from '@safe-global/safe-gateway-typescript-sdk'
import { Box, Typography } from '@mui/material'
import { Value } from '@/components/transactions/TxDetails/TxData/DecodedData/ValueArray'
import { camelCaseToSpaces } from '@/utils/formatters'

type MethodDetailsProps = {
data: DataDecoded
addressInfoIndex?: {
[key: string]: AddressEx
}
}

export const MethodDetails = ({ data }: MethodDetailsProps): ReactElement => {
export const MethodDetails = ({ data, addressInfoIndex }: MethodDetailsProps): ReactElement => {
return (
<Box>
<Typography variant="overline" fontWeight="bold" color="border.main">
Expand All @@ -20,13 +23,14 @@ export const MethodDetails = ({ data }: MethodDetailsProps): ReactElement => {
{data.parameters?.map((param, index) => {
const isArrayValueParam = isArrayParameter(param.type) || Array.isArray(param.value)
const inlineType = isAddress(param.type) ? 'address' : isByte(param.type) ? 'bytes' : undefined
const addressEx = typeof param.value === 'string' ? addressInfoIndex?.[param.value] : undefined

return (
<TxDataRow key={`${data.method}_param-${index}`} title={`${param.name}(${param.type}):`}>
{isArrayValueParam ? (
<Value method={data.method} type={param.type} value={param.value as string} />
) : (
generateDataRowValue(param.value as string, inlineType, true)
generateDataRowValue(param.value as string, inlineType, true, addressEx)
)}
</TxDataRow>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const SingleTxDecoded = ({

let details
if (tx.dataDecoded) {
details = <MethodDetails data={tx.dataDecoded} />
details = <MethodDetails data={tx.dataDecoded} addressInfoIndex={txData.addressInfoIndex} />
} else if (tx.data) {
// If data is not decoded in the backend response
details = <HexEncodedData title="Data (hex encoded)" hexData={tx.data} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const Value = ({ type, value, ...props }: ValueArrayProps): ReactElement
return <Value key={key} {...newProps} />
}
return (
<div key={`${address}_${key}`} className={css.address}>
<div key={`${address}_${key}`}>
<EthHashInfo address={address} showAvatar={false} shortAddress={false} showCopyButton hasExplorer />
</div>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
.nestedWrapper {
padding-left: 12px;
}

/* Reduce space between name/address for clarity between rows */
.address > div {
line-height: 1;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const DecodedData = ({ txData, txInfo }: Props): ReactElement | null => {

let decodedData = <></>
if (txData.dataDecoded) {
decodedData = <MethodDetails data={txData.dataDecoded} />
decodedData = <MethodDetails data={txData.dataDecoded} addressInfoIndex={txData.addressInfoIndex} />
} else if (txData.hexData) {
// When no decoded data, display raw hex data
decodedData = <HexEncodedData title="Data (hex encoded)" hexData={txData.hexData} />
Expand Down
18 changes: 13 additions & 5 deletions src/components/transactions/TxDetails/TxData/Transfer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,22 @@ const TransferTxInfoSummary = ({ txInfo, txStatus }: TransferTxInfoProps) => {
}

const TransferTxInfo = ({ txInfo, txStatus }: TransferTxInfoProps) => {
const address =
txInfo.direction.toUpperCase() === TransferDirection.INCOMING ? txInfo.sender.value : txInfo.recipient.value
const address = txInfo.direction.toUpperCase() === TransferDirection.INCOMING ? txInfo.sender : txInfo.recipient

return (
<Box>
<Box display="flex" flexDirection="column" gap={1}>
<TransferTxInfoSummary txInfo={txInfo} txStatus={txStatus} />

<Box display="flex" alignItems="center">
<EthHashInfo address={address} shortAddress={false} hasExplorer showCopyButton avatarSize={44}>
<TransferActions address={address} txInfo={txInfo} />
<EthHashInfo
address={address.value}
name={address.name}
customAvatar={address.logoUri}
shortAddress={false}
hasExplorer
showCopyButton
>
<TransferActions address={address.value} txInfo={txInfo} />
</EthHashInfo>
</Box>
</Box>
Expand Down
5 changes: 4 additions & 1 deletion src/components/tx/DecodedTx/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ const DecodedTx = ({
return getTransactionDetails(chainId, txId)
}, [chainId, txId])

const addressInfoIndex = txDetails?.txData?.addressInfoIndex

const onChangeExpand = (_: SyntheticEvent, expanded: boolean) => {
trackEvent({ ...MODALS_EVENTS.TX_DETAILS, label: expanded ? 'Open' : 'Close' })
}
Expand All @@ -68,6 +70,7 @@ const DecodedTx = ({
value: tx?.data.value,
operation: tx?.data.operation === OperationType.DelegateCall ? Operation.DELEGATE : Operation.CALL,
trustedDelegateCallTarget: false,
addressInfoIndex,
}}
compact
/>
Expand All @@ -83,7 +86,7 @@ const DecodedTx = ({

<AccordionDetails>
{decodedData ? (
<MethodDetails data={decodedData} />
<MethodDetails data={decodedData} addressInfoIndex={addressInfoIndex} />
) : decodedDataError ? (
<ErrorMessage error={decodedDataError}>Failed decoding transaction data</ErrorMessage>
) : (
Expand Down

0 comments on commit 500d687

Please sign in to comment.