@@ -19,7 +19,6 @@ import {
19
19
getRpcUrlForChain ,
20
20
} from "../../chains/utils.js" ;
21
21
import type { Chain } from "../../chains/types.js" ;
22
- import { ethereum } from "../../chains/chain-definitions/ethereum.js" ;
23
22
import { isHex , numberToHex , type Hex } from "../../utils/encoding/hex.js" ;
24
23
import { getDefaultAppMetadata } from "../utils/defaultDappMetadata.js" ;
25
24
import type { WCSupportedWalletIds } from "../__generated__/wallet-ids.js" ;
@@ -34,6 +33,8 @@ import {
34
33
getSavedConnectParamsFromStorage ,
35
34
saveConnectParamsToStorage ,
36
35
} from "../storage/walletStorage.js" ;
36
+ import type { ThirdwebClient } from "../../client/client.js" ;
37
+ import { getAddress } from "../../utils/address.js" ;
37
38
38
39
const asyncLocalStorage =
39
40
typeof window !== "undefined" ? _asyncLocalStorage : undefined ;
@@ -42,7 +43,7 @@ type WCProvider = InstanceType<typeof EthereumProvider>;
42
43
43
44
type SavedConnectParams = {
44
45
optionalChains ?: Chain [ ] ;
45
- chain : Chain ;
46
+ chain ? : Chain ;
46
47
pairingTopic ?: string ;
47
48
} ;
48
49
@@ -76,14 +77,6 @@ export async function connectWC(
76
77
77
78
const wcOptions = options . walletConnect ;
78
79
79
- const targetChain = options ?. chain || ethereum ;
80
- const targetChainId = targetChain . id ;
81
-
82
- const rpc = getRpcUrlForChain ( {
83
- chain : targetChain ,
84
- client : options . client ,
85
- } ) ;
86
-
87
80
const { onDisplayUri } = wcOptions || { } ;
88
81
89
82
if ( onDisplayUri ) {
@@ -92,17 +85,23 @@ export async function connectWC(
92
85
}
93
86
}
94
87
88
+ const { rpcMap, chainsToRequest } = getChainsToRequest ( {
89
+ client : options . client ,
90
+ chain : options . chain ,
91
+ optionalChains : options . walletConnect ?. optionalChains ,
92
+ } ) ;
93
+
95
94
// If there no active session, or the chain is stale, force connect.
96
95
if ( ! provider . session || _isChainsState ) {
97
96
await provider . connect ( {
98
- pairingTopic : wcOptions ?. pairingTopic ,
99
- chains : [ Number ( targetChainId ) ] ,
100
- rpcMap : {
101
- [ targetChainId . toString ( ) ] : rpc ,
102
- } ,
97
+ ... ( wcOptions ?. pairingTopic
98
+ ? { pairingTopic : wcOptions ?. pairingTopic }
99
+ : { } ) ,
100
+ optionalChains : chainsToRequest ,
101
+ rpcMap : rpcMap ,
103
102
} ) ;
104
103
105
- setRequestedChainsIds ( [ targetChainId ] ) ;
104
+ setRequestedChainsIds ( chainsToRequest ) ;
106
105
}
107
106
108
107
// If session exists and chains are authorized, enable provider for required chain
@@ -117,7 +116,7 @@ export async function connectWC(
117
116
if ( options ) {
118
117
const savedParams : SavedConnectParams = {
119
118
optionalChains : options . walletConnect ?. optionalChains ,
120
- chain : chain ,
119
+ chain : options . chain ,
121
120
pairingTopic : options . walletConnect ?. pairingTopic ,
122
121
} ;
123
122
@@ -205,11 +204,10 @@ async function initProvider(
205
204
"@walletconnect/ethereum-provider"
206
205
) ;
207
206
208
- const targetChain = options . chain || ethereum ;
209
-
210
- const rpc = getRpcUrlForChain ( {
211
- chain : targetChain ,
207
+ const { rpcMap, chainsToRequest } = getChainsToRequest ( {
212
208
client : options . client ,
209
+ chain : options . chain ,
210
+ optionalChains : options . walletConnect ?. optionalChains ,
213
211
} ) ;
214
212
215
213
const provider = await EthereumProvider . init ( {
@@ -220,7 +218,7 @@ async function initProvider(
220
218
projectId : wcOptions ?. projectId || defaultWCProjectId ,
221
219
optionalMethods : OPTIONAL_METHODS ,
222
220
optionalEvents : OPTIONAL_EVENTS ,
223
- optionalChains : [ targetChain . id ] ,
221
+ optionalChains : chainsToRequest ,
224
222
metadata : {
225
223
name : wcOptions ?. appMetadata ?. name || getDefaultAppMetadata ( ) . name ,
226
224
description :
@@ -231,9 +229,7 @@ async function initProvider(
231
229
wcOptions ?. appMetadata ?. logoUrl || getDefaultAppMetadata ( ) . logoUrl ,
232
230
] ,
233
231
} ,
234
- rpcMap : {
235
- [ targetChain . id ] : rpc ,
236
- } ,
232
+ rpcMap : rpcMap ,
237
233
qrModalOptions : wcOptions ?. qrModalOptions ,
238
234
disableProviderPing : true ,
239
235
} ) ;
@@ -242,15 +238,7 @@ async function initProvider(
242
238
243
239
// disconnect the provider if chains are stale when (if not auto connecting)
244
240
if ( ! isAutoConnect ) {
245
- const chains = [
246
- targetChain ,
247
- ...( options ?. walletConnect ?. optionalChains || [ ] ) ,
248
- ] ;
249
-
250
- const isStale = await isChainsStale (
251
- provider ,
252
- chains . map ( ( c ) => c . id ) ,
253
- ) ;
241
+ const isStale = await isChainsStale ( provider , chainsToRequest ) ;
254
242
255
243
if ( isStale && provider . session ) {
256
244
await provider . disconnect ( ) ;
@@ -293,20 +281,6 @@ async function initProvider(
293
281
} ) ;
294
282
}
295
283
296
- // try switching to correct chain
297
- if ( options ?. chain && provider . chainId !== options ?. chain . id ) {
298
- try {
299
- await switchChainWC ( provider , options . chain ) ;
300
- } catch ( e ) {
301
- console . error ( "Failed to Switch chain to target chain" ) ;
302
- console . error ( e ) ;
303
- // throw only if not auto connecting
304
- if ( ! isAutoConnect ) {
305
- throw e ;
306
- }
307
- }
308
- }
309
-
310
284
return provider ;
311
285
}
312
286
@@ -385,10 +359,14 @@ function onConnect(
385
359
}
386
360
387
361
function onAccountsChanged ( accounts : string [ ] ) {
388
- if ( accounts . length === 0 ) {
389
- onDisconnect ( ) ;
362
+ if ( accounts [ 0 ] ) {
363
+ const newAccount : Account = {
364
+ ...account ,
365
+ address : getAddress ( accounts [ 0 ] ) ,
366
+ } ;
367
+ emitter . emit ( "accountChanged" , newAccount ) ;
390
368
} else {
391
- emitter . emit ( "accountsChanged" , accounts ) ;
369
+ onDisconnect ( ) ;
392
370
}
393
371
}
394
372
@@ -521,3 +499,45 @@ async function getRequestedChainsIds(): Promise<number[]> {
521
499
const data = localStorage . getItem ( storageKeys . requestedChains ) ;
522
500
return data ? JSON . parse ( data ) : [ ] ;
523
501
}
502
+
503
+ type ArrayOneOrMore < T > = {
504
+ 0 : T ;
505
+ } & Array < T > ;
506
+
507
+ function getChainsToRequest ( options : {
508
+ chain ?: Chain ;
509
+ optionalChains ?: Chain [ ] ;
510
+ client : ThirdwebClient ;
511
+ } ) {
512
+ const rpcMap : Record < number , string > = { } ;
513
+
514
+ if ( options . chain ) {
515
+ rpcMap [ options . chain . id ] = getRpcUrlForChain ( {
516
+ chain : options . chain ,
517
+ client : options . client ,
518
+ } ) ;
519
+ }
520
+
521
+ // limit optional chains to 10
522
+ const optionalChains = ( options ?. optionalChains || [ ] ) . slice ( 0 , 10 ) ;
523
+
524
+ optionalChains . forEach ( ( chain ) => {
525
+ rpcMap [ chain . id ] = getRpcUrlForChain ( {
526
+ chain : chain ,
527
+ client : options . client ,
528
+ } ) ;
529
+ } ) ;
530
+
531
+ const optionalChainIds = optionalChains . map ( ( c ) => c . id ) || [ ] ;
532
+
533
+ const chainsToRequest : ArrayOneOrMore < number > = options . chain
534
+ ? [ options . chain . id , ...optionalChainIds ]
535
+ : optionalChainIds . length > 0
536
+ ? ( optionalChainIds as ArrayOneOrMore < number > )
537
+ : [ 1 ] ;
538
+
539
+ return {
540
+ rpcMap,
541
+ chainsToRequest,
542
+ } ;
543
+ }
0 commit comments