+
+
+ BOTBATTLES ARENA
+
+
+
+
+ {!isConnected ? (
+
+
+ Connect Your Wallet
+
+
+ Connect your StarkNet wallet to start placing bets on AI agents.
+
+
+
+ ) : (
+
+
+
+
+ Place Your Bets
+
+
+ {agents.map((agent) => (
+
setSelectedAgent(agent)}
+ >
+
+
+
+
+
+ {agent.name}
+
+
+
66
+ ? "bg-green-400"
+ : agent.performance > 33
+ ? "bg-yellow-400"
+ : "bg-red-400"
+ } rounded-full`}
+ style={{ width: `${agent.performance}%` }}
+ />
+
+
+
+ ))}
+
+
+ {selectedAgent && (
+
+
+ Betting on: {selectedAgent.name}
+
+
+
+
+
+ setBetAmount(e.target.value)}
+ min="0.001"
+ step="0.001"
+ className={`
+ bg-gray-700 border-2 border-gray-500
+ font-pixel text-white px-3 py-2 rounded
+ focus:border-green-400 focus:ring-1 focus:ring-green-400
+ focus:outline-none
+ hover:border-gray-400
+ shadow-[0_2px_4px_rgba(0,0,0,0.25)]
+ transition-all
+ w-full
+ `}
+ />
+
+
+
+
+ )}
+
+
+
+
+
+
+ Transaction History
+
+
+ {transactions.length > 0 ? (
+ transactions.map((tx) => (
+
+
+ {tx.status === "confirmed" ? (
+
+ ) : tx.status === "failed" ? (
+
+ ) : (
+
+ )}
+
+
+
+ {tx.message}
+
+
+
+ {tx.status === "pending"
+ ? "Processing..."
+ : tx.status === "confirmed"
+ ? "Confirmed"
+ : "Failed"}
+
+
+ {new Date(tx.timestamp).toLocaleTimeString()}
+
+
+ {tx.status === "confirmed" && (
+
+ Tx: {tx.hash.substring(0, 10)}...
+ {tx.hash.substring(tx.hash.length - 6)}
+
+ )}
+
+
+
+ ))
+ ) : (
+
+ No transactions yet. Place a bet to get started!
+
+ )}
+
+
+
+
+
+ Wallet Info
+
+
+
+ Address:{" "}
+ {address}
+
+
+ Network: StarkNet
+
+
+
+
+
+ )}
+
+ );
+}
diff --git a/frontend/src/components/wallet-connect-button.tsx b/frontend/src/components/wallet-connect-button.tsx
new file mode 100644
index 0000000..4d8a3e8
--- /dev/null
+++ b/frontend/src/components/wallet-connect-button.tsx
@@ -0,0 +1,151 @@
+"use client";
+
+import { useState, useEffect, useRef } from "react";
+import {
+ useAccount,
+ useConnect,
+ useDisconnect,
+ type Connector,
+} from "@starknet-react/core";
+import { Wallet } from "lucide-react";
+// import { Button } from "@/components/ui/button";
+import { WalletDropdown } from "./wallet-dropdown";
+import { truncateAddress } from "@/utils/wallet";
+import WalletConnectModal from "./wallet-connect-modal";
+
+export function WalletConnectButton() {
+ const [isModalOpen, setIsModalOpen] = useState(false);
+ const [isDropdownOpen, setIsDropdownOpen] = useState(false);
+ const [isConnecting, setIsConnecting] = useState(false);
+ const [connectionError, setConnectionError] = useState
(null);
+ const dropdownTimeoutRef = useRef(null);
+
+ const { address, isConnected } = useAccount();
+ const { connect, connectors } = useConnect();
+ const { disconnect } = useDisconnect();
+
+ const handleConnect = () => {
+ if (isConnected) {
+ setIsDropdownOpen(!isDropdownOpen);
+ } else {
+ setIsModalOpen(true);
+ setConnectionError(null);
+ }
+ };
+
+ const handleDisconnect = () => {
+ disconnect();
+ setIsDropdownOpen(false);
+ localStorage.removeItem("lastUsedConnector");
+ };
+
+ const handleConnectorSelect = async (connector: Connector) => {
+ if (!connector) return;
+
+ setIsConnecting(true);
+ setConnectionError(null);
+
+ try {
+ await connect({ connector });
+
+ if (connector.id) {
+ localStorage.setItem("lastUsedConnector", connector.id);
+ }
+
+ // Only close modal after successful connection
+ setIsModalOpen(false);
+ } catch (error) {
+ const errorMessage =
+ error instanceof Error ? error.message : "Failed to connect wallet";
+ console.error("Wallet connection error:", errorMessage);
+ setConnectionError(errorMessage);
+ } finally {
+ setIsConnecting(false);
+ }
+ };
+
+ // Handle dropdown hover behavior
+ const handleMouseEnter = () => {
+ if (isConnected) {
+ if (dropdownTimeoutRef.current) {
+ clearTimeout(dropdownTimeoutRef.current);
+ dropdownTimeoutRef.current = null;
+ }
+ setIsDropdownOpen(true);
+ }
+ };
+
+ const handleMouseLeave = () => {
+ if (dropdownTimeoutRef.current) {
+ clearTimeout(dropdownTimeoutRef.current);
+ }
+
+ dropdownTimeoutRef.current = setTimeout(() => {
+ setIsDropdownOpen(false);
+ }, 300);
+ };
+
+ // Listen for wallet_disconnected events
+ useEffect(() => {
+ const handleWalletDisconnected = () => {
+ setIsDropdownOpen(false);
+ };
+
+ window.addEventListener("wallet_disconnected", handleWalletDisconnected);
+
+ return () => {
+ window.removeEventListener(
+ "wallet_disconnected",
+ handleWalletDisconnected
+ );
+
+ if (dropdownTimeoutRef.current) {
+ clearTimeout(dropdownTimeoutRef.current);
+ }
+ };
+ }, []);
+
+ return (
+
+ {/* Connect Button */}
+
+
+ {/* Wallet Connect Modal */}
+ {
+ if (!isConnecting) {
+ setIsModalOpen(false);
+ setConnectionError(null);
+ }
+ }}
+ onSelect={async (walletId) => {
+ const connector = connectors.find((c) => c.id === walletId);
+ if (connector) {
+ await handleConnectorSelect(connector);
+ }
+ }}
+ />
+
+ {/* Wallet Dropdown */}
+ {isConnected && address && (
+ setIsDropdownOpen(false)}
+ address={address}
+ onDisconnect={handleDisconnect}
+ />
+ )}
+
+ );
+}
diff --git a/frontend/src/components/wallet-connect-modal.tsx b/frontend/src/components/wallet-connect-modal.tsx
index 97d87bc..e215fc3 100644
--- a/frontend/src/components/wallet-connect-modal.tsx
+++ b/frontend/src/components/wallet-connect-modal.tsx
@@ -15,37 +15,21 @@ import {
interface WalletConnectModalProps {
isOpen: boolean;
onClose: () => void;
- onSelect: (wallet: string) => void;
+ onSelect: (wallet: string) => void; // Added this prop
}
export default function WalletConnectModal({
isOpen,
onClose,
+ onSelect, // Added this prop
}: WalletConnectModalProps) {
const [selectedWallet, setSelectedWallet] = useState(null);
- const { connectors, connectAsync } = useWalletContext();
+ const { connectors } = useWalletContext();
const handleSelect = (walletId: string) => {
setSelectedWallet(walletId);
};
- // ② On confirm, look up the connector object and call connectWallet
- const handleConfirm = async () => {
- if (!selectedWallet) return;
-
- const connector = connectors.find((c) => c.id === selectedWallet);
- if (!connector) {
- console.error("Connector not found:", selectedWallet);
- return;
- }
-
- try {
- await connectAsync({ connector }); // ■ await the wallet prompt
- onClose();
- } catch (err) {
- console.error("Wallet connection failed:", err); // ■ handle rejections
- }
- };
// helper to get icon source
function getIconSource(
@@ -116,10 +100,14 @@ export default function WalletConnectModal({
))}
- {/* ③ Confirmation button */}
+ {/* Connect button now triggers onSelect */}