terry-staging #16
@@ -0,0 +1,34 @@
|
||||
---
|
||||
title: "imToken in-app browser opens but does not log in — Quick Fix"
|
||||
type: quick-fix
|
||||
date: 2026-06-04
|
||||
---
|
||||
|
||||
# imToken in-app browser opens but does not log in — Quick Fix
|
||||
|
||||
## Bug
|
||||
|
||||
imToken can be opened from Chrome into its in-app browser, but the site does not complete wallet login.
|
||||
|
||||
## Root Cause
|
||||
|
||||
`AutoInjectedLogin` only started when the URL contained `?autoLogin=imToken`. imToken's deeplink/in-app-browser navigation can open the page while dropping or not preserving that query string, so the auto-login effect never ran even though the page was inside imToken and an injected provider was available.
|
||||
|
||||
## Fix
|
||||
|
||||
Added an imToken browser fallback: if no explicit `autoLogin` query parameter exists, but the current user agent is imToken, `AutoInjectedLogin` treats it as an imToken direct-login session and runs the same injected login path.
|
||||
|
||||
### Files Modified
|
||||
|
||||
- `src/wallet/AutoInjectedLogin.tsx` — starts imToken direct login based on imToken in-app-browser detection when the deeplink query is missing.
|
||||
- `src/wallet/injected.ts` — exports `isImTokenBrowser()` so the auto-login flow can reuse the imToken browser detection.
|
||||
|
||||
## Verification
|
||||
|
||||
- `npx tsc --noEmit`
|
||||
- `npm run format:check`
|
||||
- `npm test`
|
||||
|
||||
## Notes
|
||||
|
||||
This preserves the explicit `?autoLogin=` flow for TokenPocket and other wallets, while making imToken robust when the deeplink opens the page without the query parameter.
|
||||
@@ -2,6 +2,7 @@ import { useEffect } from "react";
|
||||
import {
|
||||
connectInjectedWallet,
|
||||
getInjectedWallet,
|
||||
isImTokenBrowser,
|
||||
signInWithInjectedWallet,
|
||||
type WalletKind,
|
||||
} from "./injected";
|
||||
@@ -47,9 +48,9 @@ function waitForInjected(kind: WalletKind): Promise<boolean> {
|
||||
/**
|
||||
* When the page is opened via a `?autoLogin=<wallet>` deeplink (typically from
|
||||
* 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.
|
||||
* `window.ethereum`, then complete wallet login without WalletConnect. imToken
|
||||
* may drop the query string while opening its in-app browser, so imToken browser
|
||||
* detection also starts the same direct-login path.
|
||||
*/
|
||||
export function AutoInjectedLogin() {
|
||||
const { completeLogin, status } = useWallet();
|
||||
@@ -57,11 +58,12 @@ export function AutoInjectedLogin() {
|
||||
useEffect(() => {
|
||||
if (typeof window === "undefined") return;
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const kind = parseKind(params.get(AUTO_LOGIN_PARAM));
|
||||
const explicitKind = parseKind(params.get(AUTO_LOGIN_PARAM));
|
||||
const kind = explicitKind ?? (isImTokenBrowser() ? "imToken" : null);
|
||||
if (!kind) return;
|
||||
if (status === "loading") return;
|
||||
|
||||
stripAutoLoginParam();
|
||||
if (explicitKind) stripAutoLoginParam();
|
||||
if (status === "loggedIn") return;
|
||||
|
||||
let cancelled = false;
|
||||
|
||||
@@ -138,7 +138,7 @@ export function getInjectedEthereum(): EthereumProvider | null {
|
||||
return maybeWindow.ethereum ?? null;
|
||||
}
|
||||
|
||||
function isImTokenBrowser(): boolean {
|
||||
export function isImTokenBrowser(): boolean {
|
||||
if (typeof navigator === "undefined") return false;
|
||||
return /imtoken/i.test(navigator.userAgent || "");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user