SolanaUISolanaUI

Address Display

A truncated address display with copy-to-clipboard and optional explorer link

MFv2...VacAMFv2...VacAMFv2hW...ebVacA
import { AddressDisplay } from "@/components/sol/address-display";

export function AddressDisplayDemo() {
  return (
    <AddressDisplay
      address="MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA"
      explorerUrl="https://solscan.io/account"
    />
  );
}

Installation

pnpm dlx shadcn@latest add @solanaui/address-display
npx shadcn@latest add @solanaui/address-display
yarn dlx shadcn@latest add @solanaui/address-display

Usage

Basic

<AddressDisplay address="MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA" />

Pass a base URL for the explorer. The address is appended automatically (e.g. https://solscan.io/account/MFv2...).

<AddressDisplay
  address="MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA"
  explorerUrl="https://solscan.io/account"
/>

Custom Truncation

<AddressDisplay
  address="MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA"
  truncateChars={[8, 8]}
/>

Source Code

"use client";import { CheckIcon, CopyIcon, ExternalLinkIcon } from "lucide-react";import React from "react";import { cn } from "@/lib/utils";interface AddressDisplayProps {  address: string;  truncate?: boolean;  truncateChars?: [number, number];  copyable?: boolean;  explorerUrl?: string;  className?: string;}const formatAddress = (  address: string,  truncate: boolean,  chars: [number, number],) => {  if (!truncate || address.length <= chars[0] + chars[1] + 3) return address;  return `${address.slice(0, chars[0])}...${address.slice(-chars[1])}`;};const AddressDisplay = ({  address,  truncate = true,  truncateChars = [4, 4],  copyable = true,  explorerUrl,  className,}: AddressDisplayProps) => {  const [copied, setCopied] = React.useState(false);  const handleCopy = async () => {    try {      await navigator.clipboard.writeText(address);      setCopied(true);      setTimeout(() => setCopied(false), 2000);    } catch {      console.error("Failed to copy address to clipboard");    }  };  const displayed = formatAddress(address, truncate, truncateChars);  const fullUrl = explorerUrl    ? `${explorerUrl.replace(/\/+$/, "")}/${address}`    : undefined;  return (    <span className={cn("inline-flex items-center gap-1.5", className)}>      <span className="font-mono text-sm text-muted-foreground">        {displayed}      </span>      {copyable && (        <button          type="button"          onClick={handleCopy}          className="text-muted-foreground hover:text-foreground transition-colors cursor-pointer"          aria-label="Copy address"        >          {copied ? (            <CheckIcon className="size-3.5 text-emerald-500" />          ) : (            <CopyIcon className="size-3.5" />          )}        </button>      )}      {fullUrl && (        <a          href={fullUrl}          target="_blank"          rel="noopener noreferrer"          className="text-muted-foreground hover:text-foreground transition-colors"          aria-label="View in explorer"        >          <ExternalLinkIcon className="size-3.5" />        </a>      )}    </span>  );};export type { AddressDisplayProps };export { AddressDisplay };