Commit 077a79e6 authored by tom goriunov's avatar tom goriunov Committed by GitHub

Merge pull request #1125 from blockscout/address-entity

refactor icons for addresses and tokens
parents 1bd65cf3 835c9a54
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"> <svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.91 3H5.272C4.57 3 4 3.57 4 4.273v8.909h1.273v-8.91h7.636V3Zm1.908 2.545h-7c-.703 0-1.273.57-1.273 1.273v8.91c0 .702.57 1.272 1.273 1.272h7c.703 0 1.273-.57 1.273-1.273V6.818c0-.703-.57-1.273-1.273-1.273Zm0 10.182h-7V6.818h7v8.91Z"/> <g clip-path="url(#copy_svg__a)">
<path d="M8.597 3H1.228C.55 3 0 3.57 0 4.273v8.909h1.228v-8.91h7.369V3Zm1.842 2.545H3.684c-.678 0-1.228.57-1.228 1.273v8.91c0 .702.55 1.272 1.228 1.272h6.755c.678 0 1.228-.57 1.228-1.273V6.818c0-.703-.55-1.273-1.228-1.273Zm0 10.182H3.684V6.818h6.755v8.91Z" fill="currentColor" stroke="currentColor" stroke-width=".3"/>
</g>
<defs>
<clipPath id="copy_svg__a">
<path d="M0 0h20v20H0z"/>
</clipPath>
</defs>
</svg> </svg>
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"> <svg viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.61 25a2.262 2.262 0 0 1-1.615-.665l-6.318-6.318a2.265 2.265 0 0 1 0-3.23l8.456-8.457c.76-.76 2.138-1.33 3.183-1.33h5.416c1.235 0 2.28 1.045 2.28 2.28v5.416c0 1.045-.57 2.423-1.33 3.183l-8.456 8.456A2.262 2.262 0 0 1 13.61 25Zm3.706-18.575c-.665 0-1.71.428-2.185.903l-8.456 8.456a.832.832 0 0 0 0 1.187l6.318 6.319c.332.332.902.332 1.188 0l8.456-8.456c.475-.475.902-1.473.902-2.185V7.232a.852.852 0 0 0-.855-.855h-5.368v.047Z" stroke="currentColor" stroke-width=".5"/> <path d="M13.61 25a2.262 2.262 0 0 1-1.615-.665l-6.318-6.318a2.265 2.265 0 0 1 0-3.23l8.456-8.457c.76-.76 2.138-1.33 3.183-1.33h5.416c1.235 0 2.28 1.045 2.28 2.28v5.416c0 1.045-.57 2.423-1.33 3.183l-8.456 8.456A2.262 2.262 0 0 1 13.61 25Zm3.706-18.575c-.665 0-1.71.428-2.185.903l-8.456 8.456a.832.832 0 0 0 0 1.187l6.318 6.319c.332.332.902.332 1.188 0l8.456-8.456c.475-.475.902-1.473.902-2.185V7.232a.852.852 0 0 0-.855-.855h-5.368v.047Z" fill="currentColor" stroke="currentColor" stroke-width=".5"/>
<path d="M19.311 13.504a2.808 2.808 0 0 1-2.803-2.803 2.808 2.808 0 0 1 2.803-2.803 2.808 2.808 0 0 1 2.803 2.803 2.808 2.808 0 0 1-2.803 2.803Zm0-4.276a1.48 1.48 0 0 0-1.473 1.473 1.48 1.48 0 0 0 1.473 1.473 1.48 1.48 0 0 0 1.473-1.473 1.48 1.48 0 0 0-1.473-1.473Z" stroke="currentColor" stroke-width=".5"/> <path d="M19.311 13.504a2.808 2.808 0 0 1-2.803-2.803 2.808 2.808 0 0 1 2.803-2.803 2.808 2.808 0 0 1 2.803 2.803 2.808 2.808 0 0 1-2.803 2.803Zm0-4.276a1.48 1.48 0 0 0-1.473 1.473 1.48 1.48 0 0 0 1.473 1.473 1.48 1.48 0 0 0 1.473-1.473 1.48 1.48 0 0 0-1.473-1.473Z" fill="currentColor" stroke="currentColor" stroke-width=".5"/>
</svg> </svg>
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.094 19.3c-.58 0-1.116-.223-1.517-.625l-5.936-5.94a2.13 2.13 0 0 1 0-3.036L9.585 1.75c.714-.714 2.008-1.25 2.99-1.25h5.088c1.16 0 2.142.982 2.142 2.143v5.091c0 .983-.536 2.278-1.25 2.992l-7.944 7.949a2.125 2.125 0 0 1-1.517.625Zm3.481-17.46c-.625 0-1.607.402-2.053.848l-7.944 7.949a.782.782 0 0 0 0 1.116l5.936 5.94c.312.312.848.312 1.115 0l7.944-7.95c.447-.446.848-1.384.848-2.053V2.599a.8.8 0 0 0-.803-.804h-5.043v.045Z" fill="currentColor"/>
<path d="M14.45 8.493a2.639 2.639 0 0 1-2.634-2.634 2.639 2.639 0 0 1 2.633-2.635 2.639 2.639 0 0 1 2.634 2.635 2.639 2.639 0 0 1-2.633 2.634Zm0-4.019a1.39 1.39 0 0 0-1.384 1.385 1.39 1.39 0 0 0 1.383 1.384 1.39 1.39 0 0 0 1.384-1.384 1.39 1.39 0 0 0-1.383-1.385Z" fill="currentColor"/>
</svg>
...@@ -5,22 +5,18 @@ import React from 'react'; ...@@ -5,22 +5,18 @@ import React from 'react';
import type { Address as TAddress } from 'types/api/address'; import type { Address as TAddress } from 'types/api/address';
import { route } from 'nextjs-routes';
import type { ResourceError } from 'lib/api/resources'; import type { ResourceError } from 'lib/api/resources';
import useApiQuery from 'lib/api/useApiQuery'; import useApiQuery from 'lib/api/useApiQuery';
import getQueryParamString from 'lib/router/getQueryParamString'; import getQueryParamString from 'lib/router/getQueryParamString';
import { ADDRESS_COUNTERS } from 'stubs/address'; import { ADDRESS_COUNTERS } from 'stubs/address';
import AddressCounterItem from 'ui/address/details/AddressCounterItem'; import AddressCounterItem from 'ui/address/details/AddressCounterItem';
import AddressLink from 'ui/shared/address/AddressLink';
import AddressHeadingInfo from 'ui/shared/AddressHeadingInfo'; import AddressHeadingInfo from 'ui/shared/AddressHeadingInfo';
import DataFetchAlert from 'ui/shared/DataFetchAlert'; import DataFetchAlert from 'ui/shared/DataFetchAlert';
import DetailsInfoItem from 'ui/shared/DetailsInfoItem'; import DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsSponsoredItem from 'ui/shared/DetailsSponsoredItem'; import DetailsSponsoredItem from 'ui/shared/DetailsSponsoredItem';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import LinkInternal from 'ui/shared/LinkInternal';
import AddressBalance from './details/AddressBalance'; import AddressBalance from './details/AddressBalance';
import AddressNameInfo from './details/AddressNameInfo'; import AddressNameInfo from './details/AddressNameInfo';
...@@ -102,9 +98,13 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => { ...@@ -102,9 +98,13 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
hint="Transaction and address of creation" hint="Transaction and address of creation"
isLoading={ addressQuery.isPlaceholderData } isLoading={ addressQuery.isPlaceholderData }
> >
<AddressLink type="address" hash={ data.creator_address_hash } truncation="constant"/> <AddressEntity
address={{ hash: data.creator_address_hash }}
truncation="constant"
noIcon
/>
<Text whiteSpace="pre"> at txn </Text> <Text whiteSpace="pre"> at txn </Text>
<TxEntity hash={ data.creation_tx_hash } truncation="constant" noIcon/> <TxEntity hash={ data.creation_tx_hash } truncation="constant" noIcon noCopy={ false }/>
</DetailsInfoItem> </DetailsInfoItem>
) } ) }
{ data.is_contract && data.implementation_address && ( { data.is_contract && data.implementation_address && (
...@@ -113,14 +113,11 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => { ...@@ -113,14 +113,11 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
hint="Implementation address of the proxy contract" hint="Implementation address of the proxy contract"
columnGap={ 1 } columnGap={ 1 }
> >
<LinkInternal href={ route({ pathname: '/address/[hash]', query: { hash: data.implementation_address } }) } overflow="hidden"> <AddressEntity
{ data.implementation_name || <HashStringShortenDynamic hash={ data.implementation_address }/> } address={{ hash: data.implementation_address, name: data.implementation_name, is_contract: true }}
</LinkInternal> isLoading={ addressQuery.isPlaceholderData }
{ data.implementation_name && ( noIcon
<Text variant="secondary" overflow="hidden"> />
<HashStringShortenDynamic hash={ `(${ data.implementation_address })` }/>
</Text>
) }
</DetailsInfoItem> </DetailsInfoItem>
) } ) }
<AddressBalance data={ data } isLoading={ addressQuery.isPlaceholderData }/> <AddressBalance data={ data } isLoading={ addressQuery.isPlaceholderData }/>
......
...@@ -22,11 +22,11 @@ import TOKEN_TYPE from 'lib/token/tokenTypes'; ...@@ -22,11 +22,11 @@ import TOKEN_TYPE from 'lib/token/tokenTypes';
import { getTokenTransfersStub } from 'stubs/token'; import { getTokenTransfersStub } from 'stubs/token';
import ActionBar from 'ui/shared/ActionBar'; import ActionBar from 'ui/shared/ActionBar';
import DataListDisplay from 'ui/shared/DataListDisplay'; import DataListDisplay from 'ui/shared/DataListDisplay';
import * as TokenEntity from 'ui/shared/entities/token/TokenEntity';
import HashStringShorten from 'ui/shared/HashStringShorten'; import HashStringShorten from 'ui/shared/HashStringShorten';
import Pagination from 'ui/shared/pagination/Pagination'; import Pagination from 'ui/shared/pagination/Pagination';
import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages'; import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
import * as SocketNewItemsNotice from 'ui/shared/SocketNewItemsNotice'; import * as SocketNewItemsNotice from 'ui/shared/SocketNewItemsNotice';
import TokenLogo from 'ui/shared/TokenLogo';
import TokenTransferFilter from 'ui/shared/TokenTransfer/TokenTransferFilter'; import TokenTransferFilter from 'ui/shared/TokenTransfer/TokenTransferFilter';
import TokenTransferList from 'ui/shared/TokenTransfer/TokenTransferList'; import TokenTransferList from 'ui/shared/TokenTransfer/TokenTransferList';
import TokenTransferTable from 'ui/shared/TokenTransfer/TokenTransferTable'; import TokenTransferTable from 'ui/shared/TokenTransfer/TokenTransferTable';
...@@ -227,19 +227,20 @@ const AddressTokenTransfers = ({ scrollRef, overloadCount = OVERLOAD_COUNT }: Pr ...@@ -227,19 +227,20 @@ const AddressTokenTransfers = ({ scrollRef, overloadCount = OVERLOAD_COUNT }: Pr
address: tokenFilter || '', address: tokenFilter || '',
name: '', name: '',
icon_url: '', icon_url: '',
symbol: '',
}), [ tokenFilter ]); }), [ tokenFilter ]);
const tokenFilterComponent = tokenFilter && ( const tokenFilterComponent = tokenFilter && (
<Flex alignItems="center" flexWrap="wrap" mb={{ base: isActionBarHidden ? 3 : 6, lg: 0 }} mr={ 4 }> <Flex alignItems="center" flexWrap="wrap" mb={{ base: isActionBarHidden ? 3 : 6, lg: 0 }} mr={ 4 }>
<Text whiteSpace="nowrap" mr={ 2 } py={ 1 }>Filtered by token</Text> <Text whiteSpace="nowrap" mr={ 2 } py={ 1 }>Filtered by token</Text>
<Flex alignItems="center" py={ 1 }> <Flex alignItems="center" py={ 1 }>
<TokenLogo data={ tokenData } boxSize={ 6 } mr={ 2 }/> <TokenEntity.Icon token={ tokenData } isLoading={ isPlaceholderData }/>
{ isMobile ? <HashStringShorten hash={ tokenFilter }/> : tokenFilter } { isMobile ? <HashStringShorten hash={ tokenFilter }/> : tokenFilter }
<Tooltip label="Reset filter"> <Tooltip label="Reset filter">
<Flex> <Flex>
<Icon <Icon
as={ crossIcon } as={ crossIcon }
boxSize={ 6 } boxSize={ 5 }
ml={ 1 } ml={ 1 }
color={ resetTokenIconColor } color={ resetTokenIconColor }
cursor="pointer" cursor="pointer"
......
...@@ -47,6 +47,7 @@ base.describe('base view', () => { ...@@ -47,6 +47,7 @@ base.describe('base view', () => {
base.use({ viewport: configs.viewport.xl }); base.use({ viewport: configs.viewport.xl });
base('', async() => { base('', async() => {
base.slow();
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
}); });
......
...@@ -12,10 +12,8 @@ import dayjs from 'lib/date/dayjs'; ...@@ -12,10 +12,8 @@ import dayjs from 'lib/date/dayjs';
import useSocketChannel from 'lib/socket/useSocketChannel'; import useSocketChannel from 'lib/socket/useSocketChannel';
import useSocketMessage from 'lib/socket/useSocketMessage'; import useSocketMessage from 'lib/socket/useSocketMessage';
import * as stubs from 'stubs/contract'; import * as stubs from 'stubs/contract';
import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink';
import DataFetchAlert from 'ui/shared/DataFetchAlert'; import DataFetchAlert from 'ui/shared/DataFetchAlert';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import LinkExternal from 'ui/shared/LinkExternal'; import LinkExternal from 'ui/shared/LinkExternal';
import LinkInternal from 'ui/shared/LinkInternal'; import LinkInternal from 'ui/shared/LinkInternal';
import RawDataSnippet from 'ui/shared/RawDataSnippet'; import RawDataSnippet from 'ui/shared/RawDataSnippet';
...@@ -107,9 +105,14 @@ const ContractCode = ({ addressHash, noSocket }: Props) => { ...@@ -107,9 +105,14 @@ const ContractCode = ({ addressHash, noSocket }: Props) => {
const decoded = data.decoded_constructor_args const decoded = data.decoded_constructor_args
.map(([ value, { name, type } ], index) => { .map(([ value, { name, type } ], index) => {
const valueEl = type === 'address' ? const valueEl = type === 'address' ? (
<LinkInternal href={ route({ pathname: '/address/[hash]', query: { hash: value } }) }>{ value }</LinkInternal> : <AddressEntity
<span>{ value }</span>; address={{ hash: value }}
noIcon
display="inline-flex"
maxW="100%"
/>
) : <span>{ value }</span>;
return ( return (
<Box key={ index }> <Box key={ index }>
<span>Arg [{ index }] { name || '' } ({ type }): </span> <span>Arg [{ index }] { name || '' } ({ type }): </span>
...@@ -171,10 +174,12 @@ const ContractCode = ({ addressHash, noSocket }: Props) => { ...@@ -171,10 +174,12 @@ const ContractCode = ({ addressHash, noSocket }: Props) => {
{ !data?.is_verified && data?.verified_twin_address_hash && !data?.minimal_proxy_address_hash && ( { !data?.is_verified && data?.verified_twin_address_hash && !data?.minimal_proxy_address_hash && (
<Alert status="warning" whiteSpace="pre-wrap" flexWrap="wrap"> <Alert status="warning" whiteSpace="pre-wrap" flexWrap="wrap">
<span>Contract is not verified. However, we found a verified contract with the same bytecode in Blockscout DB </span> <span>Contract is not verified. However, we found a verified contract with the same bytecode in Blockscout DB </span>
<Address> <AddressEntity
<AddressIcon address={{ hash: data.verified_twin_address_hash, is_contract: true, implementation_name: null }}/> address={{ hash: data.verified_twin_address_hash, is_contract: true, implementation_name: null }}
<AddressLink type="address" hash={ data.verified_twin_address_hash } truncation="constant" ml={ 2 }/> truncation="constant"
</Address> fontSize="sm"
fontWeight="500"
/>
<chakra.span mt={ 1 }>All functions displayed below are from ABI of that contract. In order to verify current contract, proceed with </chakra.span> <chakra.span mt={ 1 }>All functions displayed below are from ABI of that contract. In order to verify current contract, proceed with </chakra.span>
<LinkInternal href={ route({ pathname: '/address/[hash]/contract-verification', query: { hash: addressHash || '' } }) }> <LinkInternal href={ route({ pathname: '/address/[hash]/contract-verification', query: { hash: addressHash || '' } }) }>
Verify & Publish Verify & Publish
...@@ -185,10 +190,13 @@ const ContractCode = ({ addressHash, noSocket }: Props) => { ...@@ -185,10 +190,13 @@ const ContractCode = ({ addressHash, noSocket }: Props) => {
{ data?.minimal_proxy_address_hash && ( { data?.minimal_proxy_address_hash && (
<Alert status="warning" flexWrap="wrap" whiteSpace="pre-wrap"> <Alert status="warning" flexWrap="wrap" whiteSpace="pre-wrap">
<span>Minimal Proxy Contract for </span> <span>Minimal Proxy Contract for </span>
<Address> <AddressEntity
<AddressIcon address={{ hash: data.minimal_proxy_address_hash, is_contract: true, implementation_name: null }}/> address={{ hash: data.minimal_proxy_address_hash, is_contract: true, implementation_name: null }}
<AddressLink type="address" hash={ data.minimal_proxy_address_hash } truncation="constant" ml={ 2 }/> truncation="constant"
</Address> fontSize="sm"
fontWeight="500"
noCopy
/>
<span>. </span> <span>. </span>
<Box> <Box>
<Link href="https://eips.ethereum.org/EIPS/eip-1167">EIP-1167</Link> <Link href="https://eips.ethereum.org/EIPS/eip-1167">EIP-1167</Link>
......
...@@ -4,8 +4,7 @@ import React from 'react'; ...@@ -4,8 +4,7 @@ import React from 'react';
import { useAccount, useDisconnect } from 'wagmi'; import { useAccount, useDisconnect } from 'wagmi';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import AddressIcon from 'ui/shared/address/AddressIcon'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import AddressLink from 'ui/shared/address/AddressLink';
const ContractConnectWallet = () => { const ContractConnectWallet = () => {
const { open, isOpen } = useWeb3Modal(); const { open, isOpen } = useWeb3Modal();
...@@ -47,8 +46,12 @@ const ContractConnectWallet = () => { ...@@ -47,8 +46,12 @@ const ContractConnectWallet = () => {
<Flex columnGap={ 3 } rowGap={ 3 } alignItems={{ base: 'flex-start', lg: 'center' }} flexDir={{ base: 'column', lg: 'row' }}> <Flex columnGap={ 3 } rowGap={ 3 } alignItems={{ base: 'flex-start', lg: 'center' }} flexDir={{ base: 'column', lg: 'row' }}>
<Flex alignItems="center"> <Flex alignItems="center">
<span>Connected to </span> <span>Connected to </span>
<AddressIcon address={{ hash: address, is_contract: false, implementation_name: null }} mx={ 2 }/> <AddressEntity
<AddressLink type="address" fontWeight={ 600 } hash={ address } truncation={ isMobile ? 'constant' : 'dynamic' }/> address={{ hash: address }}
truncation={ isMobile ? 'constant' : 'dynamic' }
fontWeight={ 600 }
ml={ 2 }
/>
</Flex> </Flex>
<Button onClick={ handleDisconnect } size="sm" variant="outline">Disconnect</Button> <Button onClick={ handleDisconnect } size="sm" variant="outline">Disconnect</Button>
</Flex> </Flex>
......
...@@ -24,10 +24,7 @@ import arrowIcon from 'icons/arrows/east-mini.svg'; ...@@ -24,10 +24,7 @@ import arrowIcon from 'icons/arrows/east-mini.svg';
import iconWarning from 'icons/status/warning.svg'; import iconWarning from 'icons/status/warning.svg';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import { apos } from 'lib/html-entities'; import { apos } from 'lib/html-entities';
import Address from 'ui/shared/address/Address'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
interface Props { interface Props {
className?: string; className?: string;
...@@ -38,11 +35,13 @@ const Item = (data: SmartContractExternalLibrary) => { ...@@ -38,11 +35,13 @@ const Item = (data: SmartContractExternalLibrary) => {
return ( return (
<Flex flexDir="column" py={ 2 } w="100%" rowGap={ 1 }> <Flex flexDir="column" py={ 2 } w="100%" rowGap={ 1 }>
<Box>{ data.name }</Box> <Box>{ data.name }</Box>
<Address> <AddressEntity
<AddressIcon address={{ hash: data.address_hash, is_contract: true, implementation_name: null }}/> address={{ hash: data.address_hash, is_contract: true, implementation_name: null }}
<AddressLink hash={ data.address_hash } type="address" ml={ 2 } fontWeight={ 500 } fontSize="sm" target="_blank" query={{ tab: 'contract' }}/> query={{ tab: 'contract' }}
<CopyToClipboard text={ data.address_hash }/> fontSize="sm"
</Address> fontWeight="500"
target="_blank"
/>
</Flex> </Flex>
); );
}; };
......
import { Flex } from '@chakra-ui/react';
import { useQueryClient } from '@tanstack/react-query'; import { useQueryClient } from '@tanstack/react-query';
import React from 'react'; import React from 'react';
import type { Address as TAddress } from 'types/api/address'; import type { Address as TAddress } from 'types/api/address';
import { getResourceKey } from 'lib/api/useApiQuery'; import { getResourceKey } from 'lib/api/useApiQuery';
import Address from 'ui/shared/address/Address'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import AddressLink from 'ui/shared/address/AddressLink';
interface Props { interface Props {
hash: string | undefined; hash: string | undefined;
...@@ -22,10 +22,10 @@ const ContractImplementationAddress = ({ hash }: Props) => { ...@@ -22,10 +22,10 @@ const ContractImplementationAddress = ({ hash }: Props) => {
} }
return ( return (
<Address whiteSpace="pre-wrap" flexWrap="wrap" mb={ 6 }> <Flex mb={ 6 } flexWrap="wrap" columnGap={ 2 }>
<span>Implementation address: </span> <span>Implementation address:</span>
<AddressLink type="address" hash={ data.implementation_address }/> <AddressEntity address={{ hash: data.implementation_address, is_contract: true }} noIcon noCopy/>
</Address> </Flex>
); );
}; };
......
...@@ -7,9 +7,7 @@ import type { SmartContractMethodOutput } from 'types/api/contract'; ...@@ -7,9 +7,7 @@ import type { SmartContractMethodOutput } from 'types/api/contract';
import config from 'configs/app'; import config from 'configs/app';
import { WEI } from 'lib/consts'; import { WEI } from 'lib/consts';
import Address from 'ui/shared/address/Address'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import AddressLink from 'ui/shared/address/AddressLink';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
function castValueToString(value: number | string | boolean | bigint | undefined): string { function castValueToString(value: number | string | boolean | bigint | undefined): string {
switch (typeof value) { switch (typeof value) {
...@@ -49,10 +47,10 @@ const ContractMethodStatic = ({ data }: Props) => { ...@@ -49,10 +47,10 @@ const ContractMethodStatic = ({ data }: Props) => {
const content = (() => { const content = (() => {
if (typeof data.value === 'string' && data.type === 'address' && data.value) { if (typeof data.value === 'string' && data.type === 'address' && data.value) {
return ( return (
<Address> <AddressEntity
<AddressLink type="address" hash={ data.value }/> address={{ hash: data.value }}
<CopyToClipboard text={ data.value }/> noIcon
</Address> />
); );
} }
......
...@@ -10,7 +10,6 @@ import useSocketChannel from 'lib/socket/useSocketChannel'; ...@@ -10,7 +10,6 @@ import useSocketChannel from 'lib/socket/useSocketChannel';
import useSocketMessage from 'lib/socket/useSocketMessage'; import useSocketMessage from 'lib/socket/useSocketMessage';
import CurrencyValue from 'ui/shared/CurrencyValue'; import CurrencyValue from 'ui/shared/CurrencyValue';
import DetailsInfoItem from 'ui/shared/DetailsInfoItem'; import DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import TokenLogo from 'ui/shared/TokenLogo';
interface Props { interface Props {
data: Pick<Address, 'block_number_balance_updated_at' | 'coin_balance' | 'hash' | 'exchange_rate'>; data: Pick<Address, 'block_number_balance_updated_at' | 'coin_balance' | 'hash' | 'exchange_rate'>;
...@@ -64,11 +63,6 @@ const AddressBalance = ({ data, isLoading }: Props) => { ...@@ -64,11 +63,6 @@ const AddressBalance = ({ data, isLoading }: Props) => {
handler: handleNewCoinBalanceMessage, handler: handleNewCoinBalanceMessage,
}); });
const tokenData = React.useMemo(() => ({
name: config.chain.currency.name || '',
icon_url: '',
}), [ ]);
return ( return (
<DetailsInfoItem <DetailsInfoItem
title="Balance" title="Balance"
...@@ -77,13 +71,6 @@ const AddressBalance = ({ data, isLoading }: Props) => { ...@@ -77,13 +71,6 @@ const AddressBalance = ({ data, isLoading }: Props) => {
alignItems="flex-start" alignItems="flex-start"
isLoading={ isLoading } isLoading={ isLoading }
> >
<TokenLogo
data={ tokenData }
boxSize={ 5 }
mr={ 2 }
fontSize="sm"
isLoading={ isLoading }
/>
<CurrencyValue <CurrencyValue
value={ data.coin_balance || '0' } value={ data.coin_balance || '0' }
exchangeRate={ data.exchange_rate } exchangeRate={ data.exchange_rate }
......
...@@ -4,7 +4,7 @@ import React from 'react'; ...@@ -4,7 +4,7 @@ import React from 'react';
import type { Address } from 'types/api/address'; import type { Address } from 'types/api/address';
import DetailsInfoItem from 'ui/shared/DetailsInfoItem'; import DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import TokenSnippet from 'ui/shared/TokenSnippet/TokenSnippet'; import TokenEntity from 'ui/shared/entities/token/TokenEntity';
interface Props { interface Props {
data: Pick<Address, 'name' | 'token' | 'is_contract'>; data: Pick<Address, 'name' | 'token' | 'is_contract'>;
...@@ -19,7 +19,12 @@ const AddressNameInfo = ({ data, isLoading }: Props) => { ...@@ -19,7 +19,12 @@ const AddressNameInfo = ({ data, isLoading }: Props) => {
hint="Token name and symbol" hint="Token name and symbol"
isLoading={ isLoading } isLoading={ isLoading }
> >
<TokenSnippet data={ data.token } isLoading={ isLoading } hideIcon/> <TokenEntity
token={ data.token }
isLoading={ isLoading }
noIcon
noCopy
/>
</DetailsInfoItem> </DetailsInfoItem>
); );
} }
......
...@@ -7,12 +7,9 @@ import type { InternalTransaction } from 'types/api/internalTransaction'; ...@@ -7,12 +7,9 @@ import type { InternalTransaction } from 'types/api/internalTransaction';
import config from 'configs/app'; import config from 'configs/app';
import eastArrowIcon from 'icons/arrows/east.svg'; import eastArrowIcon from 'icons/arrows/east.svg';
import dayjs from 'lib/date/dayjs'; import dayjs from 'lib/date/dayjs';
import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink';
import Icon from 'ui/shared/chakra/Icon'; import Icon from 'ui/shared/chakra/Icon';
import Tag from 'ui/shared/chakra/Tag'; import Tag from 'ui/shared/chakra/Tag';
import CopyToClipboard from 'ui/shared/CopyToClipboard'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import InOutTag from 'ui/shared/InOutTag'; import InOutTag from 'ui/shared/InOutTag';
...@@ -40,7 +37,7 @@ const TxInternalsListItem = ({ ...@@ -40,7 +37,7 @@ const TxInternalsListItem = ({
const toData = to ? to : createdContract; const toData = to ? to : createdContract;
const isOut = Boolean(currentAddress && currentAddress === from.hash); const isOut = Boolean(currentAddress && currentAddress === from.hash);
const isIn = Boolean(currentAddress && currentAddress === to?.hash); const isIn = Boolean(currentAddress && currentAddress === toData?.hash);
return ( return (
<ListItemMobile rowGap={ 3 }> <ListItemMobile rowGap={ 3 }>
...@@ -70,21 +67,25 @@ const TxInternalsListItem = ({ ...@@ -70,21 +67,25 @@ const TxInternalsListItem = ({
/> />
</HStack> </HStack>
<Box w="100%" display="flex" columnGap={ 3 }> <Box w="100%" display="flex" columnGap={ 3 }>
<Address width="calc((100% - 48px) / 2)"> <AddressEntity
<AddressIcon address={ from } isLoading={ isLoading }/> address={ from }
<AddressLink type="address" ml={ 2 } fontWeight="500" hash={ from.hash } isDisabled={ isOut } isLoading={ isLoading }/> isLoading={ isLoading }
{ isIn && <CopyToClipboard text={ from.hash } isLoading={ isLoading }/> } noLink={ isOut }
</Address> noCopy={ isOut }
width="calc((100% - 48px) / 2)"
/>
{ (isIn || isOut) ? { (isIn || isOut) ?
<InOutTag isIn={ isIn } isOut={ isOut } isLoading={ isLoading }/> : <InOutTag isIn={ isIn } isOut={ isOut } isLoading={ isLoading }/> :
<Icon as={ eastArrowIcon } boxSize={ 6 } color="gray.500" isLoading={ isLoading }/> <Icon as={ eastArrowIcon } boxSize={ 6 } color="gray.500" isLoading={ isLoading }/>
} }
{ toData && ( { toData && (
<Address width="calc((100% - 48px) / 2)"> <AddressEntity
<AddressIcon address={ toData } isLoading={ isLoading }/> address={ toData }
<AddressLink type="address" ml={ 2 } fontWeight="500" hash={ toData.hash } isDisabled={ isIn } isLoading={ isLoading }/> isLoading={ isLoading }
{ isOut && <CopyToClipboard text={ toData.hash } isLoading={ isLoading }/> } noLink={ isIn }
</Address> noCopy={ isIn }
width="calc((100% - 48px) / 2)"
/>
) } ) }
</Box> </Box>
<HStack spacing={ 3 }> <HStack spacing={ 3 }>
......
...@@ -7,12 +7,9 @@ import type { InternalTransaction } from 'types/api/internalTransaction'; ...@@ -7,12 +7,9 @@ import type { InternalTransaction } from 'types/api/internalTransaction';
import config from 'configs/app'; import config from 'configs/app';
import rightArrowIcon from 'icons/arrows/east.svg'; import rightArrowIcon from 'icons/arrows/east.svg';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement'; import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink';
import Icon from 'ui/shared/chakra/Icon'; import Icon from 'ui/shared/chakra/Icon';
import Tag from 'ui/shared/chakra/Tag'; import Tag from 'ui/shared/chakra/Tag';
import CopyToClipboard from 'ui/shared/CopyToClipboard'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import InOutTag from 'ui/shared/InOutTag'; import InOutTag from 'ui/shared/InOutTag';
...@@ -39,7 +36,7 @@ const AddressIntTxsTableItem = ({ ...@@ -39,7 +36,7 @@ const AddressIntTxsTableItem = ({
const toData = to ? to : createdContract; const toData = to ? to : createdContract;
const isOut = Boolean(currentAddress && currentAddress === from.hash); const isOut = Boolean(currentAddress && currentAddress === from.hash);
const isIn = Boolean(currentAddress && currentAddress === to?.hash); const isIn = Boolean(currentAddress && currentAddress === toData?.hash);
const timeAgo = useTimeAgoIncrement(timestamp, true); const timeAgo = useTimeAgoIncrement(timestamp, true);
...@@ -81,34 +78,27 @@ const AddressIntTxsTableItem = ({ ...@@ -81,34 +78,27 @@ const AddressIntTxsTableItem = ({
/> />
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<Address display="inline-flex" maxW="100%"> <AddressEntity
<AddressIcon address={ from } isLoading={ isLoading }/> address={ from }
<AddressLink isLoading={ isLoading }
type="address" noLink={ isOut }
ml={ 2 } noCopy={ isOut }
fontWeight="500" />
hash={ from.hash }
alias={ from.name }
flexGrow={ 1 }
isDisabled={ isOut }
isLoading={ isLoading }
/>
{ isIn && <CopyToClipboard text={ from.hash } isLoading={ isLoading }/> }
</Address>
</Td> </Td>
<Td px={ 0 } verticalAlign="middle"> <Td px={ 0 } verticalAlign="middle">
{ (isIn || isOut) ? { (isIn || isOut) ?
<InOutTag isIn={ isIn } isOut={ isOut } isLoading={ isLoading }/> : <InOutTag isIn={ isIn } isOut={ isOut } isLoading={ isLoading } w="100%"/> :
<Icon as={ rightArrowIcon } boxSize={ 6 } color="gray.500" isLoading={ isLoading }/> <Icon as={ rightArrowIcon } boxSize={ 6 } color="gray.500" isLoading={ isLoading }/>
} }
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
{ toData && ( { toData && (
<Address display="inline-flex" maxW="100%"> <AddressEntity
<AddressIcon address={ toData } isLoading={ isLoading }/> address={ toData }
<AddressLink type="address" hash={ toData.hash } alias={ toData.name } fontWeight="500" ml={ 2 } isDisabled={ isIn } isLoading={ isLoading }/> isLoading={ isLoading }
{ isOut && <CopyToClipboard text={ toData.hash } isLoading={ isLoading }/> } noLink={ isIn }
</Address> noCopy={ isIn }
/>
) } ) }
</Td> </Td>
<Td isNumeric verticalAlign="middle"> <Td isNumeric verticalAlign="middle">
......
...@@ -4,7 +4,7 @@ import React from 'react'; ...@@ -4,7 +4,7 @@ import React from 'react';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import TokenSnippet from 'ui/shared/TokenSnippet/TokenSnippet'; import TokenEntity from 'ui/shared/entities/token/TokenEntity';
import TruncatedValue from 'ui/shared/TruncatedValue'; import TruncatedValue from 'ui/shared/TruncatedValue';
import type { TokenEnhancedData } from '../utils/tokenUtils'; import type { TokenEnhancedData } from '../utils/tokenUtils';
...@@ -68,7 +68,13 @@ const TokenSelectItem = ({ data }: Props) => { ...@@ -68,7 +68,13 @@ const TokenSelectItem = ({ data }: Props) => {
href={ url } href={ url }
> >
<Flex alignItems="center" w="100%" overflow="hidden"> <Flex alignItems="center" w="100%" overflow="hidden">
<TokenSnippet data={ data.token } hideSymbol fontWeight={ 700 } isDisabled/> <TokenEntity
token={ data.token }
noSymbol
noCopy
noLink
fontWeight={ 700 }
/>
{ data.usd && <Text fontWeight={ 700 } ml="auto">${ data.usd.toFormat(2) }</Text> } { data.usd && <Text fontWeight={ 700 } ml="auto">${ data.usd.toFormat(2) }</Text> }
</Flex> </Flex>
<Flex alignItems="center" justifyContent="space-between" w="100%" whiteSpace="nowrap"> <Flex alignItems="center" justifyContent="space-between" w="100%" whiteSpace="nowrap">
......
...@@ -5,17 +5,14 @@ import type { AddressTokenBalance } from 'types/api/address'; ...@@ -5,17 +5,14 @@ import type { AddressTokenBalance } from 'types/api/address';
import getCurrencyValue from 'lib/getCurrencyValue'; import getCurrencyValue from 'lib/getCurrencyValue';
import AddressAddToWallet from 'ui/shared/address/AddressAddToWallet'; import AddressAddToWallet from 'ui/shared/address/AddressAddToWallet';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import CopyToClipboard from 'ui/shared/CopyToClipboard'; import TokenEntity from 'ui/shared/entities/token/TokenEntity';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile'; import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import TokenLogo from 'ui/shared/TokenLogo';
type Props = AddressTokenBalance & { isLoading: boolean}; type Props = AddressTokenBalance & { isLoading: boolean};
const ERC20TokensListItem = ({ token, value, isLoading }: Props) => { const ERC20TokensListItem = ({ token, value, isLoading }: Props) => {
const tokenString = [ token.name, token.symbol && `(${ token.symbol })` ].filter(Boolean).join(' ');
const { const {
valueStr: tokenQuantity, valueStr: tokenQuantity,
usd: tokenValue, usd: tokenValue,
...@@ -24,12 +21,21 @@ const ERC20TokensListItem = ({ token, value, isLoading }: Props) => { ...@@ -24,12 +21,21 @@ const ERC20TokensListItem = ({ token, value, isLoading }: Props) => {
return ( return (
<ListItemMobile rowGap={ 2 }> <ListItemMobile rowGap={ 2 }>
<Flex alignItems="center" width="100%"> <Flex alignItems="center" width="100%">
<TokenLogo data={ token } boxSize={ 6 } mr={ 2 } isLoading={ isLoading }/> <TokenEntity
<AddressLink fontWeight="700" hash={ token.address } type="token" alias={ tokenString } isLoading={ isLoading }/> token={ token }
isLoading={ isLoading }
noCopy
jointSymbol
fontWeight="700"
/>
</Flex> </Flex>
<Flex alignItems="center" pl={ 8 }> <Flex alignItems="center" pl={ 8 }>
<AddressLink hash={ token.address } type="address" truncation="constant" isLoading={ isLoading }/> <AddressEntity
<CopyToClipboard text={ token.address } isLoading={ isLoading }/> address={{ hash: token.address }}
isLoading={ isLoading }
truncation="constant"
noIcon
/>
<AddressAddToWallet token={ token } ml={ 2 } isLoading={ isLoading }/> <AddressAddToWallet token={ token } ml={ 2 } isLoading={ isLoading }/>
</Flex> </Flex>
{ token.exchange_rate !== undefined && token.exchange_rate !== null && ( { token.exchange_rate !== undefined && token.exchange_rate !== null && (
......
...@@ -5,9 +5,8 @@ import type { AddressTokenBalance } from 'types/api/address'; ...@@ -5,9 +5,8 @@ import type { AddressTokenBalance } from 'types/api/address';
import getCurrencyValue from 'lib/getCurrencyValue'; import getCurrencyValue from 'lib/getCurrencyValue';
import AddressAddToWallet from 'ui/shared/address/AddressAddToWallet'; import AddressAddToWallet from 'ui/shared/address/AddressAddToWallet';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import CopyToClipboard from 'ui/shared/CopyToClipboard'; import TokenEntity from 'ui/shared/entities/token/TokenEntity';
import TokenLogo from 'ui/shared/TokenLogo';
type Props = AddressTokenBalance & { isLoading: boolean }; type Props = AddressTokenBalance & { isLoading: boolean };
...@@ -17,8 +16,6 @@ const ERC20TokensTableItem = ({ ...@@ -17,8 +16,6 @@ const ERC20TokensTableItem = ({
isLoading, isLoading,
}: Props) => { }: Props) => {
const tokenString = [ token.name, token.symbol && `(${ token.symbol })` ].filter(Boolean).join(' ');
const { const {
valueStr: tokenQuantity, valueStr: tokenQuantity,
usd: tokenValue, usd: tokenValue,
...@@ -27,17 +24,21 @@ const ERC20TokensTableItem = ({ ...@@ -27,17 +24,21 @@ const ERC20TokensTableItem = ({
return ( return (
<Tr> <Tr>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<Flex alignItems="center"> <TokenEntity
<TokenLogo data={ token } boxSize={ 6 } mr={ 2 } isLoading={ isLoading }/> token={ token }
<AddressLink fontWeight="700" hash={ token.address } type="token" alias={ tokenString } isLoading={ isLoading }/> isLoading={ isLoading }
</Flex> noCopy
jointSymbol
fontWeight="700"
/>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<Flex alignItems="center" width="150px" justifyContent="space-between"> <Flex alignItems="center" width="150px" justifyContent="space-between">
<Flex alignItems="center"> <AddressEntity
<AddressLink hash={ token.address } type="address" truncation="constant" isLoading={ isLoading }/> address={{ hash: token.address }}
<CopyToClipboard text={ token.address } isLoading={ isLoading }/> isLoading={ isLoading }
</Flex> noIcon
/>
<AddressAddToWallet token={ token } ml={ 4 } isLoading={ isLoading }/> <AddressAddToWallet token={ token } ml={ 4 } isLoading={ isLoading }/>
</Flex> </Flex>
</Td> </Td>
......
...@@ -5,10 +5,9 @@ import React from 'react'; ...@@ -5,10 +5,9 @@ import React from 'react';
import type { AddressTokenBalance } from 'types/api/address'; import type { AddressTokenBalance } from 'types/api/address';
import AddressAddToWallet from 'ui/shared/address/AddressAddToWallet'; import AddressAddToWallet from 'ui/shared/address/AddressAddToWallet';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import CopyToClipboard from 'ui/shared/CopyToClipboard'; import TokenEntityWithAddressFilter from 'ui/shared/entities/token/TokenEntityWithAddressFilter';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile'; import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import TokenLogo from 'ui/shared/TokenLogo';
type Props = AddressTokenBalance & { isLoading: boolean}; type Props = AddressTokenBalance & { isLoading: boolean};
...@@ -17,17 +16,23 @@ const ERC721TokensListItem = ({ token, value, isLoading }: Props) => { ...@@ -17,17 +16,23 @@ const ERC721TokensListItem = ({ token, value, isLoading }: Props) => {
const hash = router.query.hash?.toString() || ''; const hash = router.query.hash?.toString() || '';
const tokenString = [ token.name, token.symbol && `(${ token.symbol })` ].filter(Boolean).join(' ');
return ( return (
<ListItemMobile rowGap={ 2 }> <ListItemMobile rowGap={ 2 }>
<Flex alignItems="center" width="100%"> <TokenEntityWithAddressFilter
<TokenLogo data={ token } boxSize={ 6 } mr={ 2 } isLoading={ isLoading }/> token={ token }
<AddressLink fontWeight="700" hash={ hash } tokenHash={ token.address } type="address_token" alias={ tokenString } isLoading={ isLoading }/> isLoading={ isLoading }
</Flex> addressHash={ hash }
noCopy
jointSymbol
fontWeight={ 700 }
/>
<Flex alignItems="center" pl={ 8 }> <Flex alignItems="center" pl={ 8 }>
<AddressLink hash={ token.address } type="address" truncation="constant" isLoading={ isLoading }/> <AddressEntity
<CopyToClipboard text={ token.address } isLoading={ isLoading }/> address={{ hash: token.address }}
isLoading={ isLoading }
truncation="constant"
noIcon
/>
<AddressAddToWallet token={ token } ml={ 2 } isLoading={ isLoading }/> <AddressAddToWallet token={ token } ml={ 2 } isLoading={ isLoading }/>
</Flex> </Flex>
<HStack spacing={ 3 }> <HStack spacing={ 3 }>
......
...@@ -5,9 +5,8 @@ import React from 'react'; ...@@ -5,9 +5,8 @@ import React from 'react';
import type { AddressTokenBalance } from 'types/api/address'; import type { AddressTokenBalance } from 'types/api/address';
import AddressAddToWallet from 'ui/shared/address/AddressAddToWallet'; import AddressAddToWallet from 'ui/shared/address/AddressAddToWallet';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import CopyToClipboard from 'ui/shared/CopyToClipboard'; import TokenEntityWithAddressFilter from 'ui/shared/entities/token/TokenEntityWithAddressFilter';
import TokenLogo from 'ui/shared/TokenLogo';
type Props = AddressTokenBalance & { isLoading: boolean}; type Props = AddressTokenBalance & { isLoading: boolean};
...@@ -19,22 +18,26 @@ const ERC721TokensTableItem = ({ ...@@ -19,22 +18,26 @@ const ERC721TokensTableItem = ({
const router = useRouter(); const router = useRouter();
const hash = router.query.hash?.toString() || ''; const hash = router.query.hash?.toString() || '';
const tokenString = [ token.name, token.symbol && `(${ token.symbol })` ].filter(Boolean).join(' ');
return ( return (
<Tr> <Tr>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<Flex alignItems="center"> <TokenEntityWithAddressFilter
<TokenLogo data={ token } boxSize={ 6 } mr={ 2 } isLoading={ isLoading }/> token={ token }
<AddressLink fontWeight="700" hash={ hash } tokenHash={ token.address } type="address_token" alias={ tokenString } isLoading={ isLoading }/> addressHash={ hash }
</Flex> isLoading={ isLoading }
noCopy
jointSymbol
fontWeight="700"
/>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<Flex alignItems="center" width="150px" justifyContent="space-between"> <Flex alignItems="center" width="150px" justifyContent="space-between">
<Flex alignItems="center"> <AddressEntity
<AddressLink hash={ token.address } type="address" truncation="dynamic" isLoading={ isLoading }/> address={{ hash: token.address }}
<CopyToClipboard text={ token.address } isLoading={ isLoading }/> isLoading={ isLoading }
</Flex> noIcon
/>
<AddressAddToWallet token={ token } ml={ 4 } isLoading={ isLoading }/> <AddressAddToWallet token={ token } ml={ 4 } isLoading={ isLoading }/>
</Flex> </Flex>
</Td> </Td>
......
...@@ -5,10 +5,9 @@ import type { AddressTokenBalance } from 'types/api/address'; ...@@ -5,10 +5,9 @@ import type { AddressTokenBalance } from 'types/api/address';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import TokenEntity from 'ui/shared/entities/token/TokenEntity';
import NftMedia from 'ui/shared/nft/NftMedia'; import NftMedia from 'ui/shared/nft/NftMedia';
import TokenLogo from 'ui/shared/TokenLogo';
import TruncatedTextTooltip from 'ui/shared/TruncatedTextTooltip'; import TruncatedTextTooltip from 'ui/shared/TruncatedTextTooltip';
import TruncatedValue from 'ui/shared/TruncatedValue';
type Props = AddressTokenBalance & { isLoading: boolean }; type Props = AddressTokenBalance & { isLoading: boolean };
...@@ -53,12 +52,12 @@ const NFTItem = ({ token, token_id: tokenId, token_instance: tokenInstance, isLo ...@@ -53,12 +52,12 @@ const NFTItem = ({ token, token_id: tokenId, token_instance: tokenInstance, isLo
</TruncatedTextTooltip> </TruncatedTextTooltip>
</Flex> </Flex>
) } ) }
{ token.name && ( <TokenEntity
<Flex alignItems="center"> token={ token }
<TokenLogo data={ token } boxSize={ 6 } ml={ 1 } mr={ 1 } isLoading={ isLoading }/> isLoading={ isLoading }
<TruncatedValue isLoading={ isLoading } value={ token.name } color="text_secondary"/> noCopy
</Flex> noSymbol
) } />
</LinkBox> </LinkBox>
); );
}; };
......
...@@ -5,11 +5,8 @@ import React from 'react'; ...@@ -5,11 +5,8 @@ import React from 'react';
import type { AddressesItem } from 'types/api/addresses'; import type { AddressesItem } from 'types/api/addresses';
import config from 'configs/app'; import config from 'configs/app';
import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink';
import Tag from 'ui/shared/chakra/Tag'; import Tag from 'ui/shared/chakra/Tag';
import CopyToClipboard from 'ui/shared/CopyToClipboard'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile'; import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
type Props = { type Props = {
...@@ -31,19 +28,12 @@ const AddressesListItem = ({ ...@@ -31,19 +28,12 @@ const AddressesListItem = ({
return ( return (
<ListItemMobile rowGap={ 3 }> <ListItemMobile rowGap={ 3 }>
<Flex alignItems="center" justifyContent="space-between" w="100%"> <Flex alignItems="center" justifyContent="space-between" w="100%">
<Address maxW="100%" mr={ 8 }> <AddressEntity
<AddressIcon address={ item } mr={ 2 } isLoading={ isLoading }/> address={ item }
<AddressLink isLoading={ isLoading }
fontWeight={ 700 } fontWeight={ 700 }
flexGrow={ 1 } mr={ 2 }
w="calc(100% - 32px)" />
hash={ item.hash }
alias={ item.name }
type="address"
isLoading={ isLoading }
/>
<CopyToClipboard text={ item.hash } isLoading={ isLoading }/>
</Address>
<Skeleton isLoaded={ !isLoading } fontSize="sm" ml="auto" minW={ 6 } color="text_secondary"> <Skeleton isLoaded={ !isLoading } fontSize="sm" ml="auto" minW={ 6 } color="text_secondary">
<span>{ index }</span> <span>{ index }</span>
</Skeleton> </Skeleton>
......
...@@ -5,11 +5,8 @@ import React from 'react'; ...@@ -5,11 +5,8 @@ import React from 'react';
import type { AddressesItem } from 'types/api/addresses'; import type { AddressesItem } from 'types/api/addresses';
import config from 'configs/app'; import config from 'configs/app';
import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink';
import Tag from 'ui/shared/chakra/Tag'; import Tag from 'ui/shared/chakra/Tag';
import CopyToClipboard from 'ui/shared/CopyToClipboard'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
type Props = { type Props = {
item: AddressesItem; item: AddressesItem;
...@@ -37,20 +34,12 @@ const AddressesTableItem = ({ ...@@ -37,20 +34,12 @@ const AddressesTableItem = ({
{ index } { index }
</Skeleton> </Skeleton>
</Td> </Td>
<Td> <Td verticalAlign="middle">
<Address display="inline-flex" maxW="100%"> <AddressEntity
<AddressIcon address={ item } mr={ 2 } isLoading={ isLoading }/> address={ item }
<AddressLink isLoading={ isLoading }
fontWeight={ 700 } fontWeight={ 700 }
flexGrow={ 1 } />
w="calc(100% - 32px)"
hash={ item.hash }
alias={ item.name }
type="address"
isLoading={ isLoading }
/>
<CopyToClipboard text={ item.hash } isLoading={ isLoading }/>
</Address>
</Td> </Td>
<Td pl={ 10 }> <Td pl={ 10 }>
{ item.public_tags && item.public_tags.length ? item.public_tags.map(tag => ( { item.public_tags && item.public_tags.length ? item.public_tags.map(tag => (
......
...@@ -20,11 +20,11 @@ import dayjs from 'lib/date/dayjs'; ...@@ -20,11 +20,11 @@ import dayjs from 'lib/date/dayjs';
import { space } from 'lib/html-entities'; import { space } from 'lib/html-entities';
import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle'; import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle';
import getQueryParamString from 'lib/router/getQueryParamString'; import getQueryParamString from 'lib/router/getQueryParamString';
import AddressLink from 'ui/shared/address/AddressLink';
import Icon from 'ui/shared/chakra/Icon'; import Icon from 'ui/shared/chakra/Icon';
import CopyToClipboard from 'ui/shared/CopyToClipboard'; import CopyToClipboard from 'ui/shared/CopyToClipboard';
import DataFetchAlert from 'ui/shared/DataFetchAlert'; import DataFetchAlert from 'ui/shared/DataFetchAlert';
import DetailsInfoItem from 'ui/shared/DetailsInfoItem'; import DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import GasUsedToTargetRatio from 'ui/shared/GasUsedToTargetRatio'; import GasUsedToTargetRatio from 'ui/shared/GasUsedToTargetRatio';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic'; import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import LinkInternal from 'ui/shared/LinkInternal'; import LinkInternal from 'ui/shared/LinkInternal';
...@@ -206,8 +206,10 @@ const BlockDetails = ({ query }: Props) => { ...@@ -206,8 +206,10 @@ const BlockDetails = ({ query }: Props) => {
columnGap={ 1 } columnGap={ 1 }
isLoading={ isPlaceholderData } isLoading={ isPlaceholderData }
> >
<AddressLink type="address" hash={ data.miner.hash } isLoading={ isPlaceholderData }/> <AddressEntity
{ data.miner.name && <Text>{ `(${ capitalize(validatorTitle) }: ${ data.miner.name })` }</Text> } address={ data.miner }
isLoading={ isPlaceholderData }
/>
{ /* api doesn't return the block processing time yet */ } { /* api doesn't return the block processing time yet */ }
{ /* <Text>{ dayjs.duration(block.minedIn, 'second').humanize(true) }</Text> */ } { /* <Text>{ dayjs.duration(block.minedIn, 'second').humanize(true) }</Text> */ }
</DetailsInfoItem> </DetailsInfoItem>
......
...@@ -13,8 +13,8 @@ import getBlockTotalReward from 'lib/block/getBlockTotalReward'; ...@@ -13,8 +13,8 @@ import getBlockTotalReward from 'lib/block/getBlockTotalReward';
import { WEI } from 'lib/consts'; import { WEI } from 'lib/consts';
import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle'; import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle';
import BlockTimestamp from 'ui/blocks/BlockTimestamp'; import BlockTimestamp from 'ui/blocks/BlockTimestamp';
import AddressLink from 'ui/shared/address/AddressLink';
import Icon from 'ui/shared/chakra/Icon'; import Icon from 'ui/shared/chakra/Icon';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import GasUsedToTargetRatio from 'ui/shared/GasUsedToTargetRatio'; import GasUsedToTargetRatio from 'ui/shared/GasUsedToTargetRatio';
import LinkInternal from 'ui/shared/LinkInternal'; import LinkInternal from 'ui/shared/LinkInternal';
...@@ -55,9 +55,12 @@ const BlocksListItem = ({ data, isLoading, enableTimeIncrement }: Props) => { ...@@ -55,9 +55,12 @@ const BlocksListItem = ({ data, isLoading, enableTimeIncrement }: Props) => {
<span>{ data.size.toLocaleString() } bytes</span> <span>{ data.size.toLocaleString() } bytes</span>
</Skeleton> </Skeleton>
</Flex> </Flex>
<Flex columnGap={ 2 }> <Flex columnGap={ 2 } w="100%">
<Text fontWeight={ 500 }>{ capitalize(getNetworkValidatorTitle()) }</Text> <Text fontWeight={ 500 }>{ capitalize(getNetworkValidatorTitle()) }</Text>
<AddressLink type="address" alias={ data.miner.name } hash={ data.miner.hash } truncation="constant" isLoading={ isLoading }/> <AddressEntity
address={ data.miner }
isLoading={ isLoading }
/>
</Flex> </Flex>
<Flex columnGap={ 2 }> <Flex columnGap={ 2 }>
<Text fontWeight={ 500 }>Txn</Text> <Text fontWeight={ 500 }>Txn</Text>
......
...@@ -25,9 +25,9 @@ const BlocksTable = ({ data, isLoading, top, page }: Props) => { ...@@ -25,9 +25,9 @@ const BlocksTable = ({ data, isLoading, top, page }: Props) => {
<Tr> <Tr>
<Th width="125px">Block</Th> <Th width="125px">Block</Th>
<Th width="120px">Size, bytes</Th> <Th width="120px">Size, bytes</Th>
<Th width={ config.features.rollup.isEnabled ? '37%' : '21%' } minW="144px">{ capitalize(getNetworkValidatorTitle()) }</Th> <Th width={ config.features.rollup.isEnabled ? '37%' : '23%' } minW="160px">{ capitalize(getNetworkValidatorTitle()) }</Th>
<Th width="64px" isNumeric>Txn</Th> <Th width="64px" isNumeric>Txn</Th>
<Th width={ config.features.rollup.isEnabled ? '63%' : '35%' }>Gas used</Th> <Th width={ config.features.rollup.isEnabled ? '63%' : '33%' }>Gas used</Th>
{ !config.features.rollup.isEnabled && !config.UI.views.block.hiddenFields?.total_reward && { !config.features.rollup.isEnabled && !config.UI.views.block.hiddenFields?.total_reward &&
<Th width="22%">Reward { config.chain.currency.symbol }</Th> } <Th width="22%">Reward { config.chain.currency.symbol }</Th> }
{ !config.features.rollup.isEnabled && !config.UI.views.block.hiddenFields?.burnt_fees && { !config.features.rollup.isEnabled && !config.UI.views.block.hiddenFields?.burnt_fees &&
......
...@@ -12,8 +12,8 @@ import flameIcon from 'icons/flame.svg'; ...@@ -12,8 +12,8 @@ import flameIcon from 'icons/flame.svg';
import getBlockTotalReward from 'lib/block/getBlockTotalReward'; import getBlockTotalReward from 'lib/block/getBlockTotalReward';
import { WEI } from 'lib/consts'; import { WEI } from 'lib/consts';
import BlockTimestamp from 'ui/blocks/BlockTimestamp'; import BlockTimestamp from 'ui/blocks/BlockTimestamp';
import AddressLink from 'ui/shared/address/AddressLink';
import Icon from 'ui/shared/chakra/Icon'; import Icon from 'ui/shared/chakra/Icon';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import GasUsedToTargetRatio from 'ui/shared/GasUsedToTargetRatio'; import GasUsedToTargetRatio from 'ui/shared/GasUsedToTargetRatio';
import LinkInternal from 'ui/shared/LinkInternal'; import LinkInternal from 'ui/shared/LinkInternal';
...@@ -65,13 +65,8 @@ const BlocksTableItem = ({ data, isLoading, enableTimeIncrement }: Props) => { ...@@ -65,13 +65,8 @@ const BlocksTableItem = ({ data, isLoading, enableTimeIncrement }: Props) => {
</Skeleton> </Skeleton>
</Td> </Td>
<Td fontSize="sm"> <Td fontSize="sm">
<AddressLink <AddressEntity
type="address" address={ data.miner }
alias={ data.miner.name }
hash={ data.miner.hash }
truncation="constant"
display="inline-flex"
maxW="100%"
isLoading={ isLoading } isLoading={ isLoading }
/> />
</Td> </Td>
......
import { Box, Skeleton } from '@chakra-ui/react';
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import type { CustomAbi } from 'types/api/account'; import type { CustomAbi } from 'types/api/account';
import AddressSnippet from 'ui/shared/AddressSnippet'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile'; import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import TableItemActionButtons from 'ui/shared/TableItemActionButtons'; import TableItemActionButtons from 'ui/shared/TableItemActionButtons';
...@@ -25,7 +26,16 @@ const CustomAbiListItem = ({ item, isLoading, onEditClick, onDeleteClick }: Prop ...@@ -25,7 +26,16 @@ const CustomAbiListItem = ({ item, isLoading, onEditClick, onDeleteClick }: Prop
return ( return (
<ListItemMobile> <ListItemMobile>
<AddressSnippet address={ item.contract_address } subtitle={ item.name } isLoading={ isLoading }/> <Box maxW="100%">
<AddressEntity
address={ item.contract_address }
fontWeight="600"
isLoading={ isLoading }
/>
<Skeleton fontSize="sm" color="text_secondary" mt={ 0.5 } ml={ 8 } display="inline-block" isLoaded={ !isLoading }>
<span>{ item.name }</span>
</Skeleton>
</Box>
<TableItemActionButtons onDeleteClick={ onItemDeleteClick } onEditClick={ onItemEditClick } isLoading={ isLoading }/> <TableItemActionButtons onDeleteClick={ onItemDeleteClick } onEditClick={ onItemEditClick } isLoading={ isLoading }/>
</ListItemMobile> </ListItemMobile>
); );
......
import { import {
Tr, Tr,
Td, Td,
Box,
Skeleton,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import type { CustomAbi } from 'types/api/account'; import type { CustomAbi } from 'types/api/account';
import AddressSnippet from 'ui/shared/AddressSnippet'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import TableItemActionButtons from 'ui/shared/TableItemActionButtons'; import TableItemActionButtons from 'ui/shared/TableItemActionButtons';
interface Props { interface Props {
...@@ -29,7 +31,16 @@ const CustomAbiTableItem = ({ item, isLoading, onEditClick, onDeleteClick }: Pro ...@@ -29,7 +31,16 @@ const CustomAbiTableItem = ({ item, isLoading, onEditClick, onDeleteClick }: Pro
return ( return (
<Tr alignItems="top" key={ item.id }> <Tr alignItems="top" key={ item.id }>
<Td> <Td>
<AddressSnippet address={ item.contract_address } subtitle={ item.name } isLoading={ isLoading }/> <Box maxW="100%">
<AddressEntity
address={ item.contract_address }
fontWeight="600"
isLoading={ isLoading }
/>
<Skeleton fontSize="sm" color="text_secondary" mt={ 0.5 } ml={ 8 } display="inline-block" isLoaded={ !isLoading }>
<span>{ item.name }</span>
</Skeleton>
</Box>
</Td> </Td>
<Td> <Td>
<TableItemActionButtons onDeleteClick={ onItemDeleteClick } onEditClick={ onItemEditClick } isLoading={ isLoading }/> <TableItemActionButtons onDeleteClick={ onItemDeleteClick } onEditClick={ onItemEditClick } isLoading={ isLoading }/>
......
...@@ -13,7 +13,7 @@ import config from 'configs/app'; ...@@ -13,7 +13,7 @@ import config from 'configs/app';
import getBlockTotalReward from 'lib/block/getBlockTotalReward'; import getBlockTotalReward from 'lib/block/getBlockTotalReward';
import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle'; import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle';
import BlockTimestamp from 'ui/blocks/BlockTimestamp'; import BlockTimestamp from 'ui/blocks/BlockTimestamp';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
type Props = { type Props = {
...@@ -66,7 +66,12 @@ const LatestBlocksItem = ({ block, h, isLoading }: Props) => { ...@@ -66,7 +66,12 @@ const LatestBlocksItem = ({ block, h, isLoading }: Props) => {
<Skeleton isLoaded={ !isLoading }>Reward</Skeleton> <Skeleton isLoaded={ !isLoading }>Reward</Skeleton>
<Skeleton isLoaded={ !isLoading } color="text_secondary"><span>{ totalReward.toFixed() }</span></Skeleton> <Skeleton isLoaded={ !isLoading } color="text_secondary"><span>{ totalReward.toFixed() }</span></Skeleton>
<Skeleton isLoaded={ !isLoading } textTransform="capitalize">{ getNetworkValidatorTitle() }</Skeleton> <Skeleton isLoaded={ !isLoading } textTransform="capitalize">{ getNetworkValidatorTitle() }</Skeleton>
<AddressLink type="address" alias={ block.miner.name } hash={ block.miner.hash } truncation="constant" maxW="100%" isLoading={ isLoading }/> <AddressEntity
address={ block.miner }
isLoading={ isLoading }
noIcon
noCopy
/>
</> </>
) } ) }
</Grid> </Grid>
......
...@@ -14,10 +14,8 @@ import config from 'configs/app'; ...@@ -14,10 +14,8 @@ import config from 'configs/app';
import rightArrowIcon from 'icons/arrows/east.svg'; import rightArrowIcon from 'icons/arrows/east.svg';
import getValueWithUnit from 'lib/getValueWithUnit'; import getValueWithUnit from 'lib/getValueWithUnit';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement'; import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink';
import Icon from 'ui/shared/chakra/Icon'; import Icon from 'ui/shared/chakra/Icon';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxStatus from 'ui/shared/TxStatus'; import TxStatus from 'ui/shared/TxStatus';
import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo'; import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo';
...@@ -83,31 +81,20 @@ const LatestTxsItem = ({ tx, isLoading }: Props) => { ...@@ -83,31 +81,20 @@ const LatestTxsItem = ({ tx, isLoading }: Props) => {
isLoading={ isLoading } isLoading={ isLoading }
/> />
<Box overflow="hidden" ml={ 1 }> <Box overflow="hidden" ml={ 1 }>
<Address mb={ 2 }> <AddressEntity
<AddressIcon address={ tx.from } isLoading={ isLoading }/> isLoading={ isLoading }
<AddressLink address={ tx.from }
type="address" fontSize="sm"
hash={ tx.from.hash } fontWeight="500"
alias={ tx.from.name } mb={ 2 }
fontWeight="500" />
ml={ 2 } { dataTo && (
fontSize="sm" <AddressEntity
isLoading={ isLoading } isLoading={ isLoading }
address={ dataTo }
fontSize="sm"
fontWeight="500"
/> />
</Address>
{ dataTo && (
<Address>
<AddressIcon address={ dataTo } isLoading={ isLoading }/>
<AddressLink
type="address"
hash={ dataTo.hash }
alias={ dataTo.name }
fontWeight="500"
ml={ 2 }
fontSize="sm"
isLoading={ isLoading }
/>
</Address>
) } ) }
</Box> </Box>
</Grid> </Grid>
......
...@@ -13,10 +13,8 @@ import config from 'configs/app'; ...@@ -13,10 +13,8 @@ import config from 'configs/app';
import rightArrowIcon from 'icons/arrows/east.svg'; import rightArrowIcon from 'icons/arrows/east.svg';
import getValueWithUnit from 'lib/getValueWithUnit'; import getValueWithUnit from 'lib/getValueWithUnit';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement'; import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink';
import Icon from 'ui/shared/chakra/Icon'; import Icon from 'ui/shared/chakra/Icon';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxStatus from 'ui/shared/TxStatus'; import TxStatus from 'ui/shared/TxStatus';
import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo'; import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo';
...@@ -67,19 +65,14 @@ const LatestTxsItem = ({ tx, isLoading }: Props) => { ...@@ -67,19 +65,14 @@ const LatestTxsItem = ({ tx, isLoading }: Props) => {
) } ) }
</Flex> </Flex>
<Flex alignItems="center" mb={ 3 }> <Flex alignItems="center" mb={ 3 }>
<Address mr={ 2 }> <AddressEntity
<AddressIcon address={ tx.from } isLoading={ isLoading }/> isLoading={ isLoading }
<AddressLink address={ tx.from }
type="address" truncation="constant"
hash={ tx.from.hash } fontSize="sm"
alias={ tx.from.name } fontWeight="500"
fontWeight="500" mr={ 2 }
ml={ 2 } />
truncation="constant"
fontSize="sm"
isLoading={ isLoading }
/>
</Address>
<Icon <Icon
as={ rightArrowIcon } as={ rightArrowIcon }
boxSize={ 6 } boxSize={ 6 }
...@@ -87,19 +80,13 @@ const LatestTxsItem = ({ tx, isLoading }: Props) => { ...@@ -87,19 +80,13 @@ const LatestTxsItem = ({ tx, isLoading }: Props) => {
isLoading={ isLoading } isLoading={ isLoading }
/> />
{ dataTo && ( { dataTo && (
<Address ml={ 2 }> <AddressEntity
<AddressIcon address={ dataTo } isLoading={ isLoading }/> isLoading={ isLoading }
<AddressLink address={ dataTo }
type="address" truncation="constant"
hash={ dataTo.hash } fontSize="sm"
alias={ dataTo.name } fontWeight="500"
fontWeight="500" />
ml={ 2 }
truncation="constant"
fontSize="sm"
isLoading={ isLoading }
/>
</Address>
) } ) }
</Flex> </Flex>
<Skeleton isLoaded={ !isLoading } mb={ 2 } fontSize="sm" w="fit-content"> <Skeleton isLoaded={ !isLoading } mb={ 2 } fontSize="sm" w="fit-content">
......
...@@ -7,7 +7,7 @@ import config from 'configs/app'; ...@@ -7,7 +7,7 @@ import config from 'configs/app';
import globeIcon from 'icons/globe.svg'; import globeIcon from 'icons/globe.svg';
import txIcon from 'icons/transactions.svg'; import txIcon from 'icons/transactions.svg';
import { sortByDateDesc } from 'ui/shared/chart/utils/sorts'; import { sortByDateDesc } from 'ui/shared/chart/utils/sorts';
import TokenLogo from 'ui/shared/TokenLogo'; import * as TokenEntity from 'ui/shared/entities/token/TokenEntity';
const dailyTxsIndicator: TChainIndicator<'homepage_chart_txs'> = { const dailyTxsIndicator: TChainIndicator<'homepage_chart_txs'> = {
id: 'daily_txs', id: 'daily_txs',
...@@ -30,13 +30,15 @@ const dailyTxsIndicator: TChainIndicator<'homepage_chart_txs'> = { ...@@ -30,13 +30,15 @@ const dailyTxsIndicator: TChainIndicator<'homepage_chart_txs'> = {
const nativeTokenData = { const nativeTokenData = {
name: config.chain.currency.name || '', name: config.chain.currency.name || '',
icon_url: '', icon_url: '',
symbol: '',
address: '',
}; };
const coinPriceIndicator: TChainIndicator<'homepage_chart_market'> = { const coinPriceIndicator: TChainIndicator<'homepage_chart_market'> = {
id: 'coin_price', id: 'coin_price',
title: `${ config.chain.currency.symbol } price`, title: `${ config.chain.currency.symbol } price`,
value: (stats) => '$' + Number(stats.coin_price).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 6 }), value: (stats) => '$' + Number(stats.coin_price).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 6 }),
icon: <TokenLogo data={ nativeTokenData } boxSize={ 6 }/>, icon: <TokenEntity.Icon token={ nativeTokenData } boxSize={ 6 } marginRight={ 0 }/>,
hint: `${ config.chain.currency.symbol } token daily price in USD.`, hint: `${ config.chain.currency.symbol } token daily price in USD.`,
api: { api: {
resourceName: 'homepage_chart_market', resourceName: 'homepage_chart_market',
......
...@@ -4,16 +4,12 @@ import React from 'react'; ...@@ -4,16 +4,12 @@ import React from 'react';
import type { L2DepositsItem } from 'types/api/l2Deposits'; import type { L2DepositsItem } from 'types/api/l2Deposits';
import { route } from 'nextjs-routes';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs'; import dayjs from 'lib/date/dayjs';
import AddressIcon from 'ui/shared/address/AddressIcon'; import AddressEntityL1 from 'ui/shared/entities/address/AddressEntityL1';
import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1'; import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import LinkExternal from 'ui/shared/LinkExternal';
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid'; import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
const feature = config.features.rollup; const feature = config.features.rollup;
...@@ -31,7 +27,7 @@ const DepositsListItem = ({ item, isLoading }: Props) => { ...@@ -31,7 +27,7 @@ const DepositsListItem = ({ item, isLoading }: Props) => {
<ListItemMobileGrid.Container> <ListItemMobileGrid.Container>
<ListItemMobileGrid.Label isLoading={ isLoading }>L1 block No</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>L1 block No</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value py="3px"> <ListItemMobileGrid.Value>
<BlockEntityL1 <BlockEntityL1
number={ item.l1_block_number } number={ item.l1_block_number }
isLoading={ isLoading } isLoading={ isLoading }
...@@ -42,7 +38,7 @@ const DepositsListItem = ({ item, isLoading }: Props) => { ...@@ -42,7 +38,7 @@ const DepositsListItem = ({ item, isLoading }: Props) => {
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
<ListItemMobileGrid.Label isLoading={ isLoading }>L2 txn hash</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>L2 txn hash</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value py="3px"> <ListItemMobileGrid.Value>
<TxEntity <TxEntity
isLoading={ isLoading } isLoading={ isLoading }
hash={ item.l2_tx_hash } hash={ item.l2_tx_hash }
...@@ -57,7 +53,7 @@ const DepositsListItem = ({ item, isLoading }: Props) => { ...@@ -57,7 +53,7 @@ const DepositsListItem = ({ item, isLoading }: Props) => {
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
<ListItemMobileGrid.Label isLoading={ isLoading }>L1 txn hash</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>L1 txn hash</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value py="3px"> <ListItemMobileGrid.Value>
<TxEntityL1 <TxEntityL1
isLoading={ isLoading } isLoading={ isLoading }
hash={ item.l1_tx_hash } hash={ item.l1_tx_hash }
...@@ -67,19 +63,12 @@ const DepositsListItem = ({ item, isLoading }: Props) => { ...@@ -67,19 +63,12 @@ const DepositsListItem = ({ item, isLoading }: Props) => {
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
<ListItemMobileGrid.Label isLoading={ isLoading }>L1 txn origin</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>L1 txn origin</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value py="3px"> <ListItemMobileGrid.Value>
<LinkExternal <AddressEntityL1
href={ feature.L1BaseUrl + route({ pathname: '/address/[hash]', query: { hash: item.l1_tx_origin } }) } address={{ hash: item.l1_tx_origin, name: '', is_contract: false, is_verified: false, implementation_name: '' }}
maxW="100%"
display="flex"
overflow="hidden"
isLoading={ isLoading } isLoading={ isLoading }
> noCopy
<AddressIcon address={{ hash: item.l1_tx_origin, is_contract: false, implementation_name: '' }} isLoading={ isLoading }/> />
<Skeleton isLoaded={ !isLoading } w="calc(100% - 44px)" overflow="hidden" whiteSpace="nowrap" ml={ 2 }>
<HashStringShortenDynamic hash={ item.l1_tx_origin }/>
</Skeleton>
</LinkExternal>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
<ListItemMobileGrid.Label isLoading={ isLoading }>Gas limit</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Gas limit</ListItemMobileGrid.Label>
......
...@@ -4,16 +4,12 @@ import React from 'react'; ...@@ -4,16 +4,12 @@ import React from 'react';
import type { L2DepositsItem } from 'types/api/l2Deposits'; import type { L2DepositsItem } from 'types/api/l2Deposits';
import { route } from 'nextjs-routes';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs'; import dayjs from 'lib/date/dayjs';
import AddressIcon from 'ui/shared/address/AddressIcon'; import AddressEntityL1 from 'ui/shared/entities/address/AddressEntityL1';
import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1'; import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import HashStringShorten from 'ui/shared/HashStringShorten';
import LinkExternal from 'ui/shared/LinkExternal';
const feature = config.features.rollup; const feature = config.features.rollup;
...@@ -59,18 +55,12 @@ const WithdrawalsTableItem = ({ item, isLoading }: Props) => { ...@@ -59,18 +55,12 @@ const WithdrawalsTableItem = ({ item, isLoading }: Props) => {
/> />
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<LinkExternal <AddressEntityL1
href={ feature.L1BaseUrl + route({ pathname: '/address/[hash]', query: { hash: item.l1_tx_origin } }) } address={{ hash: item.l1_tx_origin, name: '', is_contract: false, is_verified: false, implementation_name: '' }}
maxW="100%"
display="inline-flex"
overflow="hidden"
isLoading={ isLoading } isLoading={ isLoading }
> truncation="constant"
<AddressIcon address={{ hash: item.l1_tx_origin, is_contract: false, implementation_name: '' }} isLoading={ isLoading }/> noCopy
<Skeleton isLoaded={ !isLoading } w="calc(100% - 44px)" overflow="hidden" whiteSpace="nowrap" ml={ 2 }> />
<HashStringShorten hash={ item.l1_tx_origin }/>
</Skeleton>
</LinkExternal>
</Td> </Td>
<Td verticalAlign="middle" isNumeric> <Td verticalAlign="middle" isNumeric>
<Skeleton isLoaded={ !isLoading } color="text_secondary" display="inline-block"> <Skeleton isLoaded={ !isLoading } color="text_secondary" display="inline-block">
......
...@@ -5,9 +5,7 @@ import type { L2WithdrawalsItem } from 'types/api/l2Withdrawals'; ...@@ -5,9 +5,7 @@ import type { L2WithdrawalsItem } from 'types/api/l2Withdrawals';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs'; import dayjs from 'lib/date/dayjs';
import Address from 'ui/shared/address/Address'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import LinkExternal from 'ui/shared/LinkExternal'; import LinkExternal from 'ui/shared/LinkExternal';
...@@ -38,17 +36,17 @@ const WithdrawalsListItem = ({ item, isLoading }: Props) => { ...@@ -38,17 +36,17 @@ const WithdrawalsListItem = ({ item, isLoading }: Props) => {
{ item.from && ( { item.from && (
<> <>
<ListItemMobileGrid.Label isLoading={ isLoading }>From</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>From</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value py="3px"> <ListItemMobileGrid.Value>
<Address> <AddressEntity
<AddressIcon address={ item.from } isLoading={ isLoading }/> address={ item.from }
<AddressLink hash={ item.from.hash } type="address" truncation="dynamic" ml={ 2 } isLoading={ isLoading }/> isLoading={ isLoading }
</Address> />
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
</> </>
) } ) }
<ListItemMobileGrid.Label isLoading={ isLoading }>L2 txn hash</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>L2 txn hash</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value py="3px"> <ListItemMobileGrid.Value>
<TxEntity <TxEntity
isLoading={ isLoading } isLoading={ isLoading }
hash={ item.l2_tx_hash } hash={ item.l2_tx_hash }
...@@ -78,7 +76,7 @@ const WithdrawalsListItem = ({ item, isLoading }: Props) => { ...@@ -78,7 +76,7 @@ const WithdrawalsListItem = ({ item, isLoading }: Props) => {
{ item.l1_tx_hash && ( { item.l1_tx_hash && (
<> <>
<ListItemMobileGrid.Label isLoading={ isLoading }>L1 txn hash</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>L1 txn hash</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value py="3px"> <ListItemMobileGrid.Value>
<TxEntityL1 <TxEntityL1
isLoading={ isLoading } isLoading={ isLoading }
hash={ item.l1_tx_hash } hash={ item.l1_tx_hash }
......
...@@ -5,9 +5,7 @@ import type { L2WithdrawalsItem } from 'types/api/l2Withdrawals'; ...@@ -5,9 +5,7 @@ import type { L2WithdrawalsItem } from 'types/api/l2Withdrawals';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs'; import dayjs from 'lib/date/dayjs';
import Address from 'ui/shared/address/Address'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import LinkExternal from 'ui/shared/LinkExternal'; import LinkExternal from 'ui/shared/LinkExternal';
...@@ -31,10 +29,11 @@ const WithdrawalsTableItem = ({ item, isLoading }: Props) => { ...@@ -31,10 +29,11 @@ const WithdrawalsTableItem = ({ item, isLoading }: Props) => {
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
{ item.from ? ( { item.from ? (
<Address> <AddressEntity
<AddressIcon address={ item.from } isLoading={ isLoading }/> address={ item.from }
<AddressLink hash={ item.from.hash } type="address" truncation="constant" ml={ 2 } isLoading={ isLoading }/> isLoading={ isLoading }
</Address> truncation="constant"
/>
) : 'N/A' } ) : 'N/A' }
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment