From 93790cb885df42874f98ec5b7a5bdeeda57b3c8b Mon Sep 17 00:00:00 2001 From: TerryM Date: Thu, 4 Jun 2026 09:36:20 +0800 Subject: [PATCH] fix: remove wallet verification popup --- ...04-remove-wallet-verification-popup-fix.md | 37 +++++ src/locales/en.ts | 7 - src/locales/zh-CN.ts | 6 - src/wallet/AutoInjectedLogin.tsx | 155 ++---------------- src/wallet/injected.ts | 11 -- 5 files changed, 54 insertions(+), 162 deletions(-) create mode 100644 .unipi/docs/fix/2026-06-04-remove-wallet-verification-popup-fix.md diff --git a/.unipi/docs/fix/2026-06-04-remove-wallet-verification-popup-fix.md b/.unipi/docs/fix/2026-06-04-remove-wallet-verification-popup-fix.md new file mode 100644 index 0000000..8f5dabe --- /dev/null +++ b/.unipi/docs/fix/2026-06-04-remove-wallet-verification-popup-fix.md @@ -0,0 +1,37 @@ +--- +title: "Remove wallet address verification popup — Quick Fix" +type: quick-fix +date: 2026-06-04 +--- + +# Remove wallet address verification popup — Quick Fix + +## Bug + +The in-app-browser wallet address verification popup added friction and interfered with imToken login. The requested behavior is to remove that popup and keep the deeplink login flow direct. + +## Root Cause + +`AutoInjectedLogin` rendered a blocking confirmation dialog for `?autoLogin=` deeplink sessions before calling the injected wallet signature flow. That UI was unnecessary for the current wallet-login flow and could block or confuse imToken users. + +## Fix + +Removed the verification dialog and restored direct deeplink behavior: after the wallet in-app browser injects `window.ethereum`, the app calls `signInWithInjectedWallet()` and completes backend-verified login. Existing logged-in sessions still skip auto-login after stripping the deeplink parameter. + +### Files Modified + +- `src/wallet/AutoInjectedLogin.tsx` — removes the verification popup UI and auto-runs signature login for logged-out deeplink sessions. +- `src/wallet/injected.ts` — removes now-unused connected-address helper. +- `src/locales/zh-CN.ts` — removes unused verification popup copy. +- `src/locales/en.ts` — removes unused verification popup copy. + +## Verification + +- `rg -n "walletVerifyAddress|walletDetectedAddress|getConnectedInjectedAddress|wallet-verify" src || true` +- `npx tsc --noEmit` +- `npm run format:check` +- `npm test` + +## Notes + +The imToken injected-provider fallback remains in place; only the confirmation popup and its supporting copy/helper were removed. diff --git a/src/locales/en.ts b/src/locales/en.ts index 7ca97d5..2a6ad69 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -197,13 +197,6 @@ export const enDict: Dict = { walletTpLoginBtn: "Log in with TokenPocket", walletTpWaiting: "Waiting for your signature in TokenPocket…", walletTpReopen: "Reopen TokenPocket", - walletVerifyAddressTitle: "Verify wallet address", - walletVerifyAddressDesc: - "Confirm the wallet address you want to use. After you tap the button below, your wallet app will ask you to sign and verify the address.", - walletDetectedAddress: "Detected wallet address", - walletVerifyAddressUnknown: - "The wallet address will be requested after verification", - walletVerifyAddressButton: "Verify this address", favoritesFilters: "Filters", favoriteSessionExpired: "Your session expired. Please sign in again.", loadFailed: "Could not load your favorites.", diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index b1cd668..795a631 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -186,12 +186,6 @@ export const zhDict: Dict = { walletTpLoginBtn: "使用 TokenPocket 登录", walletTpWaiting: "等待你在 TokenPocket 中完成签名…", walletTpReopen: "重新打开 TokenPocket", - walletVerifyAddressTitle: "验证钱包地址", - walletVerifyAddressDesc: - "请确认将使用当前钱包地址登录。点击下方按钮后,钱包 App 会要求你签名验证地址。", - walletDetectedAddress: "检测到的钱包地址", - walletVerifyAddressUnknown: "点击验证后将请求钱包地址", - walletVerifyAddressButton: "验证此地址", favoritesFilters: "筛选", favoriteSessionExpired: "登录已过期,请重新登录。", loadFailed: "无法加载收藏,请稍后重试。", diff --git a/src/wallet/AutoInjectedLogin.tsx b/src/wallet/AutoInjectedLogin.tsx index 31b2d0a..0ef2d80 100644 --- a/src/wallet/AutoInjectedLogin.tsx +++ b/src/wallet/AutoInjectedLogin.tsx @@ -1,25 +1,15 @@ -import { useCallback, useEffect, useState } from "react"; -import { useI18n } from "../i18n"; +import { useEffect } from "react"; import { - getConnectedInjectedAddress, getInjectedWallet, signInWithInjectedWallet, type WalletKind, } from "./injected"; -import { shortenAddress, useWallet } from "./WalletProvider"; +import { useWallet } from "./WalletProvider"; const AUTO_LOGIN_PARAM = "autoLogin"; const ETHEREUM_WAIT_MS = 8000; const ETHEREUM_POLL_MS = 200; -type AutoLoginRequest = { - kind: WalletKind; - ready: boolean; - address: string | null; - signing: boolean; - error: string; -}; - function parseKind(value: string | null): WalletKind | null { if (value === "tokenPocket" || value === "metaMask" || value === "imToken") { return value; @@ -55,15 +45,13 @@ function waitForInjected(kind: WalletKind): Promise { /** * When the page is opened via a `?autoLogin=` deeplink (typically from - * inside TokenPocket / imToken in-app browsers), show an explicit verification - * prompt first. The wallet signature and backend verification only start after - * the user taps the verification button, so Chrome -> wallet handoff never logs - * in silently from a cached in-app-browser session. + * inside TokenPocket / imToken in-app browsers), wait for the wallet to inject + * `window.ethereum`, then require a wallet signature and complete a verified + * backend wallet session. Bypasses WalletConnect entirely so it works on + * networks where the WC relay is blocked. */ export function AutoInjectedLogin() { - const { t } = useI18n(); const { completeLogin, status } = useWallet(); - const [request, setRequest] = useState(null); useEffect(() => { if (typeof window === "undefined") return; @@ -73,133 +61,24 @@ export function AutoInjectedLogin() { if (status === "loading") return; stripAutoLoginParam(); - if (status === "loggedIn") { - setRequest(null); - return; - } + if (status === "loggedIn") return; let cancelled = false; - setRequest({ - kind, - ready: false, - address: null, - signing: false, - error: "", - }); - void waitForInjected(kind).then(async (ready) => { - if (cancelled) return; - if (!ready) { - setRequest((current) => - current?.kind === kind - ? { ...current, ready: false, error: t("walletNoBrowserWallet") } - : current, - ); - return; + if (cancelled || !ready) return; + try { + const res = await signInWithInjectedWallet(kind); + if (cancelled) return; + completeLogin(res.token, res.wallet); + } catch (err) { + // eslint-disable-next-line no-console + console.warn("[wallet-autologin] failed", err); } - - const address = await getConnectedInjectedAddress(kind); - if (cancelled) return; - setRequest((current) => - current?.kind === kind - ? { ...current, ready: true, address, error: "" } - : current, - ); }); - return () => { cancelled = true; }; - }, [status, t]); + }, [completeLogin, status]); - const verifyAddress = useCallback(async () => { - if (!request || !request.ready || request.signing) return; - - setRequest((current) => - current ? { ...current, signing: true, error: "" } : current, - ); - try { - const res = await signInWithInjectedWallet(request.kind); - completeLogin(res.token, res.wallet); - setRequest(null); - } catch (err) { - const message = - err instanceof Error ? err.message : t("walletLoginFailed"); - setRequest((current) => - current - ? { - ...current, - signing: false, - error: message || t("walletLoginFailed"), - } - : current, - ); - // eslint-disable-next-line no-console - console.warn("[wallet-autologin] verification failed", err); - } - }, [completeLogin, request, t]); - - if (!request) return null; - - const addressLabel = request.address - ? shortenAddress(request.address) - : t("walletVerifyAddressUnknown"); - - return ( -
-
-

