diff --git a/client/src/hooks/useWallet.ts b/client/src/hooks/useWallet.ts index 97ed9fc..23cba1e 100644 --- a/client/src/hooks/useWallet.ts +++ b/client/src/hooks/useWallet.ts @@ -31,29 +31,78 @@ const INITIAL_STATE: WalletState = { }; // Detect the best available EVM provider across all major wallets +// Priority order: TP Wallet (most popular in China) > OKX > Bitget > Trust > MetaMask > others export function detectProvider(): Eip1193Provider | null { if (typeof window === "undefined") return null; const w = window as unknown as Record; - const eth = w.ethereum as (Eip1193Provider & { - providers?: Eip1193Provider[]; + + type ExtProvider = Eip1193Provider & { + providers?: ExtProvider[]; isMetaMask?: boolean; isTrust?: boolean; + isTrustWallet?: boolean; isOKExWallet?: boolean; + isOkxWallet?: boolean; isCoinbaseWallet?: boolean; - }) | undefined; + isTokenPocket?: boolean; + isBitkeep?: boolean; + isBitgetWallet?: boolean; + isRabby?: boolean; + isSafePal?: boolean; + isImToken?: boolean; + isPhantom?: boolean; + }; + + const eth = w.ethereum as ExtProvider | undefined; + + // Helper: find in providers array or direct + const findIn = (pred: (p: ExtProvider) => boolean): ExtProvider | null => { + if (!eth) return null; + if (eth.providers && Array.isArray(eth.providers)) { + return eth.providers.find(pred) ?? null; + } + return pred(eth) ? eth : null; + }; + + // 1. TokenPocket (most popular in China) + const tp = findIn(p => !!p.isTokenPocket); + if (tp) return tp; + + // 2. OKX Wallet + const okx = (w.okxwallet as ExtProvider | undefined) ?? findIn(p => !!(p.isOKExWallet || p.isOkxWallet)); + if (okx) return okx; + + // 3. Bitget Wallet + const bitget = (w as { bitkeep?: { ethereum?: ExtProvider } }).bitkeep?.ethereum + ?? findIn(p => !!(p.isBitkeep || p.isBitgetWallet)); + if (bitget) return bitget; + + // 4. imToken + const imtoken = (w.imToken as ExtProvider | undefined) ?? findIn(p => !!p.isImToken); + if (imtoken) return imtoken; + + // 5. SafePal + const safepal = (w.safepalProvider as ExtProvider | undefined) ?? findIn(p => !!p.isSafePal); + if (safepal) return safepal; + + // 6. Trust Wallet + const trust = findIn(p => !!(p.isTrust || p.isTrustWallet)); + if (trust) return trust; + + // 7. MetaMask + const metamask = findIn(p => !!p.isMetaMask); + if (metamask) return metamask; if (!eth) { - // Fallback: check wallet-specific globals - if (w.okxwallet) return w.okxwallet as Eip1193Provider; + // Last resort: check wallet-specific globals if (w.coinbaseWalletExtension) return w.coinbaseWalletExtension as Eip1193Provider; return null; } - // If multiple providers are injected (common when multiple extensions installed) + // If multiple providers injected but none matched above, use first if (eth.providers && Array.isArray(eth.providers) && eth.providers.length > 0) { - const metamask = eth.providers.find((p: Eip1193Provider & { isMetaMask?: boolean }) => p.isMetaMask); - return metamask ?? eth.providers[0]; + return eth.providers[0]; } return eth;