diff --git a/package.json b/package.json
index 64889f6926..1d91b2450e 100644
--- a/package.json
+++ b/package.json
@@ -63,7 +63,7 @@
"@safe-global/safe-core-sdk": "^3.3.5",
"@safe-global/safe-core-sdk-utils": "^1.7.4",
"@safe-global/safe-ethers-lib": "^1.9.4",
- "@safe-global/safe-gateway-typescript-sdk": "3.21.0-alpha.3",
+ "@safe-global/safe-gateway-typescript-sdk": "3.21.1",
"@safe-global/safe-modules-deployments": "^1.2.0",
"@sentry/react": "^7.91.0",
"@spindl-xyz/attribution-lite": "^1.4.0",
diff --git a/src/components/common/NamedAddressInfo/index.test.tsx b/src/components/common/NamedAddressInfo/index.test.tsx
new file mode 100644
index 0000000000..9581303651
--- /dev/null
+++ b/src/components/common/NamedAddressInfo/index.test.tsx
@@ -0,0 +1,67 @@
+import { render, waitFor } from '@/tests/test-utils'
+import NamedAddressInfo from '.'
+import { faker } from '@faker-js/faker'
+import { getContract, type ChainInfo } from '@safe-global/safe-gateway-typescript-sdk'
+
+const mockChainInfo = {
+ chainId: '4',
+ shortName: 'tst',
+ blockExplorerUriTemplate: {
+ address: 'https://test.scan.eth/{address}',
+ api: 'https://test.scan.eth/',
+ txHash: 'https://test.scan.eth/{txHash}',
+ },
+} as ChainInfo
+
+jest.mock('@safe-global/safe-gateway-typescript-sdk', () => ({
+ ...jest.requireActual('@safe-global/safe-gateway-typescript-sdk'),
+ getContract: jest.fn(),
+ __esModule: true,
+}))
+
+describe('NamedAddressInfo', () => {
+ const getContractMock = getContract as jest.Mock
+ it('should not fetch contract info if name / logo is given', async () => {
+ const result = render(
+ ,
+ {
+ initialReduxState: {
+ chains: {
+ loading: false,
+ data: [mockChainInfo],
+ },
+ },
+ },
+ )
+
+ expect(result.getByText('TestAddressName')).toBeVisible()
+ expect(getContractMock).not.toHaveBeenCalled()
+ })
+
+ it('should fetch contract info if name / logo is not given', async () => {
+ const address = faker.finance.ethereumAddress()
+ getContractMock.mockResolvedValue({
+ displayName: 'Resolved Test Name',
+ name: 'ResolvedTestName',
+ logoUri: 'https://img-resolved.test.safe.global',
+ })
+ const result = render(, {
+ initialReduxState: {
+ chains: {
+ loading: false,
+ data: [mockChainInfo],
+ },
+ },
+ })
+
+ await waitFor(() => {
+ expect(result.getByText('Resolved Test Name')).toBeVisible()
+ })
+
+ expect(getContractMock).toHaveBeenCalledWith('4', address)
+ })
+})
diff --git a/src/components/common/NamedAddressInfo/index.tsx b/src/components/common/NamedAddressInfo/index.tsx
new file mode 100644
index 0000000000..7ebd1852e7
--- /dev/null
+++ b/src/components/common/NamedAddressInfo/index.tsx
@@ -0,0 +1,24 @@
+import useAsync from '@/hooks/useAsync'
+import useChainId from '@/hooks/useChainId'
+import { getContract } from '@safe-global/safe-gateway-typescript-sdk'
+import EthHashInfo from '../EthHashInfo'
+import type { EthHashInfoProps } from '../EthHashInfo/SrcEthHashInfo'
+
+const NamedAddressInfo = ({ address, name, customAvatar, ...props }: EthHashInfoProps) => {
+ const chainId = useChainId()
+ const [contract] = useAsync(
+ () => (!name && !customAvatar ? getContract(chainId, address) : undefined),
+ [address, chainId, name, customAvatar],
+ )
+
+ return (
+
+ )
+}
+
+export default NamedAddressInfo
diff --git a/src/components/transactions/TxDetails/TxData/DecodedData/SingleTxDecoded/index.tsx b/src/components/transactions/TxDetails/TxData/DecodedData/SingleTxDecoded/index.tsx
index d04b43ca1f..3aa6ea378c 100644
--- a/src/components/transactions/TxDetails/TxData/DecodedData/SingleTxDecoded/index.tsx
+++ b/src/components/transactions/TxDetails/TxData/DecodedData/SingleTxDecoded/index.tsx
@@ -13,7 +13,7 @@ import accordionCss from '@/styles/accordion.module.css'
import CodeIcon from '@mui/icons-material/Code'
import { DelegateCallWarning } from '@/components/transactions/Warning'
import { InfoDetails } from '@/components/transactions/InfoDetails'
-import EthHashInfo from '@/components/common/EthHashInfo'
+import NamedAddressInfo from '@/components/common/NamedAddressInfo'
type SingleTxDecodedProps = {
tx: InternalTransaction
@@ -74,7 +74,7 @@ export const SingleTxDecoded = ({
{isDelegateCall && }
{!isSpendingLimitMethod && (
- {
return (
<>
-
,
-
+
,
receiver && owner !== receiver ? (
<>
diff --git a/yarn.lock b/yarn.lock
index 985b249033..9cd3a71f0c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4336,10 +4336,10 @@
"@safe-global/safe-core-sdk-utils" "^1.7.4"
ethers "5.7.2"
-"@safe-global/safe-gateway-typescript-sdk@3.21.0-alpha.3":
- version "3.21.0-alpha.3"
- resolved "https://registry.yarnpkg.com/@safe-global/safe-gateway-typescript-sdk/-/safe-gateway-typescript-sdk-3.21.0-alpha.3.tgz#21e0f01e9fbc6cff504fa9c7f957c27877b3f982"
- integrity sha512-31xjB8VYUMsJ9akBd30YqHt4mreAwF5Kwbfa0LO0lE5L/DvfIwYiK/VB9uMse3LF/gVKKVOu9TIxKkaTsh9Y5w==
+"@safe-global/safe-gateway-typescript-sdk@3.21.1":
+ version "3.21.1"
+ resolved "https://registry.yarnpkg.com/@safe-global/safe-gateway-typescript-sdk/-/safe-gateway-typescript-sdk-3.21.1.tgz#984ec2d3d4211caf6a96786ab922b39909093538"
+ integrity sha512-7nakIjcRSs6781LkizYpIfXh1DYlkUDqyALciqz/BjFU/S97sVjZdL4cuKsG9NEarytE+f6p0Qbq2Bo1aocVUA==
"@safe-global/safe-gateway-typescript-sdk@^3.5.3":
version "3.19.0"