Fix browser wallet selection for injected providers

This commit is contained in:
2569718930@qq.com
2026-03-21 12:27:54 +08:00
parent 4413b31396
commit ac03fb74be
+44 -30
View File
@@ -148,6 +148,14 @@ type IntentStatusResponse = {
declare global { declare global {
interface Window { interface Window {
ethereum?: EvmProvider; ethereum?: EvmProvider;
okxwallet?: {
ethereum?: EvmProvider;
};
okexchain?: EvmProvider;
rabby?: EvmProvider;
bitkeep?: {
ethereum?: EvmProvider;
};
} }
} }
@@ -282,45 +290,51 @@ function shortAddress(address: string) {
} }
function getEvmProvider(): EvmProvider | null { function getEvmProvider(): EvmProvider | null {
if (typeof window === "undefined") return null; return listInjectedProviders()[0]?.provider || null;
}
function collectInjectedProviders(): EvmProvider[] {
if (typeof window === "undefined") return [];
const out: EvmProvider[] = [];
const seen = new Set<EvmProvider>();
const push = (provider: unknown) => {
if (!provider || typeof provider !== "object") return;
const candidate = provider as EvmProvider;
if (typeof candidate.request !== "function") return;
if (seen.has(candidate)) return;
seen.add(candidate);
out.push(candidate);
};
const root = window.ethereum; const root = window.ethereum;
if (!root) return null; if (Array.isArray(root?.providers)) {
const candidates = Array.isArray(root.providers) root.providers.forEach(push);
? root.providers.filter(
(p): p is EvmProvider => !!p && typeof p.request === "function",
)
: [];
if (candidates.length) {
return candidates.find((p) => p.isMetaMask) || candidates[0];
} }
return typeof root.request === "function" ? root : null; push(root);
push(window.okxwallet?.ethereum);
push(window.okexchain);
push(window.rabby);
push(window.bitkeep?.ethereum);
return out;
}
function getInjectedProviderStableId(provider: EvmProvider, index: number): string {
if (provider.isOkxWallet) return `okx:${index}`;
if (provider.isMetaMask) return `metamask:${index}`;
if (provider.isRabby) return `rabby:${index}`;
if (provider.isBitKeep) return `bitget:${index}`;
return `evm:${index}`;
} }
function listInjectedProviders(): InjectedProviderOption[] { function listInjectedProviders(): InjectedProviderOption[] {
if (typeof window === "undefined") return []; const candidates = collectInjectedProviders();
const root = window.ethereum;
if (!root) return [];
const candidates = Array.isArray(root.providers)
? root.providers.filter(
(p): p is EvmProvider => !!p && typeof p.request === "function",
)
: typeof root.request === "function"
? [root]
: [];
const seen = new Set<string>(); const seen = new Set<string>();
const out: InjectedProviderOption[] = []; const out: InjectedProviderOption[] = [];
candidates.forEach((provider, index) => { candidates.forEach((provider, index) => {
const label = getEvmWalletLabel(provider); const label = getEvmWalletLabel(provider);
const key = [ const key = getInjectedProviderStableId(provider, index);
provider.isMetaMask ? "metamask" : "",
provider.isRabby ? "rabby" : "",
provider.isOkxWallet ? "okx" : "",
provider.isBitKeep ? "bitget" : "",
label.toLowerCase().replace(/\s+/g, "-"),
String(index),
]
.filter(Boolean)
.join(":");
if (seen.has(key)) return; if (seen.has(key)) return;
seen.add(key); seen.add(key);
out.push({ out.push({