@reown/appkit 1.8.15-viem-upgrade.0 → 1.8.15-wc-linking-reset-headless.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 (120) hide show
  1. package/dist/esm/exports/auth-provider.js +2 -0
  2. package/dist/esm/exports/auth-provider.js.map +1 -0
  3. package/dist/esm/exports/constants.js +2 -0
  4. package/dist/esm/exports/constants.js.map +1 -0
  5. package/dist/esm/exports/core.js +11 -0
  6. package/dist/esm/exports/core.js.map +1 -0
  7. package/dist/esm/exports/index.js +14 -0
  8. package/dist/esm/exports/index.js.map +1 -0
  9. package/dist/esm/exports/library/react.js +2 -0
  10. package/dist/esm/exports/library/react.js.map +1 -0
  11. package/dist/esm/exports/library/vue.js +2 -0
  12. package/dist/esm/exports/library/vue.js.map +1 -0
  13. package/dist/esm/exports/networks.js +2 -0
  14. package/dist/esm/exports/networks.js.map +1 -0
  15. package/dist/esm/exports/react-core.js +39 -0
  16. package/dist/esm/exports/react-core.js.map +1 -0
  17. package/dist/esm/exports/react.js +50 -0
  18. package/dist/esm/exports/react.js.map +1 -0
  19. package/dist/esm/exports/testing.js +15 -0
  20. package/dist/esm/exports/testing.js.map +1 -0
  21. package/dist/esm/exports/utils.js +2 -0
  22. package/dist/esm/exports/utils.js.map +1 -0
  23. package/dist/esm/exports/vue-core.js +45 -0
  24. package/dist/esm/exports/vue-core.js.map +1 -0
  25. package/dist/esm/exports/vue.js +53 -0
  26. package/dist/esm/exports/vue.js.map +1 -0
  27. package/dist/esm/package.json +171 -0
  28. package/dist/esm/src/auth-provider/W3MFrameProviderSingleton.js +26 -0
  29. package/dist/esm/src/auth-provider/W3MFrameProviderSingleton.js.map +1 -0
  30. package/dist/esm/src/auth-provider/index.js +2 -0
  31. package/dist/esm/src/auth-provider/index.js.map +1 -0
  32. package/dist/esm/src/client/appkit-base-client.js +1893 -0
  33. package/dist/esm/src/client/appkit-base-client.js.map +1 -0
  34. package/dist/esm/src/client/appkit-core.js +44 -0
  35. package/dist/esm/src/client/appkit-core.js.map +1 -0
  36. package/dist/esm/src/client/appkit.js +540 -0
  37. package/dist/esm/src/client/appkit.js.map +1 -0
  38. package/dist/esm/src/library/react/components.js +24 -0
  39. package/dist/esm/src/library/react/components.js.map +1 -0
  40. package/dist/esm/src/library/react/index.js +110 -0
  41. package/dist/esm/src/library/react/index.js.map +1 -0
  42. package/dist/esm/src/library/react/providers.js +17 -0
  43. package/dist/esm/src/library/react/providers.js.map +1 -0
  44. package/dist/esm/src/library/vue/index.js +117 -0
  45. package/dist/esm/src/library/vue/index.js.map +1 -0
  46. package/dist/esm/src/networks/bitcoin.js +46 -0
  47. package/dist/esm/src/networks/bitcoin.js.map +1 -0
  48. package/dist/esm/src/networks/index.js +9 -0
  49. package/dist/esm/src/networks/index.js.map +1 -0
  50. package/dist/esm/src/networks/solana/index.js +4 -0
  51. package/dist/esm/src/networks/solana/index.js.map +1 -0
  52. package/dist/esm/src/networks/solana/solana.js +16 -0
  53. package/dist/esm/src/networks/solana/solana.js.map +1 -0
  54. package/dist/esm/src/networks/solana/solanaDevnet.js +16 -0
  55. package/dist/esm/src/networks/solana/solanaDevnet.js.map +1 -0
  56. package/dist/esm/src/networks/solana/solanaTestnet.js +15 -0
  57. package/dist/esm/src/networks/solana/solanaTestnet.js.map +1 -0
  58. package/dist/esm/src/networks/ton/index.js +3 -0
  59. package/dist/esm/src/networks/ton/index.js.map +1 -0
  60. package/dist/esm/src/networks/ton/ton.js +15 -0
  61. package/dist/esm/src/networks/ton/ton.js.map +1 -0
  62. package/dist/esm/src/networks/ton/tonTestnet.js +15 -0
  63. package/dist/esm/src/networks/ton/tonTestnet.js.map +1 -0
  64. package/dist/esm/src/networks/utils.js +9 -0
  65. package/dist/esm/src/networks/utils.js.map +1 -0
  66. package/dist/esm/src/universal-adapter/client.js +203 -0
  67. package/dist/esm/src/universal-adapter/client.js.map +1 -0
  68. package/dist/esm/src/universal-adapter/index.js +2 -0
  69. package/dist/esm/src/universal-adapter/index.js.map +1 -0
  70. package/dist/esm/src/utils/BalanceUtil.js +28 -0
  71. package/dist/esm/src/utils/BalanceUtil.js.map +1 -0
  72. package/dist/esm/src/utils/ConfigUtil.js +273 -0
  73. package/dist/esm/src/utils/ConfigUtil.js.map +1 -0
  74. package/dist/esm/src/utils/ConstantsUtil.js +6 -0
  75. package/dist/esm/src/utils/ConstantsUtil.js.map +1 -0
  76. package/dist/esm/src/utils/TypesUtil.js +2 -0
  77. package/dist/esm/src/utils/TypesUtil.js.map +1 -0
  78. package/dist/esm/src/utils/index.js +3 -0
  79. package/dist/esm/src/utils/index.js.map +1 -0
  80. package/dist/esm/tsconfig.build.tsbuildinfo +1 -0
  81. package/dist/types/exports/auth-provider.d.ts +1 -0
  82. package/dist/types/exports/constants.d.ts +1 -0
  83. package/dist/types/exports/core.d.ts +8 -0
  84. package/dist/types/exports/index.d.ts +10 -0
  85. package/dist/types/exports/library/react.d.ts +1 -0
  86. package/dist/types/exports/library/vue.d.ts +1 -0
  87. package/dist/types/exports/networks.d.ts +1 -0
  88. package/dist/types/exports/react-core.d.ts +16 -0
  89. package/dist/types/exports/react.d.ts +30 -0
  90. package/dist/types/exports/testing.d.ts +7 -0
  91. package/dist/types/exports/utils.d.ts +1 -0
  92. package/dist/types/exports/vue-core.d.ts +15 -0
  93. package/dist/types/exports/vue.d.ts +23 -0
  94. package/dist/types/src/auth-provider/W3MFrameProviderSingleton.d.ts +17 -0
  95. package/dist/types/src/auth-provider/index.d.ts +1 -0
  96. package/dist/types/src/client/appkit-base-client.d.ts +322 -0
  97. package/dist/types/src/client/appkit-core.d.ts +27 -0
  98. package/dist/types/src/client/appkit.d.ts +28 -0
  99. package/dist/types/src/library/react/components.d.ts +5 -0
  100. package/dist/types/src/library/react/index.d.ts +78 -0
  101. package/dist/types/src/library/react/providers.d.ts +7 -0
  102. package/dist/types/src/library/vue/index.d.ts +86 -0
  103. package/dist/types/src/networks/bitcoin.d.ts +150 -0
  104. package/dist/types/src/networks/index.d.ts +7 -0
  105. package/dist/types/src/networks/solana/index.d.ts +3 -0
  106. package/dist/types/src/networks/solana/solana.d.ts +46 -0
  107. package/dist/types/src/networks/solana/solanaDevnet.d.ts +46 -0
  108. package/dist/types/src/networks/solana/solanaTestnet.d.ts +45 -0
  109. package/dist/types/src/networks/ton/index.d.ts +2 -0
  110. package/dist/types/src/networks/ton/ton.d.ts +45 -0
  111. package/dist/types/src/networks/ton/tonTestnet.d.ts +45 -0
  112. package/dist/types/src/networks/utils.d.ts +3 -0
  113. package/dist/types/src/universal-adapter/client.d.ts +41 -0
  114. package/dist/types/src/universal-adapter/index.d.ts +1 -0
  115. package/dist/types/src/utils/BalanceUtil.d.ts +14 -0
  116. package/dist/types/src/utils/ConfigUtil.d.ts +29 -0
  117. package/dist/types/src/utils/ConstantsUtil.d.ts +5 -0
  118. package/dist/types/src/utils/TypesUtil.d.ts +98 -0
  119. package/dist/types/src/utils/index.d.ts +2 -0
  120. package/package.json +11 -11
