@reown/appkit 1.6.6-basic-test.2.0 → 1.6.6-basic-test.3.0

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.
Files changed (44) hide show
  1. package/dist/esm/exports/basic.js +2 -6
  2. package/dist/esm/exports/basic.js.map +1 -1
  3. package/dist/esm/exports/constants.js +1 -1
  4. package/dist/esm/exports/index.js +1 -1
  5. package/dist/esm/exports/index.js.map +1 -1
  6. package/dist/esm/exports/react.js +1 -1
  7. package/dist/esm/exports/react.js.map +1 -1
  8. package/dist/esm/exports/vue.js +1 -1
  9. package/dist/esm/exports/vue.js.map +1 -1
  10. package/dist/esm/package.json +6 -7
  11. package/dist/esm/src/adapters/ChainAdapterBlueprint.js +0 -1
  12. package/dist/esm/src/adapters/ChainAdapterBlueprint.js.map +1 -1
  13. package/dist/esm/src/client/appkit-basic.js +23 -0
  14. package/dist/esm/src/client/appkit-basic.js.map +1 -0
  15. package/dist/esm/src/client/appkit.js +314 -0
  16. package/dist/esm/src/client/appkit.js.map +1 -0
  17. package/dist/esm/src/{client.js → client/core.js} +731 -978
  18. package/dist/esm/src/client/core.js.map +1 -0
  19. package/dist/esm/tests/appkit.test.js +6 -3
  20. package/dist/esm/tests/appkit.test.js.map +1 -1
  21. package/dist/esm/tests/siwe.test.js +12 -0
  22. package/dist/esm/tests/siwe.test.js.map +1 -1
  23. package/dist/esm/tsconfig.build.tsbuildinfo +1 -1
  24. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  25. package/dist/types/exports/basic.d.ts +1 -3
  26. package/dist/types/exports/constants.d.ts +1 -1
  27. package/dist/types/exports/index.d.ts +1 -1
  28. package/dist/types/exports/react.d.ts +1 -1
  29. package/dist/types/exports/vue.d.ts +1 -1
  30. package/dist/types/src/adapters/ChainAdapterBlueprint.d.ts +3 -3
  31. package/dist/types/src/client/appkit-basic.d.ts +22 -0
  32. package/dist/types/src/client/appkit.d.ts +21 -0
  33. package/dist/types/src/{client.d.ts → client/core.d.ts} +111 -108
  34. package/dist/types/src/library/react/index.d.ts +1 -1
  35. package/dist/types/src/library/vue/index.d.ts +1 -1
  36. package/dist/types/tests/mocks/AppKit.d.ts +1 -1
  37. package/package.json +14 -15
  38. package/dist/esm/exports/react copy.js +0 -38
  39. package/dist/esm/exports/react copy.js.map +0 -1
  40. package/dist/esm/src/client.js.map +0 -1
  41. package/dist/esm/src/networks/solana/eclipseDevnet.js +0 -17
  42. package/dist/esm/src/networks/solana/eclipseDevnet.js.map +0 -1
  43. package/dist/types/exports/react copy.d.ts +0 -16
  44. package/dist/types/src/networks/solana/eclipseDevnet.d.ts +0 -42
@@ -1,51 +1,44 @@
1
1
  import UniversalProvider from '@walletconnect/universal-provider';
2
- import { ConstantsUtil, NetworkUtil, ParseUtil, getW3mThemeVariables } from '@reown/appkit-common';
3
- import { ConstantsUtil as CoreConstantsUtil } from '@reown/appkit-core';
4
- import { AccountController, AlertController, ApiController, AssetUtil, BlockchainApiController, ChainController, ConnectionController, ConnectorController, CoreHelperUtil, EnsController, EventsController, ModalController, OptionsController, PublicStateController, RouterController, SnackController, StorageUtil, ThemeController } from '@reown/appkit-core';
2
+ import { ConstantsUtil, NetworkUtil, ParseUtil } from '@reown/appkit-common';
3
+ import { AccountController, AlertController, ApiController, AssetUtil, BlockchainApiController, ChainController, ConnectionController, ConnectorController, ConstantsUtil as CoreConstantsUtil, CoreHelperUtil, EnsController, EventsController, ModalController, OptionsController, PublicStateController, RouterController, SnackController, StorageUtil, ThemeController } from '@reown/appkit-core';
5
4
  import { WalletUtil } from '@reown/appkit-scaffold-ui/utils';
6
5
  import { setColorTheme, setThemeVariables } from '@reown/appkit-ui';
7
6
  import { CaipNetworksUtil, ErrorUtil, HelpersUtil, LoggerUtil, ConstantsUtil as UtilConstantsUtil } from '@reown/appkit-utils';
