- Backend REST/gateway/track routes, analytics, Blockscout proxy paths. - Frontend wallet and liquidity surfaces; MetaMask token list alignment. - Deployment docs, verification scripts, address inventory updates. Check: go build ./... under backend/ (pass). Made-with: Cursor
76 lines
2.3 KiB
TypeScript
76 lines
2.3 KiB
TypeScript
import { useState } from 'react'
|
|
import clsx from 'clsx'
|
|
|
|
interface AddressProps {
|
|
address: string
|
|
chainId?: number
|
|
showCopy?: boolean
|
|
showENS?: boolean
|
|
truncate?: boolean
|
|
className?: string
|
|
}
|
|
|
|
export function Address({
|
|
address,
|
|
chainId,
|
|
showCopy = true,
|
|
showENS = false,
|
|
truncate = false,
|
|
className,
|
|
}: AddressProps) {
|
|
const [copied, setCopied] = useState(false)
|
|
|
|
const displayAddress = truncate
|
|
? `${address.slice(0, 6)}...${address.slice(-4)}`
|
|
: address
|
|
|
|
const handleCopy = async () => {
|
|
try {
|
|
await navigator.clipboard.writeText(address)
|
|
setCopied(true)
|
|
setTimeout(() => setCopied(false), 2000)
|
|
} catch {
|
|
setCopied(false)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div
|
|
className={clsx(
|
|
'flex min-w-0 items-start gap-2',
|
|
truncate ? 'flex-nowrap' : 'flex-wrap',
|
|
className
|
|
)}
|
|
>
|
|
<span
|
|
className={clsx(
|
|
'min-w-0 font-mono text-sm leading-6 text-gray-900 dark:text-gray-100',
|
|
truncate ? 'truncate' : 'break-all'
|
|
)}
|
|
>
|
|
{displayAddress}
|
|
</span>
|
|
{showCopy && (
|
|
<button
|
|
type="button"
|
|
onClick={handleCopy}
|
|
className="shrink-0 rounded-md p-1 text-gray-500 transition hover:bg-gray-100 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-gray-800 dark:hover:text-gray-200"
|
|
title="Copy address"
|
|
aria-label="Copy address"
|
|
>
|
|
{copied ? (
|
|
<svg className="h-4 w-4" viewBox="0 0 20 20" fill="currentColor" aria-hidden>
|
|
<path fillRule="evenodd" d="M16.704 5.29a1 1 0 0 1 .006 1.414l-7.25 7.313a1 1 0 0 1-1.42 0L4.79 10.766a1 1 0 1 1 1.414-1.414l2.546 2.546 6.544-6.602a1 1 0 0 1 1.41-.006Z" clipRule="evenodd" />
|
|
</svg>
|
|
) : (
|
|
<svg className="h-4 w-4" viewBox="0 0 20 20" fill="currentColor" aria-hidden>
|
|
<path d="M6 2.75A2.25 2.25 0 0 0 3.75 5v8A2.25 2.25 0 0 0 6 15.25h1.25V14H6A1 1 0 0 1 5 13V5a1 1 0 0 1 1-1h5a1 1 0 0 1 1 1v1.25h1.25V5A2.25 2.25 0 0 0 11 2.75H6Z" />
|
|
<path d="M9 6.75A2.25 2.25 0 0 0 6.75 9v6A2.25 2.25 0 0 0 9 17.25h5A2.25 2.25 0 0 0 16.25 15V9A2.25 2.25 0 0 0 14 6.75H9Zm0 1.25h5a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1Z" />
|
|
</svg>
|
|
)}
|
|
</button>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|