From 17ce1956dec8242c0e85f4d8202e39c70a4590e6 Mon Sep 17 00:00:00 2001 From: aowheel Date: Tue, 30 Sep 2025 11:09:58 +0900 Subject: [PATCH] refactor: enhance logout functionality and improve network switch dialog --- pkgs/frontend/app/components/Header.tsx | 57 +++++++-- .../frontend/app/components/SwitchNetwork.tsx | 117 ++++++++++++++++-- 2 files changed, 155 insertions(+), 19 deletions(-) diff --git a/pkgs/frontend/app/components/Header.tsx b/pkgs/frontend/app/components/Header.tsx index 65e3153d..2194953c 100644 --- a/pkgs/frontend/app/components/Header.tsx +++ b/pkgs/frontend/app/components/Header.tsx @@ -76,14 +76,57 @@ export const Header = () => { return avatar ? ipfs2https(avatar) : undefined; }, [identity]); - const handleLogout = () => { - if (isSmartWallet) { - logout(); - } else { - if (wallets.find((w) => w.connectorType === "injected")) { - alert("ウォレット拡張機能から切断してください。"); + const handleLogout = async () => { + try { + if (isSmartWallet) { + // スマートウォレットの場合、Privyのlogoutを使用 + await logout(); } else { - Promise.all(wallets.map((wallet) => wallet.disconnect())); + // 外部ウォレット(MetaMaskなど)の場合 + const hasInjectedWallet = wallets.some( + (w) => w.connectorType === "injected", + ); + + if (hasInjectedWallet) { + // MetaMaskの権限を無効化 + try { + if (window.ethereum) { + await window.ethereum.request({ + method: "wallet_revokePermissions", + params: [{ eth_accounts: {} }], + }); + } + } catch (revokeError) { + console.warn("Failed to revoke MetaMask permissions:", revokeError); + } + } else { + // その他の外部ウォレットの場合 + // Privyのlogoutを実行してからウォレット切断を試行 + await logout(); + + // 切断可能なウォレットのみ切断 + for (const wallet of wallets) { + if (wallet.connectorType !== "injected") { + try { + wallet.disconnect(); + } catch (error) { + console.warn( + "Failed to disconnect wallet:", + wallet.address, + error, + ); + } + } + } + } + } + } catch (error) { + console.error("Logout failed:", error); + // エラーが発生した場合のフォールバック処理 + try { + await logout(); + } catch (logoutError) { + console.error("Fallback logout also failed:", logoutError); } } }; diff --git a/pkgs/frontend/app/components/SwitchNetwork.tsx b/pkgs/frontend/app/components/SwitchNetwork.tsx index 20db900c..ffb8945e 100644 --- a/pkgs/frontend/app/components/SwitchNetwork.tsx +++ b/pkgs/frontend/app/components/SwitchNetwork.tsx @@ -1,22 +1,115 @@ +import { Box, Button, Stack, Text } from "@chakra-ui/react"; import { currentChain } from "hooks/useViem"; import { useActiveWallet } from "hooks/useWallet"; -import { type FC, useEffect } from "react"; +import { type FC, useEffect, useState } from "react"; +import { + DialogBody, + DialogContent, + DialogFooter, + DialogHeader, + DialogRoot, + DialogTitle, +} from "./ui/dialog"; export const SwitchNetwork: FC = () => { const { connectedWallet } = useActiveWallet(); + const [isOpen, setIsOpen] = useState(false); + const [isSwitching, setIsSwitching] = useState(false); + // チェーン不一致の検出 useEffect(() => { - const switchChain = async () => { - if ( - connectedWallet && - Number(connectedWallet.chainId) !== currentChain.id - ) { - await connectedWallet.switchChain(currentChain.id); - } - }; - - switchChain(); + if (connectedWallet?.chainId) { + const isChainMismatch = + Number(connectedWallet.chainId.replace("eip155:", "")) !== + currentChain.id; + setIsOpen(isChainMismatch); + } else { + setIsOpen(false); + } }, [connectedWallet]); - return <>; + // チェーン切り替え処理 + const handleSwitchChain = async () => { + if (!connectedWallet) return; + + try { + setIsSwitching(true); + await connectedWallet.switchChain(currentChain.id); + setIsOpen(false); + } catch (error) { + console.error("Failed to switch chain:", error); + // エラー時はModalを開いたままにする + } finally { + setIsSwitching(false); + } + }; + + return ( + + + + + ネットワークの切り替えが必要です + + + + + + + 現在のネットワークは対応していません。以下のネットワークに切り替えてください。 + + + + + 現在のネットワーク + + + {connectedWallet?.chainId + ? `Chain ID: ${connectedWallet.chainId.replace("eip155:", "")}` + : "未接続"} + + + + + + 必要なネットワーク + + + {currentChain.name} (Chain ID: {currentChain.id}) + + + + + + + + + + + ); };