fix: fallback when imToken returns empty accounts
All checks were successful
Deploy to Frontend Servers / deploy (push) Successful in 59s

This commit is contained in:
TerryM
2026-06-06 01:00:44 +08:00
parent fe8dcee9a1
commit 2b5ec54896

View File

@@ -24,6 +24,13 @@ export type EthereumProvider = {
}) => Promise<T>; }) => Promise<T>;
}; };
type LegacyWeb3 = {
currentProvider?: EthereumProvider;
eth?: {
getAccounts?: () => Promise<unknown[]>;
};
};
function isAddress(value: unknown): value is string { function isAddress(value: unknown): value is string {
return typeof value === "string" && /^0x[a-fA-F0-9]{40}$/.test(value); return typeof value === "string" && /^0x[a-fA-F0-9]{40}$/.test(value);
} }
@@ -74,10 +81,21 @@ async function ensureBnbChain(ethereum: EthereumProvider): Promise<void> {
} }
} }
function selectedInjectedAddress(ethereum: EthereumProvider): string | null {
return isAddress(ethereum.selectedAddress) ? ethereum.selectedAddress : null;
}
async function requestLegacyAccounts(): Promise<unknown[]> {
if (typeof window === "undefined") return [];
const maybeWindow = window as typeof window & { web3?: LegacyWeb3 };
return maybeWindow.web3?.eth?.getAccounts?.().catch(() => []) ?? [];
}
async function requestInjectedAddress( async function requestInjectedAddress(
ethereum: EthereumProvider, ethereum: EthereumProvider,
): Promise<string> { ): Promise<string> {
if (isAddress(ethereum.selectedAddress)) return ethereum.selectedAddress; const selectedAddress = selectedInjectedAddress(ethereum);
if (selectedAddress) return selectedAddress;
const existingAccounts: unknown[] = await ethereum const existingAccounts: unknown[] = await ethereum
.request<unknown[]>({ method: "eth_accounts" }) .request<unknown[]>({ method: "eth_accounts" })
@@ -97,7 +115,19 @@ async function requestInjectedAddress(
}); });
const requestedAddress = requestedAccounts.find(isAddress); const requestedAddress = requestedAccounts.find(isAddress);
if (requestedAddress) return requestedAddress; if (requestedAddress) return requestedAddress;
if (isAddress(ethereum.selectedAddress)) return ethereum.selectedAddress;
const enabledAccounts: unknown[] = ethereum.enable
? await ethereum.enable().catch((): unknown[] => [])
: [];
const enabledAddress = enabledAccounts.find(isAddress);
if (enabledAddress) return enabledAddress;
const legacyAccounts = await requestLegacyAccounts();
const legacyAddress = legacyAccounts.find(isAddress);
if (legacyAddress) return legacyAddress;
const latestSelectedAddress = selectedInjectedAddress(ethereum);
if (latestSelectedAddress) return latestSelectedAddress;
throw new Error("walletNoAccount"); throw new Error("walletNoAccount");
} }
@@ -105,7 +135,7 @@ export function getInjectedEthereum(): EthereumProvider | null {
if (typeof window === "undefined") return null; if (typeof window === "undefined") return null;
const maybeWindow = window as typeof window & { const maybeWindow = window as typeof window & {
ethereum?: EthereumProvider; ethereum?: EthereumProvider;
web3?: { currentProvider?: EthereumProvider }; web3?: LegacyWeb3;
}; };
return maybeWindow.ethereum ?? maybeWindow.web3?.currentProvider ?? null; return maybeWindow.ethereum ?? maybeWindow.web3?.currentProvider ?? null;
} }