'use client'; 'use no memo'; // fixes rerendering with react compiler import { AddressAvatar } from '@/components/blocks/address-avatar/address-avatar'; import { Badge } from '@/components/ui/badge'; import { CopyToClipboard } from '@/components/ui/copy'; import { HoverCard, HoverCardContent, HoverCardTrigger } from '@/components/ui/hover-card'; import { Skeleton } from '@/components/ui/skeleton'; import { useQueryKeys } from '@/hooks/use-query-keys'; import { getBlockExplorerAddressUrl } from '@/lib/block-explorer'; import { shortHex } from '@/lib/hex'; import { hasuraClient, hasuraGraphql } from '@/lib/settlemint/hasura'; import { theGraphClientStarterkits, theGraphGraphqlStarterkits } from '@/lib/settlemint/the-graph'; import { useSuspenseQuery } from '@tanstack/react-query'; import Link from 'next/link'; import { type FC, type PropsWithChildren, Suspense } from 'react'; import type { Address } from 'viem'; import { getAddress } from 'viem'; interface EvmAddressProps extends PropsWithChildren { /** The EVM address to display. */ address: Address; name?: string; symbol?: string; /** The URL of the blockchain explorer (optional). */ explorerUrl?: string; prefixLength?: number; suffixLength?: number; iconSize?: 'tiny' | 'small' | 'big'; prettyNames?: boolean; verbose?: boolean; hoverCard?: boolean; copyToClipboard?: boolean; } interface User { name: string; image: string | null; email: string; } interface Asset { name: string; symbol: string; } const EvmAddressUser = hasuraGraphql(` query EvmAddressUser($id: String!) { user(where: { wallet: { _eq: $id } }) { name image email } } `); const EvmAddressAsset = theGraphGraphqlStarterkits(` query EvmAddressAsset($id: ID = "") { asset(id: $id) { name symbol } } `); /** * Renders an EVM address with a hover card displaying additional information. * @param props - The component props. * @returns The rendered EvmAddress component. */ export function EvmAddress({ address, name, symbol, explorerUrl, children, prefixLength = 6, suffixLength = 4, iconSize = 'tiny', prettyNames = true, verbose = false, hoverCard = true, copyToClipboard = false, }: EvmAddressProps) { const { keys } = useQueryKeys(); const { data: user } = useSuspenseQuery({ queryKey: keys.user.profile({ address: getAddress(address) }), queryFn: async () => { const result = await hasuraClient.request(EvmAddressUser, { id: getAddress(address), }); return result.user[0] ?? null; }, }); const { data: asset } = useSuspenseQuery({ queryKey: keys.asset.detail({ address }), queryFn: async () => { try { const result = await theGraphClientStarterkits.request(EvmAddressAsset, { id: getAddress(address), }); return result.asset ?? null; } catch { return null; } }, }); const displayName = prettyNames ? (name ?? asset?.name ?? user?.name) : undefined; const displayEmail = prettyNames ? user?.email : undefined; const explorerLink = getBlockExplorerAddressUrl(address, explorerUrl); const MainView: FC = () => { return (
}> {!displayName && {shortHex(address, { prefixLength, suffixLength })}} {displayName && ( {displayName} {symbol && ({symbol}) } {verbose && ( {shortHex(getAddress(address), { prefixLength, suffixLength })} )} )} {copyToClipboard && }
); }; if (!hoverCard) { return ; } return (

}>
{address} {displayName && ( {displayName} {symbol && ({symbol})} )} {explorerLink && ( View on the explorer )}

{children}
); }