@@ -25,103 +25,106 @@ export async function reconnect(
2525 if ( isReconnecting ) return [ ]
2626 isReconnecting = true
2727
28- config . setState ( ( x ) => ( {
29- ...x ,
30- status : x . current ? 'reconnecting' : 'connecting' ,
31- } ) )
32-
33- const connectors : Connector [ ] = [ ]
34- if ( parameters . connectors ?. length ) {
35- for ( const connector_ of parameters . connectors ) {
36- let connector : Connector
37- // "Register" connector if not already created
38- if ( typeof connector_ === 'function' )
39- connector = config . _internal . connectors . setup ( connector_ )
40- else connector = connector_
41- connectors . push ( connector )
42- }
43- } else connectors . push ( ...config . connectors )
44-
45- // Try recently-used connectors first
46- let recentConnectorId : string | null | undefined
4728 try {
48- recentConnectorId = await config . storage ?. getItem ( 'recentConnectorId' )
49- } catch { }
50- const scores : Record < string , number > = { }
51- for ( const [ , connection ] of config . state . connections ) {
52- scores [ connection . connector . id ] = 1
53- }
54- if ( recentConnectorId ) scores [ recentConnectorId ] = 0
55- const sorted =
56- Object . keys ( scores ) . length > 0
57- ? // .toSorted()
58- [ ...connectors ] . sort (
59- ( a , b ) => ( scores [ a . id ] ?? 10 ) - ( scores [ b . id ] ?? 10 ) ,
60- )
61- : connectors
62-
63- // Iterate through each connector and try to connect
64- let connected = false
65- const connections : Connection [ ] = [ ]
66- const providers : unknown [ ] = [ ]
67- for ( const connector of sorted ) {
68- const provider = await connector . getProvider ( ) . catch ( ( ) => undefined )
69- if ( ! provider ) continue
70-
71- // If we already have an instance of this connector's provider,
72- // then we have already checked it (ie. injected connectors can
73- // share the same `window.ethereum` instance, so we don't want to
74- // connect to it again).
75- if ( providers . some ( ( x ) => x === provider ) ) continue
76-
77- const isAuthorized = await connector . isAuthorized ( )
78- if ( ! isAuthorized ) continue
79-
80- const data = await connector
81- . connect ( { isReconnecting : true } )
82- . catch ( ( ) => null )
83- if ( ! data ) continue
84-
85- connector . emitter . off ( 'connect' , config . _internal . events . connect )
86- connector . emitter . on ( 'change' , config . _internal . events . change )
87- connector . emitter . on ( 'disconnect' , config . _internal . events . disconnect )
88-
89- config . setState ( ( x ) => {
90- const connections = new Map ( connected ? x . connections : new Map ( ) ) . set (
91- connector . uid ,
92- { accounts : data . accounts , chainId : data . chainId , connector } ,
93- )
94- return {
95- ...x ,
96- current : connected ? x . current : connector . uid ,
97- connections,
29+ config . setState ( ( x ) => ( {
30+ ...x ,
31+ status : x . current ? 'reconnecting' : 'connecting' ,
32+ } ) )
33+
34+ const connectors : Connector [ ] = [ ]
35+ if ( parameters . connectors ?. length ) {
36+ for ( const connector_ of parameters . connectors ) {
37+ let connector : Connector
38+ // "Register" connector if not already created
39+ if ( typeof connector_ === 'function' )
40+ connector = config . _internal . connectors . setup ( connector_ )
41+ else connector = connector_
42+ connectors . push ( connector )
9843 }
99- } )
100- connections . push ( {
101- accounts : data . accounts as readonly [ Address , ...Address [ ] ] ,
102- chainId : data . chainId ,
103- connector,
104- } )
105- providers . push ( provider )
106- connected = true
107- }
44+ } else connectors . push ( ...config . connectors )
45+
46+ // Try recently-used connectors first
47+ let recentConnectorId : string | null | undefined
48+ try {
49+ recentConnectorId = await config . storage ?. getItem ( 'recentConnectorId' )
50+ } catch { }
51+ const scores : Record < string , number > = { }
52+ for ( const [ , connection ] of config . state . connections ) {
53+ scores [ connection . connector . id ] = 1
54+ }
55+ if ( recentConnectorId ) scores [ recentConnectorId ] = 0
56+ const sorted =
57+ Object . keys ( scores ) . length > 0
58+ ? // .toSorted()
59+ [ ...connectors ] . sort (
60+ ( a , b ) => ( scores [ a . id ] ?? 10 ) - ( scores [ b . id ] ?? 10 ) ,
61+ )
62+ : connectors
63+
64+ // Iterate through each connector and try to connect
65+ let connected = false
66+ const connections : Connection [ ] = [ ]
67+ const providers : unknown [ ] = [ ]
68+ for ( const connector of sorted ) {
69+ const provider = await connector . getProvider ( ) . catch ( ( ) => undefined )
70+ if ( ! provider ) continue
71+
72+ // If we already have an instance of this connector's provider,
73+ // then we have already checked it (ie. injected connectors can
74+ // share the same `window.ethereum` instance, so we don't want to
75+ // connect to it again).
76+ if ( providers . some ( ( x ) => x === provider ) ) continue
77+
78+ const isAuthorized = await connector . isAuthorized ( ) . catch ( ( ) => false )
79+ if ( ! isAuthorized ) continue
80+
81+ const data = await connector
82+ . connect ( { isReconnecting : true } )
83+ . catch ( ( ) => null )
84+ if ( ! data ) continue
85+
86+ connector . emitter . off ( 'connect' , config . _internal . events . connect )
87+ connector . emitter . on ( 'change' , config . _internal . events . change )
88+ connector . emitter . on ( 'disconnect' , config . _internal . events . disconnect )
89+
90+ config . setState ( ( x ) => {
91+ const connections = new Map ( connected ? x . connections : new Map ( ) ) . set (
92+ connector . uid ,
93+ { accounts : data . accounts , chainId : data . chainId , connector } ,
94+ )
95+ return {
96+ ...x ,
97+ current : connected ? x . current : connector . uid ,
98+ connections,
99+ }
100+ } )
101+ connections . push ( {
102+ accounts : data . accounts as readonly [ Address , ...Address [ ] ] ,
103+ chainId : data . chainId ,
104+ connector,
105+ } )
106+ providers . push ( provider )
107+ connected = true
108+ }
108109
109- // Prevent overwriting connected status from race condition
110- if (
111- config . state . status === 'reconnecting' ||
112- config . state . status === 'connecting'
113- ) {
114- // If connecting didn't succeed, set to disconnected
115- if ( ! connected )
116- config . setState ( ( x ) => ( {
117- ...x ,
118- connections : new Map ( ) ,
119- current : null ,
120- status : 'disconnected' ,
121- } ) )
122- else config . setState ( ( x ) => ( { ...x , status : 'connected' } ) )
123- }
110+ // Prevent overwriting connected status from race condition
111+ if (
112+ config . state . status === 'reconnecting' ||
113+ config . state . status === 'connecting'
114+ ) {
115+ // If connecting didn't succeed, set to disconnected
116+ if ( ! connected )
117+ config . setState ( ( x ) => ( {
118+ ...x ,
119+ connections : new Map ( ) ,
120+ current : null ,
121+ status : 'disconnected' ,
122+ } ) )
123+ else config . setState ( ( x ) => ( { ...x , status : 'connected' } ) )
124+ }
124125
125- isReconnecting = false
126- return connections
126+ return connections
127+ } finally {
128+ isReconnecting = false
129+ }
127130}
0 commit comments