mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
ENS: add offchain support and fix bugs (#2156)
* ens: add offchain support and fix bugs Fixes #2136 * fix ts
This commit is contained in:
@@ -63,6 +63,14 @@ export const ensDomainA: bens.DetailedDomain = {
|
||||
NEAR: 'a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48.factory.bridge.near',
|
||||
},
|
||||
protocol: protocolA,
|
||||
resolver_address: {
|
||||
hash: '0xD578780f1dA7404d9CC0eEbC9D684c140CC4b638',
|
||||
},
|
||||
resolved_with_wildcard: true,
|
||||
stored_offchain: true,
|
||||
wrapped_owner: {
|
||||
hash: '0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401',
|
||||
},
|
||||
};
|
||||
|
||||
export const ensDomainB: bens.DetailedDomain = {
|
||||
@@ -81,6 +89,8 @@ export const ensDomainB: bens.DetailedDomain = {
|
||||
expiry_date: undefined,
|
||||
other_addresses: {},
|
||||
protocol: undefined,
|
||||
resolved_with_wildcard: false,
|
||||
stored_offchain: false,
|
||||
};
|
||||
|
||||
export const ensDomainC: bens.DetailedDomain = {
|
||||
@@ -101,6 +111,8 @@ export const ensDomainC: bens.DetailedDomain = {
|
||||
expiry_date: '2022-11-01T13:10:36.000Z',
|
||||
other_addresses: {},
|
||||
protocol: undefined,
|
||||
resolved_with_wildcard: false,
|
||||
stored_offchain: false,
|
||||
};
|
||||
|
||||
export const ensDomainD: bens.DetailedDomain = {
|
||||
@@ -119,4 +131,6 @@ export const ensDomainD: bens.DetailedDomain = {
|
||||
expiry_date: '2027-09-23T13:10:36.000Z',
|
||||
other_addresses: {},
|
||||
protocol: undefined,
|
||||
resolved_with_wildcard: false,
|
||||
stored_offchain: false,
|
||||
};
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@
|
||||
"monitoring:grafana:local": "docker run -d -p 4000:3000 --name=blockscout_grafana --user $(id -u) --volume $(pwd)/grafana:/var/lib/grafana grafana/grafana-enterprise"
|
||||
},
|
||||
"dependencies": {
|
||||
"@blockscout/bens-types": "1.3.4",
|
||||
"@blockscout/bens-types": "1.4.1",
|
||||
"@blockscout/stats-types": "1.6.0",
|
||||
"@blockscout/visualizer-types": "0.2.0",
|
||||
"@chakra-ui/react": "2.7.1",
|
||||
|
||||
@@ -22,6 +22,8 @@ export const ENS_DOMAIN: bens.DetailedDomain = {
|
||||
ETH: ADDRESS_HASH,
|
||||
},
|
||||
protocol: undefined,
|
||||
resolved_with_wildcard: false,
|
||||
stored_offchain: false,
|
||||
};
|
||||
|
||||
export const ENS_DOMAIN_EVENT: bens.DomainEvent = {
|
||||
|
||||
@@ -31,7 +31,7 @@ import PopoverTriggerTooltip from 'ui/shared/PopoverTriggerTooltip';
|
||||
interface Props {
|
||||
query: UseQueryResult<bens.LookupAddressResponse, ResourceError<unknown>>;
|
||||
addressHash: string;
|
||||
mainDomainName: string | null;
|
||||
mainDomainName: string | null | undefined;
|
||||
}
|
||||
|
||||
const DomainsGrid = ({ data }: { data: Array<bens.Domain> }) => {
|
||||
@@ -64,9 +64,9 @@ const AddressEnsDomains = ({ query, addressHash, mainDomainName }: Props) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
const mainDomain = data.items.find((domain) => domain.name === mainDomainName);
|
||||
const mainDomain = data.items.find((domain) => mainDomainName && domain.name === mainDomainName);
|
||||
const ownedDomains = data.items.filter((domain) => {
|
||||
if (domain.name === mainDomainName) {
|
||||
if (mainDomainName && domain.name === mainDomainName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+203
-181
@@ -17,6 +17,7 @@ import IconSvg from 'ui/shared/IconSvg';
|
||||
import LinkInternal from 'ui/shared/links/LinkInternal';
|
||||
import TextSeparator from 'ui/shared/TextSeparator';
|
||||
|
||||
import NameDomainDetailsAlert from './details/NameDomainDetailsAlert';
|
||||
import NameDomainExpiryStatus from './NameDomainExpiryStatus';
|
||||
|
||||
interface Props {
|
||||
@@ -30,196 +31,217 @@ const NameDomainDetails = ({ query }: Props) => {
|
||||
const hasExpired = query.data?.expiry_date && dayjs(query.data.expiry_date).isBefore(dayjs());
|
||||
|
||||
return (
|
||||
<Grid columnGap={ 8 } rowGap={ 3 } templateColumns={{ base: 'minmax(0, 1fr)', lg: 'max-content minmax(728px, auto)' }}>
|
||||
{ query.data?.registration_date && (
|
||||
<>
|
||||
<DetailsInfoItem.Label
|
||||
hint="The date the name was registered"
|
||||
isLoading={ isLoading }
|
||||
>
|
||||
Registration date
|
||||
</DetailsInfoItem.Label>
|
||||
<DetailsInfoItem.Value>
|
||||
<IconSvg name="clock" boxSize={ 5 } color="gray.500" verticalAlign="middle" isLoading={ isLoading } mr={ 2 }/>
|
||||
<Skeleton isLoaded={ !isLoading } display="inline" whiteSpace="pre-wrap" lineHeight="20px">
|
||||
{ dayjs(query.data.registration_date).format('llll') }
|
||||
</Skeleton>
|
||||
</DetailsInfoItem.Value>
|
||||
</>
|
||||
) }
|
||||
|
||||
{ query.data?.expiry_date && (
|
||||
<>
|
||||
<DetailsInfoItem.Label
|
||||
// eslint-disable-next-line max-len
|
||||
hint="The date the name expires, upon which there is a 90 day grace period for the owner to renew. After the 90 days, the name is released to the market"
|
||||
isLoading={ isLoading }
|
||||
>
|
||||
Expiration date
|
||||
</DetailsInfoItem.Label>
|
||||
<DetailsInfoItem.Value>
|
||||
<IconSvg name="clock" boxSize={ 5 } color="gray.500" verticalAlign="middle" isLoading={ isLoading } mr={ 2 } mt="-2px"/>
|
||||
{ hasExpired && (
|
||||
<>
|
||||
<Skeleton isLoaded={ !isLoading } display="inline" whiteSpace="pre-wrap" lineHeight="24px">
|
||||
{ dayjs(query.data.expiry_date).fromNow() }
|
||||
</Skeleton>
|
||||
<TextSeparator color="gray.500"/>
|
||||
</>
|
||||
) }
|
||||
<Skeleton isLoaded={ !isLoading } display="inline" whiteSpace="pre-wrap" lineHeight="24px">
|
||||
{ dayjs(query.data.expiry_date).format('llll') }
|
||||
</Skeleton>
|
||||
<TextSeparator color="gray.500"/>
|
||||
<Skeleton isLoaded={ !isLoading } color="text_secondary" display="inline">
|
||||
<NameDomainExpiryStatus date={ query.data?.expiry_date }/>
|
||||
</Skeleton>
|
||||
</DetailsInfoItem.Value>
|
||||
</>
|
||||
) }
|
||||
|
||||
{ query.data?.registrant && (
|
||||
<>
|
||||
<DetailsInfoItem.Label
|
||||
hint="The account that owns the domain name and has the rights to edit its ownership and records"
|
||||
isLoading={ isLoading }
|
||||
>
|
||||
Registrant
|
||||
</DetailsInfoItem.Label>
|
||||
<DetailsInfoItem.Value
|
||||
columnGap={ 2 }
|
||||
flexWrap="nowrap"
|
||||
>
|
||||
<AddressEntity
|
||||
address={ query.data.registrant }
|
||||
isLoading={ isLoading }
|
||||
/>
|
||||
<Tooltip label="Lookup for related domain names">
|
||||
<LinkInternal
|
||||
flexShrink={ 0 }
|
||||
display="inline-flex"
|
||||
href={ route({ pathname: '/name-domains', query: { owned_by: 'true', resolved_to: 'true', address: query.data.registrant.hash } }) }
|
||||
>
|
||||
<IconSvg name="search" boxSize={ 5 } isLoading={ isLoading }/>
|
||||
</LinkInternal>
|
||||
</Tooltip>
|
||||
</DetailsInfoItem.Value>
|
||||
</>
|
||||
) }
|
||||
|
||||
{ query.data?.owner && (
|
||||
<>
|
||||
<DetailsInfoItem.Label
|
||||
hint="The account that owns the rights to edit the records of this domain name"
|
||||
isLoading={ isLoading }
|
||||
>
|
||||
Owner
|
||||
</DetailsInfoItem.Label>
|
||||
<DetailsInfoItem.Value
|
||||
columnGap={ 2 }
|
||||
flexWrap="nowrap"
|
||||
>
|
||||
<AddressEntity
|
||||
address={ query.data.owner }
|
||||
isLoading={ isLoading }
|
||||
/>
|
||||
<Tooltip label="Lookup for related domain names">
|
||||
<LinkInternal
|
||||
flexShrink={ 0 }
|
||||
display="inline-flex"
|
||||
href={ route({ pathname: '/name-domains', query: { owned_by: 'true', resolved_to: 'true', address: query.data.owner.hash } }) }
|
||||
>
|
||||
<IconSvg name="search" boxSize={ 5 } isLoading={ isLoading }/>
|
||||
</LinkInternal>
|
||||
</Tooltip>
|
||||
</DetailsInfoItem.Value>
|
||||
</>
|
||||
) }
|
||||
|
||||
{ query.data?.wrapped_owner && (
|
||||
<>
|
||||
<DetailsInfoItem.Label
|
||||
hint="Owner of this NFT domain in NameWrapper contract"
|
||||
isLoading={ isLoading }
|
||||
>
|
||||
Manager
|
||||
</DetailsInfoItem.Label>
|
||||
<DetailsInfoItem.Value
|
||||
columnGap={ 2 }
|
||||
flexWrap="nowrap"
|
||||
>
|
||||
<AddressEntity
|
||||
address={ query.data.wrapped_owner }
|
||||
isLoading={ isLoading }
|
||||
/>
|
||||
<Tooltip label="Lookup for related domain names">
|
||||
<LinkInternal
|
||||
flexShrink={ 0 }
|
||||
display="inline-flex"
|
||||
href={ route({ pathname: '/name-domains', query: { owned_by: 'true', resolved_to: 'true', address: query.data.wrapped_owner.hash } }) }
|
||||
>
|
||||
<IconSvg name="search" boxSize={ 5 } isLoading={ isLoading }/>
|
||||
</LinkInternal>
|
||||
</Tooltip>
|
||||
</DetailsInfoItem.Value>
|
||||
</>
|
||||
) }
|
||||
|
||||
{ query.data?.tokens.map((token) => {
|
||||
const isProtocolBaseChain = stripTrailingSlash(query.data.protocol?.deployment_blockscout_base_url ?? '') === config.app.baseUrl;
|
||||
const entityProps = {
|
||||
isExternal: !isProtocolBaseChain ? true : false,
|
||||
href: !isProtocolBaseChain ? (
|
||||
stripTrailingSlash(query.data.protocol?.deployment_blockscout_base_url ?? '') +
|
||||
route({ pathname: '/token/[hash]/instance/[id]', query: { hash: token.contract_hash, id: token.id } })
|
||||
) : undefined,
|
||||
};
|
||||
|
||||
return (
|
||||
<React.Fragment key={ token.type }>
|
||||
<>
|
||||
<NameDomainDetailsAlert data={ query.data }/>
|
||||
<Grid columnGap={ 8 } rowGap={ 3 } templateColumns={{ base: 'minmax(0, 1fr)', lg: 'max-content minmax(728px, auto)' }}>
|
||||
{ query.data?.registration_date && (
|
||||
<>
|
||||
<DetailsInfoItem.Label
|
||||
hint={ `The ${ token.type === bens.TokenType.WRAPPED_DOMAIN_TOKEN ? 'wrapped ' : '' }token ID of this domain name NFT` }
|
||||
hint="The date the name was registered"
|
||||
isLoading={ isLoading }
|
||||
>
|
||||
{ token.type === bens.TokenType.WRAPPED_DOMAIN_TOKEN ? 'Wrapped token ID' : 'Token ID' }
|
||||
Registration date
|
||||
</DetailsInfoItem.Label>
|
||||
<DetailsInfoItem.Value>
|
||||
<IconSvg name="clock" boxSize={ 5 } color="gray.500" verticalAlign="middle" isLoading={ isLoading } mr={ 2 }/>
|
||||
<Skeleton isLoaded={ !isLoading } display="inline" whiteSpace="pre-wrap" lineHeight="20px">
|
||||
{ dayjs(query.data.registration_date).format('llll') }
|
||||
</Skeleton>
|
||||
</DetailsInfoItem.Value>
|
||||
</>
|
||||
) }
|
||||
|
||||
{ query.data?.expiry_date && (
|
||||
<>
|
||||
<DetailsInfoItem.Label
|
||||
// eslint-disable-next-line max-len
|
||||
hint="The date the name expires, upon which there is a 90 day grace period for the owner to renew. After the 90 days, the name is released to the market"
|
||||
isLoading={ isLoading }
|
||||
>
|
||||
Expiration date
|
||||
</DetailsInfoItem.Label>
|
||||
<DetailsInfoItem.Value>
|
||||
<IconSvg name="clock" boxSize={ 5 } color="gray.500" verticalAlign="middle" isLoading={ isLoading } mr={ 2 } mt="-2px"/>
|
||||
{ hasExpired && (
|
||||
<>
|
||||
<Skeleton isLoaded={ !isLoading } display="inline" whiteSpace="pre-wrap" lineHeight="24px">
|
||||
{ dayjs(query.data.expiry_date).fromNow() }
|
||||
</Skeleton>
|
||||
<TextSeparator color="gray.500"/>
|
||||
</>
|
||||
) }
|
||||
<Skeleton isLoaded={ !isLoading } display="inline" whiteSpace="pre-wrap" lineHeight="24px">
|
||||
{ dayjs(query.data.expiry_date).format('llll') }
|
||||
</Skeleton>
|
||||
<TextSeparator color="gray.500"/>
|
||||
<Skeleton isLoaded={ !isLoading } color="text_secondary" display="inline">
|
||||
<NameDomainExpiryStatus date={ query.data?.expiry_date }/>
|
||||
</Skeleton>
|
||||
</DetailsInfoItem.Value>
|
||||
</>
|
||||
) }
|
||||
|
||||
{ query.data?.resolver_address && (
|
||||
<>
|
||||
<DetailsInfoItem.Label
|
||||
hint="The resolver contract provides information about a domain name"
|
||||
isLoading={ isLoading }
|
||||
>
|
||||
Resolver
|
||||
</DetailsInfoItem.Label>
|
||||
<DetailsInfoItem.Value
|
||||
wordBreak="break-all"
|
||||
whiteSpace="pre-wrap"
|
||||
>
|
||||
<NftEntity { ...entityProps } hash={ token.contract_hash } id={ token.id } isLoading={ isLoading } noIcon/>
|
||||
<AddressEntity
|
||||
address={ query.data.resolver_address }
|
||||
isLoading={ isLoading }
|
||||
/>
|
||||
</DetailsInfoItem.Value>
|
||||
</React.Fragment>
|
||||
);
|
||||
}) }
|
||||
</>
|
||||
) }
|
||||
|
||||
{ otherAddresses.length > 0 && (
|
||||
<>
|
||||
<DetailsInfoItem.Label
|
||||
hint="Other cryptocurrency addresses added to this domain name"
|
||||
isLoading={ isLoading }
|
||||
>
|
||||
{ query.data?.registrant && (
|
||||
<>
|
||||
<DetailsInfoItem.Label
|
||||
hint="The account that owns the domain name and has the rights to edit its ownership and records"
|
||||
isLoading={ isLoading }
|
||||
>
|
||||
Registrant
|
||||
</DetailsInfoItem.Label>
|
||||
<DetailsInfoItem.Value
|
||||
columnGap={ 2 }
|
||||
flexWrap="nowrap"
|
||||
>
|
||||
<AddressEntity
|
||||
address={ query.data.registrant }
|
||||
isLoading={ isLoading }
|
||||
/>
|
||||
<Tooltip label="Lookup for related domain names">
|
||||
<LinkInternal
|
||||
flexShrink={ 0 }
|
||||
display="inline-flex"
|
||||
href={ route({ pathname: '/name-domains', query: { owned_by: 'true', resolved_to: 'true', address: query.data.registrant.hash } }) }
|
||||
>
|
||||
<IconSvg name="search" boxSize={ 5 } isLoading={ isLoading }/>
|
||||
</LinkInternal>
|
||||
</Tooltip>
|
||||
</DetailsInfoItem.Value>
|
||||
</>
|
||||
) }
|
||||
|
||||
{ query.data?.owner && (
|
||||
<>
|
||||
<DetailsInfoItem.Label
|
||||
hint="The account that owns the rights to edit the records of this domain name"
|
||||
isLoading={ isLoading }
|
||||
>
|
||||
Owner
|
||||
</DetailsInfoItem.Label>
|
||||
<DetailsInfoItem.Value
|
||||
columnGap={ 2 }
|
||||
flexWrap="nowrap"
|
||||
>
|
||||
<AddressEntity
|
||||
address={ query.data.owner }
|
||||
isLoading={ isLoading }
|
||||
/>
|
||||
<Tooltip label="Lookup for related domain names">
|
||||
<LinkInternal
|
||||
flexShrink={ 0 }
|
||||
display="inline-flex"
|
||||
href={ route({ pathname: '/name-domains', query: { owned_by: 'true', resolved_to: 'true', address: query.data.owner.hash } }) }
|
||||
>
|
||||
<IconSvg name="search" boxSize={ 5 } isLoading={ isLoading }/>
|
||||
</LinkInternal>
|
||||
</Tooltip>
|
||||
</DetailsInfoItem.Value>
|
||||
</>
|
||||
) }
|
||||
|
||||
{ query.data?.wrapped_owner && (
|
||||
<>
|
||||
<DetailsInfoItem.Label
|
||||
hint="Owner of this NFT domain in NameWrapper contract"
|
||||
isLoading={ isLoading }
|
||||
>
|
||||
Manager
|
||||
</DetailsInfoItem.Label>
|
||||
<DetailsInfoItem.Value
|
||||
columnGap={ 2 }
|
||||
flexWrap="nowrap"
|
||||
>
|
||||
<AddressEntity
|
||||
address={ query.data.wrapped_owner }
|
||||
isLoading={ isLoading }
|
||||
/>
|
||||
<Tooltip label="Lookup for related domain names">
|
||||
<LinkInternal
|
||||
flexShrink={ 0 }
|
||||
display="inline-flex"
|
||||
href={ route({ pathname: '/name-domains', query: { owned_by: 'true', resolved_to: 'true', address: query.data.wrapped_owner.hash } }) }
|
||||
>
|
||||
<IconSvg name="search" boxSize={ 5 } isLoading={ isLoading }/>
|
||||
</LinkInternal>
|
||||
</Tooltip>
|
||||
</DetailsInfoItem.Value>
|
||||
</>
|
||||
) }
|
||||
|
||||
{ query.data?.tokens.map((token) => {
|
||||
const isProtocolBaseChain = stripTrailingSlash(query.data.protocol?.deployment_blockscout_base_url ?? '') === config.app.baseUrl;
|
||||
const entityProps = {
|
||||
isExternal: !isProtocolBaseChain ? true : false,
|
||||
href: !isProtocolBaseChain ? (
|
||||
stripTrailingSlash(query.data.protocol?.deployment_blockscout_base_url ?? '') +
|
||||
route({ pathname: '/token/[hash]/instance/[id]', query: { hash: token.contract_hash, id: token.id } })
|
||||
) : undefined,
|
||||
};
|
||||
|
||||
return (
|
||||
<React.Fragment key={ token.type }>
|
||||
<DetailsInfoItem.Label
|
||||
hint={ `The ${ token.type === bens.TokenType.WRAPPED_DOMAIN_TOKEN ? 'wrapped ' : '' }token ID of this domain name NFT` }
|
||||
isLoading={ isLoading }
|
||||
>
|
||||
{ token.type === bens.TokenType.WRAPPED_DOMAIN_TOKEN ? 'Wrapped token ID' : 'Token ID' }
|
||||
</DetailsInfoItem.Label>
|
||||
<DetailsInfoItem.Value
|
||||
wordBreak="break-all"
|
||||
whiteSpace="pre-wrap"
|
||||
>
|
||||
<NftEntity { ...entityProps } hash={ token.contract_hash } id={ token.id } isLoading={ isLoading } noIcon/>
|
||||
</DetailsInfoItem.Value>
|
||||
</React.Fragment>
|
||||
);
|
||||
}) }
|
||||
|
||||
{ otherAddresses.length > 0 && (
|
||||
<>
|
||||
<DetailsInfoItem.Label
|
||||
hint="Other cryptocurrency addresses added to this domain name"
|
||||
isLoading={ isLoading }
|
||||
>
|
||||
Other addresses
|
||||
</DetailsInfoItem.Label>
|
||||
<DetailsInfoItem.Value
|
||||
flexDir="column"
|
||||
alignItems="flex-start"
|
||||
>
|
||||
{ otherAddresses.map(([ type, address ]) => (
|
||||
<Flex key={ type } columnGap={ 2 } minW="0" w="100%" overflow="hidden">
|
||||
<Skeleton isLoaded={ !isLoading }>{ type }</Skeleton>
|
||||
<AddressEntity
|
||||
address={{ hash: address }}
|
||||
isLoading={ isLoading }
|
||||
noLink
|
||||
noIcon
|
||||
/>
|
||||
</Flex>
|
||||
)) }
|
||||
</DetailsInfoItem.Value>
|
||||
</>
|
||||
) }
|
||||
</Grid>
|
||||
</DetailsInfoItem.Label>
|
||||
<DetailsInfoItem.Value
|
||||
flexDir="column"
|
||||
alignItems="flex-start"
|
||||
>
|
||||
{ otherAddresses.map(([ type, address ]) => (
|
||||
<Flex key={ type } columnGap={ 2 } minW="0" w="100%" overflow="hidden">
|
||||
<Skeleton isLoaded={ !isLoading }>{ type }</Skeleton>
|
||||
<AddressEntity
|
||||
address={{ hash: address }}
|
||||
isLoading={ isLoading }
|
||||
noLink
|
||||
noIcon
|
||||
/>
|
||||
</Flex>
|
||||
)) }
|
||||
</DetailsInfoItem.Value>
|
||||
</>
|
||||
) }
|
||||
</Grid>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { Alert } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
import type * as bens from '@blockscout/bens-types';
|
||||
|
||||
import LinkExternal from 'ui/shared/links/LinkExternal';
|
||||
|
||||
interface Props {
|
||||
data: bens.DetailedDomain | undefined;
|
||||
}
|
||||
|
||||
const NameDomainDetailsAlert = ({ data }: Props) => {
|
||||
|
||||
if (!data?.stored_offchain || !data?.resolved_with_wildcard) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Alert status="info" colorScheme="gray" display="inline-block" whiteSpace="pre-wrap" mb={ 6 }>
|
||||
<span>The domain name is resolved offchain using </span>
|
||||
{ data.stored_offchain && <LinkExternal href="https://eips.ethereum.org/EIPS/eip-3668">EIP-3668: CCIP Read</LinkExternal> }
|
||||
{ data.stored_offchain && data.resolved_with_wildcard && <span> & </span> }
|
||||
{ data.resolved_with_wildcard && <LinkExternal href="https://eips.ethereum.org/EIPS/eip-2544">EIP-2544: Wildcard Resolution</LinkExternal> }
|
||||
</Alert>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(NameDomainDetailsAlert);
|
||||
@@ -327,8 +327,8 @@ const AddressPageContent = () => {
|
||||
<HStack ml="auto" gap={ 2 }/>
|
||||
{ !isLoading && addressQuery.data?.is_contract && addressQuery.data?.is_verified && config.UI.views.address.solidityscanEnabled &&
|
||||
<SolidityscanReport hash={ hash }/> }
|
||||
{ !isLoading && addressQuery.data && config.features.nameService.isEnabled &&
|
||||
<AddressEnsDomains query={ addressEnsDomainsQuery } addressHash={ hash } mainDomainName={ addressQuery.data.ens_domain_name }/> }
|
||||
{ !isLoading && addressEnsDomainsQuery.data && config.features.nameService.isEnabled &&
|
||||
<AddressEnsDomains query={ addressEnsDomainsQuery } addressHash={ hash } mainDomainName={ addressQuery.data?.ens_domain_name }/> }
|
||||
<NetworkExplorers type="address" pathParam={ hash }/>
|
||||
</Flex>
|
||||
);
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 110 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 41 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
@@ -1327,10 +1327,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
||||
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
||||
|
||||
"@blockscout/bens-types@1.3.4":
|
||||
version "1.3.4"
|
||||
resolved "https://registry.yarnpkg.com/@blockscout/bens-types/-/bens-types-1.3.4.tgz#e75b863c6d065e7d6d5d01e1a1d64da8df261640"
|
||||
integrity sha512-kKRa8jKu/CBLR3QbWpRXmtwIXiIwIPDrFeEPIYUQp5bg9uY+ActOyQERixo/9FE+BHZShWUDm+75FoaAmIGIOw==
|
||||
"@blockscout/bens-types@1.4.1":
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@blockscout/bens-types/-/bens-types-1.4.1.tgz#9182a79d9015b7fa2339edf0bfa3cd0c32045e66"
|
||||
integrity sha512-TlZ1HVdZ2Cswm/CcvNoxS+Ydiht/YGaLo//PJR/UmkmihlEFoY4HfVJvVcUnOQXi+Si7FwJ486DPii889nTJsQ==
|
||||
|
||||
"@blockscout/[email protected]":
|
||||
version "1.6.0"
|
||||
@@ -14899,16 +14899,7 @@ string-template@~0.2.1:
|
||||
resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add"
|
||||
integrity sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw==
|
||||
|
||||
"string-width-cjs@npm:string-width@^4.2.0":
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
dependencies:
|
||||
emoji-regex "^8.0.0"
|
||||
is-fullwidth-code-point "^3.0.0"
|
||||
strip-ansi "^6.0.1"
|
||||
|
||||
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
||||
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
@@ -15036,14 +15027,7 @@ string_decoder@~1.1.1:
|
||||
dependencies:
|
||||
safe-buffer "~5.1.0"
|
||||
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
dependencies:
|
||||
ansi-regex "^5.0.1"
|
||||
|
||||
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
@@ -16203,7 +16187,7 @@ word-wrap@^1.2.5, word-wrap@~1.2.3:
|
||||
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34"
|
||||
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
|
||||
|
||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
|
||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||
@@ -16221,15 +16205,6 @@ wrap-ansi@^6.2.0:
|
||||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
wrap-ansi@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||
dependencies:
|
||||
ansi-styles "^4.0.0"
|
||||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
wrap-ansi@^8.1.0:
|
||||
version "8.1.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
|
||||
|
||||
Reference in New Issue
Block a user