diff --git a/NetworkBadge.tsx b/NetworkBadge.tsx new file mode 100644 index 00000000..80be715d --- /dev/null +++ b/NetworkBadge.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import { AlertCircle, Globe } from 'lucide-react'; +import { Badge } from '@/components/ui/badge'; +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'; + +const SUPPORTED_NETWORKS: Record = { + 1: 'Ethereum', + 137: 'Polygon', + 56: 'BSC', +}; + +export const NetworkBadge: React.FC<{ chainId: number | null }> = ({ chainId }) => { + const isSupported = chainId !== null && !!SUPPORTED_NETWORKS[chainId]; + const networkName = isSupported ? SUPPORTED_NETWORKS[chainId!] : 'Unsupported Network'; + + if (!isSupported) { + return ( + + + + + + Unsupported + + + +

Please switch to Ethereum, Polygon, or BSC

+
+
+
+ ); + } + + return ( + + + {networkName} + + ); +}; \ No newline at end of file diff --git a/WalletConnector.tsx b/WalletConnector.tsx new file mode 100644 index 00000000..cfd3e9a4 --- /dev/null +++ b/WalletConnector.tsx @@ -0,0 +1,114 @@ +import React, { useState } from 'react'; +import { useWalletStore } from '@/store/walletStore'; +import { useWalletConnector } from '@/hooks/useWalletConnector'; +import { Button } from '@/components/ui/button'; +import { WalletModal } from '@/components/WalletModal'; +import { NetworkBadge } from './NetworkBadge'; +import { CopyButton } from '@/components/ui/CopyButton'; +import { + Loader2, + LogOut, + Wallet, + ChevronDown, + ShieldCheck +} from 'lucide-react'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, + DropdownMenuSeparator +} from '@/components/ui/dropdown-menu'; + +export const WalletConnector: React.FC = () => { + const [isModalOpen, setIsModalOpen] = useState(false); + const { isConnected, address, chainId, disconnect, isConnecting } = useWalletStore(); + const { isLoadingConnector } = useWalletConnector(); + + // Show connecting state if either the chunk is loading or the wallet is authenticating + const isPending = isConnecting || isLoadingConnector; + + const handleDisconnect = () => { + disconnect(); + }; + + const formatAddress = (addr: string) => { + return `${addr.substring(0, 6)}...${addr.substring(addr.length - 4)}`; + }; + + if (!isConnected) { + return ( + <> + + + setIsModalOpen(false)} + /> + + ); + } + + return ( +
+ {/* Network detection happens inside the Badge */} + + + + + + + + +
+
+ Wallet Address + {address} +
+ +
+ + + + + +
+ KYC Status + Verified +
+
+ + + + + + Disconnect + +
+
+
+ ); +}; \ No newline at end of file diff --git a/walletStore.ts b/walletStore.ts new file mode 100644 index 00000000..0a5d78c1 --- /dev/null +++ b/walletStore.ts @@ -0,0 +1,56 @@ +import { create } from 'zustand'; +import { persist } from 'zustand/middleware'; + +interface WalletState { + address: string | null; + chainId: number | null; + isConnected: boolean; + isConnecting: boolean; + error: string | null; + + // Actions + setConnection: (address: string, chainId: number) => void; + setConnecting: (isConnecting: boolean) => void; + setError: (error: string | null) => void; + disconnect: () => void; + updateChainId: (chainId: number) => void; +} + +export const useWalletStore = create()( + persist( + (set) => ({ + address: null, + chainId: null, + isConnected: false, + isConnecting: false, + error: null, + + setConnection: (address, chainId) => set({ + address, + chainId, + isConnected: true, + isConnecting: false, + error: null, + }), + + setConnecting: (isConnecting) => set({ isConnecting }), + + setError: (error) => set({ error, isConnecting: false }), + + updateChainId: (chainId) => set({ chainId }), + + disconnect: () => set({ + address: null, + chainId: null, + isConnected: false, + isConnecting: false, + error: null, + }), + }), + { + name: 'propchain-wallet-storage', + // Only persist connection info, not transient loading/error states + partialize: (state) => ({ address: state.address, chainId: state.chainId, isConnected: state.isConnected }), + } + ) +); \ No newline at end of file