@reown/appkit-adapter-ethers5 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,824 @@
1
+ import { NetworkUtil, SafeLocalStorage, SafeLocalStorageKeys } from '@reown/appkit-common';
2
+ import { AccountController, ChainController } from '@reown/appkit-core';
3
+ import { EthersHelpersUtil } from '@reown/appkit-utils/ethers';
4
+ import { W3mFrameHelpers, W3mFrameProvider, W3mFrameRpcConstants } from '@reown/appkit-wallet';
5
+ import { ConstantsUtil as CommonConstantsUtil } from '@reown/appkit-common';
6
+ import { ConstantsUtil, HelpersUtil, PresetsUtil } from '@reown/appkit-utils';
7
+ import UniversalProvider from '@walletconnect/universal-provider';
8
+ import { ConstantsUtil as CoreConstantsUtil } from '@reown/appkit-core';
9
+ import { WcConstantsUtil } from '@reown/appkit';
10
+ import { Ethers5Methods } from './utils/Ethers5Methods.js';
11
+ import { ethers } from 'ethers5';
12
+ import { ProviderUtil } from '@reown/appkit/store';
13
+ import { CoinbaseWalletSDK } from '@coinbase/wallet-sdk';
14
+ import { W3mFrameProviderSingleton } from '@reown/appkit/auth-provider';
15
+ export class EVMEthers5Client {
16
+ createEthersConfig(options) {
17
+ if (!options.metadata) {
18
+ return undefined;
19
+ }
20
+ let injectedProvider = undefined;
21
+ let coinbaseProvider = undefined;
22
+ function getInjectedProvider() {
23
+ if (injectedProvider) {
24
+ return injectedProvider;
25
+ }
26
+ if (typeof window === 'undefined') {
27
+ return undefined;
28
+ }
29
+ if (!window.ethereum) {
30
+ return undefined;
31
+ }
32
+ injectedProvider = window.ethereum;
33
+ return injectedProvider;
34
+ }
35
+ function getCoinbaseProvider() {
36
+ if (coinbaseProvider) {
37
+ return coinbaseProvider;
38
+ }
39
+ if (typeof window === 'undefined') {
40
+ return undefined;
41
+ }
42
+ const coinbaseWallet = new CoinbaseWalletSDK({
43
+ appName: options?.metadata?.name,
44
+ appLogoUrl: options?.metadata?.icons[0],
45
+ appChainIds: options.caipNetworks?.map(caipNetwork => caipNetwork.chainId) || [
46
+ 1, 84532
47
+ ]
48
+ });
49
+ coinbaseProvider = coinbaseWallet.makeWeb3Provider({
50
+ options: options.coinbasePreference ?? 'all'
51
+ });
52
+ return coinbaseProvider;
53
+ }
54
+ const providers = { metadata: options.metadata };
55
+ if (options.enableInjected !== false) {
56
+ providers.injected = getInjectedProvider();
57
+ }
58
+ if (options.enableCoinbase !== false) {
59
+ providers.coinbase = getCoinbaseProvider();
60
+ }
61
+ providers.EIP6963 = options.enableEIP6963 !== false;
62
+ return providers;
63
+ }
64
+ constructor() {
65
+ this.appKit = undefined;
66
+ this.EIP6963Providers = [];
67
+ this.options = undefined;
68
+ this.caipNetworks = [];
69
+ this.chainNamespace = CommonConstantsUtil.CHAIN.EVM;
70
+ this.siweControllerClient = this.options?.siweConfig;
71
+ this.tokens = HelpersUtil.getCaipTokens(this.options?.tokens);
72
+ this.defaultCaipNetwork = undefined;
73
+ this.adapterType = 'ethers';
74
+ this.providerHandlers = null;
75
+ AccountController.subscribeKey('isConnected', () => this.syncAccount({ address: this.appKit?.getAddress() }), this.chainNamespace);
76
+ AccountController.subscribeKey('shouldUpdateToAddress', newAddress => this.syncAccount({ address: newAddress }), this.chainNamespace);
77
+ }
78
+ construct(appKit, options) {
79
+ if (!options.projectId) {
80
+ throw new Error('appkit:ethers-client:initialize - projectId is undefined');
81
+ }
82
+ this.appKit = appKit;
83
+ this.options = options;
84
+ this.caipNetworks = options.caipNetworks;
85
+ this.defaultCaipNetwork = options.defaultCaipNetwork || options.caipNetworks[0];
86
+ this.tokens = HelpersUtil.getCaipTokens(options.tokens);
87
+ this.ethersConfig = this.createEthersConfig(options);
88
+ this.networkControllerClient = {
89
+ switchCaipNetwork: async (caipNetwork) => {
90
+ if (caipNetwork?.chainId) {
91
+ try {
92
+ await this.switchNetwork(caipNetwork);
93
+ }
94
+ catch (error) {
95
+ throw new Error('networkControllerClient:switchCaipNetwork - unable to switch chain');
96
+ }
97
+ }
98
+ },
99
+ getApprovedCaipNetworksData: async () => this.getApprovedCaipNetworksData()
100
+ };
101
+ this.connectionControllerClient = {
102
+ connectWalletConnect: async (onUri) => {
103
+ await this.appKit?.universalAdapter?.connectionControllerClient?.connectWalletConnect?.(onUri);
104
+ },
105
+ connectExternal: async ({ id, info, provider }) => {
106
+ this.appKit?.setClientId(null);
107
+ const connectorConfig = {
108
+ [ConstantsUtil.INJECTED_CONNECTOR_ID]: {
109
+ getProvider: () => this.ethersConfig?.injected,
110
+ providerType: 'injected'
111
+ },
112
+ [ConstantsUtil.EIP6963_CONNECTOR_ID]: {
113
+ getProvider: () => provider,
114
+ providerType: 'eip6963'
115
+ },
116
+ [ConstantsUtil.COINBASE_SDK_CONNECTOR_ID]: {
117
+ getProvider: () => this.ethersConfig?.coinbase,
118
+ providerType: 'coinbase'
119
+ },
120
+ [ConstantsUtil.AUTH_CONNECTOR_ID]: {
121
+ getProvider: () => this.authProvider,
122
+ providerType: 'w3mAuth'
123
+ }
124
+ };
125
+ const selectedConnector = connectorConfig[id];
126
+ if (!selectedConnector) {
127
+ throw new Error(`Unsupported connector ID: ${id}`);
128
+ }
129
+ const selectedProvider = selectedConnector.getProvider();
130
+ if (!selectedProvider) {
131
+ throw new Error(`Provider for connector ${id} is undefined`);
132
+ }
133
+ try {
134
+ if (selectedProvider && id !== ConstantsUtil.AUTH_CONNECTOR_ID) {
135
+ await selectedProvider.request({ method: 'eth_requestAccounts' });
136
+ }
137
+ await this.setProvider(selectedProvider, selectedConnector.providerType, info?.name);
138
+ }
139
+ catch (error) {
140
+ if (id === ConstantsUtil.COINBASE_SDK_CONNECTOR_ID) {
141
+ throw new Error(error.message);
142
+ }
143
+ }
144
+ },
145
+ checkInstalled: (ids) => {
146
+ if (!ids) {
147
+ return Boolean(window.ethereum);
148
+ }
149
+ if (this.ethersConfig?.injected) {
150
+ if (!window?.ethereum) {
151
+ return false;
152
+ }
153
+ }
154
+ return ids.some(id => Boolean(window.ethereum?.[String(id)]));
155
+ },
156
+ disconnect: async () => {
157
+ const provider = ProviderUtil.getProvider('eip155');
158
+ const providerId = ProviderUtil.state.providerIds['eip155'];
159
+ this.appKit?.setClientId(null);
160
+ if (this.options?.siweConfig?.options?.signOutOnDisconnect) {
161
+ const { SIWEController } = await import('@reown/appkit-siwe');
162
+ await SIWEController.signOut();
163
+ }
164
+ const disconnectConfig = {
165
+ [ConstantsUtil.WALLET_CONNECT_CONNECTOR_ID]: async () => await this.appKit?.universalAdapter?.connectionControllerClient?.disconnect(),
166
+ coinbaseWalletSDK: async () => await this.appKit?.universalAdapter?.connectionControllerClient?.disconnect(),
167
+ [ConstantsUtil.AUTH_CONNECTOR_ID]: async () => {
168
+ await this.authProvider?.disconnect();
169
+ },
170
+ [ConstantsUtil.EIP6963_CONNECTOR_ID]: async () => {
171
+ if (provider) {
172
+ ;
173
+ provider.emit('disconnect');
174
+ await this.revokeProviderPermissions(provider);
175
+ }
176
+ },
177
+ [ConstantsUtil.INJECTED_CONNECTOR_ID]: async () => {
178
+ if (provider) {
179
+ ;
180
+ provider.emit('disconnect');
181
+ await this.revokeProviderPermissions(provider);
182
+ }
183
+ }
184
+ };
185
+ const disconnectFunction = disconnectConfig[providerId];
186
+ if (disconnectFunction) {
187
+ await disconnectFunction();
188
+ }
189
+ else {
190
+ console.warn(`No disconnect function found for provider type: ${providerId}`);
191
+ }
192
+ SafeLocalStorage.removeItem(SafeLocalStorageKeys.WALLET_ID);
193
+ this.appKit?.resetAccount(this.chainNamespace);
194
+ },
195
+ signMessage: async (message) => {
196
+ const provider = ProviderUtil.getProvider(this.chainNamespace);
197
+ const address = this.appKit?.getAddress();
198
+ if (!address) {
199
+ throw new Error('Address is undefined');
200
+ }
201
+ if (!provider) {
202
+ throw new Error('Provider is undefined');
203
+ }
204
+ return await Ethers5Methods.signMessage(message, provider, address);
205
+ },
206
+ parseUnits: Ethers5Methods.parseUnits,
207
+ formatUnits: Ethers5Methods.formatUnits,
208
+ estimateGas: async (data) => {
209
+ if (data.chainNamespace && data.chainNamespace !== 'eip155') {
210
+ throw new Error(`Invalid chain namespace - Expected eip155, got ${data.chainNamespace}`);
211
+ }
212
+ const provider = ProviderUtil.getProvider('eip155');
213
+ const address = this.appKit?.getAddress();
214
+ const caipNetwork = this.appKit?.getCaipNetwork();
215
+ if (!address) {
216
+ throw new Error('Address is undefined');
217
+ }
218
+ if (!provider) {
219
+ throw new Error('Provider is undefined');
220
+ }
221
+ return await Ethers5Methods.estimateGas(data, provider, address, Number(caipNetwork?.chainId));
222
+ },
223
+ sendTransaction: async (data) => {
224
+ if (data.chainNamespace && data.chainNamespace !== 'eip155') {
225
+ throw new Error(`Invalid chain namespace - Expected eip155, got ${data.chainNamespace}`);
226
+ }
227
+ const provider = ProviderUtil.getProvider('eip155');
228
+ const address = this.appKit?.getAddress();
229
+ const caipNetwork = this.appKit?.getCaipNetwork();
230
+ if (!address) {
231
+ throw new Error('Address is undefined');
232
+ }
233
+ if (!provider) {
234
+ throw new Error('Provider is undefined');
235
+ }
236
+ return await Ethers5Methods.sendTransaction(data, provider, address, Number(caipNetwork?.chainId));
237
+ },
238
+ writeContract: async (data) => {
239
+ const provider = ProviderUtil.getProvider('eip155');
240
+ const address = this.appKit?.getAddress();
241
+ const caipNetwork = this.appKit?.getCaipNetwork();
242
+ if (!address) {
243
+ throw new Error('Address is undefined');
244
+ }
245
+ if (!provider) {
246
+ throw new Error('Provider is undefined');
247
+ }
248
+ return await Ethers5Methods.writeContract(data, provider, address, Number(caipNetwork?.chainId));
249
+ },
250
+ getEnsAddress: async (value) => {
251
+ if (this.appKit) {
252
+ return await Ethers5Methods.getEnsAddress(value, this.appKit);
253
+ }
254
+ return false;
255
+ },
256
+ getEnsAvatar: async (value) => {
257
+ const caipNetwork = this.appKit?.getCaipNetwork();
258
+ return await Ethers5Methods.getEnsAvatar(value, Number(caipNetwork?.chainId));
259
+ }
260
+ };
261
+ ChainController.state.chains.set(this.chainNamespace, {
262
+ chainNamespace: this.chainNamespace,
263
+ connectionControllerClient: this.connectionControllerClient,
264
+ networkControllerClient: this.networkControllerClient,
265
+ adapterType: this.adapterType
266
+ });
267
+ if (this.ethersConfig) {
268
+ this.syncConnectors(this.ethersConfig);
269
+ }
270
+ if (typeof window !== 'undefined') {
271
+ this.listenConnectors(true);
272
+ }
273
+ this.appKit?.setEIP6963Enabled(this.ethersConfig?.EIP6963);
274
+ const emailEnabled = options.features?.email === undefined
275
+ ? CoreConstantsUtil.DEFAULT_FEATURES.email
276
+ : options.features?.email;
277
+ const socialsEnabled = options.features?.socials === undefined
278
+ ? CoreConstantsUtil.DEFAULT_FEATURES.socials
279
+ : options.features?.socials?.length > 0;
280
+ if (emailEnabled || socialsEnabled) {
281
+ this.syncAuthConnector(this.options.projectId);
282
+ }
283
+ if (this.ethersConfig) {
284
+ this.checkActiveProviders(this.ethersConfig);
285
+ }
286
+ this.syncRequestedNetworks(this.caipNetworks);
287
+ }
288
+ subscribeState(callback) {
289
+ return this.appKit?.subscribeState(state => callback(state));
290
+ }
291
+ async disconnect() {
292
+ await this.connectionControllerClient?.disconnect();
293
+ }
294
+ async revokeProviderPermissions(provider) {
295
+ try {
296
+ const permissions = await provider.request({
297
+ method: 'wallet_getPermissions'
298
+ });
299
+ const ethAccountsPermission = permissions.find(permission => permission.parentCapability === 'eth_accounts');
300
+ if (ethAccountsPermission) {
301
+ await provider.request({
302
+ method: 'wallet_revokePermissions',
303
+ params: [{ eth_accounts: {} }]
304
+ });
305
+ }
306
+ }
307
+ catch (error) {
308
+ console.info('Could not revoke permissions from wallet. Disconnecting...', error);
309
+ }
310
+ }
311
+ getApprovedCaipNetworksData() {
312
+ return new Promise(resolve => {
313
+ const walletId = SafeLocalStorage.getItem(SafeLocalStorageKeys.WALLET_ID);
314
+ if (!walletId) {
315
+ throw new Error('No wallet id found to get approved networks data');
316
+ }
317
+ const providerConfigs = {
318
+ [ConstantsUtil.AUTH_CONNECTOR_ID]: {
319
+ supportsAllNetworks: true,
320
+ approvedCaipNetworkIds: PresetsUtil.WalletConnectRpcChainIds.map(id => `${ConstantsUtil.EIP155}:${id}`)
321
+ }
322
+ };
323
+ const networkData = providerConfigs[walletId];
324
+ if (networkData) {
325
+ resolve(networkData);
326
+ }
327
+ else {
328
+ resolve({
329
+ supportsAllNetworks: true,
330
+ approvedCaipNetworkIds: []
331
+ });
332
+ }
333
+ });
334
+ }
335
+ checkActiveProviders(config) {
336
+ const walletId = SafeLocalStorage.getItem(SafeLocalStorageKeys.WALLET_ID);
337
+ const walletName = SafeLocalStorage.getItem(SafeLocalStorageKeys.WALLET_NAME);
338
+ if (!walletId) {
339
+ return;
340
+ }
341
+ const providerConfigs = {
342
+ [ConstantsUtil.INJECTED_CONNECTOR_ID]: {
343
+ provider: config.injected
344
+ },
345
+ [ConstantsUtil.COINBASE_SDK_CONNECTOR_ID]: {
346
+ provider: config.coinbase
347
+ },
348
+ [ConstantsUtil.EIP6963_CONNECTOR_ID]: {
349
+ provider: this.EIP6963Providers.find(p => p.info.name === walletName)?.provider
350
+ }
351
+ };
352
+ const activeConfig = providerConfigs[walletId];
353
+ if (activeConfig?.provider) {
354
+ this.setProvider(activeConfig.provider, walletId);
355
+ this.setupProviderListeners(activeConfig.provider, walletId);
356
+ }
357
+ }
358
+ async setProvider(provider, providerId, name) {
359
+ if (providerId === 'w3mAuth') {
360
+ this.setAuthProvider();
361
+ }
362
+ else {
363
+ const walletId = providerId;
364
+ SafeLocalStorage.setItem(SafeLocalStorageKeys.WALLET_ID, walletId);
365
+ if (name) {
366
+ SafeLocalStorage.setItem(SafeLocalStorageKeys.WALLET_NAME, name);
367
+ }
368
+ if (provider) {
369
+ const { addresses, chainId } = await EthersHelpersUtil.getUserInfo(provider);
370
+ const caipNetwork = this.caipNetworks.find(c => c.chainId === chainId);
371
+ if (addresses?.[0] && chainId && caipNetwork) {
372
+ this.appKit?.setCaipNetwork(caipNetwork);
373
+ this.appKit?.setCaipAddress(`${this.chainNamespace}:${chainId}:${addresses[0]}`, this.chainNamespace);
374
+ ProviderUtil.setProviderId('eip155', providerId);
375
+ ProviderUtil.setProvider('eip155', provider);
376
+ this.appKit?.setStatus('connected', this.chainNamespace);
377
+ this.appKit?.setIsConnected(true, this.chainNamespace);
378
+ this.appKit?.setAllAccounts(addresses.map(address => ({ address, type: 'eoa' })), this.chainNamespace);
379
+ }
380
+ }
381
+ }
382
+ }
383
+ async setAuthProvider() {
384
+ SafeLocalStorage.setItem(SafeLocalStorageKeys.WALLET_ID, ConstantsUtil.AUTH_CONNECTOR_ID);
385
+ if (this.authProvider) {
386
+ this.appKit?.setLoading(true);
387
+ const { address, chainId, smartAccountDeployed, preferredAccountType, accounts = [] } = await this.authProvider.connect({
388
+ chainId: Number(NetworkUtil.caipNetworkIdToNumber(this.appKit?.getCaipNetwork()?.id) ??
389
+ this.caipNetworks[0]?.chainId)
390
+ });
391
+ const { smartAccountEnabledNetworks } = await this.authProvider.getSmartAccountEnabledNetworks();
392
+ this.appKit?.setSmartAccountEnabledNetworks(smartAccountEnabledNetworks, this.chainNamespace);
393
+ if (address && chainId) {
394
+ this.appKit?.setAllAccounts(accounts.length > 0
395
+ ? accounts
396
+ : [{ address, type: preferredAccountType }], this.chainNamespace);
397
+ const caipNetwork = this.caipNetworks.find(c => c.chainId === chainId);
398
+ this.appKit?.setCaipNetwork(caipNetwork);
399
+ this.appKit?.setStatus('connected', this.chainNamespace);
400
+ this.appKit?.setIsConnected(true, this.chainNamespace);
401
+ this.appKit?.setCaipAddress(`${this.chainNamespace}:${chainId}:${address}`, this.chainNamespace);
402
+ this.appKit?.setPreferredAccountType(preferredAccountType, this.chainNamespace);
403
+ this.appKit?.setSmartAccountDeployed(Boolean(smartAccountDeployed), this.chainNamespace);
404
+ ProviderUtil.setProvider('eip155', this.authProvider);
405
+ ProviderUtil.setProviderId('eip155', ConstantsUtil.AUTH_CONNECTOR_ID);
406
+ this.setupProviderListeners(this.authProvider, 'w3mAuth');
407
+ this.watchModal();
408
+ }
409
+ this.appKit?.setLoading(false);
410
+ }
411
+ }
412
+ watchModal() {
413
+ if (this.authProvider) {
414
+ this.subscribeState(val => {
415
+ if (!val.open) {
416
+ this.authProvider?.rejectRpcRequests();
417
+ }
418
+ });
419
+ }
420
+ }
421
+ setupProviderListeners(provider, providerId) {
422
+ const disconnectHandler = () => {
423
+ SafeLocalStorage.removeItem(SafeLocalStorageKeys.WALLET_ID);
424
+ this.removeListeners(provider);
425
+ };
426
+ const accountsChangedHandler = (accounts) => {
427
+ const currentAccount = accounts?.[0];
428
+ if (currentAccount) {
429
+ this.appKit?.setCaipAddress(currentAccount, this.chainNamespace);
430
+ if (providerId === ConstantsUtil.EIP6963_CONNECTOR_ID) {
431
+ this.appKit?.setAllAccounts(accounts.map(address => ({ address, type: 'eoa' })), this.chainNamespace);
432
+ }
433
+ }
434
+ else {
435
+ if (providerId === ConstantsUtil.EIP6963_CONNECTOR_ID) {
436
+ this.appKit?.setAllAccounts([], this.chainNamespace);
437
+ }
438
+ SafeLocalStorage.removeItem(SafeLocalStorageKeys.WALLET_ID);
439
+ this.appKit?.resetAccount(this.chainNamespace);
440
+ }
441
+ };
442
+ const chainChangedHandler = (networkId) => {
443
+ if (networkId) {
444
+ const networkIdNumber = typeof networkId === 'string'
445
+ ? EthersHelpersUtil.hexStringToNumber(networkId)
446
+ : Number(networkId);
447
+ const caipNetwork = this.caipNetworks.find(c => c.chainId === networkIdNumber);
448
+ this.appKit?.setCaipNetwork(caipNetwork);
449
+ }
450
+ };
451
+ if (providerId === ConstantsUtil.AUTH_CONNECTOR_ID) {
452
+ this.setupAuthListeners(provider);
453
+ }
454
+ else {
455
+ provider.on('disconnect', disconnectHandler);
456
+ provider.on('accountsChanged', accountsChangedHandler);
457
+ provider.on('chainChanged', chainChangedHandler);
458
+ }
459
+ this.providerHandlers = {
460
+ disconnect: disconnectHandler,
461
+ accountsChanged: accountsChangedHandler,
462
+ chainChanged: chainChangedHandler
463
+ };
464
+ }
465
+ removeListeners(provider) {
466
+ if (this.providerHandlers) {
467
+ provider.removeListener('disconnect', this.providerHandlers.disconnect);
468
+ provider.removeListener('accountsChanged', this.providerHandlers.accountsChanged);
469
+ provider.removeListener('chainChanged', this.providerHandlers.chainChanged);
470
+ this.providerHandlers = null;
471
+ }
472
+ }
473
+ setupAuthListeners(authProvider) {
474
+ authProvider.onRpcRequest(request => {
475
+ if (W3mFrameHelpers.checkIfRequestExists(request)) {
476
+ if (!W3mFrameHelpers.checkIfRequestIsSafe(request)) {
477
+ this.appKit?.handleUnsafeRPCRequest();
478
+ }
479
+ }
480
+ else {
481
+ this.handleInvalidAuthRequest();
482
+ }
483
+ });
484
+ authProvider.onRpcError(() => this.handleAuthRpcError());
485
+ authProvider.onRpcSuccess((_, request) => this.handleAuthRpcSuccess(_, request));
486
+ authProvider.onNotConnected(() => this.handleAuthNotConnected());
487
+ authProvider.onIsConnected(({ preferredAccountType }) => this.handleAuthIsConnected(preferredAccountType));
488
+ authProvider.onSetPreferredAccount(({ address, type }) => {
489
+ if (address) {
490
+ this.handleAuthSetPreferredAccount(address, type);
491
+ }
492
+ });
493
+ }
494
+ handleInvalidAuthRequest() {
495
+ this.appKit?.open();
496
+ setTimeout(() => {
497
+ this.appKit?.showErrorMessage(W3mFrameRpcConstants.RPC_METHOD_NOT_ALLOWED_UI_MESSAGE);
498
+ }, 300);
499
+ }
500
+ handleAuthRpcError() {
501
+ if (this.appKit?.isOpen()) {
502
+ if (this.appKit?.isTransactionStackEmpty()) {
503
+ this.appKit?.close();
504
+ }
505
+ else {
506
+ this.appKit?.popTransactionStack(true);
507
+ }
508
+ }
509
+ }
510
+ handleAuthRpcSuccess(_, request) {
511
+ const isSafeRequest = W3mFrameHelpers.checkIfRequestIsSafe(request);
512
+ if (isSafeRequest) {
513
+ return;
514
+ }
515
+ if (this.appKit?.isTransactionStackEmpty()) {
516
+ this.appKit?.close();
517
+ }
518
+ else {
519
+ this.appKit?.popTransactionStack();
520
+ }
521
+ }
522
+ handleAuthNotConnected() {
523
+ this.appKit?.setIsConnected(false, this.chainNamespace);
524
+ }
525
+ handleAuthIsConnected(preferredAccountType) {
526
+ this.appKit?.setIsConnected(true, this.chainNamespace);
527
+ this.appKit?.setPreferredAccountType(preferredAccountType, this.chainNamespace);
528
+ }
529
+ handleAuthSetPreferredAccount(address, type) {
530
+ if (!address) {
531
+ return;
532
+ }
533
+ this.appKit?.setLoading(true);
534
+ const chainId = NetworkUtil.caipNetworkIdToNumber(this.appKit?.getCaipNetwork()?.id);
535
+ const caipNetwork = this.caipNetworks.find(c => c.chainId === chainId);
536
+ this.appKit?.setCaipAddress(address, this.chainNamespace);
537
+ this.appKit?.setCaipNetwork(caipNetwork);
538
+ this.appKit?.setStatus('connected', this.chainNamespace);
539
+ this.appKit?.setIsConnected(true, this.chainNamespace);
540
+ this.appKit?.setPreferredAccountType(type, this.chainNamespace);
541
+ this.syncAccount({
542
+ address: address
543
+ }).then(() => this.appKit?.setLoading(false));
544
+ this.appKit?.setLoading(false);
545
+ }
546
+ async syncWalletConnectName(address) {
547
+ try {
548
+ const registeredWcNames = await this.appKit?.getWalletConnectName(address);
549
+ if (registeredWcNames?.[0]) {
550
+ const wcName = registeredWcNames[0];
551
+ this.appKit?.setProfileName(wcName.name, this.chainNamespace);
552
+ }
553
+ else {
554
+ this.appKit?.setProfileName(null, this.chainNamespace);
555
+ }
556
+ }
557
+ catch {
558
+ this.appKit?.setProfileName(null, this.chainNamespace);
559
+ }
560
+ }
561
+ async syncAccount({ address }) {
562
+ const isConnected = this.appKit?.getIsConnectedState();
563
+ const caipNetwork = this.appKit?.getCaipNetwork();
564
+ const preferredAccountType = this.appKit?.getPreferredAccountType();
565
+ if (isConnected && address && caipNetwork) {
566
+ this.appKit?.setIsConnected(isConnected, this.chainNamespace);
567
+ this.appKit?.setCaipAddress(`eip155:${caipNetwork.chainId}:${address}`, this.chainNamespace);
568
+ this.appKit?.setPreferredAccountType(preferredAccountType, this.chainNamespace);
569
+ this.syncConnectedWalletInfo();
570
+ if (caipNetwork?.explorerUrl) {
571
+ this.appKit?.setAddressExplorerUrl(`${caipNetwork.explorerUrl}/address/${address}`, this.chainNamespace);
572
+ }
573
+ await Promise.all([
574
+ this.syncProfile(address),
575
+ this.syncBalance(address),
576
+ this.appKit?.setApprovedCaipNetworksData(this.chainNamespace)
577
+ ]);
578
+ }
579
+ else if (!isConnected) {
580
+ this.appKit?.resetWcConnection();
581
+ this.appKit?.resetNetwork();
582
+ this.appKit?.setAllAccounts([], this.chainNamespace);
583
+ }
584
+ }
585
+ async syncProfile(address) {
586
+ const caipNetwork = this.appKit?.getCaipNetwork();
587
+ try {
588
+ const identity = await this.appKit?.fetchIdentity({
589
+ address
590
+ });
591
+ const name = identity?.name;
592
+ const avatar = identity?.avatar;
593
+ this.appKit?.setProfileName(name, this.chainNamespace);
594
+ this.appKit?.setProfileImage(avatar, this.chainNamespace);
595
+ if (!name) {
596
+ await this.syncWalletConnectName(address);
597
+ }
598
+ }
599
+ catch {
600
+ if (caipNetwork?.chainId === 1) {
601
+ const ensProvider = new ethers.providers.InfuraProvider('mainnet');
602
+ const name = await ensProvider.lookupAddress(address);
603
+ const avatar = await ensProvider.getAvatar(address);
604
+ if (name) {
605
+ this.appKit?.setProfileName(name, this.chainNamespace);
606
+ }
607
+ else {
608
+ await this.syncWalletConnectName(address);
609
+ }
610
+ if (avatar) {
611
+ this.appKit?.setProfileImage(avatar, this.chainNamespace);
612
+ }
613
+ }
614
+ else {
615
+ await this.syncWalletConnectName(address);
616
+ this.appKit?.setProfileImage(null, this.chainNamespace);
617
+ }
618
+ }
619
+ }
620
+ async syncBalance(address) {
621
+ const caipNetwork = this.appKit?.getCaipNetwork();
622
+ if (caipNetwork) {
623
+ const jsonRpcProvider = new ethers.providers.JsonRpcProvider(caipNetwork.rpcUrl, {
624
+ chainId: caipNetwork.chainId,
625
+ name: caipNetwork.name
626
+ });
627
+ if (jsonRpcProvider) {
628
+ const balance = await jsonRpcProvider.getBalance(address);
629
+ const formattedBalance = ethers.utils.formatEther(balance);
630
+ this.appKit?.setBalance(formattedBalance, caipNetwork.currency, this.chainNamespace);
631
+ }
632
+ }
633
+ }
634
+ syncConnectedWalletInfo() {
635
+ const currentActiveWallet = SafeLocalStorage.getItem(SafeLocalStorageKeys.WALLET_ID);
636
+ const providerType = ProviderUtil.state.providerIds['eip155'];
637
+ if (providerType === ConstantsUtil.EIP6963_CONNECTOR_ID) {
638
+ if (currentActiveWallet) {
639
+ const currentProvider = this.EIP6963Providers.find(provider => provider.info.name === currentActiveWallet);
640
+ if (currentProvider) {
641
+ this.appKit?.setConnectedWalletInfo({ ...currentProvider.info }, this.chainNamespace);
642
+ }
643
+ }
644
+ }
645
+ else if (providerType === ConstantsUtil.WALLET_CONNECT_CONNECTOR_ID) {
646
+ const provider = ProviderUtil.getProvider('eip155');
647
+ if (provider?.session) {
648
+ this.appKit?.setConnectedWalletInfo({
649
+ ...provider.session.peer.metadata,
650
+ name: provider.session.peer.metadata.name,
651
+ icon: provider.session.peer.metadata.icons?.[0]
652
+ }, this.chainNamespace);
653
+ }
654
+ }
655
+ else if (providerType === ConstantsUtil.COINBASE_SDK_CONNECTOR_ID) {
656
+ const connector = this.appKit
657
+ ?.getConnectors()
658
+ .find(c => c.id === ConstantsUtil.COINBASE_SDK_CONNECTOR_ID);
659
+ this.appKit?.setConnectedWalletInfo({ name: 'Coinbase Wallet', icon: this.appKit?.getConnectorImage(connector) }, this.chainNamespace);
660
+ }
661
+ else if (currentActiveWallet) {
662
+ this.appKit?.setConnectedWalletInfo({ name: currentActiveWallet }, this.chainNamespace);
663
+ }
664
+ }
665
+ syncRequestedNetworks(caipNetworks) {
666
+ const uniqueChainNamespaces = [
667
+ ...new Set(caipNetworks.map(caipNetwork => caipNetwork.chainNamespace))
668
+ ];
669
+ uniqueChainNamespaces.forEach(chainNamespace => {
670
+ this.appKit?.setRequestedCaipNetworks(caipNetworks.filter(caipNetwork => caipNetwork.chainNamespace === chainNamespace), chainNamespace);
671
+ });
672
+ }
673
+ async switchNetwork(caipNetwork) {
674
+ const requestSwitchNetwork = async (provider) => {
675
+ try {
676
+ await provider.request({
677
+ method: 'wallet_switchEthereumChain',
678
+ params: [{ chainId: EthersHelpersUtil.numberToHexString(caipNetwork.chainId) }]
679
+ });
680
+ this.appKit?.setCaipNetwork(caipNetwork);
681
+ }
682
+ catch (switchError) {
683
+ if (switchError.code === WcConstantsUtil.ERROR_CODE_UNRECOGNIZED_CHAIN_ID ||
684
+ switchError.code === WcConstantsUtil.ERROR_CODE_DEFAULT ||
685
+ switchError?.data?.originalError?.code ===
686
+ WcConstantsUtil.ERROR_CODE_UNRECOGNIZED_CHAIN_ID) {
687
+ await EthersHelpersUtil.addEthereumChain(provider, caipNetwork);
688
+ }
689
+ else {
690
+ throw new Error('Chain is not supported');
691
+ }
692
+ }
693
+ };
694
+ const provider = ProviderUtil.getProvider('eip155');
695
+ const providerType = ProviderUtil.state.providerIds['eip155'];
696
+ if (provider) {
697
+ switch (providerType) {
698
+ case ConstantsUtil.WALLET_CONNECT_CONNECTOR_ID:
699
+ this.appKit?.universalAdapter?.networkControllerClient.switchCaipNetwork(caipNetwork);
700
+ break;
701
+ case ConstantsUtil.INJECTED_CONNECTOR_ID:
702
+ case ConstantsUtil.EIP6963_CONNECTOR_ID:
703
+ case ConstantsUtil.COINBASE_SDK_CONNECTOR_ID:
704
+ if (provider) {
705
+ await requestSwitchNetwork(provider);
706
+ }
707
+ break;
708
+ case ConstantsUtil.AUTH_CONNECTOR_ID:
709
+ if (this.authProvider) {
710
+ try {
711
+ this.appKit?.setLoading(true);
712
+ await this.authProvider.switchNetwork(caipNetwork.chainId);
713
+ this.appKit?.setCaipNetwork(caipNetwork);
714
+ this.appKit?.setLoading(false);
715
+ const { address, preferredAccountType } = await this.authProvider.connect({
716
+ chainId: caipNetwork.chainId
717
+ });
718
+ this.appKit?.setCaipAddress(address, this.chainNamespace);
719
+ this.appKit?.setPreferredAccountType(preferredAccountType, this.chainNamespace);
720
+ await this.syncAccount({ address: address });
721
+ }
722
+ catch {
723
+ throw new Error('Switching chain failed');
724
+ }
725
+ finally {
726
+ this.appKit?.setLoading(false);
727
+ }
728
+ }
729
+ break;
730
+ default:
731
+ throw new Error('Unsupported provider type');
732
+ }
733
+ }
734
+ }
735
+ syncConnectors(config) {
736
+ const w3mConnectors = [];
737
+ if (config.injected) {
738
+ const injectedConnectorType = PresetsUtil.ConnectorTypesMap[ConstantsUtil.INJECTED_CONNECTOR_ID];
739
+ if (injectedConnectorType) {
740
+ w3mConnectors.push({
741
+ id: ConstantsUtil.INJECTED_CONNECTOR_ID,
742
+ explorerId: PresetsUtil.ConnectorExplorerIds[ConstantsUtil.INJECTED_CONNECTOR_ID],
743
+ imageId: PresetsUtil.ConnectorImageIds[ConstantsUtil.INJECTED_CONNECTOR_ID],
744
+ imageUrl: this.options?.connectorImages?.[ConstantsUtil.INJECTED_CONNECTOR_ID],
745
+ name: PresetsUtil.ConnectorNamesMap[ConstantsUtil.INJECTED_CONNECTOR_ID],
746
+ type: injectedConnectorType,
747
+ chain: this.chainNamespace
748
+ });
749
+ }
750
+ }
751
+ if (config.coinbase) {
752
+ w3mConnectors.push({
753
+ id: ConstantsUtil.COINBASE_SDK_CONNECTOR_ID,
754
+ explorerId: PresetsUtil.ConnectorExplorerIds[ConstantsUtil.COINBASE_SDK_CONNECTOR_ID],
755
+ imageId: PresetsUtil.ConnectorImageIds[ConstantsUtil.COINBASE_SDK_CONNECTOR_ID],
756
+ imageUrl: this.options?.connectorImages?.[ConstantsUtil.COINBASE_SDK_CONNECTOR_ID],
757
+ name: PresetsUtil.ConnectorNamesMap[ConstantsUtil.COINBASE_SDK_CONNECTOR_ID],
758
+ type: 'EXTERNAL',
759
+ chain: this.chainNamespace
760
+ });
761
+ }
762
+ this.appKit?.setConnectors(w3mConnectors);
763
+ }
764
+ async syncAuthConnector(projectId, bypassWindowCheck = false) {
765
+ if (bypassWindowCheck || typeof window !== 'undefined') {
766
+ this.authProvider = W3mFrameProviderSingleton.getInstance(projectId);
767
+ this.appKit?.addConnector({
768
+ id: ConstantsUtil.AUTH_CONNECTOR_ID,
769
+ type: 'AUTH',
770
+ name: 'Auth',
771
+ provider: this.authProvider,
772
+ chain: this.chainNamespace
773
+ });
774
+ this.appKit?.setLoading(true);
775
+ const isLoginEmailUsed = this.authProvider.getLoginEmailUsed();
776
+ this.appKit?.setLoading(isLoginEmailUsed);
777
+ const { isConnected } = await this.authProvider.isConnected();
778
+ if (isConnected) {
779
+ await this.setAuthProvider();
780
+ }
781
+ else {
782
+ this.appKit?.setLoading(false);
783
+ }
784
+ }
785
+ }
786
+ eip6963EventHandler(event) {
787
+ if (event.detail) {
788
+ const { info, provider } = event.detail;
789
+ const connectors = this.appKit?.getConnectors();
790
+ const existingConnector = connectors?.find(c => c.name === info.name);
791
+ const coinbaseConnector = connectors?.find(c => c.id === ConstantsUtil.COINBASE_SDK_CONNECTOR_ID);
792
+ const isCoinbaseDuplicated = coinbaseConnector &&
793
+ event.detail.info.rdns ===
794
+ ConstantsUtil.CONNECTOR_RDNS_MAP[ConstantsUtil.COINBASE_SDK_CONNECTOR_ID];
795
+ if (!existingConnector && !isCoinbaseDuplicated) {
796
+ const type = PresetsUtil.ConnectorTypesMap[ConstantsUtil.EIP6963_CONNECTOR_ID];
797
+ if (type) {
798
+ this.appKit?.addConnector({
799
+ id: ConstantsUtil.EIP6963_CONNECTOR_ID,
800
+ type,
801
+ imageUrl: info.icon ?? this.options?.connectorImages?.[ConstantsUtil.EIP6963_CONNECTOR_ID],
802
+ name: info.name,
803
+ provider,
804
+ info,
805
+ chain: this.chainNamespace
806
+ });
807
+ const eip6963ProviderObj = {
808
+ provider,
809
+ info
810
+ };
811
+ this.EIP6963Providers.push(eip6963ProviderObj);
812
+ }
813
+ }
814
+ }
815
+ }
816
+ listenConnectors(enableEIP6963) {
817
+ if (typeof window !== 'undefined' && enableEIP6963) {
818
+ const handler = this.eip6963EventHandler.bind(this);
819
+ window.addEventListener(ConstantsUtil.EIP6963_ANNOUNCE_EVENT, handler);
820
+ window.dispatchEvent(new Event(ConstantsUtil.EIP6963_REQUEST_EVENT));
821
+ }
822
+ }
823
+ }
824
+ //# sourceMappingURL=client.js.map