terry-wallet-login #15
@@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
title: "imToken in-app browser cannot connect after deeplink — Quick Fix"
|
||||||
|
type: quick-fix
|
||||||
|
date: 2026-06-04
|
||||||
|
---
|
||||||
|
|
||||||
|
# imToken in-app browser cannot connect after deeplink — Quick Fix
|
||||||
|
|
||||||
|
## Bug
|
||||||
|
|
||||||
|
After Chrome opens imToken's in-app browser, wallet login cannot complete and the wallet debug panel shows `connected: no`.
|
||||||
|
|
||||||
|
## Root Cause
|
||||||
|
|
||||||
|
The frontend looked for an injected wallet provider using the wallet-specific `isImToken` flag. Some imToken mobile versions inject a usable EIP-1193 `window.ethereum` provider but do not expose `isImToken`, so `getInjectedWallet("imToken")` returned `null`. That prevented the imToken direct-login path from using the injected provider and left the flow disconnected.
|
||||||
|
|
||||||
|
## Fix
|
||||||
|
|
||||||
|
Added a narrow imToken in-app-browser fallback: when the requested wallet is `imToken`, no provider has `isImToken`, but the user agent indicates imToken and `window.ethereum` exists, use the injected provider.
|
||||||
|
|
||||||
|
### Files Modified
|
||||||
|
|
||||||
|
- `src/wallet/injected.ts` — adds imToken user-agent fallback for injected provider detection.
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
- `npx tsc --noEmit`
|
||||||
|
- `npm run format:check`
|
||||||
|
- `npm test`
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
This fallback is limited to imToken browser user agents to avoid changing MetaMask or TokenPocket provider selection behavior.
|
||||||
@@ -138,6 +138,11 @@ export function getInjectedEthereum(): EthereumProvider | null {
|
|||||||
return maybeWindow.ethereum ?? null;
|
return maybeWindow.ethereum ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isImTokenBrowser(): boolean {
|
||||||
|
if (typeof navigator === "undefined") return false;
|
||||||
|
return /imtoken/i.test(navigator.userAgent || "");
|
||||||
|
}
|
||||||
|
|
||||||
export function getInjectedWallet(kind?: WalletKind): EthereumProvider | null {
|
export function getInjectedWallet(kind?: WalletKind): EthereumProvider | null {
|
||||||
const ethereum = getInjectedEthereum();
|
const ethereum = getInjectedEthereum();
|
||||||
if (!ethereum || !kind) return ethereum;
|
if (!ethereum || !kind) return ethereum;
|
||||||
@@ -150,7 +155,15 @@ export function getInjectedWallet(kind?: WalletKind): EthereumProvider | null {
|
|||||||
if (kind === "imToken") return provider.isImToken;
|
if (kind === "imToken") return provider.isImToken;
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
return match ?? null;
|
if (match) return match;
|
||||||
|
|
||||||
|
// Some imToken mobile versions inject a usable EIP-1193 provider without
|
||||||
|
// setting `isImToken`. Inside the imToken in-app browser, prefer the injected
|
||||||
|
// provider instead of falling back to WalletConnect, which can leave the UI at
|
||||||
|
// connected:no on China networks.
|
||||||
|
if (kind === "imToken" && isImTokenBrowser()) return providers[0] ?? ethereum;
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getConnectedInjectedAddress(
|
export async function getConnectedInjectedAddress(
|
||||||
|
|||||||
Reference in New Issue
Block a user