diff --git a/apps/dashboard/src/components/buttons/MismatchButton.tsx b/apps/dashboard/src/components/buttons/MismatchButton.tsx index fc5865f5a1e..69e3f9364a0 100644 --- a/apps/dashboard/src/components/buttons/MismatchButton.tsx +++ b/apps/dashboard/src/components/buttons/MismatchButton.tsx @@ -42,10 +42,11 @@ import { useActiveAccount, useActiveWallet, useActiveWalletChain, + useActiveWalletConnectionStatus, useSwitchActiveWalletChain, useWalletBalance, } from "thirdweb/react"; -import { privateKeyToAccount } from "thirdweb/wallets"; +import { type Wallet, privateKeyToAccount } from "thirdweb/wallets"; import { getFaucetClaimAmount } from "../../app/(app)/api/testnet-faucet/claim/claim-amount"; import { useAllChainsData } from "../../hooks/chains/allChains"; import { useV5DashboardChain } from "../../lib/v5-adapter"; @@ -78,6 +79,7 @@ function useIsNetworkMismatch(txChainId: number) { type MistmatchButtonProps = React.ComponentProps & { txChainId: number; isLoggedIn: boolean; + isPending: boolean; }; export const MismatchButton = forwardRef< @@ -93,6 +95,7 @@ export const MismatchButton = forwardRef< const client = useThirdwebClient(); const pathname = usePathname(); const txChain = useV5DashboardChain(txChainId); + const connectionStatus = useActiveWalletConnectionStatus(); const txChainBalance = useWalletBalance({ address: account?.address, @@ -101,14 +104,39 @@ export const MismatchButton = forwardRef< }); const networksMismatch = useIsNetworkMismatch(txChainId); + const switchNetwork = useSwitchActiveWalletChain(); + + const showSwitchChainPopover = + networksMismatch && wallet && !canSwitchNetworkWithoutConfirmation(wallet); + const [isMismatchPopoverOpen, setIsMismatchPopoverOpen] = useState(false); const trackEvent = useTrack(); const chainId = activeWalletChain?.id; + const switchNetworkMutation = useMutation({ + mutationFn: switchNetwork, + }); + const eventRef = useRef>(undefined); + if (connectionStatus === "connecting") { + return ( + + ); + } + if (!wallet || !chainId || !isLoggedIn) { return ( @@ -545,3 +586,7 @@ const GetLocalHostTestnetFunds: React.FC = () => { ); }; + +function canSwitchNetworkWithoutConfirmation(wallet: Wallet) { + return wallet.id === "inApp" || wallet.id === "smart"; +} diff --git a/apps/dashboard/src/components/buttons/TransactionButton.tsx b/apps/dashboard/src/components/buttons/TransactionButton.tsx index dbd9b36a4e4..98f323e1c5a 100644 --- a/apps/dashboard/src/components/buttons/TransactionButton.tsx +++ b/apps/dashboard/src/components/buttons/TransactionButton.tsx @@ -1,5 +1,4 @@ "use client"; -import { Spinner } from "@/components/ui/Spinner/Spinner"; import { Button } from "@/components/ui/button"; import { Popover, @@ -17,8 +16,9 @@ import { useActiveAccount, useActiveWallet, useActiveWalletChain, + useConnectedWallets, } from "thirdweb/react"; -import type { WalletId } from "thirdweb/wallets"; +import type { Wallet, WalletId } from "thirdweb/wallets"; import { MismatchButton } from "./MismatchButton"; type ButtonProps = React.ComponentProps; @@ -26,7 +26,6 @@ type ButtonProps = React.ComponentProps; type TransactionButtonProps = Omit & { transactionCount: number | undefined; // support for unknown number of tx count isPending: boolean; - isGasless?: boolean; txChainID: number; variant?: "destructive" | "primary" | "default"; isLoggedIn: boolean; @@ -36,19 +35,17 @@ export const TransactionButton: React.FC = ({ children, transactionCount, isPending, - isGasless, txChainID, variant, isLoggedIn, ...restButtonProps }) => { const activeWallet = useActiveWallet(); - + const connectedWallets = useConnectedWallets(); // all wallets except inApp (aka - embedded) requires external confirmation - either from mobile app or extension const walletRequiresExternalConfirmation = activeWallet && - activeWallet.id !== "inApp" && - activeWallet.id !== "embedded"; + !canSendTransactionWithoutConfirmation(activeWallet, connectedWallets); const initialFocusRef = useRef(null); @@ -58,17 +55,14 @@ export const TransactionButton: React.FC = ({ [chain], ); - const ButtonComponent = useMemo(() => { - return isGasless ? Button : MismatchButton; - }, [isGasless]); - const txCountDivWidth = 60; const disabled = isChainDeprecated || restButtonProps.disabled || isPending; return ( - = ({ {children} - {isPending && } - + @@ -200,3 +193,23 @@ const ExternalApprovalNotice: React.FC = ({ ); }; + +function canSendTransactionWithoutConfirmation( + wallet: Wallet, + connectedWallets: Wallet[], +) { + // inApp wallet + if (wallet.id === "inApp") { + return true; + } + + // smart wallet + inApp admin wallet + if (wallet.id === "smart") { + const adminWallet = connectedWallets.find( + (w) => w.getAccount()?.address === wallet.getAdminAccount?.()?.address, + ); + return adminWallet?.id === "inApp"; + } + + return false; +}