- {t(walletNameKey(request.kind))} -

-

- {t("walletVerifyAddressTitle")} -

-

- {t("walletVerifyAddressDesc")} -

- -
-

- {t("walletDetectedAddress")} -

-

- {addressLabel} -

-
- - {request.error ? ( -

- {request.error} -

- ) : null} - - -
-
- ); -} - -function walletNameKey(kind: WalletKind): string { - if (kind === "tokenPocket") return "walletTokenPocket"; - if (kind === "metaMask") return "walletMetaMask"; - return "walletImToken"; + return null; } diff --git a/src/wallet/injected.ts b/src/wallet/injected.ts index 0d811c6..992478a 100644 --- a/src/wallet/injected.ts +++ b/src/wallet/injected.ts @@ -166,17 +166,6 @@ export function getInjectedWallet(kind?: WalletKind): EthereumProvider | null { return null; } -export async function getConnectedInjectedAddress( - kind?: WalletKind, -): Promise { - const ethereum = getInjectedWallet(kind); - if (!ethereum) return null; - const accounts = await ethereum - .request({ method: "eth_accounts" }) - .catch((): unknown[] => []); - return accounts.find(isAddress) ?? null; -} - /** Diagnostic: log what injected providers the browser exposes. */ export function logWalletProviders(): void { const ethereum = getInjectedEthereum();