7.6 KiB
title, type, date, severity, status
| title | type | date | severity | status |
|---|---|---|---|---|
| imToken opens in-app browser but cannot get wallet address — Debug Report | debug | 2026-06-04 | high | needs-investigation |
imToken opens in-app browser but cannot get wallet address — Debug Report
Summary
imToken can open the site in its in-app browser, but the frontend does not obtain a wallet address and the login flow stays at connected: no.
Expected Behavior
- User taps imToken from Chrome or from imToken's in-app browser.
- The site detects the imToken injected wallet provider.
- The frontend requests accounts via the injected provider.
- The frontend receives a wallet address and completes login.
Actual Behavior
The page opens inside imToken, but the wallet modal remains stuck with:
state: connectingconnected: noaddress: -qr: -
The supplied screenshot shows the page loaded at 192.168.1.187 and the imToken card selected.
Reproduction Steps
- Open the site in Chrome on mobile.
- Tap wallet login.
- Select imToken.
- The app opens imToken's in-app browser.
- Login does not complete and no wallet address appears.
- Open the same page inside imToken's in-app browser and tap login again.
- The wallet debug panel still shows
connected: noandaddress: -.
Environment
- Branch:
terry-wallet-login - Frontend URL shown in screenshot:
192.168.1.187 - Wallet: imToken mobile in-app browser
- Network path: local LAN IP, likely non-HTTPS
Root Cause Analysis
Failure Chain
WalletLoginModalselects imToken and exposes the mobile actions.openWalletAppDirect(kind)first checksgetInjectedWallet(kind).- If no injected provider is detected, the flow deep-links to imToken or falls through to
useWalletConnectLogin.start()depending on which action is tapped. useWalletConnectLogin.start()setsstatetoconnectingbefore trying direct injected login.- The direct injected branch only runs when
getInjectedWallet(preferredWallet)returns a provider. - The screenshot shows
state: connecting,connected: no,address: -, andqr: -, which means no address was completed through either direct injected login or WalletConnect. AutoInjectedLogincan auto-start imToken login without?autoLogin=imTokenonly ifisImTokenBrowser()detects the imToken user agent; it still depends onwaitForInjected("imToken"), which depends ongetInjectedWallet("imToken").- Therefore the app is not obtaining a usable imToken injected provider, or the provider is present but
eth_accounts/eth_requestAccountsreturns no valid address.
Root Cause
The immediate root cause is failure to obtain a usable injected imToken provider/account. The most likely reason from the screenshot is that the page is running on raw LAN IP 192.168.1.187, likely over HTTP. imToken may not inject its EIP-1193 provider into non-HTTPS/raw-IP pages, or its iOS in-app browser may not expose a user agent/provider shape that matches the current checks.
The code currently assumes at least one of these is true:
- URL contains
?autoLogin=imToken, or navigator.userAgentmatches/imtoken/i, andwindow.ethereumis present and accepted bygetInjectedWallet("imToken"), andeth_accountsoreth_requestAccountsreturns a valid0x...address.
The observed behavior shows that this assumption chain is breaking before a valid address is produced.
Evidence
- File:
src/wallet/WalletLoginModal.tsx—openWalletAppDirect()usesgetInjectedWallet(kind)as the gate for direct injected login; if it is false, the flow navigates/deep-links instead of reading an address. - File:
src/wallet/useWalletConnectLogin.ts—start()setsstatetoconnecting; the imToken direct local-session path only executes insideif (mode === "deeplink" && preferredWallet && getInjectedWallet(preferredWallet)). - File:
src/wallet/AutoInjectedLogin.tsx— auto-login picks imToken from the query parameter orisImTokenBrowser(), then waits forgetInjectedWallet("imToken")before callingconnectInjectedWallet("imToken"). - File:
src/wallet/injected.ts—getInjectedWallet("imToken")falls back to genericwindow.ethereumonly whenisImTokenBrowser()is true. - Screenshot evidence: modal shows
state: connecting,connected: no,address: -,qr: -, and URL192.168.1.187.
Affected Files
src/wallet/WalletLoginModal.tsx— user entry point for mobile imToken login.src/wallet/AutoInjectedLogin.tsx— auto-login effect for wallet in-app browsers.src/wallet/useWalletConnectLogin.ts— direct injected login vs WalletConnect fallback selection.src/wallet/injected.ts— provider/account detection and account request logic.src/wallet/deepLinks.ts— imToken in-app browser deeplink target.
Suggested Fix
Do not guess blindly from connected: no; first make the runtime state visible. Add a temporary imToken diagnostic surface or alert that reports:
navigator.userAgentlocation.href- whether
window.ethereumexists - whether
window.ethereum.providersexists and its length - provider flags:
isImToken,isMetaMask,isTokenPocket - result/error of
eth_accounts - result/error of
eth_requestAccounts - current
isSecureContext
Then apply one of these fixes based on the diagnostic result:
Fix Strategy
- If
window.ethereumis missing on192.168.1.187, test and deploy through an HTTPS domain/tunnel because imToken is likely not injecting on the LAN IP origin. - If
window.ethereumexists butisImTokenBrowser()is false, broaden imToken detection or allow a user-selected imToken flow to try genericwindow.ethereumbefore WalletConnect. - If
eth_accountsis empty andeth_requestAccountserrors, surface that wallet error in the modal instead of leavingstate: connecting. - If a valid address is returned, complete imToken login with the local-session path already used by
connectInjectedWallet()+localWalletToken(). - Ensure the imToken mobile button never silently falls into WalletConnect when the user is already inside imToken and selected imToken; it should either get an address or show a clear injected-provider/account error.
Risk Assessment
- Broadly accepting generic
window.ethereumcould pick the wrong provider in multi-wallet browsers. Mitigation: only do this for explicit user selection of imToken or when already inside imToken. - Testing on LAN IP can produce false negatives. Mitigation: verify on the actual HTTPS domain or an HTTPS tunnel before judging imToken support.
- More diagnostics can expose wallet details on screen. Mitigation: keep diagnostics temporary or behind a debug flag.
Verification Plan
- Test in imToken in-app browser on the production HTTPS domain.
- Test in imToken in-app browser on the current LAN IP to confirm whether
window.ethereumis missing there. - Record diagnostic output for
userAgent,hasEthereum, provider flags,eth_accounts, andeth_requestAccounts. - From Chrome, tap imToken and confirm the in-app browser receives either
?autoLogin=imTokenor the imToken browser fallback runs. - Inside imToken, tap wallet login and confirm it does not remain at
state: connectingwithout an address.
Related Issues
.unipi/docs/fix/2026-06-04-imtoken-injected-provider-detection-fix.md.unipi/docs/fix/2026-06-04-imtoken-restore-local-session-login-fix.md.unipi/docs/fix/2026-06-04-imtoken-auto-login-without-query-fix.md
Notes
The current screenshot strongly suggests that the problem is not backend verification or local token writing. The flow never reaches an address. The next useful step is to confirm whether imToken is injecting window.ethereum on the tested origin.