import { useCollections, useTokens } from '@reservoir0x/reservoir-kit-ui' import { Anchor, Button, Flex, Text, Tooltip } from 'components/primitives' import { ComponentPropsWithoutRef, FC, useRef, useState, useMemo } from 'react' import { faDiscord, faTwitter } from '@fortawesome/free-brands-svg-icons' import { faExternalLink, faGlobe, faInfoCircle, } from '@fortawesome/free-solid-svg-icons' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { styled } from '../../stitches.config' import { useTheme } from 'next-themes' import { useMarketplaceChain, useMounted } from 'hooks' import { truncateAddress } from 'utils/truncate' import ReactMarkdown from 'react-markdown' import { OpenSeaVerified } from 'components/common/OpenSeaVerified' import titleCase from 'utils/titleCase' import { useRouter } from 'next/router' import optimizeImage from 'utils/optimizeImage' import supportedChains, { DefaultChain } from 'utils/chains' type Props = { token: ReturnType['data'][0] | null collection: NonNullable['data']>[0] | null } export const TokenInfo: FC = ({ token, collection }) => { const marketplaceChain = useMarketplaceChain() const { theme } = useTheme() const [isExpanded, setIsExpanded] = useState(false) const descriptionRef = useRef(null) const isMounted = useMounted() const router = useRouter() const collectionChain = supportedChains.find( (chain) => router.query?.chain === chain.routePrefix ) || DefaultChain let chainName = collectionChain?.name const hasSecurityConfig = collection?.securityConfig && Object.values(collection.securityConfig).some(Boolean) const tokenStandard = `${token?.token?.kind}${hasSecurityConfig ? 'C' : ''}` const CollectionAction = styled(Flex, { px: '$4', py: '$3', color: '$gray12', background: '$gray3', cursor: 'pointer', transition: 'background 0.25s ease-in', height: 40, alignItems: 'center', '&:hover': { background: '$gray4', }, }) const collectionImage = useMemo(() => { return optimizeImage( token?.token?.collection?.image || collection?.image, 50 ) }, [token?.token?.collection?.image, collection?.image]) const etherscanImage = ( {`${ ) const blockExplorerUrl = `${ marketplaceChain?.blockExplorers?.default.url || 'https://etherscan.io' }/token/${token?.token?.contract}?a=${token?.token?.tokenId}` const twitterLink = collection?.twitterUsername ? `https://twitter.com/${collection?.twitterUsername}` : null const expandedCss: ComponentPropsWithoutRef['css'] = { maxWidth: '100%', display: '-webkit-box', WebkitBoxOrient: 'vertical', WebkitLineClamp: 2, textOverflow: 'ellipsis', overflow: 'hidden', verticalAlign: 'top', '*': { display: 'inline', }, } let isLongDescription = false if (descriptionRef.current) { isLongDescription = descriptionRef.current.offsetHeight > 50 } return ( <> {token?.token?.collection?.name || collection?.name} {collection?.description as string} {isLongDescription && ( )} {etherscanImage} {twitterLink && ( )} {collection?.discordUrl && ( )} {collection?.externalUrl && ( )} Contract Address {truncateAddress(token?.token?.contract as string)} Chain {chainName} Token ID {token?.token?.tokenId} Token Standard {tokenStandard} Creator Royalties A fee on every order that goes to the collection creator. } style={{ maxWidth: '210px' }} > {collection?.royalties?.bps ? collection?.royalties?.bps * 0.01 : 0} % ) }