11import { getAddress } from "ethers/address" ;
2- import { createStore , EIP6963ProviderDetail } from "mipd" ;
3- import { isMobile } from "../utils" ;
2+ import { createStore , EIP6963ProviderDetail , Store } from "mipd" ;
43import { chainIdToPlatform } from "./platform" ;
54import {
65 ExternalPlatform ,
@@ -10,14 +9,24 @@ import {
109 WalletAdapter ,
1110} from "./types" ;
1211
12+ // Shared store across all EthereumWalletBase instances so late EIP-6963
13+ // announcements are captured once and visible to every wallet adapter.
14+ let sharedStore : Store | undefined ;
15+
16+ function getSharedStore ( ) : Store {
17+ if ( ! sharedStore ) {
18+ sharedStore = createStore ( ) ;
19+ }
20+ return sharedStore ;
21+ }
22+
1323export abstract class EthereumWalletBase implements WalletAdapter {
1424 abstract readonly type : ExternalWalletType ;
1525 abstract readonly rdns : string ;
1626 abstract readonly displayName : string ;
1727
1828 platform : ExternalPlatform | undefined ;
1929 protected account : string | undefined = undefined ;
20- protected store = createStore ( ) ;
2130 protected provider : EIP6963ProviderDetail | undefined ;
2231 protected connectedAccounts : string [ ] = [ ] ;
2332
@@ -26,10 +35,10 @@ export abstract class EthereumWalletBase implements WalletAdapter {
2635 }
2736
2837 private getProvider ( ) : EIP6963ProviderDetail | undefined {
29- if ( ! this . provider ) {
30- this . provider = this . store
31- . getProviders ( )
32- . find ( ( provider ) => provider . info . rdns === this . rdns ) ;
38+ // Use shared store's findProvider which reflects late announcements
39+ const found = getSharedStore ( ) . findProvider ( { rdns : this . rdns as any } ) ;
40+ if ( found ) {
41+ this . provider = found ;
3342 }
3443 return this . provider ;
3544 }
@@ -40,15 +49,14 @@ export abstract class EthereumWalletBase implements WalletAdapter {
4049 return provider . provider ;
4150 }
4251
43- // Fallback for MetaMask when not announced via EIP-6963
44- if (
45- this . rdns === "io.metamask" &&
46- typeof window !== "undefined" &&
47- ( window as any ) . ethereum ?. isMetaMask
48- ) {
49- return ( window as any ) . ethereum ;
50- }
52+ return this . getFallbackProvider ( ) ;
53+ }
5154
55+ /**
56+ * Fallback provider detection when EIP-6963 announcement is missed.
57+ * Subclasses can override to provide wallet-specific fallback logic.
58+ */
59+ protected getFallbackProvider ( ) : any {
5260 return null ;
5361 }
5462
@@ -101,29 +109,20 @@ export abstract class EthereumWalletBase implements WalletAdapter {
101109 }
102110
103111 isAvailable ( ) : boolean {
104- if ( isMobile ( ) ) {
105- return false ;
106- }
107-
108112 // Check dynamically each time, as the provider might be announced after instantiation
109113 const provider = this . getProvider ( ) ;
110114
111- // Also check for MetaMask via window.ethereum as a fallback for MetaMask specifically
112- if (
113- ! provider &&
114- this . rdns === "io.metamask" &&
115- typeof window !== "undefined"
116- ) {
117- // MetaMask might be available via window.ethereum even if not announced via EIP-6963 yet
118- return ! ! ( window as any ) . ethereum ?. isMetaMask ;
119- }
120-
121115 // Initialize if we just found the provider
122116 if ( provider && ! this . initialized ) {
123117 this . initializeIfAvailable ( ) ;
124118 }
125119
126- return typeof window !== "undefined" && ! ! provider ;
120+ if ( provider ) {
121+ return true ;
122+ }
123+
124+ // Fall back to wallet-specific detection when EIP-6963 announcement is missed
125+ return typeof window !== "undefined" && ! ! this . getFallbackProvider ( ) ;
127126 }
128127
129128 getInfo ( ) : ExternalWallet {
@@ -158,18 +157,7 @@ export abstract class EthereumWalletBase implements WalletAdapter {
158157 throw new Error ( `${ this . displayName } is not available` ) ;
159158 }
160159
161- let ethereum : any ;
162- const provider = this . getProvider ( ) ;
163-
164- if ( provider ) {
165- ethereum = provider . provider ;
166- } else if (
167- this . rdns === "io.metamask" &&
168- ( window as any ) . ethereum ?. isMetaMask
169- ) {
170- // Fallback for MetaMask when not announced via EIP-6963
171- ethereum = ( window as any ) . ethereum ;
172- }
160+ const ethereum = this . getEthereumProvider ( ) ;
173161
174162 if ( ! ethereum ) {
175163 throw new Error ( `${ this . displayName } provider not found` ) ;
@@ -183,15 +171,14 @@ export abstract class EthereumWalletBase implements WalletAdapter {
183171 this . account = getAddress ( accounts [ 0 ] ) ;
184172 this . connectedAccounts = accounts . map ( getAddress ) ;
185173
186- // If we used the fallback, store the ethereum provider for future use
187- if ( ! provider && this . rdns === "io.metamask" ) {
188- // Create a mock EIP6963ProviderDetail for consistency
174+ // If we used a fallback provider, store it for future use
175+ if ( ! this . getProvider ( ) ) {
189176 this . provider = {
190177 info : {
191- uuid : "metamask -fallback" ,
192- name : "MetaMask" ,
178+ uuid : ` ${ this . rdns } -fallback` ,
179+ name : this . displayName ,
193180 icon : "data:image/svg+xml;base64," ,
194- rdns : "io.metamask" ,
181+ rdns : this . rdns ,
195182 } ,
196183 provider : ethereum ,
197184 } as EIP6963ProviderDetail ;
0 commit comments