Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Certified contract icon for tokens in search and more #2425

Merged
merged 5 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions nextjs/csp/policies/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ export function app(): CspDev.DirectiveDescriptor {

'frame-ancestors': [
KEY_WORDS.SELF,

// allow remix.ethereum.org to embed our contract page in iframe
'remix.ethereum.org',
],

...((() => {
Expand Down
1 change: 1 addition & 0 deletions types/api/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface SearchResultToken {
is_verified_via_admin_panel: boolean;
is_smart_contract_verified: boolean;
filecoin_robust_address?: string | null;
certified?: boolean;
}

export interface SearchResultAddressOrContract {
Expand Down
2 changes: 1 addition & 1 deletion ui/nameDomain/NameDomainDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const NameDomainDetails = ({ query }: Props) => {
<>
<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"
hint="The date the name expires, upon which there is a grace period for the owner to renew. After grace period ends, the name is released to the market"
isLoading={ isLoading }
>
Expiration date
Expand Down
13 changes: 7 additions & 6 deletions ui/pages/Address.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import PageTitle from 'ui/shared/Page/PageTitle';
import RoutedTabs from 'ui/shared/Tabs/RoutedTabs';

const TOKEN_TABS = [ 'tokens_erc20', 'tokens_nfts', 'tokens_nfts_collection', 'tokens_nfts_list' ];
const PREDEFINED_TAG_PRIORITY = 100;

const txInterpretation = config.features.txInterpretation;
const addressProfileAPIFeature = config.features.addressProfileAPI;
Expand Down Expand Up @@ -275,12 +276,12 @@ const AddressPageContent = () => {
const tags: Array<EntityTag> = React.useMemo(() => {
return [
...(addressQuery.data?.public_tags?.map((tag) => ({ slug: tag.label, name: tag.display_name, tagType: 'custom' as const, ordinal: -1 })) || []),
!addressQuery.data?.is_contract ? { slug: 'eoa', name: 'EOA', tagType: 'custom' as const, ordinal: -1 } : undefined,
!addressQuery.data?.is_contract ? { slug: 'eoa', name: 'EOA', tagType: 'custom' as const, ordinal: PREDEFINED_TAG_PRIORITY } : undefined,
config.features.validators.isEnabled && addressQuery.data?.has_validated_blocks ?
{ slug: 'validator', name: 'Validator', tagType: 'custom' as const, ordinal: 10 } :
{ slug: 'validator', name: 'Validator', tagType: 'custom' as const, ordinal: PREDEFINED_TAG_PRIORITY } :
undefined,
addressQuery.data?.implementations?.length ? { slug: 'proxy', name: 'Proxy', tagType: 'custom' as const, ordinal: -1 } : undefined,
addressQuery.data?.token ? { slug: 'token', name: 'Token', tagType: 'custom' as const, ordinal: -1 } : undefined,
addressQuery.data?.implementations?.length ? { slug: 'proxy', name: 'Proxy', tagType: 'custom' as const, ordinal: PREDEFINED_TAG_PRIORITY } : undefined,
addressQuery.data?.token ? { slug: 'token', name: 'Token', tagType: 'custom' as const, ordinal: PREDEFINED_TAG_PRIORITY } : undefined,
isSafeAddress ? { slug: 'safe', name: 'Multisig: Safe', tagType: 'custom' as const, ordinal: -10 } : undefined,
addressProfileAPIFeature.isEnabled && usernameApiTag ? {
slug: 'username_api',
Expand All @@ -295,10 +296,10 @@ const AddressPageContent = () => {
},
} : undefined,
config.features.userOps.isEnabled && userOpsAccountQuery.data ?
{ slug: 'user_ops_acc', name: 'Smart contract wallet', tagType: 'custom' as const, ordinal: -10 } :
{ slug: 'user_ops_acc', name: 'Smart contract wallet', tagType: 'custom' as const, ordinal: PREDEFINED_TAG_PRIORITY } :
undefined,
config.features.mudFramework.isEnabled && mudTablesCountQuery.data ?
{ slug: 'mud', name: 'MUD World', tagType: 'custom' as const, ordinal: -10 } :
{ slug: 'mud', name: 'MUD World', tagType: 'custom' as const, ordinal: PREDEFINED_TAG_PRIORITY } :
undefined,
...formatUserTags(addressQuery.data),
...(addressMetadataQuery.data?.addresses?.[hash.toLowerCase()]?.tags.filter(tag => tag.tagType !== 'note') || []),
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions ui/searchResults/SearchResultListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ const SearchResultListItem = ({ data, searchTerm, isLoading, addressFormat }: Pr
textOverflow="ellipsis"
/>
</LinkInternal>
{ data.is_verified_via_admin_panel && <IconSvg name="certified" boxSize={ 4 } ml={ 1 } color="green.500"/> }
{ data.certified && <ContractCertifiedLabel iconSize={ 4 } boxSize={ 4 } ml={ 1 }/> }
{ data.is_verified_via_admin_panel && !data.certified && <IconSvg name="certified" boxSize={ 4 } ml={ 1 } color="green.500"/> }
</Flex>
);
}
Expand Down Expand Up @@ -385,7 +386,7 @@ const SearchResultListItem = ({ data, searchTerm, isLoading, addressFormat }: Pr
<chakra.span color="text_secondary">{ expiresText }</chakra.span>
) }
</Text>
{ data.certified && <ContractCertifiedLabel iconSize={ 5 } boxSize={ 5 } ml={ 1 }/> }
{ data.certified && <ContractCertifiedLabel iconSize={ 4 } boxSize={ 4 } ml={ 1 }/> }
</Flex>
) :
null;
Expand Down
5 changes: 3 additions & 2 deletions ui/searchResults/SearchResultTableItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ const SearchResultTableItem = ({ data, searchTerm, isLoading, addressFormat }: P
dangerouslySetInnerHTML={{ __html: highlightText(name, searchTerm) }}
/>
</LinkInternal>
{ data.is_verified_via_admin_panel && <IconSvg name="certified" boxSize={ 4 } ml={ 1 } color="green.500"/> }
{ data.certified && <ContractCertifiedLabel iconSize={ 4 } boxSize={ 4 } ml={ 1 }/> }
{ data.is_verified_via_admin_panel && !data.certified && <IconSvg name="certified" boxSize={ 4 } ml={ 1 } color="green.500"/> }
</Flex>
</Td>
<Td fontSize="sm" verticalAlign="middle">
Expand Down Expand Up @@ -154,7 +155,7 @@ const SearchResultTableItem = ({ data, searchTerm, isLoading, addressFormat }: P
<chakra.span color="text_secondary">{ expiresText }</chakra.span>
) }
</Text>
{ data.certified && <ContractCertifiedLabel iconSize={ 5 } boxSize={ 5 } mx={ 1 }/> }
{ data.certified && <ContractCertifiedLabel iconSize={ 4 } boxSize={ 4 } mx={ 1 }/> }
</Flex>
</Td>
) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const SearchBarSuggestAddress = ({ data, isMobile, searchTerm, addressFormat }:
<span>{ expiresText }</span>
) }
</Text>
{ data.certified && <ContractCertifiedLabel boxSize={ 5 } iconSize={ 5 } ml={ 1 }/> }
{ data.certified && <ContractCertifiedLabel boxSize={ 4 } iconSize={ 4 } ml={ 1 }/> }
</Flex>
);
const addressEl = <HashStringShortenDynamic hash={ hash } isTooltipDisabled/>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import type { SearchResultToken } from 'types/api/search';

import { toBech32Address } from 'lib/address/bech32';
import highlightText from 'lib/highlightText';
import ContractCertifiedLabel from 'ui/shared/ContractCertifiedLabel';
import * as TokenEntity from 'ui/shared/entities/token/TokenEntity';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import IconSvg from 'ui/shared/IconSvg';

const SearchBarSuggestToken = ({ data, isMobile, searchTerm, addressFormat }: ItemsProps<SearchResultToken>) => {
const icon = <TokenEntity.Icon token={{ ...data, type: data.token_type }}/>;
const verifiedIcon = <IconSvg name="certified" boxSize={ 4 } color="green.500" ml={ 1 }/>;
const certifiedIcon = <ContractCertifiedLabel iconSize={ 4 } boxSize={ 4 } ml={ 1 }/>;
const hash = data.filecoin_robust_address || (addressFormat === 'bech32' ? toBech32Address(data.address) : data.address);

const name = (
Expand Down Expand Up @@ -49,7 +51,8 @@ const SearchBarSuggestToken = ({ data, isMobile, searchTerm, addressFormat }: It
<Flex alignItems="center">
{ icon }
{ name }
{ data.is_verified_via_admin_panel && verifiedIcon }
{ data.certified && certifiedIcon }
{ data.is_verified_via_admin_panel && !data.certified && verifiedIcon }
</Flex>
<Grid templateColumns={ templateCols } alignItems="center" gap={ 2 }>
<Flex alignItems="center" overflow="hidden">
Expand All @@ -67,7 +70,8 @@ const SearchBarSuggestToken = ({ data, isMobile, searchTerm, addressFormat }: It
<Flex alignItems="center">
{ icon }
{ name }
{ data.is_verified_via_admin_panel && verifiedIcon }
{ data.certified && certifiedIcon }
{ data.is_verified_via_admin_panel && !data.certified && verifiedIcon }
</Flex>
<Flex alignItems="center" overflow="hidden">
{ address }
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 9 additions & 2 deletions ui/token/TokenPageTitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import PageTitle from 'ui/shared/Page/PageTitle';

import TokenVerifiedInfo from './TokenVerifiedInfo';

const PREDEFINED_TAG_PRIORITY = 100;

interface Props {
tokenQuery: UseQueryResult<TokenInfo, ResourceError<unknown>>;
addressQuery: UseQueryResult<Address, ResourceError<unknown>>;
Expand Down Expand Up @@ -69,13 +71,18 @@ const TokenPageTitle = ({ tokenQuery, addressQuery, hash }: Props) => {

const tags: Array<EntityTag> = React.useMemo(() => {
return [
tokenQuery.data ? { slug: tokenQuery.data?.type, name: getTokenTypeName(tokenQuery.data.type), tagType: 'custom' as const, ordinal: -20 } : undefined,
tokenQuery.data ? {
slug: tokenQuery.data?.type,
name: getTokenTypeName(tokenQuery.data.type),
tagType: 'custom' as const,
ordinal: PREDEFINED_TAG_PRIORITY,
} : undefined,
config.features.bridgedTokens.isEnabled && tokenQuery.data?.is_bridged ?
{
slug: 'bridged',
name: 'Bridged',
tagType: 'custom' as const,
ordinal: -10,
ordinal: PREDEFINED_TAG_PRIORITY,
meta: { bgColor: bridgedTokenTagBgColor, textColor: bridgedTokenTagTextColor },
} :
undefined,
Expand Down
6 changes: 3 additions & 3 deletions ui/tx/state/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export function getStateElements(data: TxStateChange, isLoading?: boolean) {
const changeSign = differenceBn.isGreaterThanOrEqualTo(0) ? '+' : '-';

return (
<Skeleton isLoaded={ !isLoading } display="inline-block" color={ changeColor }>
<Skeleton isLoaded={ !isLoading } display="inline-block" color={ changeColor } wordBreak="break-all">
<span>{ changeSign }{ nbsp }{ differenceBn.abs().toFormat() }</span>
</Skeleton>
);
Expand All @@ -132,14 +132,14 @@ export function getStateElements(data: TxStateChange, isLoading?: boolean) {
return {
before: data.balance_before ? (
<Flex whiteSpace="pre-wrap" justifyContent={{ base: 'flex-start', lg: 'flex-end' }} flexWrap="wrap">
<Skeleton isLoaded={ !isLoading }>{ beforeBn.toFormat() }</Skeleton>
<Skeleton isLoaded={ !isLoading } wordBreak="break-all">{ beforeBn.toFormat() }</Skeleton>
<span>{ space }</span>
{ tokenLink }
</Flex>
) : null,
after: data.balance_after ? (
<Flex whiteSpace="pre-wrap" justifyContent={{ base: 'flex-start', lg: 'flex-end' }} flexWrap="wrap">
<Skeleton isLoaded={ !isLoading }>{ afterBn.toFormat() }</Skeleton>
<Skeleton isLoaded={ !isLoading } wordBreak="break-all">{ afterBn.toFormat() }</Skeleton>
<span>{ space }</span>
{ tokenLink }
</Flex>
Expand Down
Loading