fix(wallet): handle desktop walletconnect reconnect

This commit is contained in:
TerryM
2026-06-02 22:18:35 +08:00
parent 4d38c4513d
commit 850daf3a2a
2 changed files with 54 additions and 16 deletions

View File

@@ -181,6 +181,16 @@ export function WalletLoginModal() {
</p> </p>
) : null} ) : null}
{selected ? (
<div className="mt-4 rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3 text-xs leading-5 text-neutral-400">
<p className="font-semibold text-neutral-200">Wallet debug</p>
<p>state: {wc.state}</p>
<p>connected: {wc.isConnected ? "yes" : "no"}</p>
<p className="break-all">address: {wc.address || "-"}</p>
<p>qr: {wc.qrUri ? "received" : "-"}</p>
</div>
) : null}
{selected ? ( {selected ? (
<p className="mt-4 text-xs leading-5 text-amber-300/80"> <p className="mt-4 text-xs leading-5 text-amber-300/80">
{t("walletNetworkWarning")} {t("walletNetworkWarning")}

View File

@@ -1,5 +1,5 @@
import { useCallback, useEffect, useRef, useState } from "react"; import { useCallback, useRef, useState } from "react";
import { useAccount, useConnect, useDisconnect } from "wagmi"; import { useConnect, useDisconnect } from "wagmi";
import { bsc } from "wagmi/chains"; import { bsc } from "wagmi/chains";
import { hasWalletConnectProjectId } from "./RainbowWalletProvider"; import { hasWalletConnectProjectId } from "./RainbowWalletProvider";
import type { WalletKind } from "./injected"; import type { WalletKind } from "./injected";
@@ -45,12 +45,12 @@ function walletConnectDeeplink(
export function useWalletConnectLogin() { export function useWalletConnectLogin() {
const available = hasWalletConnectProjectId(); const available = hasWalletConnectProjectId();
const { completeLogin } = useWallet(); const { completeLogin } = useWallet();
const { address, isConnected } = useAccount();
const { connectAsync, connectors } = useConnect(); const { connectAsync, connectors } = useConnect();
const { disconnect } = useDisconnect(); const { disconnect, disconnectAsync } = useDisconnect();
const [state, setState] = useState<WalletConnectLoginState>("idle"); const [state, setState] = useState<WalletConnectLoginState>("idle");
const [error, setError] = useState(""); const [error, setError] = useState("");
const [qrUri, setQrUri] = useState(""); const [qrUri, setQrUri] = useState("");
const [connectedAddress, setConnectedAddress] = useState("");
const pendingRef = useRef(false); const pendingRef = useRef(false);
const cleanupMessageRef = useRef<(() => void) | null>(null); const cleanupMessageRef = useRef<(() => void) | null>(null);
@@ -61,6 +61,7 @@ export function useWalletConnectLogin() {
setState("idle"); setState("idle");
setError(""); setError("");
setQrUri(""); setQrUri("");
setConnectedAddress("");
}, []); }, []);
const start = useCallback( const start = useCallback(
@@ -71,6 +72,7 @@ export function useWalletConnectLogin() {
if (!available) return; if (!available) return;
setError(""); setError("");
setQrUri(""); setQrUri("");
setConnectedAddress("");
pendingRef.current = true; pendingRef.current = true;
setState("connecting"); setState("connecting");
@@ -122,8 +124,27 @@ export function useWalletConnectLogin() {
connector.emitter.off("message", onMessage); connector.emitter.off("message", onMessage);
try { try {
await disconnectAsync().catch(() => undefined);
await connector.disconnect().catch(() => undefined); await connector.disconnect().catch(() => undefined);
await connectAsync({ chainId: bsc.id, connector }); const result = await connectAsync({ chainId: bsc.id, connector });
const connectedAddress = result.accounts[0];
if (!connectedAddress)
throw new Error("Wallet connected without an account");
pendingRef.current = false;
setConnectedAddress(connectedAddress);
console.info("[wallet-login] walletconnect connected", {
address: connectedAddress,
chain: "BNB Chain",
chainId: bsc.id,
});
window.alert(`扫码成功,已拿到钱包地址:\n${connectedAddress}`);
completeLogin(localWalletToken(connectedAddress), connectedAddress);
console.info("[wallet-login] local wallet session completed", {
address: connectedAddress,
});
setQrUri("");
setState("idle");
disconnect();
} catch (err) { } catch (err) {
pendingRef.current = false; pendingRef.current = false;
setState("idle"); setState("idle");
@@ -134,17 +155,24 @@ export function useWalletConnectLogin() {
cleanupMessageRef.current = null; cleanupMessageRef.current = null;
} }
}, },
[available, connectAsync, connectors], [
available,
completeLogin,
connectAsync,
connectors,
disconnect,
disconnectAsync,
],
); );
useEffect(() => { return {
if (!pendingRef.current || !isConnected || !address) return; available,
pendingRef.current = false; state,
completeLogin(localWalletToken(address), address); error,
setQrUri(""); qrUri,
setState("idle"); address: connectedAddress,
disconnect(); isConnected: Boolean(connectedAddress),
}, [address, completeLogin, disconnect, isConnected]); start,
reset,
return { available, state, error, qrUri, start, reset }; };
} }