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