diff --git a/src/wallet/injected.ts b/src/wallet/injected.ts index 32983cc..bf96ecf 100644 --- a/src/wallet/injected.ts +++ b/src/wallet/injected.ts @@ -24,6 +24,13 @@ export type EthereumProvider = { }) => Promise; }; +type LegacyWeb3 = { + currentProvider?: EthereumProvider; + eth?: { + getAccounts?: () => Promise; + }; +}; + function isAddress(value: unknown): value is string { return typeof value === "string" && /^0x[a-fA-F0-9]{40}$/.test(value); } @@ -74,10 +81,21 @@ async function ensureBnbChain(ethereum: EthereumProvider): Promise { } } +function selectedInjectedAddress(ethereum: EthereumProvider): string | null { + return isAddress(ethereum.selectedAddress) ? ethereum.selectedAddress : null; +} + +async function requestLegacyAccounts(): Promise { + if (typeof window === "undefined") return []; + const maybeWindow = window as typeof window & { web3?: LegacyWeb3 }; + return maybeWindow.web3?.eth?.getAccounts?.().catch(() => []) ?? []; +} + async function requestInjectedAddress( ethereum: EthereumProvider, ): Promise { - if (isAddress(ethereum.selectedAddress)) return ethereum.selectedAddress; + const selectedAddress = selectedInjectedAddress(ethereum); + if (selectedAddress) return selectedAddress; const existingAccounts: unknown[] = await ethereum .request({ method: "eth_accounts" }) @@ -97,7 +115,19 @@ async function requestInjectedAddress( }); const requestedAddress = requestedAccounts.find(isAddress); 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"); } @@ -105,7 +135,7 @@ export function getInjectedEthereum(): EthereumProvider | null { if (typeof window === "undefined") return null; const maybeWindow = window as typeof window & { ethereum?: EthereumProvider; - web3?: { currentProvider?: EthereumProvider }; + web3?: LegacyWeb3; }; return maybeWindow.ethereum ?? maybeWindow.web3?.currentProvider ?? null; }