@@ -0,0 +1,1893 @@
1
+ import UniversalProvider from '@walletconnect/universal-provider';
2
+ import { ConstantsUtil, NetworkUtil, ParseUtil } from '@reown/appkit-common';
3
+ import { AdapterController, AlertController, ApiController, AssetUtil, BlockchainApiController, ChainController, ConnectionController, ConnectionControllerUtil, ConnectorController, ConnectorUtil, ConstantsUtil as CoreConstantsUtil, CoreHelperUtil, EnsController, EventsController, ModalController, OnRampController, OptionsController, ProviderController, PublicStateController, RouterController, SIWXUtil, SendController, SnackController, StorageUtil, ThemeController, WalletUtil, WcHelpersUtil, getPreferredAccountType } from '@reown/appkit-controllers';
4
+ import { setColorTheme, setThemeVariables } from '@reown/appkit-ui';
5
+ import { CaipNetworksUtil, ErrorUtil, HelpersUtil, LoggerUtil, TokenUtil, ConstantsUtil as UtilConstantsUtil } from '@reown/appkit-utils';
6
+ import { UniversalAdapter } from '../universal-adapter/client.js';
7
+ import { ConfigUtil } from '../utils/ConfigUtil.js';
8
+ export class AppKitBaseClient {
9
+ constructor(options) {
10
+ this.chainNamespaces = [];
11
+ this.features = {};
12
+ this.remoteFeatures = {};
13
+ this.reportedAlertErrors = {};
14
+ // -- Public Internal ---------------------------------------------------
15
+ this.getCaipNetwork = (chainNamespace, id) => {
16
+ if (chainNamespace) {
17
+ const caipNetworkWithId = ChainController.getCaipNetworks(chainNamespace)?.find(c => c.id === id);
18
+ if (caipNetworkWithId) {
19
+ return caipNetworkWithId;
20
+ }
21
+ const namespaceCaipNetwork = ChainController.getNetworkData(chainNamespace)?.caipNetwork;
22
+ if (namespaceCaipNetwork) {
23
+ return namespaceCaipNetwork;
24
+ }
25
+ const requestedCaipNetworks = ChainController.getRequestedCaipNetworks(chainNamespace);
26
+ return requestedCaipNetworks.filter(c => c.chainNamespace === chainNamespace)?.[0];
27
+ }
28
+ return ChainController.state.activeCaipNetwork || this.defaultCaipNetwork;
29
+ };
30
+ this.getCaipNetworkId = () => {
31
+ const network = this.getCaipNetwork();
32
+ if (network) {
33
+ return network.id;
34
+ }
35
+ return undefined;
36
+ };
37
+ this.getCaipNetworks = (namespace) => ChainController.getCaipNetworks(namespace);
38
+ this.getActiveChainNamespace = () => ChainController.state.activeChain;
39
+ this.setRequestedCaipNetworks = (requestedCaipNetworks, chain) => {
40
+ ChainController.setRequestedCaipNetworks(requestedCaipNetworks, chain);
41
+ };
42
+ this.getApprovedCaipNetworkIds = () => ChainController.getAllApprovedCaipNetworkIds();
43
+ this.getCaipAddress = (chainNamespace) => {
44
+ if (ChainController.state.activeChain === chainNamespace || !chainNamespace) {
45
+ return ChainController.state.activeCaipAddress;
46
+ }
47
+ return ChainController.state.chains.get(chainNamespace)?.accountState?.caipAddress;
48
+ };
49
+ this.setClientId = clientId => {
50
+ BlockchainApiController.setClientId(clientId);
51
+ };
52
+ this.getProvider = (namespace) => ProviderController.getProvider(namespace);
53
+ this.getProviderType = (namespace) => ProviderController.getProviderId(namespace);
54
+ this.getPreferredAccountType = (namespace) => getPreferredAccountType(namespace);
55
+ this.setCaipAddress = (caipAddress, chain, shouldRefresh = false) => {
56
+ ChainController.setAccountProp('caipAddress', caipAddress, chain, shouldRefresh);
57
+ ChainController.setAccountProp('address', CoreHelperUtil.getPlainAddress(caipAddress), chain, shouldRefresh);
58
+ };
59
+ this.setBalance = (balance, balanceSymbol, chain) => {
60
+ ChainController.setAccountProp('balance', balance, chain);
61
+ ChainController.setAccountProp('balanceSymbol', balanceSymbol, chain);
62
+ };
63
+ this.setProfileName = (profileName, chain) => {
64
+ ChainController.setAccountProp('profileName', profileName, chain);
65
+ };
66
+ this.setProfileImage = (profileImage, chain) => {
67
+ ChainController.setAccountProp('profileImage', profileImage, chain);
68
+ };
69
+ this.setUser = (user, chain) => {
70
+ ChainController.setAccountProp('user', user, chain);
71
+ };
72
+ this.resetAccount = (chain) => {
73
+ ChainController.resetAccount(chain);
74
+ };
75
+ this.setCaipNetwork = caipNetwork => {
76
+ ChainController.setActiveCaipNetwork(caipNetwork);
77
+ };
78
+ this.setCaipNetworkOfNamespace = (caipNetwork, chainNamespace) => {
79
+ ChainController.setChainNetworkData(chainNamespace, { caipNetwork });
80
+ };
81
+ this.setStatus = (status, chain) => {
82
+ ChainController.setAccountProp('status', status, chain);
83
+ // If at least one namespace is connected, set the connection status
84
+ if (ConnectorController.isConnected()) {
85
+ StorageUtil.setConnectionStatus('connected');
86
+ }
87
+ else {
88
+ StorageUtil.setConnectionStatus('disconnected');
89
+ }
90
+ };
91
+ this.getAddressByChainNamespace = (chainNamespace) => ChainController.getAccountData(chainNamespace)?.address;
92
+ this.setConnectors = connectors => {
93
+ const allConnectors = [...ConnectorController.state.allConnectors, ...connectors];
94
+ ConnectorController.setConnectors(allConnectors);
95
+ };
96
+ this.setConnections = (connections, chainNamespace) => {
97
+ StorageUtil.setConnections(connections, chainNamespace);
98
+ ConnectionController.setConnections(connections, chainNamespace);
99
+ };
100
+ this.fetchIdentity = request => BlockchainApiController.fetchIdentity(request);
101
+ this.getReownName = address => EnsController.getNamesForAddress(address);
102
+ this.getConnectors = () => ConnectorController.getConnectors();
103
+ this.getConnectorImage = connector => AssetUtil.getConnectorImage(connector);
104
+ this.getConnections = (namespace) => {
105
+ if (!this.remoteFeatures.multiWallet) {
106
+ AlertController.open(ConstantsUtil.REMOTE_FEATURES_ALERTS.MULTI_WALLET_NOT_ENABLED.DEFAULT, 'info');
107
+ return [];
108
+ }
109
+ return ConnectionControllerUtil.getConnectionsData(namespace).connections;
110
+ };
111
+ this.getRecentConnections = (namespace) => {
112
+ if (!this.remoteFeatures.multiWallet) {
113
+ AlertController.open(ConstantsUtil.REMOTE_FEATURES_ALERTS.MULTI_WALLET_NOT_ENABLED.DEFAULT, 'info');
114
+ return [];
115
+ }
116
+ return ConnectionControllerUtil.getConnectionsData(namespace).recentConnections;
117
+ };
118
+ this.switchConnection = async (params) => {
119
+ if (!this.remoteFeatures.multiWallet) {
120
+ AlertController.open(ConstantsUtil.REMOTE_FEATURES_ALERTS.MULTI_WALLET_NOT_ENABLED.DEFAULT, 'info');
121
+ return;
122
+ }
123
+ await ConnectionController.switchConnection(params);
124
+ };
125
+ this.deleteConnection = params => {
126
+ if (!this.remoteFeatures.multiWallet) {
127
+ AlertController.open(ConstantsUtil.REMOTE_FEATURES_ALERTS.MULTI_WALLET_NOT_ENABLED.DEFAULT, 'info');
128
+ return;
129
+ }
130
+ StorageUtil.deleteAddressFromConnection(params);
131
+ ConnectionController.syncStorageConnections();
132
+ };
133
+ this.setConnectedWalletInfo = (connectedWalletInfo, chain) => {
134
+ const type = ProviderController.getProviderId(chain);
135
+ const walletInfo = connectedWalletInfo ? { ...connectedWalletInfo, type } : undefined;
136
+ ChainController.setAccountProp('connectedWalletInfo', walletInfo, chain);
137
+ };
138
+ this.getIsConnectedState = () => Boolean(ChainController.state.activeCaipAddress);
139
+ this.addAddressLabel = (address, label, chain) => {
140
+ const addressLabels = ChainController.getAccountData(chain)?.addressLabels || {};
141
+ ChainController.setAccountProp('addressLabels', { ...addressLabels, [address]: label }, chain);
142
+ };
143
+ this.removeAddressLabel = (address, chain) => {
144
+ const addressLabels = ChainController.getAccountData(chain)?.addressLabels || {};
145
+ ChainController.setAccountProp('addressLabels', { ...addressLabels, [address]: undefined }, chain);
146
+ };
147
+ this.getAddress = (chainNamespace) => {
148
+ const namespace = chainNamespace || ChainController.state.activeChain;
149
+ return ChainController.getAccountData(namespace)?.address;
150
+ };
151
+ this.resetNetwork = (namespace) => {
152
+ ChainController.resetNetwork(namespace);
153
+ };
154
+ this.addConnector = connector => {
155
+ ConnectorController.addConnector(connector);
156
+ };
157
+ this.resetWcConnection = () => {
158
+ ConnectionController.resetWcConnection();
159
+ };
160
+ this.setAddressExplorerUrl = (addressExplorerUrl, chain) => {
161
+ ChainController.setAccountProp('addressExplorerUrl', addressExplorerUrl, chain);
162
+ };
163
+ this.setSmartAccountDeployed = (isDeployed, chain) => {
164
+ ChainController.setAccountProp('smartAccountDeployed', isDeployed, chain);
165
+ };
166
+ this.setPreferredAccountType = (preferredAccountType, chain) => {
167
+ ChainController.setAccountProp('preferredAccountType', preferredAccountType, chain);
168
+ };
169
+ this.setEIP6963Enabled = enabled => {
170
+ OptionsController.setEIP6963Enabled(enabled);
171
+ };
172
+ this.handleUnsafeRPCRequest = () => {
173
+ if (this.isOpen()) {
174
+ // If we are on the modal but there is no transaction stack, close the modal
175
+ if (this.isTransactionStackEmpty()) {
176
+ return;
177
+ }
178
+ // Check if we need to replace or redirect
179
+ this.redirect('ApproveTransaction');
180
+ }
181
+ else {
182
+ // If called from outside the modal, open ApproveTransaction
183
+ this.open({ view: 'ApproveTransaction' });
184
+ }
185
+ };
186
+ this.options = options;
187
+ this.version = options.sdkVersion;
188
+ this.caipNetworks = this.extendCaipNetworks(options);
189
+ this.chainNamespaces = this.getChainNamespacesSet(options.adapters, this.caipNetworks);
190
+ this.defaultCaipNetwork = this.extendDefaultCaipNetwork(options);
191
+ this.chainAdapters = this.createAdapters(options.adapters);
192
+ this.readyPromise = this.initialize(options);
193
+ }
194
+ getChainNamespacesSet(adapters, caipNetworks) {
195
+ const adapterNamespaces = adapters
196
+ ?.map(adapter => adapter.namespace)
197
+ .filter((namespace) => Boolean(namespace));
198
+ if (adapterNamespaces?.length) {
199
+ return [...new Set(adapterNamespaces)];
200
+ }
201
+ const networkNamespaces = caipNetworks?.map(network => network.chainNamespace);
202
+ return [...new Set(networkNamespaces)];
203
+ }
204
+ async initialize(options) {
205
+ this.initializeProjectSettings(options);
206
+ this.initControllers(options);
207
+ await this.initChainAdapters();
208
+ this.sendInitializeEvent(options);
209
+ if (options.features?.headless && !ConnectorUtil.hasInjectedConnectors()) {
210
+ ApiController.prefetch({
211
+ fetchNetworkImages: false,
212
+ fetchConnectorImages: false,
213
+ fetchWalletRanks: false,
214
+ fetchRecommendedWallets: true
215
+ });
216
+ }
217
+ if (OptionsController.state.enableReconnect) {
218
+ await this.syncExistingConnection();
219
+ await this.syncAdapterConnections();
220
+ }
221
+ else {
222
+ await this.unSyncExistingConnection();
223
+ }
224
+ if (!options.basic && !options.manualWCControl) {
225
+ this.remoteFeatures = await ConfigUtil.fetchRemoteFeatures(options);
226
+ }
227
+ await ApiController.fetchUsage();
228
+ OptionsController.setRemoteFeatures(this.remoteFeatures);
229
+ if (this.remoteFeatures.onramp) {
230
+ OnRampController.setOnrampProviders(this.remoteFeatures.onramp);
231
+ }
232
+ // Check allowed origins only if email or social features are enabled
233
+ if (OptionsController.state.remoteFeatures?.email ||
234
+ (Array.isArray(OptionsController.state.remoteFeatures?.socials) &&
235
+ OptionsController.state.remoteFeatures?.socials.length > 0)) {
236
+ await this.checkAllowedOrigins();
237
+ }
238
+ if (OptionsController.state.features?.reownAuthentication ||
239
+ OptionsController.state.remoteFeatures?.reownAuthentication) {
240
+ const { ReownAuthentication } = await import('@reown/appkit-controllers/features');
241
+ const currentSIWX = OptionsController.state.siwx;
242
+ if (!(currentSIWX instanceof ReownAuthentication)) {
243
+ if (currentSIWX) {
244
+ console.warn('ReownAuthentication option is enabled, SIWX configuration will be overridden.');
245
+ }
246
+ OptionsController.setSIWX(new ReownAuthentication());
247
+ }
248
+ // If siwx is already configured for ReownAuthentication we keep the current instance
249
+ }
250
+ }
251
+ async openSend(args) {
252
+ const namespaceToUse = args.namespace || ChainController.state.activeChain;
253
+ const caipAddress = this.getCaipAddress(namespaceToUse);
254
+ const chainId = this.getCaipNetwork(namespaceToUse)?.id;
255
+ if (!caipAddress) {
256
+ throw new Error('openSend: caipAddress not found');
257
+ }
258
+ if (chainId?.toString() !== args.chainId.toString()) {
259
+ const caipNetwork = ChainController.getCaipNetworkById(args.chainId, namespaceToUse);
260
+ if (!caipNetwork) {
261
+ throw new Error(`openSend: caipNetwork with chainId ${args.chainId} not found`);
262
+ }
263
+ await this.switchNetwork(caipNetwork, { throwOnFailure: true });
264
+ }
265
+ try {
266
+ const symbol = TokenUtil.getTokenSymbolByAddress(args.assetAddress);
267
+ if (symbol) {
268
+ await ApiController.fetchTokenImages([symbol]);
269
+ }
270
+ }
271
+ catch {
272
+ /* Ignore */
273
+ }
274
+ await ModalController.open({
275
+ view: 'WalletSend',
276
+ data: { send: args }
277
+ });
278
+ return new Promise((resolve, reject) => {
279
+ const unsubscribe = SendController.subscribeKey('hash', hash => {
280
+ if (hash) {
281
+ cleanup();
282
+ resolve({ hash });
283
+ }
284
+ });
285
+ const unsubscribeModal = ModalController.subscribe(modal => {
286
+ if (!modal.open) {
287
+ cleanup();
288
+ reject(new Error('Modal closed'));
289
+ }
290
+ });
291
+ const cleanup = this.createCleanupHandler([unsubscribe, unsubscribeModal]);
292
+ });
293
+ }
294
+ toModalOptions() {
295
+ function isSwap(options) {
296
+ return options?.view === 'Swap';
297
+ }
298
+ function isSend(options) {
299
+ return options?.view === 'WalletSend';
300
+ }
301
+ return {
302
+ isSwap,
303
+ isSend
304
+ };
305
+ }
306
+ async checkAllowedOrigins() {
307
+ try {
308
+ const allowedOrigins = await ApiController.fetchAllowedOrigins();
309
+ if (!CoreHelperUtil.isClient()) {
310
+ return;
311
+ }
312
+ const currentOrigin = window.location.origin;
313
+ const isOriginAllowed = WcHelpersUtil.isOriginAllowed(currentOrigin, allowedOrigins, ConstantsUtil.DEFAULT_ALLOWED_ANCESTORS);
314
+ if (!isOriginAllowed) {
315
+ AlertController.open(ErrorUtil.ALERT_ERRORS.ORIGIN_NOT_ALLOWED, 'error');
316
+ }
317
+ }
318
+ catch (error) {
319
+ if (!(error instanceof Error)) {
320
+ return;
321
+ }
322
+ switch (error.message) {
323
+ case 'RATE_LIMITED':
324
+ AlertController.open(ErrorUtil.ALERT_ERRORS.RATE_LIMITED_APP_CONFIGURATION, 'error');
325
+ break;
326
+ case 'SERVER_ERROR': {
327
+ const originalError = error.cause instanceof Error ? error.cause : error;
328
+ AlertController.open({
329
+ displayMessage: ErrorUtil.ALERT_ERRORS.SERVER_ERROR_APP_CONFIGURATION.displayMessage,
330
+ debugMessage: ErrorUtil.ALERT_ERRORS.SERVER_ERROR_APP_CONFIGURATION.debugMessage(originalError.message)
331
+ }, 'error');
332
+ break;
333
+ }
334
+ default:
335
+ break;
336
+ }
337
+ }
338
+ }
339
+ createCleanupHandler(unsubscribeFunctions) {
340
+ return () => {
341
+ unsubscribeFunctions.forEach(unsubscribe => {
342
+ try {
343
+ unsubscribe();
344
+ }
345
+ catch {
346
+ // Ignore cleanup errors
347
+ }
348
+ });
349
+ };
350
+ }
351
+ sendInitializeEvent(options) {
352
+ const { ...optionsCopy } = options;
353
+ delete optionsCopy.adapters;
354
+ delete optionsCopy.universalProvider;
355
+ EventsController.sendEvent({
356
+ type: 'track',
357
+ event: 'INITIALIZE',
358
+ properties: {
359
+ ...optionsCopy,
360
+ networks: options.networks.map(n => n.id),
361
+ siweConfig: {
362
+ options: options.siweConfig?.options || {}
363
+ }
364
+ }
365
+ });
366
+ }
367
+ // -- Controllers initialization ---------------------------------------------------
368
+ initControllers(options) {
369
+ this.initializeOptionsController(options);
370
+ this.initializeChainController(options);
371
+ this.initializeThemeController(options);
372
+ this.initializeConnectionController(options);
373
+ this.initializeConnectorController();
374
+ }
375
+ initAdapterController() {
376
+ AdapterController.initialize(this.chainAdapters);
377
+ }
378
+ initializeThemeController(options) {
379
+ if (options.themeMode) {
380
+ ThemeController.setThemeMode(options.themeMode);
381
+ }
382
+ if (options.themeVariables) {
383
+ ThemeController.setThemeVariables(options.themeVariables);
384
+ }
385
+ }
386
+ initializeChainController(options) {
387
+ if (!this.connectionControllerClient) {
388
+ throw new Error('ConnectionControllerClient must be set');
389
+ }
390
+ ChainController.initialize(options.adapters ?? [], this.caipNetworks, {
391
+ connectionControllerClient: this.connectionControllerClient
392
+ });
393
+ const network = this.getDefaultNetwork();
394
+ if (network) {
395
+ ChainController.setActiveCaipNetwork(network);
396
+ }
397
+ }
398
+ initializeConnectionController(options) {
399
+ ConnectionController.initialize(options.adapters ?? []);
400
+ ConnectionController.setWcBasic(options.basic ?? false);
401
+ }
402
+ initializeConnectorController() {
403
+ ConnectorController.initialize(this.chainNamespaces);
404
+ }
405
+ initializeProjectSettings(options) {
406
+ OptionsController.setProjectId(options.projectId);
407
+ OptionsController.setSdkVersion(options.sdkVersion);
408
+ }
409
+ initializeOptionsController(options) {
410
+ OptionsController.setDebug(options.debug !== false);
411
+ // On by default
412
+ OptionsController.setEnableWalletGuide(options.enableWalletGuide !== false);
413
+ OptionsController.setEnableWallets(options.enableWallets !== false);
414
+ OptionsController.setEIP6963Enabled(options.enableEIP6963 !== false);
415
+ OptionsController.setEnableNetworkSwitch(options.enableNetworkSwitch !== false);
416
+ OptionsController.setEnableReconnect(options.enableReconnect !== false);
417
+ OptionsController.setEnableMobileFullScreen(options.enableMobileFullScreen === true);
418
+ OptionsController.setCoinbasePreference(options.coinbasePreference);
419
+ OptionsController.setEnableAuthLogger(options.enableAuthLogger !== false);
420
+ OptionsController.setCustomRpcUrls(options.customRpcUrls);
421
+ OptionsController.setEnableEmbedded(options.enableEmbedded);
422
+ OptionsController.setAllWallets(options.allWallets);
423
+ OptionsController.setIncludeWalletIds(options.includeWalletIds);
424
+ OptionsController.setExcludeWalletIds(options.excludeWalletIds);
425
+ OptionsController.setFeaturedWalletIds(options.featuredWalletIds);
426
+ OptionsController.setTokens(options.tokens);
427
+ OptionsController.setTermsConditionsUrl(options.termsConditionsUrl);
428
+ OptionsController.setPrivacyPolicyUrl(options.privacyPolicyUrl);
429
+ OptionsController.setCustomWallets(options.customWallets);
430
+ OptionsController.setFeatures(options.features);
431
+ OptionsController.setAllowUnsupportedChain(options.allowUnsupportedChain);
432
+ OptionsController.setUniversalProviderConfigOverride(options.universalProviderConfigOverride);
433
+ OptionsController.setPreferUniversalLinks(options.experimental_preferUniversalLinks);
434
+ // Save option in controller
435
+ OptionsController.setDefaultAccountTypes(options.defaultAccountTypes);
436
+ const defaultMetaData = this.getDefaultMetaData();
437
+ if (!options.metadata && defaultMetaData) {
438
+ options.metadata = defaultMetaData;
439
+ }
440
+ OptionsController.setMetadata(options.metadata);
441
+ OptionsController.setDisableAppend(options.disableAppend);
442
+ OptionsController.setEnableEmbedded(options.enableEmbedded);
443
+ OptionsController.setSIWX(options.siwx);
444
+ this.features = OptionsController.state.features ?? {};
445
+ if (!options.projectId) {
446
+ AlertController.open(ErrorUtil.ALERT_ERRORS.PROJECT_ID_NOT_CONFIGURED, 'error');
447
+ return;
448
+ }
449
+ const evmAdapter = options.adapters?.find(adapter => adapter.namespace === ConstantsUtil.CHAIN.EVM);
450
+ // Set the SIWE client for EVM chains
451
+ if (evmAdapter) {
452
+ if (options.siweConfig) {
453
+ if (options.siwx) {
454
+ throw new Error('Cannot set both `siweConfig` and `siwx` options');
455
+ }
456
+ OptionsController.setSIWX(options.siweConfig.mapToSIWX());
457
+ }
458
+ }
459
+ }
460
+ getDefaultMetaData() {
461
+ if (CoreHelperUtil.isClient()) {
462
+ return {
463
+ name: document.getElementsByTagName('title')?.[0]?.textContent || '',
464
+ description: document.querySelector('meta[property="og:description"]')?.content || '',
465
+ url: window.location.origin,
466
+ icons: [document.querySelector('link[rel~="icon"]')?.href || '']
467
+ };
468
+ }
469
+ return null;
470
+ }
471
+ // -- Network Initialization ---------------------------------------------------
472
+ setUnsupportedNetwork(chainId) {
473
+ const namespace = this.getActiveChainNamespace();
474
+ if (namespace) {
475
+ const unsupportedNetwork = CaipNetworksUtil.getUnsupportedNetwork(`${namespace}:${chainId}`);
476
+ ChainController.setActiveCaipNetwork(unsupportedNetwork);
477
+ }
478
+ }
479
+ getDefaultNetwork() {
480
+ return CaipNetworksUtil.getCaipNetworkFromStorage(this.defaultCaipNetwork);
481
+ }
482
+ extendCaipNetwork(network, options) {
483
+ const extendedNetwork = CaipNetworksUtil.extendCaipNetwork(network, {
484
+ customNetworkImageUrls: options.chainImages,
485
+ projectId: options.projectId
486
+ });
487
+ return extendedNetwork;
488
+ }
489
+ extendCaipNetworks(options) {
490
+ const extendedNetworks = CaipNetworksUtil.extendCaipNetworks(options.networks, {
491
+ customNetworkImageUrls: options.chainImages,
492
+ customRpcUrls: options.customRpcUrls,
493
+ projectId: options.projectId
494
+ });
495
+ return extendedNetworks;
496
+ }
497
+ extendDefaultCaipNetwork(options) {
498
+ const defaultNetwork = options.networks.find(n => n.id === options.defaultNetwork?.id);
499
+ const extendedNetwork = defaultNetwork
500
+ ? CaipNetworksUtil.extendCaipNetwork(defaultNetwork, {
501
+ customNetworkImageUrls: options.chainImages,
502
+ customRpcUrls: options.customRpcUrls,
503
+ projectId: options.projectId
504
+ })
505
+ : undefined;
506
+ return extendedNetwork;
507
+ }
508
+ /**
509
+ * Disconnects a connector with the given namespace and id. If the connector id is not provided, disconnects the adapter (namespace).
510
+ * @param namespace ChainNamespace
511
+ * @param id string
512
+ * @returns
513
+ */
514
+ async disconnectConnector(namespace, id) {
515
+ try {
516
+ this.setLoading(true, namespace);
517
+ let disconnectResult = {
518
+ connections: []
519
+ };
520
+ const adapter = this.getAdapter(namespace);
521
+ const caipAddress = ChainController.state.chains.get(namespace)?.accountState?.caipAddress;
522
+ /**
523
+ * When the page loaded, the controller doesn't have address yet.
524
+ * To disconnect, we are checking enableReconnect flag to disconnect the namespace.
525
+ */
526
+ if ((caipAddress || !OptionsController.state.enableReconnect) && adapter?.disconnect) {
527
+ disconnectResult = await adapter.disconnect({ id });
528
+ }
529
+ this.setLoading(false, namespace);
530
+ return disconnectResult;
531
+ }
532
+ catch (error) {
533
+ this.setLoading(false, namespace);
534
+ throw new Error(`Failed to disconnect chains: ${error.message}`);
535
+ }
536
+ }
537
+ // -- Client Initialization ---------------------------------------------------
538
+ createClients() {
539
+ this.connectionControllerClient = {
540
+ connectWalletConnect: async () => {
541
+ const activeChain = ChainController.state.activeChain;
542
+ const adapter = this.getAdapter(activeChain);
543
+ const chainId = this.getCaipNetwork(activeChain)?.id;
544
+ const connections = ConnectionController.getConnections(activeChain);
545
+ const isMultiWallet = this.remoteFeatures.multiWallet;
546
+ const hasConnections = connections.length > 0;
547
+ if (!adapter) {
548
+ throw new Error('Adapter not found');
549
+ }
550
+ const result = await adapter.connectWalletConnect(chainId);
551
+ const shouldClose = !hasConnections || !isMultiWallet;
552
+ if (shouldClose) {
553
+ this.close();
554
+ }
555
+ this.setClientId(result?.clientId || null);
556
+ StorageUtil.setConnectedNamespaces([...ChainController.state.chains.keys()]);
557
+ await this.syncWalletConnectAccount();
558
+ await SIWXUtil.initializeIfEnabled();
559
+ },
560
+ connectExternal: async (params) => {
561
+ const connectResult = await this.onConnectExternal(params);
562
+ await this.connectInactiveNamespaces(params, connectResult);
563
+ return connectResult ? { address: connectResult.address } : undefined;
564
+ },
565
+ reconnectExternal: async ({ id, info, type, provider }) => {
566
+ const namespace = ChainController.state.activeChain;
567
+ const adapter = this.getAdapter(namespace);
568
+ if (!namespace) {
569
+ throw new Error('reconnectExternal: namespace not found');
570
+ }
571
+ if (!adapter) {
572
+ throw new Error('reconnectExternal: adapter not found');
573
+ }
574
+ if (adapter?.reconnect) {
575
+ await adapter?.reconnect({ id, info, type, provider, chainId: this.getCaipNetwork()?.id });
576
+ StorageUtil.addConnectedNamespace(namespace);
577
+ this.syncConnectedWalletInfo(namespace);
578
+ }
579
+ },
580
+ disconnectConnector: async (params) => {
581
+ await this.disconnectConnector(params.namespace, params.id);
582
+ },
583
+ disconnect: async (params) => {
584
+ const { id: connectorIdParam, chainNamespace, initialDisconnect } = params || {};
585
+ const namespace = chainNamespace || ChainController.state.activeChain;
586
+ const namespaceConnectorId = ConnectorController.getConnectorId(namespace);
587
+ const isAuth = connectorIdParam === ConstantsUtil.CONNECTOR_ID.AUTH ||
588
+ namespaceConnectorId === ConstantsUtil.CONNECTOR_ID.AUTH;
589
+ const isWalletConnect = connectorIdParam === ConstantsUtil.CONNECTOR_ID.WALLET_CONNECT ||
590
+ namespaceConnectorId === ConstantsUtil.CONNECTOR_ID.WALLET_CONNECT;
591
+ try {
592
+ const namespaces = Array.from(ChainController.state.chains.keys());
593
+ let namespacesToDisconnect = chainNamespace ? [chainNamespace] : namespaces;
594
+ /*
595
+ * If the connector is WalletConnect or Auth, disconnect all namespaces
596
+ * since they share a single connector instance across all adapters
597
+ */
598
+ if (isWalletConnect || isAuth) {
599
+ namespacesToDisconnect = namespaces;
600
+ }
601
+ const disconnectPromises = namespacesToDisconnect.map(async (ns) => {
602
+ const currentConnectorId = ConnectorController.getConnectorId(ns);
603
+ const connectorIdToDisconnect = connectorIdParam || currentConnectorId;
604
+ const disconnectData = await this.disconnectConnector(ns, connectorIdToDisconnect);
605
+ if (disconnectData) {
606
+ if (isAuth) {
607
+ StorageUtil.deleteConnectedSocialProvider();
608
+ }
609
+ disconnectData.connections.forEach(connection => {
610
+ StorageUtil.addDisconnectedConnectorId(connection.connectorId, ns);
611
+ });
612
+ }
613
+ if (initialDisconnect) {
614
+ this.onDisconnectNamespace({ chainNamespace: ns, closeModal: false });
615
+ }
616
+ });
617
+ const disconnectResults = await Promise.allSettled(disconnectPromises);
618
+ SendController.resetSend();
619
+ ConnectionController.resetWcConnection();
620
+ if (SIWXUtil.getSIWX()?.signOutOnDisconnect) {
621
+ await SIWXUtil.clearSessions();
622
+ }
623
+ ConnectorController.setFilterByNamespace(undefined);
624
+ ConnectionController.syncStorageConnections();
625
+ const failures = disconnectResults.filter((result) => result.status === 'rejected');
626
+ if (failures.length > 0) {
627
+ throw new Error(failures.map(f => f.reason.message).join(', '));
628
+ }
629
+ EventsController.sendEvent({
630
+ type: 'track',
631
+ event: 'DISCONNECT_SUCCESS',
632
+ properties: {
633
+ namespace: chainNamespace || 'all'
634
+ }
635
+ });
636
+ }
637
+ catch (error) {
638
+ throw new Error(`Failed to disconnect chains: ${error.message}`);
639
+ }
640
+ },
641
+ checkInstalled: (ids) => {
642
+ if (!ids) {
643
+ return Boolean(window.ethereum);
644
+ }
645
+ return ids.some(id => Boolean(window.ethereum?.[String(id)]));
646
+ },
647
+ signMessage: async (message) => {
648
+ const namespace = ChainController.state.activeChain;
649
+ const adapter = this.getAdapter(ChainController.state.activeChain);
650
+ if (!namespace) {
651
+ throw new Error('signMessage: namespace not found');
652
+ }
653
+ if (!adapter) {
654
+ throw new Error('signMessage: adapter not found');
655
+ }
656
+ const address = this.getAddress(namespace);
657
+ if (!address) {
658
+ throw new Error('signMessage: address not found');
659
+ }
660
+ const result = await adapter?.signMessage({
661
+ message,
662
+ address,
663
+ provider: ProviderController.getProvider(namespace)
664
+ });
665
+ return result?.signature || '';
666
+ },
667
+ sendTransaction: async (args) => {
668
+ const namespace = args.chainNamespace;
669
+ if (!namespace) {
670
+ throw new Error('sendTransaction: namespace not found');
671
+ }
672
+ if (CoreConstantsUtil.SEND_SUPPORTED_NAMESPACES.includes(namespace)) {
673
+ const adapter = this.getAdapter(namespace);
674
+ if (!adapter) {
675
+ throw new Error('sendTransaction: adapter not found');
676
+ }
677
+ const provider = ProviderController.getProvider(namespace);
678
+ const result = await adapter?.sendTransaction({
679
+ ...args,
680
+ caipNetwork: this.getCaipNetwork(),
681
+ provider
682
+ });
683
+ return result?.hash || '';
684
+ }
685
+ return '';
686
+ },
687
+ estimateGas: async (args) => {
688
+ const namespace = args.chainNamespace;
689
+ if (namespace === ConstantsUtil.CHAIN.EVM) {
690
+ const adapter = this.getAdapter(namespace);
691
+ if (!adapter) {
692
+ throw new Error('estimateGas: adapter is required but got undefined');
693
+ }
694
+ const provider = ProviderController.getProvider(namespace);
695
+ const caipNetwork = this.getCaipNetwork();
696
+ if (!caipNetwork) {
697
+ throw new Error('estimateGas: caipNetwork is required but got undefined');
698
+ }
699
+ const result = await adapter?.estimateGas({ ...args, provider, caipNetwork });
700
+ return result?.gas || 0n;
701
+ }
702
+ return 0n;
703
+ },
704
+ getEnsAvatar: async () => {
705
+ const namespace = ChainController.state.activeChain;
706
+ if (!namespace) {
707
+ throw new Error('getEnsAvatar: namespace is required but got undefined');
708
+ }
709
+ const address = this.getAddress(namespace);
710
+ if (!address) {
711
+ throw new Error('getEnsAvatar: address not found');
712
+ }
713
+ await this.syncIdentity({
714
+ address,
715
+ chainId: Number(this.getCaipNetwork()?.id),
716
+ chainNamespace: namespace
717
+ });
718
+ const accountData = ChainController.getAccountData();
719
+ return accountData?.profileImage || false;
720
+ },
721
+ getEnsAddress: async (name) => await WcHelpersUtil.resolveReownName(name),
722
+ writeContract: async (args) => {
723
+ const namespace = ChainController.state.activeChain;
724
+ const adapter = this.getAdapter(namespace);
725
+ if (!namespace) {
726
+ throw new Error('writeContract: namespace is required but got undefined');
727
+ }
728
+ if (!adapter) {
729
+ throw new Error('writeContract: adapter is required but got undefined');
730
+ }
731
+ const caipNetwork = this.getCaipNetwork();
732
+ const caipAddress = this.getCaipAddress();
733
+ const provider = ProviderController.getProvider(namespace);
734
+ if (!caipNetwork || !caipAddress) {
735
+ throw new Error('writeContract: caipNetwork or caipAddress is required but got undefined');
736
+ }
737
+ const result = await adapter?.writeContract({ ...args, caipNetwork, provider, caipAddress });
738
+ return result?.hash;
739
+ },
740
+ parseUnits: (value, decimals) => {
741
+ const adapter = this.getAdapter(ChainController.state.activeChain);
742
+ if (!adapter) {
743
+ throw new Error('parseUnits: adapter is required but got undefined');
744
+ }
745
+ return adapter?.parseUnits({ value, decimals }) ?? 0n;
746
+ },
747
+ formatUnits: (value, decimals) => {
748
+ const adapter = this.getAdapter(ChainController.state.activeChain);
749
+ if (!adapter) {
750
+ throw new Error('formatUnits: adapter is required but got undefined');
751
+ }
752
+ return adapter?.formatUnits({ value, decimals }) ?? '0';
753
+ },
754
+ getCapabilities: async (params) => {
755
+ const adapter = this.getAdapter(ChainController.state.activeChain);
756
+ if (!adapter) {
757
+ throw new Error('getCapabilities: adapter is required but got undefined');
758
+ }
759
+ return await adapter?.getCapabilities(params);
760
+ },
761
+ grantPermissions: async (params) => {
762
+ const adapter = this.getAdapter(ChainController.state.activeChain);
763
+ if (!adapter) {
764
+ throw new Error('grantPermissions: adapter is required but got undefined');
765
+ }
766
+ return await adapter?.grantPermissions(params);
767
+ },
768
+ revokePermissions: async (params) => {
769
+ const adapter = this.getAdapter(ChainController.state.activeChain);
770
+ if (!adapter) {
771
+ throw new Error('revokePermissions: adapter is required but got undefined');
772
+ }
773
+ if (adapter?.revokePermissions) {
774
+ return await adapter.revokePermissions(params);
775
+ }
776
+ return '0x';
777
+ },
778
+ walletGetAssets: async (params) => {
779
+ const adapter = this.getAdapter(ChainController.state.activeChain);
780
+ if (!adapter) {
781
+ throw new Error('walletGetAssets: adapter is required but got undefined');
782
+ }
783
+ return (await adapter?.walletGetAssets(params)) ?? {};
784
+ },
785
+ updateBalance: (namespace) => {
786
+ const address = this.getAddress(namespace);
787
+ const caipNetwork = this.getCaipNetwork(namespace);
788
+ if (!caipNetwork || !address) {
789
+ return;
790
+ }
791
+ this.updateNativeBalance(address, caipNetwork?.id, namespace);
792
+ }
793
+ };
794
+ ConnectionController.setClient(this.connectionControllerClient);
795
+ }
796
+ async onConnectExternal(params) {
797
+ const activeChain = ChainController.state.activeChain;
798
+ const namespace = params.chain || activeChain;
799
+ const adapter = this.getAdapter(namespace);
800
+ let shouldUpdateNetwork = true;
801
+ if (params.type === UtilConstantsUtil.CONNECTOR_TYPE_AUTH) {
802
+ const authNamespaces = ConstantsUtil.AUTH_CONNECTOR_SUPPORTED_CHAINS;
803
+ const hasConnectedAuthNamespace = authNamespaces.some(namespace => ConnectorController.getConnectorId(namespace) === ConstantsUtil.CONNECTOR_ID.AUTH);
804
+ if (hasConnectedAuthNamespace && params.chain !== activeChain) {
805
+ shouldUpdateNetwork = false;
806
+ }
807
+ }
808
+ if (params.chain && params.chain !== activeChain && !params.caipNetwork) {
809
+ const toConnectNetwork = this.getCaipNetworks().find(network => network.chainNamespace === params.chain);
810
+ if (toConnectNetwork && shouldUpdateNetwork) {
811
+ this.setCaipNetwork(toConnectNetwork);
812
+ }
813
+ }
814
+ if (!namespace) {
815
+ throw new Error('connectExternal: namespace not found');
816
+ }
817
+ if (!adapter) {
818
+ throw new Error('connectExternal: adapter not found');
819
+ }
820
+ const fallbackCaipNetwork = this.getCaipNetwork(namespace);
821
+ const caipNetworkToUse = params.caipNetwork || fallbackCaipNetwork;
822
+ const res = await adapter.connect({
823
+ id: params.id,
824
+ address: params.address,
825
+ info: params.info,
826
+ type: params.type,
827
+ provider: params.provider,
828
+ socialUri: params.socialUri,
829
+ chainId: params.caipNetwork?.id || fallbackCaipNetwork?.id,
830
+ rpcUrl: params.caipNetwork?.rpcUrls?.default?.http?.[0] ||
831
+ fallbackCaipNetwork?.rpcUrls?.default?.http?.[0]
832
+ });
833
+ if (!res) {
834
+ return undefined;
835
+ }
836
+ StorageUtil.addConnectedNamespace(namespace);
837
+ this.syncProvider({ ...res, chainNamespace: namespace });
838
+ this.setStatus('connected', namespace);
839
+ this.syncConnectedWalletInfo(namespace);
840
+ StorageUtil.removeDisconnectedConnectorId(params.id, namespace);
841
+ return { address: res.address, connectedCaipNetwork: caipNetworkToUse };
842
+ }
843
+ async connectInactiveNamespaces(params, connectResult) {
844
+ const isConnectingToAuth = params.type === UtilConstantsUtil.CONNECTOR_TYPE_AUTH;
845
+ const otherAuthNamespaces = HelpersUtil.getOtherAuthNamespaces(connectResult?.connectedCaipNetwork?.chainNamespace);
846
+ const activeCaipNetwork = ChainController.state.activeCaipNetwork;
847
+ const activeAdapter = this.getAdapter(activeCaipNetwork?.chainNamespace);
848
+ if (isConnectingToAuth) {
849
+ await Promise.all(otherAuthNamespaces.map(async (ns) => {
850
+ try {
851
+ const provider = ProviderController.getProvider(ns);
852
+ const caipNetworkToUse = this.getCaipNetwork(ns);
853
+ const adapter = this.getAdapter(ns);
854
+ const res = await adapter?.connect({
855
+ ...params,
856
+ provider,
857
+ socialUri: undefined,
858
+ chainId: caipNetworkToUse?.id,
859
+ rpcUrl: caipNetworkToUse?.rpcUrls?.default?.http?.[0]
860
+ });
861
+ if (res) {
862
+ StorageUtil.addConnectedNamespace(ns);
863
+ StorageUtil.removeDisconnectedConnectorId(params.id, ns);
864
+ this.setStatus('connected', ns);
865
+ this.syncConnectedWalletInfo(ns);
866
+ }
867
+ }
868
+ catch (error) {
869
+ AlertController.warn(ErrorUtil.ALERT_WARNINGS.INACTIVE_NAMESPACE_NOT_CONNECTED.displayMessage, ErrorUtil.ALERT_WARNINGS.INACTIVE_NAMESPACE_NOT_CONNECTED.debugMessage(ns, error instanceof Error ? error.message : undefined), ErrorUtil.ALERT_WARNINGS.INACTIVE_NAMESPACE_NOT_CONNECTED.code);
870
+ }
871
+ }));
872
+ // Make the secure site back to current network after reconnecting the other namespaces
873
+ if (activeCaipNetwork) {
874
+ await activeAdapter?.switchNetwork({
875
+ caipNetwork: activeCaipNetwork
876
+ });
877
+ }
878
+ }
879
+ }
880
+ getApprovedCaipNetworksData() {
881
+ const providerType = ProviderController.getProviderId(ChainController.state.activeChain);
882
+ if (providerType === UtilConstantsUtil.CONNECTOR_TYPE_WALLET_CONNECT) {
883
+ const namespaces = this.universalProvider?.session?.namespaces;
884
+ return {
885
+ /*
886
+ * MetaMask Wallet only returns 1 namespace in the session object. This makes it imposible
887
+ * to switch to other networks. Setting supportsAllNetworks to true for MetaMask Wallet
888
+ * will make it possible to switch to other networks.
889
+ */
890
+ supportsAllNetworks: this.universalProvider?.session?.peer?.metadata.name === 'MetaMask Wallet',
891
+ approvedCaipNetworkIds: this.getChainsFromNamespaces(namespaces)
892
+ };
893
+ }
894
+ return { supportsAllNetworks: true, approvedCaipNetworkIds: [] };
895
+ }
896
+ async switchCaipNetwork(caipNetwork) {
897
+ const networkNamespace = caipNetwork.chainNamespace;
898
+ const namespaceAddress = this.getAddressByChainNamespace(caipNetwork.chainNamespace);
899
+ if (namespaceAddress) {
900
+ const providerType = ProviderController.getProviderId(networkNamespace);
901
+ if (caipNetwork.chainNamespace === ChainController.state.activeChain) {
902
+ const adapter = this.getAdapter(networkNamespace);
903
+ await adapter?.switchNetwork({ caipNetwork });
904
+ }
905
+ else {
906
+ this.setCaipNetwork(caipNetwork);
907
+ if (providerType === UtilConstantsUtil.CONNECTOR_TYPE_WALLET_CONNECT) {
908
+ this.syncWalletConnectAccount();
909
+ }
910
+ else {
911
+ const address = this.getAddressByChainNamespace(networkNamespace);
912
+ if (address) {
913
+ this.syncAccount({
914
+ address,
915
+ chainId: caipNetwork.id,
916
+ chainNamespace: networkNamespace
917
+ });
918
+ }
919
+ }
920
+ }
921
+ }
922
+ else {
923
+ this.setCaipNetwork(caipNetwork);
924
+ }
925
+ }
926
+ getChainsFromNamespaces(namespaces = {}) {
927
+ return Object.values(namespaces).flatMap((namespace) => {
928
+ const chains = (namespace.chains || []);
929
+ const accountsChains = namespace.accounts.map(account => {
930
+ const { chainId, chainNamespace } = ParseUtil.parseCaipAddress(account);
931
+ return `${chainNamespace}:${chainId}`;
932
+ });
933
+ return Array.from(new Set([...chains, ...accountsChains]));
934
+ });
935
+ }
936
+ // -- Adapter Initialization ---------------------------------------------------
937
+ createAdapters(blueprints) {
938
+ this.createClients();
939
+ return this.chainNamespaces.reduce((adapters, namespace) => {
940
+ const blueprint = blueprints?.find(b => b.namespace === namespace);
941
+ if (blueprint) {
942
+ blueprint.construct({
943
+ namespace,
944
+ projectId: this.options?.projectId,
945
+ networks: this.caipNetworks?.filter(({ chainNamespace }) => chainNamespace === namespace)
946
+ });
947
+ adapters[namespace] = blueprint;
948
+ }
949
+ else {
950
+ adapters[namespace] = new UniversalAdapter({
951
+ namespace,
952
+ networks: this.getCaipNetworks()
953
+ });
954
+ }
955
+ return adapters;
956
+ // eslint-disable-next-line @typescript-eslint/prefer-reduce-type-parameter
957
+ }, {});
958
+ }
959
+ async initChainAdapter(namespace) {
960
+ this.onConnectors(namespace);
961
+ this.listenAdapter(namespace);
962
+ const adapter = this.getAdapter(namespace);
963
+ if (!adapter) {
964
+ throw new Error('adapter not found');
965
+ }
966
+ await adapter.syncConnectors();
967
+ await this.createUniversalProviderForAdapter(namespace);
968
+ }
969
+ async initChainAdapters() {
970
+ await Promise.all(this.chainNamespaces.map(async (namespace) => {
971
+ await this.initChainAdapter(namespace);
972
+ }));
973
+ this.initAdapterController();
974
+ }
975
+ onConnectors(chainNamespace) {
976
+ const adapter = this.getAdapter(chainNamespace);
977
+ adapter?.on('connectors', this.setConnectors.bind(this));
978
+ }
979
+ listenAdapter(chainNamespace) {
980
+ const adapter = this.getAdapter(chainNamespace);
981
+ if (!adapter) {
982
+ return;
983
+ }
984
+ const connectionStatus = StorageUtil.getConnectionStatus();
985
+ if (OptionsController.state.enableReconnect === false) {
986
+ this.setStatus('disconnected', chainNamespace);
987
+ }
988
+ else if (connectionStatus === 'connected') {
989
+ this.setStatus('connecting', chainNamespace);
990
+ }
991
+ else if (connectionStatus === 'disconnected') {
992
+ /*
993
+ * Address cache is kept after disconnecting from the wallet
994
+ * but should be cleared if appkit is launched in disconnected state
995
+ */
996
+ StorageUtil.clearAddressCache();
997
+ this.setStatus(connectionStatus, chainNamespace);
998
+ }
999
+ else {
1000
+ this.setStatus(connectionStatus, chainNamespace);
1001
+ }
1002
+ adapter.on('switchNetwork', ({ address, chainId }) => {
1003
+ const caipNetwork = this.getCaipNetworks().find(n => n.id.toString() === chainId.toString() ||
1004
+ n.caipNetworkId.toString() === chainId.toString());
1005
+ const isSameNamespace = ChainController.state.activeChain === chainNamespace;
1006
+ const accountAddress = ChainController.state.chains.get(chainNamespace)?.accountState?.address;
1007
+ if (caipNetwork) {
1008
+ const account = isSameNamespace && address ? address : accountAddress;
1009
+ if (account) {
1010
+ this.syncAccount({ address: account, chainId: caipNetwork.id, chainNamespace });
1011
+ }
1012
+ }
1013
+ else {
1014
+ this.setUnsupportedNetwork(chainId);
1015
+ }
1016
+ });
1017
+ adapter.on('disconnect', () => {
1018
+ const isMultiWallet = this.remoteFeatures.multiWallet;
1019
+ const allConnections = Array.from(ConnectionController.state.connections.values()).flat();
1020
+ this.onDisconnectNamespace({
1021
+ chainNamespace,
1022
+ closeModal: !isMultiWallet || allConnections.length === 0
1023
+ });
1024
+ });
1025
+ adapter.on('connections', connections => {
1026
+ this.setConnections(connections, chainNamespace);
1027
+ });
1028
+ adapter.on('pendingTransactions', () => {
1029
+ const address = this.getAddress(chainNamespace);
1030
+ const activeCaipNetwork = ChainController.state.activeCaipNetwork;
1031
+ if (!address || !activeCaipNetwork?.id) {
1032
+ return;
1033
+ }
1034
+ this.updateNativeBalance(address, activeCaipNetwork.id, activeCaipNetwork.chainNamespace);
1035
+ });
1036
+ adapter.on('accountChanged', ({ address, chainId, connector }) => {
1037
+ this.handlePreviousConnectorConnection(connector);
1038
+ const isActiveChain = ChainController.state.activeChain === chainNamespace;
1039
+ if (connector?.provider) {
1040
+ this.syncProvider({
1041
+ id: connector.id,
1042
+ type: connector.type,
1043
+ provider: connector?.provider,
1044
+ chainNamespace
1045
+ });
1046
+ this.syncConnectedWalletInfo(chainNamespace);
1047
+ }
1048
+ const namespaceNetworkId = ChainController.getNetworkData(chainNamespace)?.caipNetwork?.id;
1049
+ const syncAccountChainId = chainId || namespaceNetworkId;
1050
+ if (isActiveChain && syncAccountChainId) {
1051
+ this.syncAccount({
1052
+ address,
1053
+ chainId: syncAccountChainId,
1054
+ chainNamespace
1055
+ });
1056
+ }
1057
+ else if (!isActiveChain && syncAccountChainId) {
1058
+ this.syncAccountInfo(address, syncAccountChainId, chainNamespace);
1059
+ this.syncBalance({ address, chainId: syncAccountChainId, chainNamespace });
1060
+ }
1061
+ else {
1062
+ this.syncAccountInfo(address, chainId, chainNamespace);
1063
+ }
1064
+ StorageUtil.addConnectedNamespace(chainNamespace);
1065
+ });
1066
+ }
1067
+ /**
1068
+ * Checks the incoming connector and handles the previous connection in the connector's namespace, and if necessary (i.e multi-wallet is disabled) disconnects the previous connector
1069
+ * @param connector
1070
+ */
1071
+ async handlePreviousConnectorConnection(connector) {
1072
+ const namespace = connector?.chain;
1073
+ const newConnectorId = connector?.id;
1074
+ const currentConnectorId = ConnectorController.getConnectorId(namespace);
1075
+ const isMultiWalletEnabled = OptionsController.state.remoteFeatures?.multiWallet;
1076
+ const hasNewConnectorConnected = currentConnectorId !== newConnectorId;
1077
+ const shouldDisconnectPreviousConnector = namespace &&
1078
+ newConnectorId &&
1079
+ currentConnectorId &&
1080
+ hasNewConnectorConnected &&
1081
+ !isMultiWalletEnabled;
1082
+ try {
1083
+ if (shouldDisconnectPreviousConnector) {
1084
+ await ConnectionController.disconnect({ id: currentConnectorId, namespace });
1085
+ }
1086
+ }
1087
+ catch (error) {
1088
+ console.warn('Error disconnecting previous connector', error);
1089
+ }
1090
+ }
1091
+ async createUniversalProviderForAdapter(chainNamespace) {
1092
+ await this.getUniversalProvider();
1093
+ if (this.universalProvider) {
1094
+ await this.chainAdapters?.[chainNamespace]?.setUniversalProvider?.(this.universalProvider);
1095
+ }
1096
+ }
1097
+ // -- Connection Sync ---------------------------------------------------
1098
+ async syncExistingConnection() {
1099
+ await Promise.allSettled(this.chainNamespaces.map(namespace => this.syncNamespaceConnection(namespace)));
1100
+ }
1101
+ async unSyncExistingConnection() {
1102
+ try {
1103
+ await Promise.allSettled(this.chainNamespaces.map(namespace => ConnectionController.disconnect({ namespace, initialDisconnect: true })));
1104
+ }
1105
+ catch (error) {
1106
+ // eslint-disable-next-line no-console
1107
+ console.error('Error disconnecting existing connections:', error);
1108
+ }
1109
+ }
1110
+ async reconnectWalletConnect() {
1111
+ await this.syncWalletConnectAccount();
1112
+ const address = this.getAddress();
1113
+ if (!this.getCaipAddress()) {
1114
+ StorageUtil.deleteRecentWallet();
1115
+ }
1116
+ const recentWallet = StorageUtil.getRecentWallet();
1117
+ EventsController.sendEvent({
1118
+ type: 'track',
1119
+ event: 'CONNECT_SUCCESS',
1120
+ address,
1121
+ properties: {
1122
+ method: CoreHelperUtil.isMobile() ? 'mobile' : 'qrcode',
1123
+ name: recentWallet?.name || 'Unknown',
1124
+ reconnect: true,
1125
+ view: RouterController.state.view,
1126
+ walletRank: recentWallet?.order
1127
+ }
1128
+ });
1129
+ }
1130
+ async syncNamespaceConnection(namespace) {
1131
+ try {
1132
+ if (namespace === ConstantsUtil.CHAIN.EVM && CoreHelperUtil.isSafeApp()) {
1133
+ ConnectorController.setConnectorId(ConstantsUtil.CONNECTOR_ID.SAFE, namespace);
1134
+ }
1135
+ const connectorId = ConnectorController.getConnectorId(namespace);
1136
+ this.setStatus('connecting', namespace);
1137
+ switch (connectorId) {
1138
+ case ConstantsUtil.CONNECTOR_ID.WALLET_CONNECT:
1139
+ await this.reconnectWalletConnect();
1140
+ break;
1141
+ case ConstantsUtil.CONNECTOR_ID.AUTH:
1142
+ // Handled during initialization of adapters' auth provider
1143
+ break;
1144
+ default:
1145
+ await this.syncAdapterConnection(namespace);
1146
+ }
1147
+ }
1148
+ catch (err) {
1149
+ console.warn("AppKit couldn't sync existing connection", err);
1150
+ this.setStatus('disconnected', namespace);
1151
+ }
1152
+ }
1153
+ onDisconnectNamespace(options) {
1154
+ const { chainNamespace, closeModal } = options || {};
1155
+ ChainController.resetAccount(chainNamespace);
1156
+ ChainController.resetNetwork(chainNamespace);
1157
+ StorageUtil.removeConnectedNamespace(chainNamespace);
1158
+ const namespaces = Array.from(ChainController.state.chains.keys());
1159
+ const namespacesToDisconnect = chainNamespace ? [chainNamespace] : namespaces;
1160
+ namespacesToDisconnect.forEach(ns => StorageUtil.addDisconnectedConnectorId(ConnectorController.getConnectorId(ns) || '', ns));
1161
+ ConnectorController.removeConnectorId(chainNamespace);
1162
+ ProviderController.resetChain(chainNamespace);
1163
+ this.setUser(null, chainNamespace);
1164
+ this.setStatus('disconnected', chainNamespace);
1165
+ this.setConnectedWalletInfo(null, chainNamespace);
1166
+ if (closeModal !== false) {
1167
+ ModalController.close();
1168
+ }
1169
+ }
1170
+ async syncAdapterConnections() {
1171
+ await Promise.allSettled(this.chainNamespaces.map(namespace => {
1172
+ const adapter = this.getAdapter(namespace);
1173
+ const caipAddress = this.getCaipAddress(namespace);
1174
+ const caipNetwork = this.getCaipNetwork(namespace);
1175
+ return adapter?.syncConnections({
1176
+ connectToFirstConnector: !caipAddress,
1177
+ caipNetwork
1178
+ });
1179
+ }));
1180
+ }
1181
+ async syncAdapterConnection(namespace) {
1182
+ const adapter = this.getAdapter(namespace);
1183
+ const caipNetwork = this.getCaipNetwork(namespace);
1184
+ const connectorId = ConnectorController.getConnectorId(namespace);
1185
+ const connectors = ConnectorController.getConnectors(namespace);
1186
+ const connector = connectors.find(c => c.id === connectorId);
1187
+ try {
1188
+ if (!adapter || !connector) {
1189
+ throw new Error(`Adapter or connector not found for namespace ${namespace}`);
1190
+ }
1191
+ if (!caipNetwork?.id) {
1192
+ throw new Error('CaipNetwork not found');
1193
+ }
1194
+ const connection = await adapter?.syncConnection({
1195
+ namespace,
1196
+ id: connector.id,
1197
+ chainId: caipNetwork.id,
1198
+ rpcUrl: caipNetwork?.rpcUrls?.default?.http?.[0]
1199
+ });
1200
+ if (connection) {
1201
+ this.syncProvider({ ...connection, chainNamespace: namespace });
1202
+ await this.syncAccount({ ...connection, chainNamespace: namespace });
1203
+ this.setStatus('connected', namespace);
1204
+ EventsController.sendEvent({
1205
+ type: 'track',
1206
+ event: 'CONNECT_SUCCESS',
1207
+ address: connection.address,
1208
+ properties: {
1209
+ method: 'browser',
1210
+ name: connector.info?.name || connector.name || 'Unknown',
1211
+ reconnect: true,
1212
+ view: RouterController.state.view,
1213
+ walletRank: connector?.explorerWallet?.order
1214
+ }
1215
+ });
1216
+ }
1217
+ else {
1218
+ this.setStatus('disconnected', namespace);
1219
+ }
1220
+ }
1221
+ catch (e) {
1222
+ this.onDisconnectNamespace({ chainNamespace: namespace, closeModal: false });
1223
+ }
1224
+ }
1225
+ async syncWalletConnectAccount() {
1226
+ const sessionNamespaces = Object.keys(this.universalProvider?.session?.namespaces || {});
1227
+ const syncTasks = this.chainNamespaces.map(async (chainNamespace) => {
1228
+ const adapter = this.getAdapter(chainNamespace);
1229
+ if (!adapter) {
1230
+ return;
1231
+ }
1232
+ const namespaceAccounts = this.universalProvider?.session?.namespaces?.[chainNamespace]?.accounts || [];
1233
+ // We try and find the address for this network in the session object.
1234
+ const activeChainId = ChainController.state.activeCaipNetwork?.id;
1235
+ const sessionAddress = namespaceAccounts.find(account => {
1236
+ const { chainId } = ParseUtil.parseCaipAddress(account);
1237
+ return chainId === activeChainId?.toString();
1238
+ }) || namespaceAccounts[0];
1239
+ if (sessionAddress) {
1240
+ const caipAddress = ParseUtil.validateCaipAddress(sessionAddress);
1241
+ const { chainId, address } = ParseUtil.parseCaipAddress(caipAddress);
1242
+ ProviderController.setProviderId(chainNamespace, UtilConstantsUtil.CONNECTOR_TYPE_WALLET_CONNECT);
1243
+ if (this.caipNetworks &&
1244
+ ChainController.state.activeCaipNetwork &&
1245
+ adapter.namespace !== ConstantsUtil.CHAIN.EVM) {
1246
+ const provider = adapter.getWalletConnectProvider({
1247
+ caipNetworks: this.getCaipNetworks(),
1248
+ provider: this.universalProvider,
1249
+ activeCaipNetwork: ChainController.state.activeCaipNetwork
1250
+ });
1251
+ ProviderController.setProvider(chainNamespace, provider);
1252
+ }
1253
+ else {
1254
+ ProviderController.setProvider(chainNamespace, this.universalProvider);
1255
+ }
1256
+ ConnectorController.setConnectorId(ConstantsUtil.CONNECTOR_ID.WALLET_CONNECT, chainNamespace);
1257
+ StorageUtil.addConnectedNamespace(chainNamespace);
1258
+ await this.syncAccount({
1259
+ address,
1260
+ chainId,
1261
+ chainNamespace
1262
+ });
1263
+ }
1264
+ else if (sessionNamespaces.includes(chainNamespace)) {
1265
+ this.setStatus('disconnected', chainNamespace);
1266
+ }
1267
+ const data = this.getApprovedCaipNetworksData();
1268
+ this.syncConnectedWalletInfo(chainNamespace);
1269
+ ChainController.setApprovedCaipNetworksData(chainNamespace, {
1270
+ approvedCaipNetworkIds: data.approvedCaipNetworkIds,
1271
+ supportsAllNetworks: data.supportsAllNetworks
1272
+ });
1273
+ });
1274
+ await Promise.all(syncTasks);
1275
+ }
1276
+ syncProvider({ type, provider, id, chainNamespace }) {
1277
+ ProviderController.setProviderId(chainNamespace, type);
1278
+ ProviderController.setProvider(chainNamespace, provider);
1279
+ ConnectorController.setConnectorId(id, chainNamespace);
1280
+ }
1281
+ async syncAccount(params) {
1282
+ const isActiveNamespace = params.chainNamespace === ChainController.state.activeChain;
1283
+ const networkOfChain = ChainController.getCaipNetworkByNamespace(params.chainNamespace, params.chainId);
1284
+ const { address, chainId, chainNamespace } = params;
1285
+ const { chainId: activeChainId } = StorageUtil.getActiveNetworkProps();
1286
+ const chainIdToUse = networkOfChain?.id || activeChainId;
1287
+ const isUnsupportedNetwork = ChainController.state.activeCaipNetwork?.name === ConstantsUtil.UNSUPPORTED_NETWORK_NAME;
1288
+ const shouldSupportAllNetworks = ChainController.getNetworkProp('supportsAllNetworks', chainNamespace);
1289
+ this.setStatus('connected', chainNamespace);
1290
+ if (isUnsupportedNetwork && !shouldSupportAllNetworks) {
1291
+ return;
1292
+ }
1293
+ if (chainIdToUse) {
1294
+ let caipNetwork = this.getCaipNetworks().find(n => n.id.toString() === chainIdToUse.toString());
1295
+ let fallbackCaipNetwork = this.getCaipNetworks().find(n => n.chainNamespace === chainNamespace);
1296
+ // If doesn't support all networks, we need to use approved networks
1297
+ if (!shouldSupportAllNetworks && !caipNetwork && !fallbackCaipNetwork) {
1298
+ // Connection can be requested for a chain that is not supported by the wallet so we need to use approved networks here
1299
+ const caipNetworkIds = this.getApprovedCaipNetworkIds() || [];
1300
+ const caipNetworkId = caipNetworkIds.find(id => ParseUtil.parseCaipNetworkId(id)?.chainId === chainIdToUse.toString());
1301
+ const fallBackCaipNetworkId = caipNetworkIds.find(id => ParseUtil.parseCaipNetworkId(id)?.chainNamespace === chainNamespace);
1302
+ caipNetwork = this.getCaipNetworks().find(n => n.caipNetworkId === caipNetworkId);
1303
+ fallbackCaipNetwork = this.getCaipNetworks().find(n => n.caipNetworkId === fallBackCaipNetworkId ||
1304
+ // This is a workaround used in Solana network to support deprecated caipNetworkId
1305
+ ('deprecatedCaipNetworkId' in n && n.deprecatedCaipNetworkId === fallBackCaipNetworkId));
1306
+ }
1307
+ const network = caipNetwork || fallbackCaipNetwork;
1308
+ if (network?.chainNamespace === ChainController.state.activeChain) {
1309
+ // If the network is unsupported and the user doesn't allow unsupported chains, we show the unsupported chain UI
1310
+ if (OptionsController.state.enableNetworkSwitch &&
1311
+ !OptionsController.state.allowUnsupportedChain &&
1312
+ ChainController.state.activeCaipNetwork?.name === ConstantsUtil.UNSUPPORTED_NETWORK_NAME) {
1313
+ ChainController.showUnsupportedChainUI();
1314
+ }
1315
+ else {
1316
+ this.setCaipNetwork(network);
1317
+ }
1318
+ }
1319
+ else if (!isActiveNamespace) {
1320
+ if (networkOfChain) {
1321
+ this.setCaipNetworkOfNamespace(networkOfChain, chainNamespace);
1322
+ }
1323
+ }
1324
+ this.syncConnectedWalletInfo(chainNamespace);
1325
+ const currentAddress = this.getAddress(chainNamespace);
1326
+ if (!HelpersUtil.isLowerCaseMatch(address, currentAddress)) {
1327
+ this.syncAccountInfo(address, network?.id, chainNamespace);
1328
+ }
1329
+ if (isActiveNamespace) {
1330
+ await this.syncBalance({ address, chainId: network?.id, chainNamespace });
1331
+ }
1332
+ else {
1333
+ await this.syncBalance({ address, chainId: networkOfChain?.id, chainNamespace });
1334
+ }
1335
+ this.syncIdentity({
1336
+ address,
1337
+ chainId,
1338
+ chainNamespace
1339
+ });
1340
+ }
1341
+ }
1342
+ async syncAccountInfo(address, chainId, chainNamespace) {
1343
+ const caipAddress = this.getCaipAddress(chainNamespace);
1344
+ const newChainId = chainId || caipAddress?.split(':')[1];
1345
+ if (!newChainId) {
1346
+ return;
1347
+ }
1348
+ const newCaipAddress = `${chainNamespace}:${newChainId}:${address}`;
1349
+ this.setCaipAddress(newCaipAddress, chainNamespace, true);
1350
+ await this.syncIdentity({
1351
+ address,
1352
+ chainId: newChainId,
1353
+ chainNamespace
1354
+ });
1355
+ }
1356
+ async syncReownName(address, chainNamespace) {
1357
+ try {
1358
+ const registeredWcNames = await this.getReownName(address);
1359
+ if (registeredWcNames[0]) {
1360
+ const wcName = registeredWcNames[0];
1361
+ this.setProfileName(wcName.name, chainNamespace);
1362
+ }
1363
+ else {
1364
+ this.setProfileName(null, chainNamespace);
1365
+ }
1366
+ }
1367
+ catch {
1368
+ this.setProfileName(null, chainNamespace);
1369
+ }
1370
+ }
1371
+ syncConnectedWalletInfo(chainNamespace) {
1372
+ const connectorId = ConnectorController.getConnectorId(chainNamespace);
1373
+ const providerType = ProviderController.getProviderId(chainNamespace);
1374
+ if (providerType === UtilConstantsUtil.CONNECTOR_TYPE_ANNOUNCED ||
1375
+ providerType === UtilConstantsUtil.CONNECTOR_TYPE_INJECTED) {
1376
+ if (connectorId) {
1377
+ const connectors = this.getConnectors();
1378
+ const connector = connectors.find(c => {
1379
+ const isConnectorId = c.id === connectorId;
1380
+ const isRdns = c.info?.rdns === connectorId;
1381
+ const hasMultiChainConnector = c.connectors?.some(_c => _c.id === connectorId || _c.info?.rdns === connectorId);
1382
+ return isConnectorId || isRdns || Boolean(hasMultiChainConnector);
1383
+ });
1384
+ if (connector) {
1385
+ const { info, name, imageUrl } = connector;
1386
+ const icon = imageUrl || this.getConnectorImage(connector);
1387
+ this.setConnectedWalletInfo({ name, icon, ...info }, chainNamespace);
1388
+ }
1389
+ }
1390
+ }
1391
+ else if (providerType === UtilConstantsUtil.CONNECTOR_TYPE_WALLET_CONNECT) {
1392
+ const provider = ProviderController.getProvider(chainNamespace);
1393
+ if (provider?.session) {
1394
+ this.setConnectedWalletInfo({
1395
+ ...provider.session.peer.metadata,
1396
+ name: provider.session.peer.metadata.name,
1397
+ icon: provider.session.peer.metadata.icons?.[0]
1398
+ }, chainNamespace);
1399
+ }
1400
+ }
1401
+ else if (connectorId) {
1402
+ if (connectorId === ConstantsUtil.CONNECTOR_ID.COINBASE_SDK ||
1403
+ connectorId === ConstantsUtil.CONNECTOR_ID.COINBASE) {
1404
+ const connector = this.getConnectors().find(c => c.id === connectorId);
1405
+ const name = connector?.name || 'Coinbase Wallet';
1406
+ const icon = connector?.imageUrl || this.getConnectorImage(connector);
1407
+ const info = connector?.info;
1408
+ this.setConnectedWalletInfo({
1409
+ ...info,
1410
+ name,
1411
+ icon
1412
+ }, chainNamespace);
1413
+ }
1414
+ }
1415
+ }
1416
+ async syncBalance(params) {
1417
+ const caipNetwork = NetworkUtil.getNetworksByNamespace(this.getCaipNetworks(), params.chainNamespace).find(n => n.id.toString() === params.chainId?.toString());
1418
+ if (!caipNetwork || !params.chainId) {
1419
+ return;
1420
+ }
1421
+ await this.updateNativeBalance(params.address, params.chainId, params.chainNamespace);
1422
+ }
1423
+ async ready() {
1424
+ await this.readyPromise;
1425
+ }
1426
+ async updateNativeBalance(address, chainId, namespace) {
1427
+ const adapter = this.getAdapter(namespace);
1428
+ const caipNetwork = ChainController.getCaipNetworkByNamespace(namespace, chainId);
1429
+ if (adapter) {
1430
+ const balance = await adapter.getBalance({
1431
+ address,
1432
+ chainId,
1433
+ caipNetwork,
1434
+ tokens: this.options.tokens
1435
+ });
1436
+ this.setBalance(balance.balance, balance.symbol, namespace);
1437
+ return balance;
1438
+ }
1439
+ return undefined;
1440
+ }
1441
+ // -- Universal Provider ---------------------------------------------------
1442
+ async initializeUniversalAdapter() {
1443
+ const logger = LoggerUtil.createLogger((error, ...args) => {
1444
+ if (error) {
1445
+ this.handleAlertError(error);
1446
+ }
1447
+ // eslint-disable-next-line no-console
1448
+ console.error(...args);
1449
+ });
1450
+ const universalProviderOptions = {
1451
+ projectId: this.options?.projectId,
1452
+ metadata: {
1453
+ name: this.options?.metadata ? this.options?.metadata.name : '',
1454
+ description: this.options?.metadata ? this.options?.metadata.description : '',
1455
+ url: this.options?.metadata ? this.options?.metadata.url : '',
1456
+ icons: this.options?.metadata ? this.options?.metadata.icons : ['']
1457
+ },
1458
+ logger
1459
+ };
1460
+ OptionsController.setManualWCControl(Boolean(this.options?.manualWCControl));
1461
+ this.universalProvider =
1462
+ this.options.universalProvider ?? (await UniversalProvider.init(universalProviderOptions));
1463
+ const originalDisconnect = this.universalProvider.disconnect.bind(this.universalProvider);
1464
+ this.universalProvider.disconnect = async () => {
1465
+ try {
1466
+ return await originalDisconnect();
1467
+ }
1468
+ catch (error) {
1469
+ if (error instanceof Error) {
1470
+ const isAlreadyDisconnected = error.message.includes('Missing or invalid. Record was recently deleted');
1471
+ if (isAlreadyDisconnected) {
1472
+ return undefined;
1473
+ }
1474
+ }
1475
+ throw error;
1476
+ }
1477
+ };
1478
+ if (OptionsController.state.enableReconnect === false && this.universalProvider.session) {
1479
+ await this.universalProvider.disconnect();
1480
+ }
1481
+ this.listenWalletConnect();
1482
+ }
1483
+ listenWalletConnect() {
1484
+ if (this.universalProvider) {
1485
+ this.chainNamespaces.forEach(namespace => {
1486
+ WcHelpersUtil.listenWcProvider({
1487
+ universalProvider: this.universalProvider,
1488
+ namespace,
1489
+ onDisplayUri: uri => {
1490
+ ConnectionController.setUri(uri);
1491
+ },
1492
+ onConnect: accounts => {
1493
+ const { address } = CoreHelperUtil.getAccount(accounts[0]);
1494
+ ConnectionController.finalizeWcConnection(address);
1495
+ },
1496
+ onDisconnect: () => {
1497
+ if (ChainController.state.noAdapters) {
1498
+ this.resetAccount(namespace);
1499
+ }
1500
+ ConnectionController.resetWcConnection();
1501
+ },
1502
+ onChainChanged: chainId => {
1503
+ const activeNamespace = ChainController.state.activeChain;
1504
+ const isCurrentConnectorWalletConnect = activeNamespace &&
1505
+ ConnectorController.state.activeConnectorIds[activeNamespace] ===
1506
+ ConstantsUtil.CONNECTOR_ID.WALLET_CONNECT;
1507
+ if (activeNamespace === namespace &&
1508
+ (ChainController.state.noAdapters || isCurrentConnectorWalletConnect)) {
1509
+ const caipNetwork = this.getCaipNetworks().find(n => n.id.toString() === chainId.toString() ||
1510
+ n.caipNetworkId.toString() === chainId.toString());
1511
+ const currentCaipNetwork = this.getCaipNetwork();
1512
+ if (!caipNetwork) {
1513
+ this.setUnsupportedNetwork(chainId);
1514
+ return;
1515
+ }
1516
+ if (currentCaipNetwork?.id.toString() !== caipNetwork?.id.toString() &&
1517
+ currentCaipNetwork?.chainNamespace === caipNetwork?.chainNamespace) {
1518
+ this.setCaipNetwork(caipNetwork);
1519
+ }
1520
+ }
1521
+ },
1522
+ onAccountsChanged: accounts => {
1523
+ const activeNamespace = ChainController.state.activeChain;
1524
+ const isCurrentConnectorWalletConnect = activeNamespace &&
1525
+ ConnectorController.state.activeConnectorIds[activeNamespace] ===
1526
+ ConstantsUtil.CONNECTOR_ID.WALLET_CONNECT;
1527
+ if (activeNamespace === namespace &&
1528
+ (ChainController.state.noAdapters || isCurrentConnectorWalletConnect)) {
1529
+ const account = accounts?.[0];
1530
+ if (account) {
1531
+ this.syncAccount({
1532
+ address: account.address,
1533
+ chainId: account.chainId,
1534
+ chainNamespace: account.chainNamespace
1535
+ });
1536
+ }
1537
+ }
1538
+ }
1539
+ });
1540
+ });
1541
+ }
1542
+ }
1543
+ createUniversalProvider() {
1544
+ if (!this.universalProviderInitPromise &&
1545
+ CoreHelperUtil.isClient() &&
1546
+ this.options?.projectId) {
1547
+ this.universalProviderInitPromise = this.initializeUniversalAdapter();
1548
+ }
1549
+ return this.universalProviderInitPromise;
1550
+ }
1551
+ async getUniversalProvider() {
1552
+ if (!this.universalProvider) {
1553
+ try {
1554
+ await this.createUniversalProvider();
1555
+ }
1556
+ catch (err) {
1557
+ EventsController.sendEvent({
1558
+ type: 'error',
1559
+ event: 'INTERNAL_SDK_ERROR',
1560
+ properties: {
1561
+ errorType: 'UniversalProviderInitError',
1562
+ errorMessage: err instanceof Error ? err.message : 'Unknown',
1563
+ uncaught: false
1564
+ }
1565
+ });
1566
+ // eslint-disable-next-line no-console
1567
+ console.error('AppKit:getUniversalProvider - Cannot create provider', err);
1568
+ }
1569
+ }
1570
+ return this.universalProvider;
1571
+ }
1572
+ getDisabledCaipNetworks() {
1573
+ const approvedCaipNetworkIds = ChainController.getAllApprovedCaipNetworkIds();
1574
+ const requestedCaipNetworks = ChainController.getAllRequestedCaipNetworks();
1575
+ const sortedNetworks = CoreHelperUtil.sortRequestedNetworks(approvedCaipNetworkIds, requestedCaipNetworks);
1576
+ return sortedNetworks.filter(network => ChainController.isCaipNetworkDisabled(network));
1577
+ }
1578
+ // - Utils -------------------------------------------------------------------
1579
+ handleAlertError(error) {
1580
+ const matchedUniversalProviderError = Object.entries(ErrorUtil.UniversalProviderErrors).find(([, { message }]) => error.message.includes(message));
1581
+ const [errorKey, errorValue] = matchedUniversalProviderError ?? [];
1582
+ const { message, alertErrorKey } = errorValue ?? {};
1583
+ if (errorKey && message && !this.reportedAlertErrors[errorKey]) {
1584
+ const alertError = ErrorUtil.ALERT_ERRORS[alertErrorKey];
1585
+ if (alertError) {
1586
+ AlertController.open(alertError, 'error');
1587
+ this.reportedAlertErrors[errorKey] = true;
1588
+ }
1589
+ }
1590
+ }
1591
+ getAdapter(namespace) {
1592
+ if (!namespace) {
1593
+ return undefined;
1594
+ }
1595
+ return this.chainAdapters?.[namespace];
1596
+ }
1597
+ createAdapter(blueprint) {
1598
+ if (!blueprint) {
1599
+ return;
1600
+ }
1601
+ const namespace = blueprint.namespace;
1602
+ if (!namespace) {
1603
+ return;
1604
+ }
1605
+ this.createClients();
1606
+ const adapterBlueprint = blueprint;
1607
+ adapterBlueprint.namespace = namespace;
1608
+ adapterBlueprint.construct({
1609
+ namespace,
1610
+ projectId: this.options?.projectId,
1611
+ networks: this.caipNetworks?.filter(({ chainNamespace }) => chainNamespace === namespace)
1612
+ });
1613
+ if (!this.chainNamespaces.includes(namespace)) {
1614
+ this.chainNamespaces.push(namespace);
1615
+ }
1616
+ if (this.chainAdapters) {
1617
+ this.chainAdapters[namespace] = adapterBlueprint;
1618
+ }
1619
+ }
1620
+ // -- Public -------------------------------------------------------------------
1621
+ async open(options) {
1622
+ await this.injectModalUi();
1623
+ if (options?.uri) {
1624
+ ConnectionController.setUri(options.uri);
1625
+ }
1626
+ const { isSwap, isSend } = this.toModalOptions();
1627
+ if (isSwap(options)) {
1628
+ return ModalController.open({
1629
+ ...options,
1630
+ data: { swap: options.arguments }
1631
+ });
1632
+ }
1633
+ else if (isSend(options)) {
1634
+ if (options.arguments) {
1635
+ return this.openSend(options.arguments);
1636
+ }
1637
+ }
1638
+ return ModalController.open(options);
1639
+ }
1640
+ async close() {
1641
+ await this.injectModalUi();
1642
+ ModalController.close();
1643
+ }
1644
+ setLoading(loading, namespace) {
1645
+ ModalController.setLoading(loading, namespace);
1646
+ }
1647
+ async disconnect(chainNamespace) {
1648
+ await ConnectionController.disconnect({ namespace: chainNamespace });
1649
+ }
1650
+ getSIWX() {
1651
+ return OptionsController.state.siwx;
1652
+ }
1653
+ // -- review these -------------------------------------------------------------------
1654
+ getError() {
1655
+ return '';
1656
+ }
1657
+ getChainId() {
1658
+ return ChainController.state.activeCaipNetwork?.id;
1659
+ }
1660
+ async switchNetwork(appKitNetwork, { throwOnFailure = false } = {}) {
1661
+ const network = this.getCaipNetworks().find(n => n.id === appKitNetwork.id);
1662
+ if (!network) {
1663
+ AlertController.open(ErrorUtil.ALERT_ERRORS.SWITCH_NETWORK_NOT_FOUND, 'error');
1664
+ return;
1665
+ }
1666
+ await ChainController.switchActiveNetwork(network, { throwOnFailure });
1667
+ }
1668
+ getWalletProvider() {
1669
+ return ChainController.state.activeChain
1670
+ ? ProviderController.state.providers[ChainController.state.activeChain]
1671
+ : null;
1672
+ }
1673
+ getWalletProviderType() {
1674
+ return ProviderController.getProviderId(ChainController.state.activeChain);
1675
+ }
1676
+ subscribeProviders(callback) {
1677
+ return ProviderController.subscribeProviders(callback);
1678
+ }
1679
+ getThemeMode() {
1680
+ return ThemeController.state.themeMode;
1681
+ }
1682
+ getThemeVariables() {
1683
+ return ThemeController.state.themeVariables;
1684
+ }
1685
+ setThemeMode(themeMode) {
1686
+ ThemeController.setThemeMode(themeMode);
1687
+ setColorTheme(ThemeController.state.themeMode);
1688
+ }
1689
+ setTermsConditionsUrl(termsConditionsUrl) {
1690
+ OptionsController.setTermsConditionsUrl(termsConditionsUrl);
1691
+ }
1692
+ setPrivacyPolicyUrl(privacyPolicyUrl) {
1693
+ OptionsController.setPrivacyPolicyUrl(privacyPolicyUrl);
1694
+ }
1695
+ setThemeVariables(themeVariables) {
1696
+ ThemeController.setThemeVariables(themeVariables);
1697
+ setThemeVariables(ThemeController.state.themeVariables);
1698
+ }
1699
+ subscribeTheme(callback) {
1700
+ return ThemeController.subscribe(callback);
1701
+ }
1702
+ subscribeConnections(callback) {
1703
+ if (!this.remoteFeatures.multiWallet) {
1704
+ AlertController.open(ConstantsUtil.REMOTE_FEATURES_ALERTS.MULTI_WALLET_NOT_ENABLED.DEFAULT, 'info');
1705
+ return () => undefined;
1706
+ }
1707
+ return ConnectionController.subscribe(callback);
1708
+ }
1709
+ getWalletInfo(namespace) {
1710
+ if (namespace) {
1711
+ return ChainController.state.chains.get(namespace)?.accountState?.connectedWalletInfo;
1712
+ }
1713
+ const accountData = ChainController.getAccountData();
1714
+ return accountData?.connectedWalletInfo;
1715
+ }
1716
+ getAccount(_namespace) {
1717
+ const namespace = _namespace || ChainController.state.activeChain;
1718
+ const authConnector = ConnectorController.getAuthConnector(namespace);
1719
+ const accountState = ChainController.getAccountData(namespace);
1720
+ const activeConnectorId = StorageUtil.getConnectedConnectorId(ChainController.state.activeChain);
1721
+ const connections = ConnectionController.getConnections(namespace);
1722
+ if (!namespace) {
1723
+ throw new Error('AppKit:getAccount - namespace is required');
1724
+ }
1725
+ const allAccounts = connections.flatMap(connection => connection.accounts.map(({ address, type, publicKey }) => CoreHelperUtil.createAccount(namespace, address, (type || 'eoa'), publicKey)));
1726
+ if (!accountState) {
1727
+ return undefined;
1728
+ }
1729
+ return {
1730
+ allAccounts,
1731
+ caipAddress: accountState.caipAddress,
1732
+ address: CoreHelperUtil.getPlainAddress(accountState.caipAddress),
1733
+ isConnected: Boolean(accountState.caipAddress),
1734
+ status: accountState.status,
1735
+ embeddedWalletInfo: authConnector && activeConnectorId === ConstantsUtil.CONNECTOR_ID.AUTH
1736
+ ? {
1737
+ user: accountState.user
1738
+ ? {
1739
+ ...accountState.user,
1740
+ /*
1741
+ * Getting the username from the chain controller works well for social logins,
1742
+ * but Farcaster uses a different connection flow and doesn't emit the username via events.
1743
+ * Since the username is stored in local storage before the chain controller updates,
1744
+ * it's safe to use the local storage value here.
1745
+ */
1746
+ username: StorageUtil.getConnectedSocialUsername()
1747
+ }
1748
+ : undefined,
1749
+ authProvider: accountState.socialProvider || 'email',
1750
+ accountType: getPreferredAccountType(namespace),
1751
+ isSmartAccountDeployed: Boolean(accountState.smartAccountDeployed)
1752
+ }
1753
+ : undefined
1754
+ };
1755
+ }
1756
+ subscribeAccount(callback, namespace) {
1757
+ const updateVal = () => {
1758
+ const account = this.getAccount(namespace);
1759
+ if (!account) {
1760
+ return;
1761
+ }
1762
+ callback(account);
1763
+ };
1764
+ if (namespace) {
1765
+ ChainController.subscribeChainProp('accountState', updateVal, namespace);
1766
+ }
1767
+ else {
1768
+ ChainController.subscribe(updateVal);
1769
+ }
1770
+ ConnectorController.subscribe(updateVal);
1771
+ }
1772
+ subscribeNetwork(callback) {
1773
+ return ChainController.subscribe(({ activeCaipNetwork }) => {
1774
+ callback({
1775
+ caipNetwork: activeCaipNetwork,
1776
+ chainId: activeCaipNetwork?.id,
1777
+ caipNetworkId: activeCaipNetwork?.caipNetworkId
1778
+ });
1779
+ });
1780
+ }
1781
+ subscribeWalletInfo(callback, namespace) {
1782
+ if (namespace) {
1783
+ return ChainController.subscribeChainProp('accountState', accountState => callback(accountState?.connectedWalletInfo), namespace);
1784
+ }
1785
+ return ChainController.subscribeChainProp('accountState', accountState => callback(accountState?.connectedWalletInfo));
1786
+ }
1787
+ subscribeShouldUpdateToAddress(callback) {
1788
+ ChainController.subscribeChainProp('accountState', accountState => callback(accountState?.shouldUpdateToAddress));
1789
+ }
1790
+ subscribeCaipNetworkChange(callback) {
1791
+ ChainController.subscribeKey('activeCaipNetwork', callback);
1792
+ }
1793
+ getState() {
1794
+ return PublicStateController.state;
1795
+ }
1796
+ getRemoteFeatures() {
1797
+ return OptionsController.state.remoteFeatures;
1798
+ }
1799
+ subscribeState(callback) {
1800
+ return PublicStateController.subscribe(callback);
1801
+ }
1802
+ subscribeRemoteFeatures(callback) {
1803
+ return OptionsController.subscribeKey('remoteFeatures', callback);
1804
+ }
1805
+ showErrorMessage(message) {
1806
+ SnackController.showError(message);
1807
+ }
1808
+ showSuccessMessage(message) {
1809
+ SnackController.showSuccess(message);
1810
+ }
1811
+ getEvent() {
1812
+ return { ...EventsController.state };
1813
+ }
1814
+ subscribeEvents(callback) {
1815
+ return EventsController.subscribe(callback);
1816
+ }
1817
+ replace(route) {
1818
+ RouterController.replace(route);
1819
+ }
1820
+ redirect(route) {
1821
+ RouterController.push(route);
1822
+ }
1823
+ popTransactionStack(status) {
1824
+ RouterController.popTransactionStack(status);
1825
+ }
1826
+ isOpen() {
1827
+ return ModalController.state.open;
1828
+ }
1829
+ isTransactionStackEmpty() {
1830
+ return RouterController.state.transactionStack.length === 0;
1831
+ }
1832
+ static getInstance() {
1833
+ return this.instance;
1834
+ }
1835
+ updateFeatures(newFeatures) {
1836
+ OptionsController.setFeatures(newFeatures);
1837
+ }
1838
+ updateRemoteFeatures(newRemoteFeatures) {
1839
+ OptionsController.setRemoteFeatures(newRemoteFeatures);
1840
+ }
1841
+ updateOptions(newOptions) {
1842
+ const currentOptions = OptionsController.state || {};
1843
+ const updatedOptions = { ...currentOptions, ...newOptions };
1844
+ OptionsController.setOptions(updatedOptions);
1845
+ }
1846
+ setConnectMethodsOrder(connectMethodsOrder) {
1847
+ OptionsController.setConnectMethodsOrder(connectMethodsOrder);
1848
+ }
1849
+ setWalletFeaturesOrder(walletFeaturesOrder) {
1850
+ OptionsController.setWalletFeaturesOrder(walletFeaturesOrder);
1851
+ }
1852
+ setCollapseWallets(collapseWallets) {
1853
+ OptionsController.setCollapseWallets(collapseWallets);
1854
+ }
1855
+ setSocialsOrder(socialsOrder) {
1856
+ OptionsController.setSocialsOrder(socialsOrder);
1857
+ }
1858
+ getConnectMethodsOrder() {
1859
+ return WalletUtil.getConnectOrderMethod(OptionsController.state.features, ConnectorController.getConnectors());
1860
+ }
1861
+ /**
1862
+ * Adds a network to an existing adapter in AppKit.
1863
+ * @param namespace - The chain namespace to add the network to (e.g. 'eip155', 'solana')
1864
+ * @param network - The network configuration to add
1865
+ * @throws Error if adapter for namespace doesn't exist
1866
+ */
1867
+ addNetwork(namespace, network) {
1868
+ if (this.chainAdapters && !this.chainAdapters[namespace]) {
1869
+ throw new Error(`Adapter for namespace ${namespace} doesn't exist`);
1870
+ }
1871
+ const extendedNetwork = this.extendCaipNetwork(network, this.options);
1872
+ if (!this.getCaipNetworks().find(n => n.id === extendedNetwork.id)) {
1873
+ ChainController.addNetwork(extendedNetwork);
1874
+ }
1875
+ }
1876
+ /**
1877
+ * Removes a network from an existing adapter in AppKit.
1878
+ * @param namespace - The chain namespace the network belongs to
1879
+ * @param networkId - The network ID to remove
1880
+ * @throws Error if adapter for namespace doesn't exist or if removing last network
1881
+ */
1882
+ removeNetwork(namespace, networkId) {
1883
+ if (this.chainAdapters && !this.chainAdapters[namespace]) {
1884
+ throw new Error(`Adapter for namespace ${namespace} doesn't exist`);
1885
+ }
1886
+ const networkToRemove = this.getCaipNetworks().find(n => n.id === networkId);
1887
+ if (!networkToRemove) {
1888
+ return;
1889
+ }
1890
+ ChainController.removeNetwork(namespace, networkId);
1891
+ }
1892
+ }
1893
+ //# sourceMappingURL=appkit-base-client.js.map