8
- import { W3mFrameHelpers, W3mFrameProvider, W3mFrameRpcConstants } from '@reown/appkit-wallet';
9
- import { W3mFrameProviderSingleton } from './auth-provider/W3MFrameProviderSingleton.js';
10
- import { ProviderUtil } from './store/ProviderUtil.js';
11
- import { UniversalAdapter, UniversalAdapter as UniversalAdapterClient } from './universal-adapter/client.js';
12
- import { WcHelpersUtil } from './utils/HelpersUtil.js';
13
- // -- Export Controllers -------------------------------------------------------
14
- export { AccountController };
15
- // -- Helpers -------------------------------------------------------------------
16
- let isInitialized = false;
17
- // -- Client --------------------------------------------------------------------
18
- export class AppKit {
7
+ import { ProviderUtil } from '../store/ProviderUtil.js';
8
+ import { UniversalAdapter } from '../universal-adapter/client.js';
9
+ import { WcHelpersUtil } from '../utils/index.js';
10
+ export class AppKitCore {
19
11
  constructor(options) {
20
12
  this.chainNamespaces = [];
21
13
  this.reportedAlertErrors = {};
22
- this.setStatus = (status, chain) => {
23
- StorageUtil.setConnectionStatus(status);
24
- AccountController.setStatus(status, chain);
25
- };
26
- this.getIsConnectedState = () => Boolean(ChainController.state.activeCaipAddress);
27
- this.setAllAccounts = (addresses, chain) => {
28
- AccountController.setAllAccounts(addresses, chain);
29
- OptionsController.setHasMultipleAddresses(addresses?.length > 1);
14
+ // -- Public Internal ---------------------------------------------------
15
+ this.getCaipNetwork = (chainNamespace) => {
16
+ if (chainNamespace) {
17
+ return ChainController.getRequestedCaipNetworks(chainNamespace).filter(c => c.chainNamespace === chainNamespace)?.[0];
18
+ }
19
+ return ChainController.state.activeCaipNetwork || this.defaultCaipNetwork;
30
20
  };
31
- this.addAddressLabel = (address, label, chain) => {
32
- AccountController.addAddressLabel(address, label, chain);
21
+ this.getCaipNetworkId = () => {
22
+ const network = this.getCaipNetwork();
23
+ if (network) {
24
+ return network.id;
25
+ }
26
+ return undefined;
33
27
  };
34
- this.removeAddressLabel = (address, chain) => {
35
- AccountController.removeAddressLabel(address, chain);
28
+ this.getCaipNetworks = (namespace) => ChainController.getRequestedCaipNetworks(namespace);
29
+ this.getActiveChainNamespace = () => ChainController.state.activeChain;
30
+ this.setRequestedCaipNetworks = (requestedCaipNetworks, chain) => {
31
+ ChainController.setRequestedCaipNetworks(requestedCaipNetworks, chain);
36
32
  };
33
+ this.getApprovedCaipNetworkIds = () => ChainController.getAllApprovedCaipNetworkIds();
37
34
  this.getCaipAddress = (chainNamespace) => {
38
35
  if (ChainController.state.activeChain === chainNamespace || !chainNamespace) {
39
36
  return ChainController.state.activeCaipAddress;
40
37
  }
41
38
  return ChainController.getAccountProp('caipAddress', chainNamespace);
42
39
  };
43
- this.getAddressByChainNamespace = (chainNamespace) => ChainController.getAccountProp('address', chainNamespace);
44
- this.getAddress = (chainNamespace) => {
45
- if (ChainController.state.activeChain === chainNamespace || !chainNamespace) {
46
- return AccountController.state.address;
47
- }
48
- return ChainController.getAccountProp('address', chainNamespace);
40
+ this.setClientId = clientId => {
41
+ BlockchainApiController.setClientId(clientId);
49
42
  };
50
43
  this.getProvider = (namespace) => ProviderUtil.getProvider(namespace);
51
44
  this.getProviderType = (namespace) => ProviderUtil.state.providerIds[namespace];
@@ -71,64 +64,64 @@ export class AppKit {
71
64
  this.setCaipNetwork = caipNetwork => {
72
65
  ChainController.setActiveCaipNetwork(caipNetwork);
73
66
  };
74
- this.getCaipNetwork = (chainNamespace) => {
75
- if (chainNamespace) {
76
- return ChainController.getRequestedCaipNetworks(chainNamespace).filter(c => c.chainNamespace === chainNamespace)?.[0];
77
- }
78
- return ChainController.state.activeCaipNetwork || this.defaultCaipNetwork;
67
+ this.setAllAccounts = (addresses, chain) => {
68
+ AccountController.setAllAccounts(addresses, chain);
69
+ OptionsController.setHasMultipleAddresses(addresses?.length > 1);
79
70
  };
80
- this.getCaipNetworkId = () => {
81
- const network = this.getCaipNetwork();
82
- if (network) {
83
- return network.id;
84
- }
85
- return undefined;
71
+ this.setStatus = (status, chain) => {
72
+ StorageUtil.setConnectionStatus(status);
73
+ AccountController.setStatus(status, chain);
86
74
  };
87
- this.getCaipNetworks = (namespace) => ChainController.getRequestedCaipNetworks(namespace);
88
- this.getActiveChainNamespace = () => ChainController.state.activeChain;
89
- this.setRequestedCaipNetworks = (requestedCaipNetworks, chain) => {
90
- ChainController.setRequestedCaipNetworks(requestedCaipNetworks, chain);
75
+ this.getAddressByChainNamespace = (chainNamespace) => ChainController.getAccountProp('address', chainNamespace);
76
+ this.setConnectors = connectors => {
77
+ const allConnectors = [...ConnectorController.getConnectors(), ...connectors];
78
+ ConnectorController.setConnectors(allConnectors);
79
+ };
80
+ this.fetchIdentity = request => BlockchainApiController.fetchIdentity(request);
81
+ this.getReownName = address => EnsController.getNamesForAddress(address);
82
+ this.getConnectors = () => ConnectorController.getConnectors();
83
+ this.getConnectorImage = connector => AssetUtil.getConnectorImage(connector);
84
+ this.setConnectedWalletInfo = (connectedWalletInfo, chain) => {
85
+ AccountController.setConnectedWalletInfo(connectedWalletInfo, chain);
86
+ };
87
+ this.getIsConnectedState = () => Boolean(ChainController.state.activeCaipAddress);
88
+ this.addAddressLabel = (address, label, chain) => {
89
+ AccountController.addAddressLabel(address, label, chain);
90
+ };
91
+ this.removeAddressLabel = (address, chain) => {
92
+ AccountController.removeAddressLabel(address, chain);
93
+ };
94
+ this.getAddress = (chainNamespace) => {
95
+ if (ChainController.state.activeChain === chainNamespace || !chainNamespace) {
96
+ return AccountController.state.address;
97
+ }
98
+ return ChainController.getAccountProp('address', chainNamespace);
91
99
  };
92
- this.getApprovedCaipNetworkIds = () => ChainController.getAllApprovedCaipNetworkIds();
93
100
  this.setApprovedCaipNetworksData = namespace => ChainController.setApprovedCaipNetworksData(namespace);
94
101
  this.resetNetwork = (namespace) => {
95
102
  ChainController.resetNetwork(namespace);
96
103
  };
97
- this.setConnectors = connectors => {
98
- const allConnectors = [...ConnectorController.getConnectors(), ...connectors];
99
- ConnectorController.setConnectors(allConnectors);
100
- };
101
104
  this.addConnector = connector => {
102
105
  ConnectorController.addConnector(connector);
103
106
  };
104
- this.getConnectors = () => ConnectorController.getConnectors();
105
107
  this.resetWcConnection = () => {
106
108
  ConnectionController.resetWcConnection();
107
109
  };
108
- this.fetchIdentity = request => BlockchainApiController.fetchIdentity(request);
109
110
  this.setAddressExplorerUrl = (addressExplorerUrl, chain) => {
110
111
  AccountController.setAddressExplorerUrl(addressExplorerUrl, chain);
111
112
  };
112
113
  this.setSmartAccountDeployed = (isDeployed, chain) => {
113
114
  AccountController.setSmartAccountDeployed(isDeployed, chain);
114
115
  };
115
- this.setConnectedWalletInfo = (connectedWalletInfo, chain) => {
116
- AccountController.setConnectedWalletInfo(connectedWalletInfo, chain);
117
- };
118
116
  this.setSmartAccountEnabledNetworks = (smartAccountEnabledNetworks, chain) => {
119
117
  ChainController.setSmartAccountEnabledNetworks(smartAccountEnabledNetworks, chain);
120
118
  };
121
119
  this.setPreferredAccountType = (preferredAccountType, chain) => {
122
120
  AccountController.setPreferredAccountType(preferredAccountType, chain);
123
121
  };
124
- this.getReownName = address => EnsController.getNamesForAddress(address);
125
122
  this.setEIP6963Enabled = enabled => {
126
123
  OptionsController.setEIP6963Enabled(enabled);
127
124
  };
128
- this.setClientId = clientId => {
129
- BlockchainApiController.setClientId(clientId);
130
- };
131
- this.getConnectorImage = connector => AssetUtil.getConnectorImage(connector);
132
125
  this.handleUnsafeRPCRequest = () => {
133
126
  if (this.isOpen()) {
134
127
  // If we are on the modal but there is no transaction stack, close the modal
@@ -153,9 +146,6 @@ export class AppKit {
153
146
  this.chainAdapters = this.createAdapters(options.adapters);
154
147
  this.initialize(options);
155
148
  }
156
- static getInstance() {
157
- return this.instance;
158
- }
159
149
  async initialize(options) {
160
150
  this.initControllers(options);
161
151
  await this.initChainAdapters();
@@ -176,323 +166,141 @@ export class AppKit {
176
166
  });
177
167
  PublicStateController.set({ initialized: true });
178
168
  }
179
- // -- Public -------------------------------------------------------------------
180
- async open(options) {
181
- await this.injectModalUi();
182
- if (options?.uri && this.universalAdapter) {
183
- ConnectionController.setUri(options.uri);
169
+ // -- Controllers initialization ---------------------------------------------------
170
+ initControllers(options) {
171
+ this.initializeOptionsController(options);
172
+ this.initializeChainController(options);
173
+ this.initializeThemeController(options);
174
+ this.initializeBlockchainApiController(options);
175
+ if (options.excludeWalletIds) {
176
+ ApiController.initializeExcludedWalletRdns({ ids: options.excludeWalletIds });
184
177
  }
185
- ModalController.open(options);
186
- }
187
- async close() {
188
- await this.injectModalUi();
189
- ModalController.close();
190
178
  }
191
- setLoading(loading) {
192
- ModalController.setLoading(loading);
179
+ initializeThemeController(options) {
180
+ if (options.themeMode) {
181
+ ThemeController.setThemeMode(options.themeMode);
182
+ }
183
+ if (options.themeVariables) {
184
+ ThemeController.setThemeVariables(options.themeVariables);
185
+ }
193
186
  }
194
- // -- Adapter Methods ----------------------------------------------------------
195
- getError() {
196
- return '';
187
+ initializeChainController(options) {
188
+ if (!this.connectionControllerClient || !this.networkControllerClient) {
189
+ throw new Error('ConnectionControllerClient and NetworkControllerClient must be set');
190
+ }
191
+ ChainController.initialize(options.adapters ?? [], this.caipNetworks, {
192
+ connectionControllerClient: this.connectionControllerClient,
193
+ networkControllerClient: this.networkControllerClient
194
+ });
195
+ const network = this.getDefaultNetwork();
196
+ if (network) {
197
+ ChainController.setActiveCaipNetwork(network);
198
+ }
197
199
  }
198
- getChainId() {
199
- return ChainController.state.activeCaipNetwork?.id;
200
+ async initializeBlockchainApiController(options) {
201
+ await BlockchainApiController.getSupportedNetworks({
202
+ projectId: options.projectId
203
+ });
200
204
  }
201
- switchNetwork(appKitNetwork) {
202
- const network = this.caipNetworks?.find(n => n.id === appKitNetwork.id);
203
- if (!network) {
204
- AlertController.open(ErrorUtil.ALERT_ERRORS.SWITCH_NETWORK_NOT_FOUND, 'error');
205
+ initializeOptionsController(options) {
206
+ OptionsController.setDebug(options.debug !== false);
207
+ if (!options.projectId) {
208
+ AlertController.open(ErrorUtil.ALERT_ERRORS.PROJECT_ID_NOT_CONFIGURED, 'error');
205
209
  return;
206
210
  }
207
- ChainController.switchActiveNetwork(network);
211
+ // On by default
212
+ OptionsController.setEnableWalletConnect(options.enableWalletConnect !== false);
213
+ OptionsController.setEnableWalletGuide(options.enableWalletGuide !== false);
214
+ OptionsController.setEnableWallets(options.enableWallets !== false);
215
+ OptionsController.setEIP6963Enabled(options.enableEIP6963 !== false);
216
+ OptionsController.setEnableAuthLogger(options.enableAuthLogger !== false);
217
+ OptionsController.setSdkVersion(options.sdkVersion);
218
+ OptionsController.setProjectId(options.projectId);
219
+ OptionsController.setEnableEmbedded(options.enableEmbedded);
220
+ OptionsController.setAllWallets(options.allWallets);
221
+ OptionsController.setIncludeWalletIds(options.includeWalletIds);
222
+ OptionsController.setExcludeWalletIds(options.excludeWalletIds);
223
+ OptionsController.setFeaturedWalletIds(options.featuredWalletIds);
224
+ OptionsController.setTokens(options.tokens);
225
+ OptionsController.setTermsConditionsUrl(options.termsConditionsUrl);
226
+ OptionsController.setPrivacyPolicyUrl(options.privacyPolicyUrl);
227
+ OptionsController.setCustomWallets(options.customWallets);
228
+ OptionsController.setFeatures(options.features);
229
+ OptionsController.setAllowUnsupportedChain(options.allowUnsupportedChain);
230
+ OptionsController.setDefaultAccountTypes(options.defaultAccountTypes);
231
+ const defaultMetaData = this.getDefaultMetaData();
232
+ if (!options.metadata && defaultMetaData) {
233
+ options.metadata = defaultMetaData;
234
+ }
235
+ OptionsController.setMetadata(options.metadata);
236
+ OptionsController.setDisableAppend(options.disableAppend);
237
+ OptionsController.setEnableEmbedded(options.enableEmbedded);
238
+ OptionsController.setSIWX(options.siwx);
239
+ const evmAdapter = options.adapters?.find(adapter => adapter.namespace === ConstantsUtil.CHAIN.EVM);
240
+ // Set the SIWE client for EVM chains
241
+ if (evmAdapter) {
242
+ if (options.siweConfig) {
243
+ if (options.siwx) {
244
+ throw new Error('Cannot set both `siweConfig` and `siwx` options');
245
+ }
246
+ OptionsController.setSIWX(options.siweConfig.mapToSIWX());
247
+ }
248
+ }
208
249
  }
209
- getWalletProvider() {
210
- return ChainController.state.activeChain
211
- ? ProviderUtil.state.providers[ChainController.state.activeChain]
212
- : null;
250
+ getDefaultMetaData() {
251
+ if (typeof window !== 'undefined' && typeof document !== 'undefined') {
252
+ return {
253
+ name: document.getElementsByTagName('title')?.[0]?.textContent || '',
254
+ description: document.querySelector('meta[property="og:description"]')?.content || '',
255
+ url: window.location.origin,
256
+ icons: [document.querySelector('link[rel~="icon"]')?.href || '']
257
+ };
258
+ }
259
+ return null;
213
260
  }
214
- getWalletProviderType() {
215
- return ChainController.state.activeChain
216
- ? ProviderUtil.state.providerIds[ChainController.state.activeChain]
217
- : null;
261
+ // -- Network Initialization ---------------------------------------------------
262
+ getUnsupportedNetwork(caipNetworkId) {
263
+ return {
264
+ id: caipNetworkId.split(':')[1],
265
+ caipNetworkId,
266
+ name: ConstantsUtil.UNSUPPORTED_NETWORK_NAME,
267
+ chainNamespace: caipNetworkId.split(':')[0],
268
+ nativeCurrency: {
269
+ name: '',
270
+ decimals: 0,
271
+ symbol: ''
272
+ },
273
+ rpcUrls: {
274
+ default: {
275
+ http: []
276
+ }
277
+ }
278
+ };
218
279
  }
219
- subscribeProviders(callback) {
220
- return ProviderUtil.subscribeProviders(callback);
280
+ setUnsupportedNetwork(chainId) {
281
+ const namespace = this.getActiveChainNamespace();
282
+ if (namespace) {
283
+ const unsupportedNetwork = this.getUnsupportedNetwork(`${namespace}:${chainId}`);
284
+ ChainController.setActiveCaipNetwork(unsupportedNetwork);
285
+ }
221
286
  }
222
- getThemeMode() {
223
- return ThemeController.state.themeMode;
287
+ getDefaultNetwork() {
288
+ const caipNetworkId = StorageUtil.getActiveCaipNetworkId();
289
+ if (caipNetworkId) {
290
+ const caipNetwork = this.caipNetworks?.find(n => n.caipNetworkId === caipNetworkId);
291
+ if (caipNetwork) {
292
+ return caipNetwork;
293
+ }
294
+ return this.getUnsupportedNetwork(caipNetworkId);
295
+ }
296
+ return this.caipNetworks?.[0];
224
297
  }
225
- getThemeVariables() {
226
- return ThemeController.state.themeVariables;
227
- }
228
- setThemeMode(themeMode) {
229
- ThemeController.setThemeMode(themeMode);
230
- setColorTheme(ThemeController.state.themeMode);
231
- }
232
- setTermsConditionsUrl(termsConditionsUrl) {
233
- OptionsController.setTermsConditionsUrl(termsConditionsUrl);
234
- }
235
- setPrivacyPolicyUrl(privacyPolicyUrl) {
236
- OptionsController.setPrivacyPolicyUrl(privacyPolicyUrl);
237
- }
238
- setThemeVariables(themeVariables) {
239
- ThemeController.setThemeVariables(themeVariables);
240
- setThemeVariables(ThemeController.state.themeVariables);
241
- }
242
- subscribeTheme(callback) {
243
- return ThemeController.subscribe(callback);
244
- }
245
- getWalletInfo() {
246
- return AccountController.state.connectedWalletInfo;
247
- }
248
- subscribeAccount(callback) {
249
- const authConnector = ConnectorController.getAuthConnector();
250
- function updateVal() {
251
- callback({
252
- allAccounts: AccountController.state.allAccounts,
253
- caipAddress: ChainController.state.activeCaipAddress,
254
- address: CoreHelperUtil.getPlainAddress(ChainController.state.activeCaipAddress),
255
- isConnected: Boolean(ChainController.state.activeCaipAddress),
256
- status: AccountController.state.status,
257
- embeddedWalletInfo: authConnector
258
- ? {
259
- user: AccountController.state.user,
260
- authProvider: AccountController.state.socialProvider || 'email',
261
- accountType: AccountController.state.preferredAccountType,
262
- isSmartAccountDeployed: Boolean(AccountController.state.smartAccountDeployed)
263
- }
264
- : undefined
265
- });
266
- }
267
- ChainController.subscribe(updateVal);
268
- AccountController.subscribe(updateVal);
269
- }
270
- subscribeNetwork(callback) {
271
- return ChainController.subscribe(({ activeCaipNetwork }) => {
272
- callback({
273
- caipNetwork: activeCaipNetwork,
274
- chainId: activeCaipNetwork?.id,
275
- caipNetworkId: activeCaipNetwork?.caipNetworkId
276
- });
277
- });
278
- }
279
- subscribeWalletInfo(callback) {
280
- return AccountController.subscribeKey('connectedWalletInfo', callback);
281
- }
282
- subscribeShouldUpdateToAddress(callback) {
283
- AccountController.subscribeKey('shouldUpdateToAddress', callback);
284
- }
285
- subscribeCaipNetworkChange(callback) {
286
- ChainController.subscribeKey('activeCaipNetwork', callback);
287
- }
288
- getState() {
289
- return PublicStateController.state;
290
- }
291
- subscribeState(callback) {
292
- return PublicStateController.subscribe(callback);
293
- }
294
- showErrorMessage(message) {
295
- SnackController.showError(message);
296
- }
297
- showSuccessMessage(message) {
298
- SnackController.showSuccess(message);
299
- }
300
- getEvent() {
301
- return { ...EventsController.state };
302
- }
303
- subscribeEvents(callback) {
304
- return EventsController.subscribe(callback);
305
- }
306
- replace(route) {
307
- RouterController.replace(route);
308
- }
309
- redirect(route) {
310
- RouterController.push(route);
311
- }
312
- popTransactionStack(cancel) {
313
- RouterController.popTransactionStack(cancel);
314
- }
315
- isOpen() {
316
- return ModalController.state.open;
317
- }
318
- isTransactionStackEmpty() {
319
- return RouterController.state.transactionStack.length === 0;
320
- }
321
- isTransactionShouldReplaceView() {
322
- return RouterController.state.transactionStack[RouterController.state.transactionStack.length - 1]?.replace;
323
- }
324
- updateFeatures(newFeatures) {
325
- OptionsController.setFeatures(newFeatures);
326
- }
327
- updateOptions(newOptions) {
328
- const currentOptions = OptionsController.state || {};
329
- const updatedOptions = { ...currentOptions, ...newOptions };
330
- OptionsController.setOptions(updatedOptions);
331
- }
332
- setConnectMethodsOrder(connectMethodsOrder) {
333
- OptionsController.setConnectMethodsOrder(connectMethodsOrder);
334
- }
335
- setWalletFeaturesOrder(walletFeaturesOrder) {
336
- OptionsController.setWalletFeaturesOrder(walletFeaturesOrder);
337
- }
338
- setCollapseWallets(collapseWallets) {
339
- OptionsController.setCollapseWallets(collapseWallets);
340
- }
341
- setSocialsOrder(socialsOrder) {
342
- OptionsController.setSocialsOrder(socialsOrder);
343
- }
344
- async disconnect() {
345
- await ConnectionController.disconnect();
346
- }
347
- getConnectMethodsOrder() {
348
- return WalletUtil.getConnectOrderMethod(OptionsController.state.features, ConnectorController.getConnectors());
349
- }
350
- /**
351
- * Removes an adapter from the AppKit.
352
- * @param namespace - The namespace of the adapter to remove.
353
- */
354
- removeAdapter(namespace) {
355
- const isConnected = this.getIsConnectedState();
356
- const adapter = this.getAdapter(namespace);
357
- if (!adapter || !this.chainAdapters || isConnected) {
358
- return;
359
- }
360
- const newCaipNetworks = this.caipNetworks?.filter(network => network.chainNamespace !== namespace);
361
- ChainController.removeAdapter(namespace);
362
- ConnectorController.removeAdapter(namespace);
363
- this.chainNamespaces = this.chainNamespaces.filter(n => n !== namespace);
364
- this.caipNetworks = newCaipNetworks;
365
- adapter.removeAllEventListeners();
366
- Reflect.deleteProperty(this.chainAdapters, namespace);
367
- }
368
- /**
369
- * Adds an adapter to the AppKit.
370
- * @param adapter - The adapter instance.
371
- * @param networks - The list of networks that this adapter supports / uses.
372
- */
373
- addAdapter(adapter, networks) {
374
- const namespace = adapter.namespace;
375
- if (!this.connectionControllerClient || !this.networkControllerClient) {
376
- return;
377
- }
378
- if (!this.chainAdapters || !namespace) {
379
- return;
380
- }
381
- const extendedAdapterNetworks = this.extendCaipNetworks({ ...this.options, networks });
382
- this.caipNetworks = [...(this.caipNetworks || []), ...extendedAdapterNetworks];
383
- this.createAdapter(adapter);
384
- this.initChainAdapter(namespace);
385
- ChainController.addAdapter(adapter, {
386
- connectionControllerClient: this.connectionControllerClient,
387
- networkControllerClient: this.networkControllerClient
388
- }, extendedAdapterNetworks);
389
- }
390
- // -- Private ------------------------------------------------------------------
391
- initializeOptionsController(options) {
392
- OptionsController.setDebug(options.debug !== false);
393
- OptionsController.setBasic(options.basic === true);
394
- if (!options.projectId) {
395
- AlertController.open(ErrorUtil.ALERT_ERRORS.PROJECT_ID_NOT_CONFIGURED, 'error');
396
- return;
397
- }
398
- // On by default
399
- OptionsController.setEnableWalletConnect(options.enableWalletConnect !== false);
400
- OptionsController.setEnableWalletGuide(options.enableWalletGuide !== false);
401
- OptionsController.setEnableWallets(options.enableWallets !== false);
402
- OptionsController.setEIP6963Enabled(options.enableEIP6963 !== false);
403
- OptionsController.setEnableAuthLogger(options.enableAuthLogger !== false);
404
- OptionsController.setSdkVersion(options.sdkVersion);
405
- OptionsController.setProjectId(options.projectId);
406
- OptionsController.setEnableEmbedded(options.enableEmbedded);
407
- OptionsController.setAllWallets(options.allWallets);
408
- OptionsController.setIncludeWalletIds(options.includeWalletIds);
409
- OptionsController.setExcludeWalletIds(options.excludeWalletIds);
410
- OptionsController.setFeaturedWalletIds(options.featuredWalletIds);
411
- OptionsController.setTokens(options.tokens);
412
- OptionsController.setTermsConditionsUrl(options.termsConditionsUrl);
413
- OptionsController.setPrivacyPolicyUrl(options.privacyPolicyUrl);
414
- OptionsController.setCustomWallets(options.customWallets);
415
- OptionsController.setFeatures(options.features);
416
- OptionsController.setAllowUnsupportedChain(options.allowUnsupportedChain);
417
- OptionsController.setDefaultAccountTypes(options.defaultAccountTypes);
418
- const defaultMetaData = this.getDefaultMetaData();
419
- if (!options.metadata && defaultMetaData) {
420
- options.metadata = defaultMetaData;
421
- }
422
- OptionsController.setMetadata(options.metadata);
423
- OptionsController.setDisableAppend(options.disableAppend);
424
- OptionsController.setEnableEmbedded(options.enableEmbedded);
425
- OptionsController.setSIWX(options.siwx);
426
- const evmAdapter = options.adapters?.find(adapter => adapter.namespace === ConstantsUtil.CHAIN.EVM);
427
- // Set the SIWE client for EVM chains
428
- if (evmAdapter) {
429
- if (options.siweConfig) {
430
- if (options.siwx) {
431
- throw new Error('Cannot set both `siweConfig` and `siwx` options');
432
- }
433
- OptionsController.setSIWX(options.siweConfig.mapToSIWX());
434
- }
435
- }
436
- }
437
- initializeThemeController(options) {
438
- if (options.themeMode) {
439
- ThemeController.setThemeMode(options.themeMode);
440
- }
441
- if (options.themeVariables) {
442
- ThemeController.setThemeVariables(options.themeVariables);
443
- }
444
- }
445
- initializeChainController(options) {
446
- if (!this.connectionControllerClient || !this.networkControllerClient) {
447
- throw new Error('ConnectionControllerClient and NetworkControllerClient must be set');
448
- }
449
- ChainController.initialize(options.adapters ?? [], this.caipNetworks, {
450
- connectionControllerClient: this.connectionControllerClient,
451
- networkControllerClient: this.networkControllerClient
452
- });
453
- const network = this.getDefaultNetwork();
454
- if (network) {
455
- ChainController.setActiveCaipNetwork(network);
456
- }
457
- }
458
- async initializeBlockchainApiController(options) {
459
- await BlockchainApiController.getSupportedNetworks({
460
- projectId: options.projectId
461
- });
462
- }
463
- initControllers(options) {
464
- this.initializeOptionsController(options);
465
- this.initializeChainController(options);
466
- this.initializeThemeController(options);
467
- this.initializeBlockchainApiController(options);
468
- if (options.excludeWalletIds) {
469
- ApiController.initializeExcludedWalletRdns({ ids: options.excludeWalletIds });
470
- }
471
- }
472
- getDefaultMetaData() {
473
- if (typeof window !== 'undefined' && typeof document !== 'undefined') {
474
- return {
475
- name: document.getElementsByTagName('title')?.[0]?.textContent || '',
476
- description: document.querySelector('meta[property="og:description"]')?.content || '',
477
- url: window.location.origin,
478
- icons: [document.querySelector('link[rel~="icon"]')?.href || '']
479
- };
480
- }
481
- return null;
482
- }
483
- setUnsupportedNetwork(chainId) {
484
- const namespace = this.getActiveChainNamespace();
485
- if (namespace) {
486
- const unsupportedNetwork = this.getUnsupportedNetwork(`${namespace}:${chainId}`);
487
- ChainController.setActiveCaipNetwork(unsupportedNetwork);
488
- }
489
- }
490
- extendCaipNetworks(options) {
491
- const extendedNetworks = CaipNetworksUtil.extendCaipNetworks(options.networks, {
492
- customNetworkImageUrls: options.chainImages,
493
- projectId: options.projectId
494
- });
495
- return extendedNetworks;
298
+ extendCaipNetworks(options) {
299
+ const extendedNetworks = CaipNetworksUtil.extendCaipNetworks(options.networks, {
300
+ customNetworkImageUrls: options.chainImages,
301
+ projectId: options.projectId
302
+ });
303
+ return extendedNetworks;
496
304
  }
497
305
  extendDefaultCaipNetwork(options) {
498
306
  const defaultNetwork = options.networks.find(n => n.id === options.defaultNetwork?.id);
@@ -504,6 +312,7 @@ export class AppKit {
504
312
  : undefined;
505
313
  return extendedNetwork;
506
314
  }
315
+ // -- Client Initialization ---------------------------------------------------
507
316
  createClients() {
508
317
  this.connectionControllerClient = {
509
318
  connectWalletConnect: async () => {
@@ -664,260 +473,115 @@ export class AppKit {
664
473
  }
665
474
  };
666
475
  this.networkControllerClient = {
667
- switchCaipNetwork: async (caipNetwork) => {
668
- if (!caipNetwork) {
669
- return;
670
- }
671
- if (AccountController.state.address &&
672
- caipNetwork.chainNamespace === ChainController.state.activeChain) {
673
- const adapter = this.getAdapter(ChainController.state.activeChain);
674
- const provider = ProviderUtil.getProvider(ChainController.state.activeChain);
675
- const providerType = ProviderUtil.state.providerIds[ChainController.state.activeChain];
676
- await adapter?.switchNetwork({ caipNetwork, provider, providerType });
677
- this.setCaipNetwork(caipNetwork);
678
- await this.syncAccount({
679
- address: AccountController.state.address,
680
- chainId: caipNetwork.id,
681
- chainNamespace: caipNetwork.chainNamespace
682
- });
683
- }
684
- else if (AccountController.state.address) {
685
- const providerType = ProviderUtil.state.providerIds[ChainController.state.activeChain];
686
- if (providerType === UtilConstantsUtil.CONNECTOR_TYPE_AUTH) {
687
- try {
688
- ChainController.state.activeChain = caipNetwork.chainNamespace;
689
- await this.connectionControllerClient?.connectExternal?.({
690
- id: ConstantsUtil.CONNECTOR_ID.AUTH,
691
- provider: this.authProvider,
692
- chain: caipNetwork.chainNamespace,
693
- chainId: caipNetwork.id,
694
- type: UtilConstantsUtil.CONNECTOR_TYPE_AUTH,
695
- caipNetwork
696
- });
697
- this.setCaipNetwork(caipNetwork);
698
- }
699
- catch (error) {
700
- const adapter = this.getAdapter(caipNetwork.chainNamespace);
701
- await adapter?.switchNetwork({
702
- caipNetwork,
703
- provider: this.authProvider,
704
- providerType
705
- });
706
- }
707
- }
708
- else if (providerType === 'WALLET_CONNECT') {
709
- this.setCaipNetwork(caipNetwork);
710
- this.syncWalletConnectAccount();
711
- }
712
- else {
713
- this.setCaipNetwork(caipNetwork);
714
- const address = this.getAddressByChainNamespace(caipNetwork.chainNamespace);
715
- if (address) {
716
- this.syncAccount({
717
- address,
718
- chainId: caipNetwork.id,
719
- chainNamespace: caipNetwork.chainNamespace
720
- });
721
- }
722
- }
723
- }
724
- else {
725
- this.setCaipNetwork(caipNetwork);
726
- }
727
- },
476
+ switchCaipNetwork: async (caipNetwork) => await this.switchCaipNetwork(caipNetwork),
728
477
  // eslint-disable-next-line @typescript-eslint/require-await
729
- getApprovedCaipNetworksData: async () => {
730
- const providerType = ProviderUtil.state.providerIds[ChainController.state.activeChain];
731
- if (providerType === UtilConstantsUtil.CONNECTOR_TYPE_WALLET_CONNECT) {
732
- const namespaces = this.universalProvider?.session?.namespaces;
733
- return {
734
- /*
735
- * MetaMask Wallet only returns 1 namespace in the session object. This makes it imposible
736
- * to switch to other networks. Setting supportsAllNetworks to true for MetaMask Wallet
737
- * will make it possible to switch to other networks.
738
- */
739
- supportsAllNetworks: this.universalProvider?.session?.peer?.metadata.name === 'MetaMask Wallet',
740
- approvedCaipNetworkIds: this.getChainsFromNamespaces(namespaces)
741
- };
742
- }
743
- return { supportsAllNetworks: true, approvedCaipNetworkIds: [] };
744
- }
478
+ getApprovedCaipNetworksData: async () => this.getApprovedCaipNetworksData()
745
479
  };
746
480
  ConnectionController.setClient(this.connectionControllerClient);
747
481
  }
748
- setupAuthConnectorListeners(provider) {
749
- provider.onRpcRequest((request) => {
750
- if (W3mFrameHelpers.checkIfRequestExists(request)) {
751
- if (!W3mFrameHelpers.checkIfRequestIsSafe(request)) {
752
- this.handleUnsafeRPCRequest();
753
- }
754
- }
755
- else {
756
- this.open();
757
- // eslint-disable-next-line no-console
758
- console.error(W3mFrameRpcConstants.RPC_METHOD_NOT_ALLOWED_MESSAGE, {
759
- method: request.method
482
+ getApprovedCaipNetworksData() {
483
+ const providerType = ProviderUtil.state.providerIds[ChainController.state.activeChain];
484
+ if (providerType === UtilConstantsUtil.CONNECTOR_TYPE_WALLET_CONNECT) {
485
+ const namespaces = this.universalProvider?.session?.namespaces;
486
+ return {
487
+ /*
488
+ * MetaMask Wallet only returns 1 namespace in the session object. This makes it imposible
489
+ * to switch to other networks. Setting supportsAllNetworks to true for MetaMask Wallet
490
+ * will make it possible to switch to other networks.
491
+ */
492
+ supportsAllNetworks: this.universalProvider?.session?.peer?.metadata.name === 'MetaMask Wallet',
493
+ approvedCaipNetworkIds: this.getChainsFromNamespaces(namespaces)
494
+ };
495
+ }
496
+ return { supportsAllNetworks: true, approvedCaipNetworkIds: [] };
497
+ }
498
+ async switchCaipNetwork(caipNetwork) {
499
+ if (!caipNetwork) {
500
+ return;
501
+ }
502
+ if (AccountController.state.address) {
503
+ if (caipNetwork.chainNamespace === ChainController.state.activeChain) {
504
+ const adapter = this.getAdapter(ChainController.state.activeChain);
505
+ const provider = ProviderUtil.getProvider(ChainController.state.activeChain);
506
+ const providerType = ProviderUtil.state.providerIds[ChainController.state.activeChain];
507
+ await adapter?.switchNetwork({ caipNetwork, provider, providerType });
508
+ this.setCaipNetwork(caipNetwork);
509
+ await this.syncAccount({
510
+ address: AccountController.state.address,
511
+ chainId: caipNetwork.id,
512
+ chainNamespace: caipNetwork.chainNamespace
760
513
  });
761
- setTimeout(() => {
762
- this.showErrorMessage(W3mFrameRpcConstants.RPC_METHOD_NOT_ALLOWED_UI_MESSAGE);
763
- }, 300);
764
- provider.rejectRpcRequests();
765
514
  }
766
- });
767
- provider.onRpcError(() => {
768
- const isModalOpen = this.isOpen();
769
- if (isModalOpen) {
770
- if (this.isTransactionStackEmpty()) {
771
- this.close();
515
+ else {
516
+ const providerType = ProviderUtil.state.providerIds[ChainController.state.activeChain];
517
+ this.setCaipNetwork(caipNetwork);
518
+ if (providerType === 'WALLET_CONNECT') {
519
+ this.syncWalletConnectAccount();
772
520
  }
773
521
  else {
774
- this.popTransactionStack(true);
522
+ const address = this.getAddressByChainNamespace(caipNetwork.chainNamespace);
523
+ if (address) {
524
+ this.syncAccount({
525
+ address,
526
+ chainId: caipNetwork.id,
527
+ chainNamespace: caipNetwork.chainNamespace
528
+ });
529
+ }
775
530
  }
776
531
  }
532
+ }
533
+ else {
534
+ this.setCaipNetwork(caipNetwork);
535
+ }
536
+ }
537
+ getChainsFromNamespaces(namespaces = {}) {
538
+ return Object.values(namespaces).flatMap((namespace) => {
539
+ const chains = (namespace.chains || []);
540
+ const accountsChains = namespace.accounts.map(account => {
541
+ const { chainId, chainNamespace } = ParseUtil.parseCaipAddress(account);
542
+ return `${chainNamespace}:${chainId}`;
543
+ });
544
+ return Array.from(new Set([...chains, ...accountsChains]));
777
545
  });
778
- provider.onRpcSuccess((_, request) => {
779
- const isSafeRequest = W3mFrameHelpers.checkIfRequestIsSafe(request);
780
- if (isSafeRequest) {
781
- return;
782
- }
783
- if (this.isTransactionStackEmpty()) {
784
- this.close();
785
- if (AccountController.state.address && ChainController.state.activeCaipNetwork?.id) {
786
- this.updateNativeBalance();
787
- }
546
+ }
547
+ // -- Adapter Initialization ---------------------------------------------------
548
+ createAdapters(blueprints) {
549
+ this.createClients();
550
+ return this.chainNamespaces.reduce((adapters, namespace) => {
551
+ const blueprint = blueprints?.find(b => b.namespace === namespace);
552
+ if (blueprint) {
553
+ adapters[namespace] = blueprint;
554
+ adapters[namespace].namespace = namespace;
555
+ adapters[namespace].construct({
556
+ namespace,
557
+ projectId: this.options?.projectId,
558
+ networks: this.caipNetworks
559
+ });
788
560
  }
789
561
  else {
790
- this.popTransactionStack();
791
- if (AccountController.state.address && ChainController.state.activeCaipNetwork?.id) {
792
- this.updateNativeBalance();
793
- }
794
- }
795
- });
796
- provider.onNotConnected(() => {
797
- const namespace = ChainController.state.activeChain;
798
- const connectorId = StorageUtil.getConnectedConnectorId(namespace);
799
- const isConnectedWithAuth = connectorId === ConstantsUtil.CONNECTOR_ID.AUTH;
800
- if (isConnectedWithAuth) {
801
- this.setCaipAddress(undefined, namespace);
802
- this.setLoading(false);
803
- }
804
- });
805
- provider.onConnect(async (user) => {
806
- const namespace = ChainController.state.activeChain;
807
- // To keep backwards compatibility, eip155 chainIds are numbers and not actual caipChainIds
808
- const caipAddress = namespace === ConstantsUtil.CHAIN.EVM
809
- ? `eip155:${user.chainId}:${user.address}`
810
- : `${user.chainId}:${user.address}`;
811
- this.setSmartAccountDeployed(Boolean(user.smartAccountDeployed), namespace);
812
- if (!HelpersUtil.isLowerCaseMatch(user.address, AccountController.state.address)) {
813
- this.syncIdentity({
814
- address: user.address,
815
- chainId: user.chainId,
816
- chainNamespace: namespace
562
+ adapters[namespace] = new UniversalAdapter({
563
+ namespace,
564
+ networks: this.caipNetworks
817
565
  });
818
566
  }
819
- this.setCaipAddress(caipAddress, namespace);
820
- this.setUser({ ...(AccountController.state.user || {}), email: user.email });
821
- const preferredAccountType = (user.preferredAccountType ||
822
- OptionsController.state.defaultAccountTypes[namespace]);
823
- this.setPreferredAccountType(preferredAccountType, namespace);
824
- const userAccounts = user.accounts?.map(account => CoreHelperUtil.createAccount(namespace, account.address, account.type || OptionsController.state.defaultAccountTypes[namespace]));
825
- this.setAllAccounts(userAccounts || [
826
- CoreHelperUtil.createAccount(namespace, user.address, preferredAccountType)
827
- ], namespace);
828
- await provider.getSmartAccountEnabledNetworks();
829
- this.setLoading(false);
830
- });
831
- provider.onSocialConnected(({ userName }) => {
832
- this.setUser({ ...(AccountController.state.user || {}), username: userName });
833
- });
834
- provider.onGetSmartAccountEnabledNetworks(networks => {
835
- this.setSmartAccountEnabledNetworks(networks, ChainController.state.activeChain);
836
- });
837
- provider.onSetPreferredAccount(({ address, type }) => {
838
- if (!address) {
839
- return;
840
- }
841
- this.setPreferredAccountType(type, ChainController.state.activeChain);
842
- });
567
+ return adapters;
568
+ // eslint-disable-next-line @typescript-eslint/prefer-reduce-type-parameter
569
+ }, {});
843
570
  }
844
- async syncAuthConnector(provider) {
845
- this.setLoading(true);
846
- const isLoginEmailUsed = provider.getLoginEmailUsed();
847
- this.setLoading(isLoginEmailUsed);
848
- if (isLoginEmailUsed) {
849
- this.setStatus('connecting', ChainController.state.activeChain);
850
- }
851
- const email = provider.getEmail();
852
- const username = provider.getUsername();
853
- this.setUser({ ...(AccountController.state?.user || {}), username, email });
854
- this.setupAuthConnectorListeners(provider);
855
- const { isConnected } = await provider.isConnected();
856
- const theme = ThemeController.getSnapshot();
857
- const options = OptionsController.getSnapshot();
858
- provider.syncDappData({
859
- metadata: options.metadata,
860
- sdkVersion: options.sdkVersion,
861
- projectId: options.projectId,
862
- sdkType: options.sdkType
863
- });
864
- provider.syncTheme({
865
- themeMode: theme.themeMode,
866
- themeVariables: theme.themeVariables,
867
- w3mThemeVariables: getW3mThemeVariables(theme.themeVariables, theme.themeMode)
868
- });
869
- const namespace = StorageUtil.getActiveNamespace();
870
- if (namespace) {
871
- if (isConnected && this.connectionControllerClient?.connectExternal) {
872
- await this.connectionControllerClient?.connectExternal({
873
- id: ConstantsUtil.CONNECTOR_ID.AUTH,
874
- info: { name: ConstantsUtil.CONNECTOR_ID.AUTH },
875
- type: UtilConstantsUtil.CONNECTOR_TYPE_AUTH,
876
- provider,
877
- chainId: ChainController.state.activeCaipNetwork?.id,
878
- chain: namespace
879
- });
880
- this.setStatus('connected', namespace);
881
- }
882
- else if (StorageUtil.getConnectedConnectorId(namespace) === ConstantsUtil.CONNECTOR_ID.AUTH) {
883
- this.setStatus('disconnected', namespace);
884
- StorageUtil.removeConnectedNamespace(namespace);
885
- }
886
- }
887
- this.setLoading(false);
571
+ async initChainAdapter(namespace) {
572
+ this.onConnectors(namespace);
573
+ this.listenAdapter(namespace);
574
+ this.chainAdapters?.[namespace].syncConnectors(this.options, this);
575
+ await this.createUniversalProviderForAdapter(namespace);
888
576
  }
889
- listenWalletConnect() {
890
- if (this.universalProvider) {
891
- this.universalProvider.on('display_uri', ConnectionController.setUri.bind(ConnectionController));
892
- this.universalProvider.on('disconnect', () => {
893
- this.chainNamespaces.forEach(namespace => {
894
- this.resetAccount(namespace);
895
- });
896
- ConnectionController.resetWcConnection();
897
- });
898
- this.universalProvider.on('chainChanged', (chainId) => {
899
- // eslint-disable-next-line eqeqeq
900
- const caipNetwork = this.caipNetworks?.find(c => c.id == chainId);
901
- const currentCaipNetwork = this.getCaipNetwork();
902
- if (!caipNetwork) {
903
- this.setUnsupportedNetwork(chainId);
904
- return;
905
- }
906
- if (currentCaipNetwork?.id !== caipNetwork?.id) {
907
- this.setCaipNetwork(caipNetwork);
908
- }
909
- });
910
- this.universalProvider.on('session_event', (callbackData) => {
911
- if (WcHelpersUtil.isSessionEventData(callbackData)) {
912
- const { name, data } = callbackData.params.event;
913
- if (name === 'accountsChanged' &&
914
- Array.isArray(data) &&
915
- CoreHelperUtil.isCaipAddress(data[0])) {
916
- this.syncAccount(ParseUtil.parseCaipAddress(data[0]));
917
- }
918
- }
919
- });
920
- }
577
+ async initChainAdapters() {
578
+ await Promise.all(this.chainNamespaces.map(async (namespace) => {
579
+ await this.initChainAdapter(namespace);
580
+ }));
581
+ }
582
+ onConnectors(chainNamespace) {
583
+ const adapter = this.getAdapter(chainNamespace);
584
+ adapter?.on('connectors', this.setConnectors.bind(this));
921
585
  }
922
586
  listenAdapter(chainNamespace) {
923
587
  const adapter = this.getAdapter(chainNamespace);
@@ -977,31 +641,78 @@ export class AppKit {
977
641
  }
978
642
  });
979
643
  }
980
- async updateNativeBalance() {
981
- const adapter = this.getAdapter(ChainController.state.activeChain);
982
- if (adapter && ChainController.state.activeChain && AccountController.state.address) {
983
- const balance = await adapter.getBalance({
984
- address: AccountController.state.address,
985
- chainId: ChainController.state.activeCaipNetwork?.id,
986
- caipNetwork: this.getCaipNetwork(),
987
- tokens: this.options.tokens
988
- });
989
- this.setBalance(balance.balance, balance.symbol, ChainController.state.activeChain);
644
+ async createUniversalProviderForAdapter(chainNamespace) {
645
+ await this.getUniversalProvider();
646
+ if (this.universalProvider) {
647
+ this.chainAdapters?.[chainNamespace]?.setUniversalProvider?.(this.universalProvider);
990
648
  }
991
649
  }
992
- getChainsFromNamespaces(namespaces = {}) {
993
- return Object.values(namespaces).flatMap((namespace) => {
994
- const chains = (namespace.chains || []);
995
- const accountsChains = namespace.accounts.map(account => {
996
- const { chainId, chainNamespace } = ParseUtil.parseCaipAddress(account);
997
- return `${chainNamespace}:${chainId}`;
650
+ // -- Connection Sync ---------------------------------------------------
651
+ async syncExistingConnection() {
652
+ await Promise.allSettled(this.chainNamespaces.map(namespace => this.syncNamespaceConnection(namespace)));
653
+ }
654
+ async syncNamespaceConnection(namespace) {
655
+ try {
656
+ const connectorId = StorageUtil.getConnectedConnectorId(namespace);
657
+ this.setStatus('connecting', namespace);
658
+ switch (connectorId) {
659
+ case ConstantsUtil.CONNECTOR_ID.WALLET_CONNECT:
660
+ await this.syncWalletConnectAccount();
661
+ break;
662
+ case ConstantsUtil.CONNECTOR_ID.AUTH:
663
+ // Handled during initialization of adapters' auth provider
664
+ break;
665
+ default:
666
+ await this.syncAdapterConnection(namespace);
667
+ }
668
+ }
669
+ catch (err) {
670
+ console.warn("AppKit couldn't sync existing connection", err);
671
+ StorageUtil.deleteConnectedConnectorId(namespace);
672
+ this.setStatus('disconnected', namespace);
673
+ }
674
+ }
675
+ async syncAdapterConnection(namespace) {
676
+ const adapter = this.getAdapter(namespace);
677
+ const connectorId = StorageUtil.getConnectedConnectorId(namespace);
678
+ const caipNetwork = this.getCaipNetwork();
679
+ try {
680
+ if (!adapter || !connectorId) {
681
+ throw new Error(`Adapter or connectorId not found for namespace ${namespace}`);
682
+ }
683
+ const connection = await adapter?.syncConnection({
684
+ namespace,
685
+ id: connectorId,
686
+ chainId: caipNetwork?.id,
687
+ rpcUrl: caipNetwork?.rpcUrls?.default?.http?.[0]
998
688
  });
999
- return Array.from(new Set([...chains, ...accountsChains]));
1000
- });
689
+ if (connection) {
690
+ const accounts = await adapter?.getAccounts({
691
+ namespace,
692
+ id: connectorId
693
+ });
694
+ if (accounts && accounts.accounts.length > 0) {
695
+ this.setAllAccounts(accounts.accounts, namespace);
696
+ }
697
+ else {
698
+ this.setAllAccounts([CoreHelperUtil.createAccount(namespace, connection.address, 'eoa')], namespace);
699
+ }
700
+ this.syncProvider({ ...connection, chainNamespace: namespace });
701
+ await this.syncAccount({ ...connection, chainNamespace: namespace });
702
+ this.setStatus('connected', namespace);
703
+ }
704
+ else {
705
+ this.setStatus('disconnected', namespace);
706
+ }
707
+ }
708
+ catch (e) {
709
+ StorageUtil.deleteConnectedConnectorId(namespace);
710
+ this.setStatus('disconnected', namespace);
711
+ }
1001
712
  }
1002
713
  async syncWalletConnectAccount() {
1003
- const adapter = this.getAdapter(ChainController.state.activeChain);
1004
714
  this.chainNamespaces.forEach(async (chainNamespace) => {
715
+ const adapter = this.getAdapter(chainNamespace);
1005
716
  const namespaceAccounts = this.universalProvider?.session?.namespaces?.[chainNamespace]?.accounts || [];
1006
717
  // We try and find the address for this network in the session object.
1007
718
  const activeChainId = ChainController.state.activeCaipNetwork?.id;
@@ -1112,20 +823,60 @@ export class AppKit {
1112
823
  await this.syncBalance({ address, chainId: network?.id, chainNamespace });
1113
824
  }
1114
825
  }
1115
- async syncBalance(params) {
1116
- const caipNetwork = NetworkUtil.getNetworksByNamespace(this.caipNetworks, params.chainNamespace).find(n => n.id.toString() === params.chainId?.toString());
1117
- if (!caipNetwork) {
826
+ async syncIdentity({ address, chainId, chainNamespace }) {
827
+ const activeCaipNetwork = this.caipNetworks?.find(n => n.caipNetworkId === `${chainNamespace}:${chainId}`);
828
+ if (chainNamespace !== ConstantsUtil.CHAIN.EVM || activeCaipNetwork?.testnet) {
1118
829
  return;
1119
830
  }
1120
- const isApiBalanceSupported = CoreConstantsUtil.BALANCE_SUPPORTED_CHAINS.includes(caipNetwork?.chainNamespace);
1121
- if (caipNetwork.testnet || !isApiBalanceSupported) {
1122
- await this.updateNativeBalance();
1123
- return;
831
+ try {
832
+ const { name, avatar } = await this.fetchIdentity({
833
+ address
834
+ });
835
+ this.setProfileName(name, chainNamespace);
836
+ this.setProfileImage(avatar, chainNamespace);
837
+ if (!name) {
838
+ await this.syncReownName(address, chainNamespace);
839
+ const adapter = this.getAdapter(chainNamespace);
840
+ const result = await adapter?.getProfile({
841
+ address,
842
+ chainId: Number(chainId)
843
+ });
844
+ if (result?.profileName) {
845
+ this.setProfileName(result.profileName, chainNamespace);
846
+ if (result.profileImage) {
847
+ this.setProfileImage(result.profileImage, chainNamespace);
848
+ }
849
+ }
850
+ else {
851
+ await this.syncReownName(address, chainNamespace);
852
+ this.setProfileImage(null, chainNamespace);
853
+ }
854
+ }
855
+ }
856
+ catch {
857
+ if (chainId === 1) {
858
+ await this.syncReownName(address, chainNamespace);
859
+ }
860
+ else {
861
+ await this.syncReownName(address, chainNamespace);
862
+ this.setProfileImage(null, chainNamespace);
863
+ }
864
+ }
865
+ }
866
+ async syncReownName(address, chainNamespace) {
867
+ try {
868
+ const registeredWcNames = await this.getReownName(address);
869
+ if (registeredWcNames[0]) {
870
+ const wcName = registeredWcNames[0];
871
+ this.setProfileName(wcName.name, chainNamespace);
872
+ }
873
+ else {
874
+ this.setProfileName(null, chainNamespace);
875
+ }
876
+ }
877
+ catch {
878
+ this.setProfileName(null, chainNamespace);
1124
879
  }
1125
- const balances = await AccountController.fetchTokenBalance(() => this.setBalance('0.00', caipNetwork.nativeCurrency.symbol, caipNetwork.chainNamespace));
1126
- const balance = balances.find(b => b.chainId === `${params.chainNamespace}:${params.chainId}` &&
1127
- b.symbol === caipNetwork.nativeCurrency.symbol);
1128
- this.setBalance(balance?.quantity?.numeric || '0.00', caipNetwork.nativeCurrency.symbol, params.chainNamespace);
1129
880
  }
1130
881
  syncConnectedWalletInfo(chainNamespace) {
1131
882
  const connectorId = StorageUtil.getConnectedConnectorId(chainNamespace);
@@ -1141,381 +892,383 @@ export class AppKit {
1141
892
  }
1142
893
  }
1143
894
  }
1144
- else if (providerType === UtilConstantsUtil.CONNECTOR_TYPE_WALLET_CONNECT) {
1145
- const provider = ProviderUtil.getProvider(chainNamespace);
1146
- if (provider?.session) {
1147
- this.setConnectedWalletInfo({
1148
- ...provider.session.peer.metadata,
1149
- name: provider.session.peer.metadata.name,
1150
- icon: provider.session.peer.metadata.icons?.[0]
1151
- }, chainNamespace);
895
+ else if (providerType === UtilConstantsUtil.CONNECTOR_TYPE_WALLET_CONNECT) {
896
+ const provider = ProviderUtil.getProvider(chainNamespace);
897
+ if (provider?.session) {
898
+ this.setConnectedWalletInfo({
899
+ ...provider.session.peer.metadata,
900
+ name: provider.session.peer.metadata.name,
901
+ icon: provider.session.peer.metadata.icons?.[0]
902
+ }, chainNamespace);
903
+ }
904
+ }
905
+ else if (connectorId) {
906
+ if (connectorId === ConstantsUtil.CONNECTOR_ID.COINBASE) {
907
+ const connector = this.getConnectors().find(c => c.id === ConstantsUtil.CONNECTOR_ID.COINBASE);
908
+ this.setConnectedWalletInfo({ name: 'Coinbase Wallet', icon: this.getConnectorImage(connector) }, chainNamespace);
909
+ }
910
+ this.setConnectedWalletInfo({ name: connectorId }, chainNamespace);
911
+ }
912
+ }
913
+ async syncBalance(params) {
914
+ const caipNetwork = NetworkUtil.getNetworksByNamespace(this.caipNetworks, params.chainNamespace).find(n => n.id.toString() === params.chainId?.toString());
915
+ if (!caipNetwork) {
916
+ return;
917
+ }
918
+ const isApiBalanceSupported = CoreConstantsUtil.BALANCE_SUPPORTED_CHAINS.includes(caipNetwork?.chainNamespace);
919
+ if (caipNetwork.testnet || !isApiBalanceSupported) {
920
+ await this.updateNativeBalance();
921
+ return;
922
+ }
923
+ const balances = await AccountController.fetchTokenBalance(() => this.setBalance('0.00', caipNetwork.nativeCurrency.symbol, caipNetwork.chainNamespace));
924
+ const balance = balances.find(b => b.chainId === `${params.chainNamespace}:${params.chainId}` &&
925
+ b.symbol === caipNetwork.nativeCurrency.symbol);
926
+ this.setBalance(balance?.quantity?.numeric || '0.00', caipNetwork.nativeCurrency.symbol, params.chainNamespace);
927
+ }
928
+ async updateNativeBalance() {
929
+ const adapter = this.getAdapter(ChainController.state.activeChain);
930
+ if (adapter && ChainController.state.activeChain && AccountController.state.address) {
931
+ const balance = await adapter.getBalance({
932
+ address: AccountController.state.address,
933
+ chainId: ChainController.state.activeCaipNetwork?.id,
934
+ caipNetwork: this.getCaipNetwork(),
935
+ tokens: this.options.tokens
936
+ });
937
+ this.setBalance(balance.balance, balance.symbol, ChainController.state.activeChain);
938
+ }
939
+ }
940
+ // -- Universal Provider ---------------------------------------------------
941
+ async initializeUniversalAdapter() {
942
+ const logger = LoggerUtil.createLogger((error, ...args) => {
943
+ if (error) {
944
+ this.handleAlertError(error);
945
+ }
946
+ // eslint-disable-next-line no-console
947
+ console.error(...args);
948
+ });
949
+ const universalProviderOptions = {
950
+ projectId: this.options?.projectId,
951
+ metadata: {
952
+ name: this.options?.metadata ? this.options?.metadata.name : '',
953
+ description: this.options?.metadata ? this.options?.metadata.description : '',
954
+ url: this.options?.metadata ? this.options?.metadata.url : '',
955
+ icons: this.options?.metadata ? this.options?.metadata.icons : ['']
956
+ },
957
+ logger
958
+ };
959
+ OptionsController.setUsingInjectedUniversalProvider(Boolean(this.options?.universalProvider));
960
+ this.universalProvider =
961
+ this.options.universalProvider ?? (await UniversalProvider.init(universalProviderOptions));
962
+ this.listenWalletConnect();
963
+ }
964
+ listenWalletConnect() {
965
+ if (this.universalProvider) {
966
+ this.universalProvider.on('display_uri', ConnectionController.setUri.bind(ConnectionController));
967
+ this.universalProvider.on('disconnect', () => {
968
+ this.chainNamespaces.forEach(namespace => {
969
+ this.resetAccount(namespace);
970
+ });
971
+ ConnectionController.resetWcConnection();
972
+ });
973
+ this.universalProvider.on('chainChanged', (chainId) => {
974
+ // eslint-disable-next-line eqeqeq
975
+ const caipNetwork = this.caipNetworks?.find(c => c.id == chainId);
976
+ const currentCaipNetwork = this.getCaipNetwork();
977
+ if (!caipNetwork) {
978
+ this.setUnsupportedNetwork(chainId);
979
+ return;
980
+ }
981
+ if (currentCaipNetwork?.id !== caipNetwork?.id) {
982
+ this.setCaipNetwork(caipNetwork);
983
+ }
984
+ });
985
+ this.universalProvider.on('session_event', (callbackData) => {
986
+ if (WcHelpersUtil.isSessionEventData(callbackData)) {
987
+ const { name, data } = callbackData.params.event;
988
+ if (name === 'accountsChanged' &&
989
+ Array.isArray(data) &&
990
+ CoreHelperUtil.isCaipAddress(data[0])) {
991
+ this.syncAccount(ParseUtil.parseCaipAddress(data[0]));
992
+ }
993
+ }
994
+ });
995
+ }
996
+ }
997
+ createUniversalProvider() {
998
+ if (!this.universalProviderInitPromise &&
999
+ CoreHelperUtil.isClient() &&
1000
+ this.options?.projectId) {
1001
+ this.universalProviderInitPromise = this.initializeUniversalAdapter();
1002
+ }
1003
+ return this.universalProviderInitPromise;
1004
+ }
1005
+ async getUniversalProvider() {
1006
+ if (!this.universalProvider) {
1007
+ try {
1008
+ await this.createUniversalProvider();
1009
+ }
1010
+ catch (error) {
1011
+ throw new Error('AppKit:getUniversalProvider - Cannot create provider');
1152
1012
  }
1153
1013
  }
1154
- else if (connectorId) {
1155
- if (connectorId === ConstantsUtil.CONNECTOR_ID.COINBASE) {
1156
- const connector = this.getConnectors().find(c => c.id === ConstantsUtil.CONNECTOR_ID.COINBASE);
1157
- this.setConnectedWalletInfo({ name: 'Coinbase Wallet', icon: this.getConnectorImage(connector) }, chainNamespace);
1014
+ return this.universalProvider;
1015
+ }
1016
+ // - Utils -------------------------------------------------------------------
1017
+ handleAlertError(error) {
1018
+ const matchedUniversalProviderError = Object.entries(ErrorUtil.UniversalProviderErrors).find(([, { message }]) => error.message.includes(message));
1019
+ const [errorKey, errorValue] = matchedUniversalProviderError ?? [];
1020
+ const { message, alertErrorKey } = errorValue ?? {};
1021
+ if (errorKey && message && !this.reportedAlertErrors[errorKey]) {
1022
+ const alertError = ErrorUtil.ALERT_ERRORS[alertErrorKey];
1023
+ if (alertError) {
1024
+ AlertController.open(alertError, 'error');
1025
+ this.reportedAlertErrors[errorKey] = true;
1158
1026
  }
1159
- this.setConnectedWalletInfo({ name: connectorId }, chainNamespace);
1160
1027
  }
1161
1028
  }
1162
- async syncIdentity({ address, chainId, chainNamespace }) {
1163
- const activeCaipNetwork = this.caipNetworks?.find(n => n.caipNetworkId === `${chainNamespace}:${chainId}`);
1164
- if (chainNamespace !== ConstantsUtil.CHAIN.EVM || activeCaipNetwork?.testnet) {
1029
+ getAdapter(namespace) {
1030
+ if (!namespace) {
1031
+ return undefined;
1032
+ }
1033
+ return this.chainAdapters?.[namespace];
1034
+ }
1035
+ createAdapter(blueprint) {
1036
+ if (!blueprint) {
1165
1037
  return;
1166
1038
  }
1167
- try {
1168
- const { name, avatar } = await this.fetchIdentity({
1169
- address
1170
- });
1171
- this.setProfileName(name, chainNamespace);
1172
- this.setProfileImage(avatar, chainNamespace);
1173
- if (!name) {
1174
- await this.syncReownName(address, chainNamespace);
1175
- const adapter = this.getAdapter(chainNamespace);
1176
- const result = await adapter?.getProfile({
1177
- address,
1178
- chainId: Number(chainId)
1179
- });
1180
- if (result?.profileName) {
1181
- this.setProfileName(result.profileName, chainNamespace);
1182
- if (result.profileImage) {
1183
- this.setProfileImage(result.profileImage, chainNamespace);
1184
- }
1185
- }
1186
- else {
1187
- await this.syncReownName(address, chainNamespace);
1188
- this.setProfileImage(null, chainNamespace);
1189
- }
1190
- }
1039
+ const namespace = blueprint.namespace;
1040
+ if (!namespace) {
1041
+ return;
1191
1042
  }
1192
- catch {
1193
- if (chainId === 1) {
1194
- await this.syncReownName(address, chainNamespace);
1195
- }
1196
- else {
1197
- await this.syncReownName(address, chainNamespace);
1198
- this.setProfileImage(null, chainNamespace);
1199
- }
1043
+ this.createClients();
1044
+ const adapterBlueprint = blueprint;
1045
+ adapterBlueprint.namespace = namespace;
1046
+ adapterBlueprint.construct({
1047
+ namespace,
1048
+ projectId: this.options?.projectId,
1049
+ networks: this.caipNetworks
1050
+ });
1051
+ if (!this.chainNamespaces.includes(namespace)) {
1052
+ this.chainNamespaces.push(namespace);
1053
+ }
1054
+ if (this.chainAdapters) {
1055
+ this.chainAdapters[namespace] = adapterBlueprint;
1200
1056
  }
1201
1057
  }
1202
- async syncReownName(address, chainNamespace) {
1203
- try {
1204
- const registeredWcNames = await this.getReownName(address);
1205
- if (registeredWcNames[0]) {
1206
- const wcName = registeredWcNames[0];
1207
- this.setProfileName(wcName.name, chainNamespace);
1208
- }
1209
- else {
1210
- this.setProfileName(null, chainNamespace);
1211
- }
1058
+ // -- Public -------------------------------------------------------------------
1059
+ async open(options) {
1060
+ await this.injectModalUi();
1061
+ if (options?.uri && this.universalProvider) {
1062
+ ConnectionController.setUri(options.uri);
1212
1063
  }
1213
- catch {
1214
- this.setProfileName(null, chainNamespace);
1064
+ ModalController.open(options);
1065
+ }
1066
+ async close() {
1067
+ await this.injectModalUi();
1068
+ ModalController.close();
1069
+ }
1070
+ setLoading(loading) {
1071
+ ModalController.setLoading(loading);
1072
+ }
1073
+ async disconnect() {
1074
+ await ConnectionController.disconnect();
1075
+ }
1076
+ // -- review these -------------------------------------------------------------------
1077
+ getError() {
1078
+ return '';
1079
+ }
1080
+ getChainId() {
1081
+ return ChainController.state.activeCaipNetwork?.id;
1082
+ }
1083
+ switchNetwork(appKitNetwork) {
1084
+ const network = this.caipNetworks?.find(n => n.id === appKitNetwork.id);
1085
+ if (!network) {
1086
+ AlertController.open(ErrorUtil.ALERT_ERRORS.SWITCH_NETWORK_NOT_FOUND, 'error');
1087
+ return;
1215
1088
  }
1089
+ ChainController.switchActiveNetwork(network);
1216
1090
  }
1217
- async syncAdapterConnection(namespace) {
1218
- const adapter = this.getAdapter(namespace);
1219
- const connectorId = StorageUtil.getConnectedConnectorId(namespace);
1220
- const caipNetwork = this.getCaipNetwork();
1221
- try {
1222
- if (!adapter || !connectorId) {
1223
- throw new Error(`Adapter or connectorId not found for namespace ${namespace}`);
1224
- }
1225
- const connection = await adapter?.syncConnection({
1226
- namespace,
1227
- id: connectorId,
1228
- chainId: caipNetwork?.id,
1229
- rpcUrl: caipNetwork?.rpcUrls?.default?.http?.[0]
1091
+ getWalletProvider() {
1092
+ return ChainController.state.activeChain
1093
+ ? ProviderUtil.state.providers[ChainController.state.activeChain]
1094
+ : null;
1095
+ }
1096
+ getWalletProviderType() {
1097
+ return ChainController.state.activeChain
1098
+ ? ProviderUtil.state.providerIds[ChainController.state.activeChain]
1099
+ : null;
1100
+ }
1101
+ subscribeProviders(callback) {
1102
+ return ProviderUtil.subscribeProviders(callback);
1103
+ }
1104
+ getThemeMode() {
1105
+ return ThemeController.state.themeMode;
1106
+ }
1107
+ getThemeVariables() {
1108
+ return ThemeController.state.themeVariables;
1109
+ }
1110
+ setThemeMode(themeMode) {
1111
+ ThemeController.setThemeMode(themeMode);
1112
+ setColorTheme(ThemeController.state.themeMode);
1113
+ }
1114
+ setTermsConditionsUrl(termsConditionsUrl) {
1115
+ OptionsController.setTermsConditionsUrl(termsConditionsUrl);
1116
+ }
1117
+ setPrivacyPolicyUrl(privacyPolicyUrl) {
1118
+ OptionsController.setPrivacyPolicyUrl(privacyPolicyUrl);
1119
+ }
1120
+ setThemeVariables(themeVariables) {
1121
+ ThemeController.setThemeVariables(themeVariables);
1122
+ setThemeVariables(ThemeController.state.themeVariables);
1123
+ }
1124
+ subscribeTheme(callback) {
1125
+ return ThemeController.subscribe(callback);
1126
+ }
1127
+ getWalletInfo() {
1128
+ return AccountController.state.connectedWalletInfo;
1129
+ }
1130
+ subscribeAccount(callback) {
1131
+ function updateVal() {
1132
+ const authConnector = ConnectorController.getAuthConnector();
1133
+ callback({
1134
+ allAccounts: AccountController.state.allAccounts,
1135
+ caipAddress: ChainController.state.activeCaipAddress,
1136
+ address: CoreHelperUtil.getPlainAddress(ChainController.state.activeCaipAddress),
1137
+ isConnected: Boolean(ChainController.state.activeCaipAddress),
1138
+ status: AccountController.state.status,
1139
+ embeddedWalletInfo: authConnector
1140
+ ? {
1141
+ user: AccountController.state.user,
1142
+ authProvider: AccountController.state.socialProvider || 'email',
1143
+ accountType: AccountController.state.preferredAccountType,
1144
+ isSmartAccountDeployed: Boolean(AccountController.state.smartAccountDeployed)
1145
+ }
1146
+ : undefined
1230
1147
  });
1231
- if (connection) {
1232
- const accounts = await adapter?.getAccounts({
1233
- namespace,
1234
- id: connectorId
1235
- });
1236
- if (accounts && accounts.accounts.length > 0) {
1237
- this.setAllAccounts(accounts.accounts, namespace);
1238
- }
1239
- else {
1240
- this.setAllAccounts([CoreHelperUtil.createAccount(namespace, connection.address, 'eoa')], namespace);
1241
- }
1242
- this.syncProvider({ ...connection, chainNamespace: namespace });
1243
- await this.syncAccount({ ...connection, chainNamespace: namespace });
1244
- this.setStatus('connected', namespace);
1245
- }
1246
- else {
1247
- this.setStatus('disconnected', namespace);
1248
- }
1249
- }
1250
- catch (e) {
1251
- StorageUtil.deleteConnectedConnectorId(namespace);
1252
- this.setStatus('disconnected', namespace);
1253
1148
  }
1149
+ ChainController.subscribe(updateVal);
1150
+ AccountController.subscribe(updateVal);
1151
+ ConnectorController.subscribe(updateVal);
1152
+ }
1153
+ subscribeNetwork(callback) {
1154
+ return ChainController.subscribe(({ activeCaipNetwork }) => {
1155
+ callback({
1156
+ caipNetwork: activeCaipNetwork,
1157
+ chainId: activeCaipNetwork?.id,
1158
+ caipNetworkId: activeCaipNetwork?.caipNetworkId
1159
+ });
1160
+ });
1161
+ }
1162
+ subscribeWalletInfo(callback) {
1163
+ return AccountController.subscribeKey('connectedWalletInfo', callback);
1164
+ }
1165
+ subscribeShouldUpdateToAddress(callback) {
1166
+ AccountController.subscribeKey('shouldUpdateToAddress', callback);
1167
+ }
1168
+ subscribeCaipNetworkChange(callback) {
1169
+ ChainController.subscribeKey('activeCaipNetwork', callback);
1170
+ }
1171
+ getState() {
1172
+ return PublicStateController.state;
1173
+ }
1174
+ subscribeState(callback) {
1175
+ return PublicStateController.subscribe(callback);
1176
+ }
1177
+ showErrorMessage(message) {
1178
+ SnackController.showError(message);
1179
+ }
1180
+ showSuccessMessage(message) {
1181
+ SnackController.showSuccess(message);
1254
1182
  }
1255
- async syncNamespaceConnection(namespace) {
1256
- try {
1257
- const connectorId = StorageUtil.getConnectedConnectorId(namespace);
1258
- const isEmailUsed = this.authProvider?.getLoginEmailUsed();
1259
- if (isEmailUsed) {
1260
- return;
1261
- }
1262
- this.setStatus('connecting', namespace);
1263
- switch (connectorId) {
1264
- case ConstantsUtil.CONNECTOR_ID.WALLET_CONNECT:
1265
- await this.syncWalletConnectAccount();
1266
- break;
1267
- case ConstantsUtil.CONNECTOR_ID.AUTH:
1268
- // Handled during initialization of adapters' auth provider
1269
- break;
1270
- default:
1271
- await this.syncAdapterConnection(namespace);
1272
- }
1273
- }
1274
- catch (err) {
1275
- console.warn("AppKit couldn't sync existing connection", err);
1276
- StorageUtil.deleteConnectedConnectorId(namespace);
1277
- this.setStatus('disconnected', namespace);
1278
- }
1183
+ getEvent() {
1184
+ return { ...EventsController.state };
1279
1185
  }
1280
- async syncExistingConnection() {
1281
- await Promise.allSettled(this.chainNamespaces.map(namespace => this.syncNamespaceConnection(namespace)));
1186
+ subscribeEvents(callback) {
1187
+ return EventsController.subscribe(callback);
1282
1188
  }
1283
- getAdapter(namespace) {
1284
- if (!namespace) {
1285
- return undefined;
1286
- }
1287
- return this.chainAdapters?.[namespace];
1189
+ replace(route) {
1190
+ RouterController.replace(route);
1288
1191
  }
1289
- createUniversalProvider() {
1290
- if (!this.universalProviderInitPromise &&
1291
- CoreHelperUtil.isClient() &&
1292
- this.options?.projectId) {
1293
- this.universalProviderInitPromise = this.initializeUniversalAdapter();
1294
- }
1295
- return this.universalProviderInitPromise;
1192
+ redirect(route) {
1193
+ RouterController.push(route);
1296
1194
  }
1297
- handleAlertError(error) {
1298
- const matchedUniversalProviderError = Object.entries(ErrorUtil.UniversalProviderErrors).find(([, { message }]) => error.message.includes(message));
1299
- const [errorKey, errorValue] = matchedUniversalProviderError ?? [];
1300
- const { message, alertErrorKey } = errorValue ?? {};
1301
- if (errorKey && message && !this.reportedAlertErrors[errorKey]) {
1302
- const alertError = ErrorUtil.ALERT_ERRORS[alertErrorKey];
1303
- if (alertError) {
1304
- AlertController.open(alertError, 'error');
1305
- this.reportedAlertErrors[errorKey] = true;
1306
- }
1307
- }
1195
+ popTransactionStack(cancel) {
1196
+ RouterController.popTransactionStack(cancel);
1308
1197
  }
1309
- async initializeUniversalAdapter() {
1310
- const logger = LoggerUtil.createLogger((error, ...args) => {
1311
- if (error) {
1312
- this.handleAlertError(error);
1313
- }
1314
- // eslint-disable-next-line no-console
1315
- console.error(...args);
1316
- });
1317
- const universalProviderOptions = {
1318
- projectId: this.options?.projectId,
1319
- metadata: {
1320
- name: this.options?.metadata ? this.options?.metadata.name : '',
1321
- description: this.options?.metadata ? this.options?.metadata.description : '',
1322
- url: this.options?.metadata ? this.options?.metadata.url : '',
1323
- icons: this.options?.metadata ? this.options?.metadata.icons : ['']
1324
- },
1325
- logger
1326
- };
1327
- OptionsController.setUsingInjectedUniversalProvider(Boolean(this.options?.universalProvider));
1328
- this.universalProvider =
1329
- this.options.universalProvider ?? (await UniversalProvider.init(universalProviderOptions));
1330
- this.listenWalletConnect();
1198
+ isOpen() {
1199
+ return ModalController.state.open;
1331
1200
  }
1332
- async getUniversalProvider() {
1333
- if (!this.universalProvider) {
1334
- try {
1335
- await this.createUniversalProvider();
1336
- }
1337
- catch (error) {
1338
- throw new Error('AppKit:getUniversalProvider - Cannot create provider');
1339
- }
1340
- }
1341
- return this.universalProvider;
1201
+ isTransactionStackEmpty() {
1202
+ return RouterController.state.transactionStack.length === 0;
1342
1203
  }
1343
- createAuthProvider() {
1344
- const isEmailEnabled = this.options?.features?.email === undefined
1345
- ? CoreConstantsUtil.DEFAULT_FEATURES.email
1346
- : this.options?.features?.email;
1347
- const isSocialsEnabled = this.options?.features?.socials
1348
- ? this.options?.features?.socials?.length > 0
1349
- : CoreConstantsUtil.DEFAULT_FEATURES.socials;
1350
- const isAuthEnabled = isEmailEnabled || isSocialsEnabled;
1351
- if (!this.authProvider && this.options?.projectId && isAuthEnabled) {
1352
- this.authProvider = W3mFrameProviderSingleton.getInstance({
1353
- projectId: this.options.projectId,
1354
- enableLogger: this.options.enableAuthLogger,
1355
- chainId: this.getCaipNetwork()?.caipNetworkId,
1356
- onTimeout: () => {
1357
- AlertController.open(ErrorUtil.ALERT_ERRORS.SOCIALS_TIMEOUT, 'error');
1358
- }
1359
- });
1360
- this.subscribeState(val => {
1361
- if (!val.open) {
1362
- this.authProvider?.rejectRpcRequests();
1363
- }
1364
- });
1365
- this.syncAuthConnector(this.authProvider);
1366
- }
1204
+ isTransactionShouldReplaceView() {
1205
+ return RouterController.state.transactionStack[RouterController.state.transactionStack.length - 1]?.replace;
1367
1206
  }
1368
- async createUniversalProviderForAdapter(chainNamespace) {
1369
- await this.getUniversalProvider();
1370
- if (this.universalProvider) {
1371
- this.chainAdapters?.[chainNamespace]?.setUniversalProvider?.(this.universalProvider);
1372
- }
1207
+ static getInstance() {
1208
+ return this.instance;
1373
1209
  }
1374
- createAuthProviderForAdapter(chainNamespace) {
1375
- this.createAuthProvider();
1376
- if (this.authProvider) {
1377
- this.chainAdapters?.[chainNamespace]?.setAuthProvider?.(this.authProvider);
1378
- }
1210
+ updateFeatures(newFeatures) {
1211
+ OptionsController.setFeatures(newFeatures);
1379
1212
  }
1380
- createAdapter(blueprint) {
1381
- if (!blueprint) {
1382
- return;
1383
- }
1384
- const namespace = blueprint.namespace;
1385
- if (!namespace) {
1386
- return;
1387
- }
1388
- this.createClients();
1389
- const adapterBlueprint = blueprint;
1390
- adapterBlueprint.namespace = namespace;
1391
- adapterBlueprint.construct({
1392
- namespace,
1393
- projectId: this.options?.projectId,
1394
- networks: this.caipNetworks
1395
- });
1396
- if (!this.chainNamespaces.includes(namespace)) {
1397
- this.chainNamespaces.push(namespace);
1398
- }
1399
- if (this.chainAdapters) {
1400
- this.chainAdapters[namespace] = adapterBlueprint;
1401
- }
1213
+ updateOptions(newOptions) {
1214
+ const currentOptions = OptionsController.state || {};
1215
+ const updatedOptions = { ...currentOptions, ...newOptions };
1216
+ OptionsController.setOptions(updatedOptions);
1402
1217
  }
1403
- createAdapters(blueprints) {
1404
- this.createClients();
1405
- return this.chainNamespaces.reduce((adapters, namespace) => {
1406
- const blueprint = blueprints?.find(b => b.namespace === namespace);
1407
- if (blueprint) {
1408
- adapters[namespace] = blueprint;
1409
- adapters[namespace].namespace = namespace;
1410
- adapters[namespace].construct({
1411
- namespace,
1412
- projectId: this.options?.projectId,
1413
- networks: this.caipNetworks
1414
- });
1415
- }
1416
- else {
1417
- adapters[namespace] = new UniversalAdapter({
1418
- namespace,
1419
- networks: this.caipNetworks
1420
- });
1421
- }
1422
- return adapters;
1423
- // eslint-disable-next-line @typescript-eslint/prefer-reduce-type-parameter
1424
- }, {});
1218
+ setConnectMethodsOrder(connectMethodsOrder) {
1219
+ OptionsController.setConnectMethodsOrder(connectMethodsOrder);
1425
1220
  }
1426
- onConnectors(chainNamespace) {
1427
- const adapter = this.getAdapter(chainNamespace);
1428
- adapter?.on('connectors', this.setConnectors.bind(this));
1221
+ setWalletFeaturesOrder(walletFeaturesOrder) {
1222
+ OptionsController.setWalletFeaturesOrder(walletFeaturesOrder);
1429
1223
  }
1430
- async initChainAdapter(namespace) {
1431
- this.onConnectors(namespace);
1432
- this.listenAdapter(namespace);
1433
- this.chainAdapters?.[namespace].syncConnectors(this.options, this);
1434
- await this.createUniversalProviderForAdapter(namespace);
1435
- this.createAuthProviderForAdapter(namespace);
1224
+ setCollapseWallets(collapseWallets) {
1225
+ OptionsController.setCollapseWallets(collapseWallets);
1436
1226
  }
1437
- async initChainAdapters() {
1438
- await Promise.all(this.chainNamespaces.map(async (namespace) => {
1439
- await this.initChainAdapter(namespace);
1440
- }));
1227
+ setSocialsOrder(socialsOrder) {
1228
+ OptionsController.setSocialsOrder(socialsOrder);
1441
1229
  }
1442
- getUnsupportedNetwork(caipNetworkId) {
1443
- return {
1444
- id: caipNetworkId.split(':')[1],
1445
- caipNetworkId,
1446
- name: ConstantsUtil.UNSUPPORTED_NETWORK_NAME,
1447
- chainNamespace: caipNetworkId.split(':')[0],
1448
- nativeCurrency: {
1449
- name: '',
1450
- decimals: 0,
1451
- symbol: ''
1452
- },
1453
- rpcUrls: {
1454
- default: {
1455
- http: []
1456
- }
1457
- }
1458
- };
1230
+ getConnectMethodsOrder() {
1231
+ return WalletUtil.getConnectOrderMethod(OptionsController.state.features, ConnectorController.getConnectors());
1459
1232
  }
1460
- getDefaultNetwork() {
1461
- const caipNetworkId = StorageUtil.getActiveCaipNetworkId();
1462
- if (caipNetworkId) {
1463
- const caipNetwork = this.caipNetworks?.find(n => n.caipNetworkId === caipNetworkId);
1464
- if (caipNetwork) {
1465
- return caipNetwork;
1466
- }
1467
- return this.getUnsupportedNetwork(caipNetworkId);
1233
+ /**
1234
+ * Removes an adapter from the AppKit.
1235
+ * @param namespace - The namespace of the adapter to remove.
1236
+ */
1237
+ removeAdapter(namespace) {
1238
+ const isConnected = this.getIsConnectedState();
1239
+ const adapter = this.getAdapter(namespace);
1240
+ if (!adapter || !this.chainAdapters || isConnected) {
1241
+ return;
1468
1242
  }
1469
- return this.caipNetworks?.[0];
1243
+ const newCaipNetworks = this.caipNetworks?.filter(network => network.chainNamespace !== namespace);
1244
+ ChainController.removeAdapter(namespace);
1245
+ ConnectorController.removeAdapter(namespace);
1246
+ this.chainNamespaces = this.chainNamespaces.filter(n => n !== namespace);
1247
+ this.caipNetworks = newCaipNetworks;
1248
+ adapter.removeAllEventListeners();
1249
+ Reflect.deleteProperty(this.chainAdapters, namespace);
1470
1250
  }
1471
- async injectModalUi() {
1472
- if (!isInitialized && CoreHelperUtil.isClient()) {
1473
- const { basic } = this.options;
1474
- const features = { ...CoreConstantsUtil.DEFAULT_FEATURES, ...this.options.features };
1475
- if (basic) {
1476
- // Import only basic views
1477
- await import('@reown/appkit-scaffold-ui/basic');
1478
- }
1479
- else {
1480
- // Import all views
1481
- await import('@reown/appkit-scaffold-ui');
1482
- // Selectively import views based on feature flags
1483
- if (features) {
1484
- const usingEmbeddedWallet = features.email || (features.socials && features.socials.length);
1485
- if (usingEmbeddedWallet) {
1486
- await import('@reown/appkit-scaffold-ui/embedded-wallet');
1487
- }
1488
- if (features.email) {
1489
- await import('@reown/appkit-scaffold-ui/email');
1490
- }
1491
- if (features.socials) {
1492
- await import('@reown/appkit-scaffold-ui/socials');
1493
- }
1494
- if (features.swaps) {
1495
- await import('@reown/appkit-scaffold-ui/swaps');
1496
- }
1497
- if (features.send) {
1498
- await import('@reown/appkit-scaffold-ui/send');
1499
- }
1500
- if (features.receive) {
1501
- await import('@reown/appkit-scaffold-ui/receive');
1502
- }
1503
- if (features.onramp) {
1504
- await import('@reown/appkit-scaffold-ui/onramp');
1505
- }
1506
- if (features.history) {
1507
- await import('@reown/appkit-scaffold-ui/transactions');
1508
- }
1509
- }
1510
- }
1511
- // Import core modal
1512
- await import('@reown/appkit-scaffold-ui/w3m-modal');
1513
- const modal = document.createElement('w3m-modal');
1514
- if (!OptionsController.state.disableAppend && !OptionsController.state.enableEmbedded) {
1515
- document.body.insertAdjacentElement('beforeend', modal);
1516
- }
1517
- isInitialized = true;
1251
+ /**
1252
+ * Adds an adapter to the AppKit.
1253
+ * @param adapter - The adapter instance.
1254
+ * @param networks - The list of networks that this adapter supports / uses.
1255
+ */
1256
+ addAdapter(adapter, networks) {
1257
+ const namespace = adapter.namespace;
1258
+ if (!this.connectionControllerClient || !this.networkControllerClient) {
1259
+ return;
1260
+ }
1261
+ if (!this.chainAdapters || !namespace) {
1262
+ return;
1518
1263
  }
1264
+ const extendedAdapterNetworks = this.extendCaipNetworks({ ...this.options, networks });
1265
+ this.caipNetworks = [...(this.caipNetworks || []), ...extendedAdapterNetworks];
1266
+ this.createAdapter(adapter);
1267
+ this.initChainAdapter(namespace);
1268
+ ChainController.addAdapter(adapter, {
1269
+ connectionControllerClient: this.connectionControllerClient,
1270
+ networkControllerClient: this.networkControllerClient
1271
+ }, extendedAdapterNetworks);
1519
1272
  }
1520
1273
  }
1521
- //# sourceMappingURL=client.js.map
1274
+ //# sourceMappingURL=core.js.map