@reown/appkit-adapter-ethers 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,822 @@
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 CoreConstantsUtil } from '@reown/appkit-core';
6
+ import { ConstantsUtil as CommonConstantsUtil } from '@reown/appkit-common';
7
+ import { ConstantsUtil, HelpersUtil, PresetsUtil } from '@reown/appkit-utils';
8
+ import UniversalProvider from '@walletconnect/universal-provider';
9
+ import { WcConstantsUtil } from '@reown/appkit';
10
+ import { EthersMethods } from './utils/EthersMethods.js';
11
+ import { formatEther, InfuraProvider, JsonRpcProvider } from 'ethers';
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 EVMEthersClient {
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
+ await this.revokeProviderPermissions(provider);
173
+ }
174
+ },
175
+ [ConstantsUtil.INJECTED_CONNECTOR_ID]: async () => {
176
+ if (provider) {
177
+ ;
178
+ provider.emit('disconnect');
179
+ await this.revokeProviderPermissions(provider);
180
+ }
181
+ }
182
+ };
183
+ const disconnectFunction = disconnectConfig[providerId];
184
+ if (disconnectFunction) {
185
+ await disconnectFunction();
186
+ }
187
+ else {
188
+ console.warn(`No disconnect function found for provider type: ${providerId}`);
189
+ }
190
+ SafeLocalStorage.removeItem(SafeLocalStorageKeys.WALLET_ID);
191
+ this.appKit?.resetAccount(this.chainNamespace);
192
+ },
193
+ signMessage: async (message) => {
194
+ const provider = ProviderUtil.getProvider(this.chainNamespace);
195
+ const address = this.appKit?.getAddress();
196
+ if (!address) {
197
+ throw new Error('Address is undefined');
198
+ }
199
+ if (!provider) {
200
+ throw new Error('Provider is undefined');
201
+ }
202
+ return await EthersMethods.signMessage(message, provider, address);
203
+ },
204
+ parseUnits: EthersMethods.parseUnits,
205
+ formatUnits: EthersMethods.formatUnits,
206
+ estimateGas: async (data) => {
207
+ if (data.chainNamespace && data.chainNamespace !== 'eip155') {
208
+ throw new Error(`Invalid chain namespace - Expected eip155, got ${data.chainNamespace}`);
209
+ }
210
+ const provider = ProviderUtil.getProvider('eip155');
211
+ const address = this.appKit?.getAddress();
212
+ const caipNetwork = this.appKit?.getCaipNetwork();
213
+ if (!address) {
214
+ throw new Error('Address is undefined');
215
+ }
216
+ if (!provider) {
217
+ throw new Error('Provider is undefined');
218
+ }
219
+ return await EthersMethods.estimateGas(data, provider, address, Number(caipNetwork?.chainId));
220
+ },
221
+ sendTransaction: async (data) => {
222
+ if (data.chainNamespace && data.chainNamespace !== 'eip155') {
223
+ throw new Error(`Invalid chain namespace - Expected eip155, got ${data.chainNamespace}`);
224
+ }
225
+ const provider = ProviderUtil.getProvider('eip155');
226
+ const address = this.appKit?.getAddress();
227
+ const caipNetwork = this.appKit?.getCaipNetwork();
228
+ if (!address) {
229
+ throw new Error('Address is undefined');
230
+ }
231
+ if (!provider) {
232
+ throw new Error('Provider is undefined');
233
+ }
234
+ return await EthersMethods.sendTransaction(data, provider, address, Number(caipNetwork?.chainId));
235
+ },
236
+ writeContract: async (data) => {
237
+ const provider = ProviderUtil.getProvider('eip155');
238
+ const address = this.appKit?.getAddress();
239
+ const caipNetwork = this.appKit?.getCaipNetwork();
240
+ if (!address) {
241
+ throw new Error('Address is undefined');
242
+ }
243
+ if (!provider) {
244
+ throw new Error('Provider is undefined');
245
+ }
246
+ return await EthersMethods.writeContract(data, provider, address, Number(caipNetwork?.chainId));
247
+ },
248
+ getEnsAddress: async (value) => {
249
+ if (this.appKit) {
250
+ return await EthersMethods.getEnsAddress(value, this.appKit);
251
+ }
252
+ return false;
253
+ },
254
+ getEnsAvatar: async (value) => {
255
+ const caipNetwork = this.appKit?.getCaipNetwork();
256
+ return await EthersMethods.getEnsAvatar(value, Number(caipNetwork?.chainId));
257
+ }
258
+ };
259
+ ChainController.state.chains.set(this.chainNamespace, {
260
+ chainNamespace: this.chainNamespace,
261
+ connectionControllerClient: this.connectionControllerClient,
262
+ networkControllerClient: this.networkControllerClient,
263
+ adapterType: this.adapterType
264
+ });
265
+ if (this.ethersConfig) {
266
+ this.syncConnectors(this.ethersConfig);
267
+ }
268
+ if (typeof window !== 'undefined') {
269
+ this.listenConnectors(true);
270
+ }
271
+ this.appKit?.setEIP6963Enabled(this.ethersConfig?.EIP6963);
272
+ const emailEnabled = options.features?.email === undefined
273
+ ? CoreConstantsUtil.DEFAULT_FEATURES.email
274
+ : options.features?.email;
275
+ const socialsEnabled = options.features?.socials === undefined
276
+ ? CoreConstantsUtil.DEFAULT_FEATURES.socials
277
+ : options.features?.socials?.length > 0;
278
+ if (emailEnabled || socialsEnabled) {
279
+ this.syncAuthConnector(this.options.projectId);
280
+ }
281
+ if (this.ethersConfig) {
282
+ this.checkActiveProviders(this.ethersConfig);
283
+ }
284
+ this.syncRequestedNetworks(this.caipNetworks);
285
+ }
286
+ subscribeState(callback) {
287
+ return this.appKit?.subscribeState(state => callback(state));
288
+ }
289
+ async disconnect() {
290
+ await this.connectionControllerClient?.disconnect();
291
+ }
292
+ async revokeProviderPermissions(provider) {
293
+ try {
294
+ const permissions = await provider.request({
295
+ method: 'wallet_getPermissions'
296
+ });
297
+ const ethAccountsPermission = permissions.find(permission => permission.parentCapability === 'eth_accounts');
298
+ if (ethAccountsPermission) {
299
+ await provider.request({
300
+ method: 'wallet_revokePermissions',
301
+ params: [{ eth_accounts: {} }]
302
+ });
303
+ }
304
+ }
305
+ catch (error) {
306
+ console.info('Could not revoke permissions from wallet. Disconnecting...', error);
307
+ }
308
+ }
309
+ getApprovedCaipNetworksData() {
310
+ return new Promise(resolve => {
311
+ const walletId = SafeLocalStorage.getItem(SafeLocalStorageKeys.WALLET_ID);
312
+ if (!walletId) {
313
+ throw new Error('No wallet id found to get approved networks data');
314
+ }
315
+ const providerConfigs = {
316
+ [ConstantsUtil.AUTH_CONNECTOR_ID]: {
317
+ supportsAllNetworks: true,
318
+ approvedCaipNetworkIds: PresetsUtil.WalletConnectRpcChainIds.map(id => `${ConstantsUtil.EIP155}:${id}`)
319
+ }
320
+ };
321
+ const networkData = providerConfigs[walletId];
322
+ if (networkData) {
323
+ resolve(networkData);
324
+ }
325
+ else {
326
+ resolve({
327
+ supportsAllNetworks: true,
328
+ approvedCaipNetworkIds: []
329
+ });
330
+ }
331
+ });
332
+ }
333
+ checkActiveProviders(config) {
334
+ const walletId = SafeLocalStorage.getItem(SafeLocalStorageKeys.WALLET_ID);
335
+ const walletName = SafeLocalStorage.getItem(SafeLocalStorageKeys.WALLET_NAME);
336
+ if (!walletId) {
337
+ return;
338
+ }
339
+ const providerConfigs = {
340
+ [ConstantsUtil.INJECTED_CONNECTOR_ID]: {
341
+ provider: config.injected
342
+ },
343
+ [ConstantsUtil.COINBASE_SDK_CONNECTOR_ID]: {
344
+ provider: config.coinbase
345
+ },
346
+ [ConstantsUtil.EIP6963_CONNECTOR_ID]: {
347
+ provider: this.EIP6963Providers.find(p => p.info.name === walletName)?.provider
348
+ }
349
+ };
350
+ const activeConfig = providerConfigs[walletId];
351
+ if (activeConfig?.provider) {
352
+ this.setProvider(activeConfig.provider, walletId);
353
+ this.setupProviderListeners(activeConfig.provider, walletId);
354
+ }
355
+ }
356
+ async setProvider(provider, providerId, name) {
357
+ if (providerId === 'w3mAuth') {
358
+ this.setAuthProvider();
359
+ }
360
+ else {
361
+ const walletId = providerId;
362
+ SafeLocalStorage.setItem(SafeLocalStorageKeys.WALLET_ID, walletId);
363
+ if (name) {
364
+ SafeLocalStorage.setItem(SafeLocalStorageKeys.WALLET_NAME, name);
365
+ }
366
+ if (provider) {
367
+ const { addresses, chainId } = await EthersHelpersUtil.getUserInfo(provider);
368
+ const caipNetwork = this.caipNetworks.find(c => c.chainId === chainId);
369
+ if (addresses?.[0] && chainId && caipNetwork) {
370
+ this.appKit?.setCaipNetwork(caipNetwork);
371
+ this.appKit?.setCaipAddress(`${this.chainNamespace}:${chainId}:${addresses[0]}`, this.chainNamespace);
372
+ ProviderUtil.setProviderId('eip155', providerId);
373
+ ProviderUtil.setProvider('eip155', provider);
374
+ this.appKit?.setStatus('connected', this.chainNamespace);
375
+ this.appKit?.setIsConnected(true, this.chainNamespace);
376
+ this.appKit?.setAllAccounts(addresses.map(address => ({ address, type: 'eoa' })), this.chainNamespace);
377
+ }
378
+ }
379
+ }
380
+ }
381
+ async setAuthProvider() {
382
+ SafeLocalStorage.setItem(SafeLocalStorageKeys.WALLET_ID, ConstantsUtil.AUTH_CONNECTOR_ID);
383
+ if (this.authProvider) {
384
+ this.appKit?.setLoading(true);
385
+ const { address, chainId, smartAccountDeployed, preferredAccountType, accounts = [] } = await this.authProvider.connect({
386
+ chainId: Number(NetworkUtil.caipNetworkIdToNumber(this.appKit?.getCaipNetwork()?.id) ??
387
+ this.caipNetworks[0]?.chainId)
388
+ });
389
+ const { smartAccountEnabledNetworks } = await this.authProvider.getSmartAccountEnabledNetworks();
390
+ this.appKit?.setSmartAccountEnabledNetworks(smartAccountEnabledNetworks, this.chainNamespace);
391
+ if (address && chainId) {
392
+ this.appKit?.setAllAccounts(accounts.length > 0
393
+ ? accounts
394
+ : [{ address, type: preferredAccountType }], this.chainNamespace);
395
+ const caipNetwork = this.caipNetworks.find(c => c.chainId === chainId);
396
+ this.appKit?.setCaipNetwork(caipNetwork);
397
+ this.appKit?.setStatus('connected', this.chainNamespace);
398
+ this.appKit?.setIsConnected(true, this.chainNamespace);
399
+ this.appKit?.setCaipAddress(`${this.chainNamespace}:${chainId}:${address}`, this.chainNamespace);
400
+ this.appKit?.setPreferredAccountType(preferredAccountType, this.chainNamespace);
401
+ this.appKit?.setSmartAccountDeployed(Boolean(smartAccountDeployed), this.chainNamespace);
402
+ ProviderUtil.setProvider('eip155', this.authProvider);
403
+ ProviderUtil.setProviderId('eip155', ConstantsUtil.AUTH_CONNECTOR_ID);
404
+ this.setupProviderListeners(this.authProvider, 'w3mAuth');
405
+ this.watchModal();
406
+ }
407
+ this.appKit?.setLoading(false);
408
+ }
409
+ }
410
+ watchModal() {
411
+ if (this.authProvider) {
412
+ this.subscribeState(val => {
413
+ if (!val.open) {
414
+ this.authProvider?.rejectRpcRequests();
415
+ }
416
+ });
417
+ }
418
+ }
419
+ setupProviderListeners(provider, providerId) {
420
+ const disconnectHandler = () => {
421
+ SafeLocalStorage.removeItem(SafeLocalStorageKeys.WALLET_ID);
422
+ this.removeListeners(provider);
423
+ };
424
+ const accountsChangedHandler = (accounts) => {
425
+ const currentAccount = accounts?.[0];
426
+ if (currentAccount) {
427
+ this.appKit?.setCaipAddress(currentAccount, this.chainNamespace);
428
+ if (providerId === ConstantsUtil.EIP6963_CONNECTOR_ID) {
429
+ this.appKit?.setAllAccounts(accounts.map(address => ({ address, type: 'eoa' })), this.chainNamespace);
430
+ }
431
+ }
432
+ else {
433
+ if (providerId === ConstantsUtil.EIP6963_CONNECTOR_ID) {
434
+ this.appKit?.setAllAccounts([], this.chainNamespace);
435
+ }
436
+ SafeLocalStorage.removeItem(SafeLocalStorageKeys.WALLET_ID);
437
+ this.appKit?.resetAccount(this.chainNamespace);
438
+ }
439
+ };
440
+ const chainChangedHandler = (networkId) => {
441
+ if (networkId) {
442
+ const networkIdNumber = typeof networkId === 'string'
443
+ ? EthersHelpersUtil.hexStringToNumber(networkId)
444
+ : Number(networkId);
445
+ const caipNetwork = this.caipNetworks.find(c => c.chainId === networkIdNumber);
446
+ this.appKit?.setCaipNetwork(caipNetwork);
447
+ }
448
+ };
449
+ if (providerId === ConstantsUtil.AUTH_CONNECTOR_ID) {
450
+ this.setupAuthListeners(provider);
451
+ }
452
+ else {
453
+ provider.on('disconnect', disconnectHandler);
454
+ provider.on('accountsChanged', accountsChangedHandler);
455
+ provider.on('chainChanged', chainChangedHandler);
456
+ }
457
+ this.providerHandlers = {
458
+ disconnect: disconnectHandler,
459
+ accountsChanged: accountsChangedHandler,
460
+ chainChanged: chainChangedHandler
461
+ };
462
+ }
463
+ removeListeners(provider) {
464
+ if (this.providerHandlers) {
465
+ provider.removeListener('disconnect', this.providerHandlers.disconnect);
466
+ provider.removeListener('accountsChanged', this.providerHandlers.accountsChanged);
467
+ provider.removeListener('chainChanged', this.providerHandlers.chainChanged);
468
+ this.providerHandlers = null;
469
+ }
470
+ }
471
+ setupAuthListeners(authProvider) {
472
+ authProvider.onRpcRequest(request => {
473
+ if (W3mFrameHelpers.checkIfRequestExists(request)) {
474
+ if (!W3mFrameHelpers.checkIfRequestIsSafe(request)) {
475
+ this.appKit?.handleUnsafeRPCRequest();
476
+ }
477
+ }
478
+ else {
479
+ this.handleInvalidAuthRequest();
480
+ }
481
+ });
482
+ authProvider.onRpcError(() => this.handleAuthRpcError());
483
+ authProvider.onRpcSuccess((_, request) => this.handleAuthRpcSuccess(_, request));
484
+ authProvider.onNotConnected(() => this.handleAuthNotConnected());
485
+ authProvider.onIsConnected(({ preferredAccountType }) => this.handleAuthIsConnected(preferredAccountType));
486
+ authProvider.onSetPreferredAccount(({ address, type }) => {
487
+ if (address) {
488
+ this.handleAuthSetPreferredAccount(address, type);
489
+ }
490
+ });
491
+ }
492
+ handleInvalidAuthRequest() {
493
+ this.appKit?.open();
494
+ setTimeout(() => {
495
+ this.appKit?.showErrorMessage(W3mFrameRpcConstants.RPC_METHOD_NOT_ALLOWED_UI_MESSAGE);
496
+ }, 300);
497
+ }
498
+ handleAuthRpcError() {
499
+ if (this.appKit?.isOpen()) {
500
+ if (this.appKit?.isTransactionStackEmpty()) {
501
+ this.appKit?.close();
502
+ }
503
+ else {
504
+ this.appKit?.popTransactionStack(true);
505
+ }
506
+ }
507
+ }
508
+ handleAuthRpcSuccess(_, request) {
509
+ const isSafeRequest = W3mFrameHelpers.checkIfRequestIsSafe(request);
510
+ if (isSafeRequest) {
511
+ return;
512
+ }
513
+ if (this.appKit?.isTransactionStackEmpty()) {
514
+ this.appKit?.close();
515
+ }
516
+ else {
517
+ this.appKit?.popTransactionStack();
518
+ }
519
+ }
520
+ handleAuthNotConnected() {
521
+ this.appKit?.setIsConnected(false, this.chainNamespace);
522
+ }
523
+ handleAuthIsConnected(preferredAccountType) {
524
+ this.appKit?.setIsConnected(true, this.chainNamespace);
525
+ this.appKit?.setPreferredAccountType(preferredAccountType, this.chainNamespace);
526
+ }
527
+ handleAuthSetPreferredAccount(address, type) {
528
+ if (!address) {
529
+ return;
530
+ }
531
+ this.appKit?.setLoading(true);
532
+ const chainId = NetworkUtil.caipNetworkIdToNumber(this.appKit?.getCaipNetwork()?.id);
533
+ const caipNetwork = this.caipNetworks.find(c => c.chainId === chainId);
534
+ this.appKit?.setCaipAddress(address, this.chainNamespace);
535
+ this.appKit?.setCaipNetwork(caipNetwork);
536
+ this.appKit?.setStatus('connected', this.chainNamespace);
537
+ this.appKit?.setIsConnected(true, this.chainNamespace);
538
+ this.appKit?.setPreferredAccountType(type, this.chainNamespace);
539
+ this.syncAccount({
540
+ address: address
541
+ }).then(() => this.appKit?.setLoading(false));
542
+ this.appKit?.setLoading(false);
543
+ }
544
+ async syncWalletConnectName(address) {
545
+ try {
546
+ const registeredWcNames = await this.appKit?.getWalletConnectName(address);
547
+ if (registeredWcNames?.[0]) {
548
+ const wcName = registeredWcNames[0];
549
+ this.appKit?.setProfileName(wcName.name, this.chainNamespace);
550
+ }
551
+ else {
552
+ this.appKit?.setProfileName(null, this.chainNamespace);
553
+ }
554
+ }
555
+ catch {
556
+ this.appKit?.setProfileName(null, this.chainNamespace);
557
+ }
558
+ }
559
+ async syncAccount({ address }) {
560
+ const isConnected = this.appKit?.getIsConnectedState();
561
+ const caipNetwork = this.appKit?.getCaipNetwork();
562
+ const preferredAccountType = this.appKit?.getPreferredAccountType();
563
+ if (isConnected && address && caipNetwork) {
564
+ this.appKit?.setIsConnected(isConnected, this.chainNamespace);
565
+ this.appKit?.setCaipAddress(`eip155:${caipNetwork.chainId}:${address}`, this.chainNamespace);
566
+ this.appKit?.setPreferredAccountType(preferredAccountType, this.chainNamespace);
567
+ this.syncConnectedWalletInfo();
568
+ if (caipNetwork?.explorerUrl) {
569
+ this.appKit?.setAddressExplorerUrl(`${caipNetwork.explorerUrl}/address/${address}`, this.chainNamespace);
570
+ }
571
+ await Promise.all([
572
+ this.syncProfile(address),
573
+ this.syncBalance(address),
574
+ this.appKit?.setApprovedCaipNetworksData(this.chainNamespace)
575
+ ]);
576
+ }
577
+ else if (!isConnected) {
578
+ this.appKit?.resetWcConnection();
579
+ this.appKit?.resetNetwork();
580
+ this.appKit?.setAllAccounts([], this.chainNamespace);
581
+ }
582
+ }
583
+ async syncProfile(address) {
584
+ const caipNetwork = this.appKit?.getCaipNetwork();
585
+ try {
586
+ const identity = await this.appKit?.fetchIdentity({
587
+ address
588
+ });
589
+ const name = identity?.name;
590
+ const avatar = identity?.avatar;
591
+ this.appKit?.setProfileName(name, this.chainNamespace);
592
+ this.appKit?.setProfileImage(avatar, this.chainNamespace);
593
+ if (!name) {
594
+ await this.syncWalletConnectName(address);
595
+ }
596
+ }
597
+ catch {
598
+ if (caipNetwork?.chainId === 1) {
599
+ const ensProvider = new InfuraProvider('mainnet');
600
+ const name = await ensProvider.lookupAddress(address);
601
+ const avatar = await ensProvider.getAvatar(address);
602
+ if (name) {
603
+ this.appKit?.setProfileName(name, this.chainNamespace);
604
+ }
605
+ else {
606
+ await this.syncWalletConnectName(address);
607
+ }
608
+ if (avatar) {
609
+ this.appKit?.setProfileImage(avatar, this.chainNamespace);
610
+ }
611
+ }
612
+ else {
613
+ await this.syncWalletConnectName(address);
614
+ this.appKit?.setProfileImage(null, this.chainNamespace);
615
+ }
616
+ }
617
+ }
618
+ async syncBalance(address) {
619
+ const caipNetwork = this.appKit?.getCaipNetwork();
620
+ if (caipNetwork) {
621
+ const jsonRpcProvider = new JsonRpcProvider(caipNetwork.rpcUrl, {
622
+ chainId: caipNetwork.chainId,
623
+ name: caipNetwork.name
624
+ });
625
+ if (jsonRpcProvider) {
626
+ const balance = await jsonRpcProvider.getBalance(address);
627
+ const formattedBalance = formatEther(balance);
628
+ this.appKit?.setBalance(formattedBalance, caipNetwork.currency, this.chainNamespace);
629
+ }
630
+ }
631
+ }
632
+ syncConnectedWalletInfo() {
633
+ const currentActiveWallet = SafeLocalStorage.getItem(SafeLocalStorageKeys.WALLET_ID);
634
+ const providerType = ProviderUtil.state.providerIds['eip155'];
635
+ if (providerType === ConstantsUtil.EIP6963_CONNECTOR_ID) {
636
+ if (currentActiveWallet) {
637
+ const currentProvider = this.EIP6963Providers.find(provider => provider.info.name === currentActiveWallet);
638
+ if (currentProvider) {
639
+ this.appKit?.setConnectedWalletInfo({ ...currentProvider.info }, this.chainNamespace);
640
+ }
641
+ }
642
+ }
643
+ else if (providerType === ConstantsUtil.WALLET_CONNECT_CONNECTOR_ID) {
644
+ const provider = ProviderUtil.getProvider('eip155');
645
+ if (provider?.session) {
646
+ this.appKit?.setConnectedWalletInfo({
647
+ ...provider.session.peer.metadata,
648
+ name: provider.session.peer.metadata.name,
649
+ icon: provider.session.peer.metadata.icons?.[0]
650
+ }, this.chainNamespace);
651
+ }
652
+ }
653
+ else if (providerType === ConstantsUtil.COINBASE_SDK_CONNECTOR_ID) {
654
+ const connector = this.appKit
655
+ ?.getConnectors()
656
+ .find(c => c.id === ConstantsUtil.COINBASE_SDK_CONNECTOR_ID);
657
+ this.appKit?.setConnectedWalletInfo({ name: 'Coinbase Wallet', icon: this.appKit?.getConnectorImage(connector) }, this.chainNamespace);
658
+ }
659
+ else if (currentActiveWallet) {
660
+ this.appKit?.setConnectedWalletInfo({ name: currentActiveWallet }, this.chainNamespace);
661
+ }
662
+ }
663
+ syncRequestedNetworks(caipNetworks) {
664
+ const uniqueChainNamespaces = [
665
+ ...new Set(caipNetworks.map(caipNetwork => caipNetwork.chainNamespace))
666
+ ];
667
+ uniqueChainNamespaces.forEach(chainNamespace => {
668
+ this.appKit?.setRequestedCaipNetworks(caipNetworks.filter(caipNetwork => caipNetwork.chainNamespace === chainNamespace), chainNamespace);
669
+ });
670
+ }
671
+ async switchNetwork(caipNetwork) {
672
+ const requestSwitchNetwork = async (provider) => {
673
+ try {
674
+ await provider.request({
675
+ method: 'wallet_switchEthereumChain',
676
+ params: [{ chainId: EthersHelpersUtil.numberToHexString(caipNetwork.chainId) }]
677
+ });
678
+ this.appKit?.setCaipNetwork(caipNetwork);
679
+ }
680
+ catch (switchError) {
681
+ if (switchError.code === WcConstantsUtil.ERROR_CODE_UNRECOGNIZED_CHAIN_ID ||
682
+ switchError.code === WcConstantsUtil.ERROR_CODE_DEFAULT ||
683
+ switchError?.data?.originalError?.code ===
684
+ WcConstantsUtil.ERROR_CODE_UNRECOGNIZED_CHAIN_ID) {
685
+ await EthersHelpersUtil.addEthereumChain(provider, caipNetwork);
686
+ }
687
+ else {
688
+ throw new Error('Chain is not supported');
689
+ }
690
+ }
691
+ };
692
+ const provider = ProviderUtil.getProvider('eip155');
693
+ const providerType = ProviderUtil.state.providerIds['eip155'];
694
+ if (provider) {
695
+ switch (providerType) {
696
+ case ConstantsUtil.WALLET_CONNECT_CONNECTOR_ID:
697
+ this.appKit?.universalAdapter?.networkControllerClient.switchCaipNetwork(caipNetwork);
698
+ break;
699
+ case ConstantsUtil.INJECTED_CONNECTOR_ID:
700
+ case ConstantsUtil.EIP6963_CONNECTOR_ID:
701
+ case ConstantsUtil.COINBASE_SDK_CONNECTOR_ID:
702
+ if (provider) {
703
+ await requestSwitchNetwork(provider);
704
+ }
705
+ break;
706
+ case ConstantsUtil.AUTH_CONNECTOR_ID:
707
+ if (this.authProvider) {
708
+ try {
709
+ this.appKit?.setLoading(true);
710
+ await this.authProvider.switchNetwork(caipNetwork.chainId);
711
+ this.appKit?.setCaipNetwork(caipNetwork);
712
+ this.appKit?.setLoading(false);
713
+ const { address, preferredAccountType } = await this.authProvider.connect({
714
+ chainId: caipNetwork.chainId
715
+ });
716
+ this.appKit?.setCaipAddress(address, this.chainNamespace);
717
+ this.appKit?.setPreferredAccountType(preferredAccountType, this.chainNamespace);
718
+ await this.syncAccount({ address: address });
719
+ }
720
+ catch {
721
+ throw new Error('Switching chain failed');
722
+ }
723
+ finally {
724
+ this.appKit?.setLoading(false);
725
+ }
726
+ }
727
+ break;
728
+ default:
729
+ throw new Error('Unsupported provider type');
730
+ }
731
+ }
732
+ }
733
+ syncConnectors(config) {
734
+ const w3mConnectors = [];
735
+ if (config.injected) {
736
+ const injectedConnectorType = PresetsUtil.ConnectorTypesMap[ConstantsUtil.INJECTED_CONNECTOR_ID];
737
+ if (injectedConnectorType) {
738
+ w3mConnectors.push({
739
+ id: ConstantsUtil.INJECTED_CONNECTOR_ID,
740
+ explorerId: PresetsUtil.ConnectorExplorerIds[ConstantsUtil.INJECTED_CONNECTOR_ID],
741
+ imageId: PresetsUtil.ConnectorImageIds[ConstantsUtil.INJECTED_CONNECTOR_ID],
742
+ imageUrl: this.options?.connectorImages?.[ConstantsUtil.INJECTED_CONNECTOR_ID],
743
+ name: PresetsUtil.ConnectorNamesMap[ConstantsUtil.INJECTED_CONNECTOR_ID],
744
+ type: injectedConnectorType,
745
+ chain: this.chainNamespace
746
+ });
747
+ }
748
+ }
749
+ if (config.coinbase) {
750
+ w3mConnectors.push({
751
+ id: ConstantsUtil.COINBASE_SDK_CONNECTOR_ID,
752
+ explorerId: PresetsUtil.ConnectorExplorerIds[ConstantsUtil.COINBASE_SDK_CONNECTOR_ID],
753
+ imageId: PresetsUtil.ConnectorImageIds[ConstantsUtil.COINBASE_SDK_CONNECTOR_ID],
754
+ imageUrl: this.options?.connectorImages?.[ConstantsUtil.COINBASE_SDK_CONNECTOR_ID],
755
+ name: PresetsUtil.ConnectorNamesMap[ConstantsUtil.COINBASE_SDK_CONNECTOR_ID],
756
+ type: 'EXTERNAL',
757
+ chain: this.chainNamespace
758
+ });
759
+ }
760
+ this.appKit?.setConnectors(w3mConnectors);
761
+ }
762
+ async syncAuthConnector(projectId, bypassWindowCheck = false) {
763
+ if (bypassWindowCheck || typeof window !== 'undefined') {
764
+ this.authProvider = W3mFrameProviderSingleton.getInstance(projectId);
765
+ this.appKit?.addConnector({
766
+ id: ConstantsUtil.AUTH_CONNECTOR_ID,
767
+ type: 'AUTH',
768
+ name: 'Auth',
769
+ provider: this.authProvider,
770
+ chain: this.chainNamespace
771
+ });
772
+ this.appKit?.setLoading(true);
773
+ const isLoginEmailUsed = this.authProvider.getLoginEmailUsed();
774
+ this.appKit?.setLoading(isLoginEmailUsed);
775
+ const { isConnected } = await this.authProvider.isConnected();
776
+ if (isConnected) {
777
+ await this.setAuthProvider();
778
+ }
779
+ else {
780
+ this.appKit?.setLoading(false);
781
+ }
782
+ }
783
+ }
784
+ eip6963EventHandler(event) {
785
+ if (event.detail) {
786
+ const { info, provider } = event.detail;
787
+ const connectors = this.appKit?.getConnectors();
788
+ const existingConnector = connectors?.find(c => c.name === info.name);
789
+ const coinbaseConnector = connectors?.find(c => c.id === ConstantsUtil.COINBASE_SDK_CONNECTOR_ID);
790
+ const isCoinbaseDuplicated = coinbaseConnector &&
791
+ event.detail.info.rdns ===
792
+ ConstantsUtil.CONNECTOR_RDNS_MAP[ConstantsUtil.COINBASE_SDK_CONNECTOR_ID];
793
+ if (!existingConnector && !isCoinbaseDuplicated) {
794
+ const type = PresetsUtil.ConnectorTypesMap[ConstantsUtil.EIP6963_CONNECTOR_ID];
795
+ if (type) {
796
+ this.appKit?.addConnector({
797
+ id: ConstantsUtil.EIP6963_CONNECTOR_ID,
798
+ type,
799
+ imageUrl: info.icon ?? this.options?.connectorImages?.[ConstantsUtil.EIP6963_CONNECTOR_ID],
800
+ name: info.name,
801
+ provider,
802
+ info,
803
+ chain: this.chainNamespace
804
+ });
805
+ const eip6963ProviderObj = {
806
+ provider,
807
+ info
808
+ };
809
+ this.EIP6963Providers.push(eip6963ProviderObj);
810
+ }
811
+ }
812
+ }
813
+ }
814
+ listenConnectors(enableEIP6963) {
815
+ if (typeof window !== 'undefined' && enableEIP6963) {
816
+ const handler = this.eip6963EventHandler.bind(this);
817
+ window.addEventListener(ConstantsUtil.EIP6963_ANNOUNCE_EVENT, handler);
818
+ window.dispatchEvent(new Event(ConstantsUtil.EIP6963_REQUEST_EVENT));
819
+ }
820
+ }
821
+ }
822
+ //# sourceMappingURL=client.js.map