Skip to main content
Display the user’s wallet connection status with a visual indicator, showing wallet address and connection state.

Implementation

import { useMoonKey } from '@moon-key/react-auth';

export default function WalletStatus() {
  const { user, isAuthenticated, ready } = useMoonKey();

  if (!ready) {
    return <div className="wallet-status connecting">Connecting...</div>;
  }

  if (!isAuthenticated) {
    return <div className="wallet-status disconnected">Not Connected</div>;
  }

  const walletAddress = user?.wallet?.address;
  const shortAddress = walletAddress
    ? `${walletAddress.slice(0, 6)}...${walletAddress.slice(-4)}`
    : 'No wallet';

  return (
    <div className="wallet-status connected">
      <span className="status-dot" />
      <span className="address">{shortAddress}</span>
      {user?.email && <span className="email">{user.email.address}</span>}
    </div>
  );
}

Styling

.wallet-status {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 8px 16px;
  border-radius: 20px;
  font-size: 14px;
}

.wallet-status.connected {
  background: #d1fae5;
  color: #065f46;
}

.wallet-status.disconnected {
  background: #fee;
  color: #991b1b;
}

.wallet-status.connecting {
  background: #fef3c7;
  color: #92400e;
}

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
}

.address {
  font-family: monospace;
  font-weight: 600;
}

.email {
  opacity: 0.7;
  font-size: 12px;
}

Variants

Compact version

export function CompactWalletStatus() {
  const { user, isAuthenticated, ready } = useMoonKey();

  if (!ready || !isAuthenticated || !user?.wallet) {
    return null;
  }

  const shortAddress = `${user.wallet.address.slice(0, 4)}...${user.wallet.address.slice(-4)}`;

  return (
    <div className="compact-status">
      <span className="dot-connected" />
      {shortAddress}
    </div>
  );
}

With copy functionality

import { useState } from 'react';

export function CopyableWalletStatus() {
  const { user, isAuthenticated } = useMoonKey();
  const [copied, setCopied] = useState(false);

  if (!isAuthenticated || !user?.wallet) {
    return null;
  }

  const handleCopy = async () => {
    await navigator.clipboard.writeText(user.wallet.address);
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  };

  const shortAddress = `${user.wallet.address.slice(0, 6)}...${user.wallet.address.slice(-4)}`;

  return (
    <button className="wallet-status connected" onClick={handleCopy}>
      <span className="status-dot" />
      <span className="address">{shortAddress}</span>
      {copied ? <span>✓ Copied</span> : <span>Copy</span>}
    </button>
  );
}

With dropdown menu

import { useState } from 'react';
import { useLogout } from '@moon-key/react-auth';

export function WalletStatusMenu() {
  const { user, isAuthenticated } = useMoonKey();
  const { logout } = useLogout();
  const [isOpen, setIsOpen] = useState(false);

  if (!isAuthenticated || !user?.wallet) {
    return null;
  }

  const shortAddress = `${user.wallet.address.slice(0, 6)}...${user.wallet.address.slice(-4)}`;

  return (
    <div className="wallet-menu">
      <button 
        className="wallet-status connected"
        onClick={() => setIsOpen(!isOpen)}
      >
        <span className="status-dot" />
        <span className="address">{shortAddress}</span>
        <span className="dropdown-arrow"></span>
      </button>

      {isOpen && (
        <div className="dropdown-menu">
          <div className="menu-item">
            <strong>Wallet</strong>
            <div className="full-address">{user.wallet.address}</div>
          </div>
          <div className="menu-item">
            <strong>Email</strong>
            <div>{user.email?.address}</div>
          </div>
          <hr />
          <button className="menu-item" onClick={() => {
            navigator.clipboard.writeText(user.wallet.address);
          }}>
            Copy Address
          </button>
          <button className="menu-item danger" onClick={logout}>
            Disconnect
          </button>
        </div>
      )}
    </div>
  );
}

Header integration

export function Header() {
  const { isAuthenticated } = useMoonKey();

  return (
    <header className="site-header">
      <div className="logo">
        <img src="/logo.svg" alt="Logo" />
        <span>My App</span>
      </div>

      <nav className="nav-links">
        <a href="/dashboard">Dashboard</a>
        <a href="/wallet">Wallet</a>
        <a href="/settings">Settings</a>
      </nav>

      <div className="header-actions">
        {isAuthenticated ? (
          <WalletStatus />
        ) : (
          <button className="login-button">Connect Wallet</button>
        )}
      </div>
    </header>
  );
}

Key features

  • Connection state - Shows connecting, connected, or disconnected status
  • Address formatting - Truncates long addresses for better display
  • Visual indicator - Colored dot shows connection status at a glance
  • Additional info - Can display email or other user information
  • Copy functionality - Easy to add clipboard copy feature
  • Extensible - Can be expanded with menus, dropdowns, etc.

Important notes

The status indicator automatically updates when the user logs in or out, thanks to MoonKey’s reactive hooks.
Place the wallet status in your app’s header or navigation bar for constant visibility.

Next steps