import { useState, useEffect } from "react"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Badge } from "@/components/ui/badge"; import { CheckCircle, AlertCircle, Copy, Unlink } from "lucide-react"; import { useAuth } from "@/contexts/AuthContext"; import { aethexToast } from "@/lib/aethex-toast"; const API_BASE = import.meta.env.VITE_API_BASE || ""; interface WalletVerificationProps { onWalletUpdated?: (walletAddress: string | null) => void; } const isValidEthereumAddress = (address: string): boolean => { return /^0x[a-fA-F0-9]{40}$/.test(address); }; const formatWalletAddress = (address: string): string => { if (!isValidEthereumAddress(address)) return address; return `${address.slice(0, 6)}...${address.slice(-4)}`; }; export const WalletVerification = ({ onWalletUpdated, }: WalletVerificationProps) => { const { user, profile } = useAuth(); const [walletInput, setWalletInput] = useState(""); const [connectedWallet, setConnectedWallet] = useState(null); const [isLoading, setIsLoading] = useState(false); const [isCopied, setIsCopied] = useState(false); useEffect(() => { // Initialize with existing wallet address if available if (profile?.wallet_address) { setConnectedWallet(profile.wallet_address); } }, [profile?.wallet_address]); const handleConnect = async () => { if (!walletInput.trim()) { aethexToast.warning("Please enter a wallet address"); return; } const normalized = walletInput.trim().toLowerCase(); if (!isValidEthereumAddress(normalized)) { aethexToast.warning( "Invalid Ethereum address. Must be 0x followed by 40 hexadecimal characters.", ); return; } if (!user?.id) { aethexToast.error("User not authenticated"); return; } setIsLoading(true); try { const response = await fetch(`${API_BASE}/api/profile/wallet-verify`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ user_id: user.id, wallet_address: normalized, }), }); if (!response.ok) { const errorData = await response.json().catch(() => ({})); throw new Error( errorData.error || `HTTP ${response.status}: Failed to connect wallet`, ); } const data = await response.json(); setConnectedWallet(normalized); setWalletInput(""); aethexToast.success("✅ Wallet connected successfully!"); if (onWalletUpdated) { onWalletUpdated(normalized); } } catch (error: any) { console.error("[Wallet Verification] Error:", error?.message); aethexToast.error( error?.message || "Failed to connect wallet. Please try again.", ); } finally { setIsLoading(false); } }; const handleDisconnect = async () => { if (!user?.id || !connectedWallet) return; setIsLoading(true); try { const response = await fetch(`${API_BASE}/api/profile/wallet-verify`, { method: "DELETE", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ user_id: user.id, }), }); if (!response.ok) { const errorData = await response.json().catch(() => ({})); throw new Error( errorData.error || `HTTP ${response.status}: Failed to disconnect wallet`, ); } setConnectedWallet(null); aethexToast.success("Wallet disconnected"); if (onWalletUpdated) { onWalletUpdated(null); } } catch (error: any) { console.error("[Wallet Verification] Error:", error?.message); aethexToast.error( error?.message || "Failed to disconnect wallet. Please try again.", ); } finally { setIsLoading(false); } }; const handleCopyAddress = () => { if (connectedWallet) { navigator.clipboard.writeText(connectedWallet); setIsCopied(true); setTimeout(() => setIsCopied(false), 2000); } }; return ( 🔐 Wallet Verification {connectedWallet && ( Connected )} Connect your Ethereum wallet to enable Web3 identity verification. This wallet address will be used to verify ownership of your{" "} .aethex TLD once the Axiom Protocol is live. {connectedWallet ? (
Connected Wallet
{formatWalletAddress(connectedWallet)}
{isCopied && (

✓ Copied to clipboard

)}

What's this for?

  • ✓ Proves you're the owner of this wallet (Web3 identity)
  • ✓ Will unlock your{" "} .aethex TLD verification when the Protocol launches
  • ✓ No smart contracts or gas fees required right now
  • ✓ Your wallet address is private and only visible to you
) : (

No wallet connected yet.

Enter your Ethereum wallet address below to verify your identity.

setWalletInput(e.target.value)} disabled={isLoading} className="mt-2 font-mono text-sm" />

Format: 0x followed by 40 hexadecimal characters

💡 How it works:

  1. 1. Enter your wallet address
  2. 2. We save it securely to your profile
  3. 3. When Phase 2 launches, we'll verify you own the .aethex TLD registered to this wallet
)}
); }; export default WalletVerification;