@dynamic-labs/ethereum 2.0.0-alpha.2 → 2.0.0-alpha.21

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 (42) hide show
  1. package/CHANGELOG.md +236 -0
  2. package/package.json +10 -11
  3. package/src/EthWalletConnector.cjs +1 -20
  4. package/src/EthWalletConnector.d.ts +9 -10
  5. package/src/EthWalletConnector.js +3 -22
  6. package/src/coinbase/client/client.cjs +2 -2
  7. package/src/coinbase/client/client.d.ts +2 -2
  8. package/src/coinbase/client/client.js +2 -2
  9. package/src/coinbase/coinbase.cjs +30 -9
  10. package/src/coinbase/coinbase.d.ts +19 -17
  11. package/src/coinbase/coinbase.js +31 -10
  12. package/src/ethProviderHelper.cjs +10 -5
  13. package/src/ethProviderHelper.d.ts +4 -3
  14. package/src/ethProviderHelper.js +10 -5
  15. package/src/index.cjs +7 -13
  16. package/src/index.d.ts +1 -0
  17. package/src/index.js +7 -13
  18. package/src/injected/ExodusEvm.cjs +1 -0
  19. package/src/injected/ExodusEvm.d.ts +1 -0
  20. package/src/injected/ExodusEvm.js +1 -0
  21. package/src/injected/InjectedWalletBase.cjs +6 -14
  22. package/src/injected/InjectedWalletBase.d.ts +2 -2
  23. package/src/injected/InjectedWalletBase.js +6 -14
  24. package/src/injected/PhantomEvm.cjs +4 -3
  25. package/src/injected/PhantomEvm.d.ts +2 -1
  26. package/src/injected/PhantomEvm.js +4 -3
  27. package/src/injected/fetchInjectedWalletConnectors.d.ts +0 -1
  28. package/src/walletConnect/fetchWalletConnectWallets.cjs +14 -33
  29. package/src/walletConnect/fetchWalletConnectWallets.d.ts +2 -5
  30. package/src/walletConnect/fetchWalletConnectWallets.js +14 -33
  31. package/src/walletConnect/index.d.ts +1 -2
  32. package/src/walletConnect/walletConnect.cjs +427 -79
  33. package/src/walletConnect/walletConnect.d.ts +309 -28
  34. package/src/walletConnect/walletConnect.js +426 -79
  35. package/src/walletConnect/client/client.cjs +0 -201
  36. package/src/walletConnect/client/client.d.ts +0 -17
  37. package/src/walletConnect/client/client.js +0 -187
  38. package/src/walletConnect/client/index.d.ts +0 -1
  39. package/src/walletConnect/client/types.d.ts +0 -4
  40. package/src/walletConnect/walletConnectV2.cjs +0 -475
  41. package/src/walletConnect/walletConnectV2.d.ts +0 -333
  42. package/src/walletConnect/walletConnectV2.js +0 -466
@@ -1,100 +1,425 @@
1
- import { __rest, __awaiter } from '../../_virtual/_tslib.js';
2
- import WalletConnectProvider from '@walletconnect/ethereum-provider';
1
+ import { __awaiter } from '../../_virtual/_tslib.js';
2
+ import Provider from '@walletconnect/universal-provider';
3
+ import EventEmitter from 'eventemitter3';
3
4
  import { createWalletClient, custom } from 'viem';
4
- import { getDeepLink } from '@dynamic-labs/wallet-connector-core';
5
+ import { toAccount } from 'viem/accounts';
6
+ import { DynamicError, sleep, isMobile } from '@dynamic-labs/utils';
5
7
  import { getWalletBookWallet } from '@dynamic-labs/wallet-book';
6
- import { isMobile, DynamicError } from '@dynamic-labs/utils';
8
+ import { logger, performPlatformSpecificConnectionMethod, getDeepLink } from '@dynamic-labs/wallet-connector-core';
9
+ import { chainsMap } from '@dynamic-labs/viem-utils';
7
10
  import { EthWalletConnector } from '../EthWalletConnector.js';
8
- import { INFURA_ID } from '../constants.js';
9
- import { initClient, setupWalletConnectEventListeners, teardownWalletConnectEventListeners, fetchWalletConnectEVMPublicAddress, signWalletConnectPersonalMessage, killWalletConnectSession } from './client/client.js';
11
+ import { parseIntSafe } from '../utils/parseIntSafe.js';
10
12
 
13
+ const activeAccountKey = (walletName) => `dynamic-wc2-active-account-${walletName}`;
14
+ const sessionTopicKey = (walletName) => `dynamic-wc2-session-topic-${walletName}`;
15
+ const swicthedNetworkKey = (walletName) => `dynamic-wc2-switched-network-${walletName}`;
16
+ const currentChainKey = (walletName) => `dynamic-wc2-current-chain-${walletName}`;
17
+ const ee = new EventEmitter();
11
18
  class WalletConnect extends EthWalletConnector {
12
- constructor(_a) {
13
- var { walletConnectV1Bridge, walletName } = _a, props = __rest(_a, ["walletConnectV1Bridge", "walletName"]);
14
- super(props);
19
+ constructor(opts) {
20
+ var _a;
21
+ super(opts);
15
22
  this.supportedChains = ['EVM', 'ETH'];
16
23
  this.connectedChain = 'EVM';
17
- this.bridge = 'https://bridge.walletconnect.org';
24
+ this.isInitialized = false;
18
25
  this.canConnectViaQrCode = true;
19
26
  this.isWalletConnect = true;
20
- this.switchNetworkOnlyFromWallet = false;
21
- this.name = walletName;
22
- if (walletConnectV1Bridge) {
23
- this.bridge = walletConnectV1Bridge;
27
+ this.preferredChains = [];
28
+ // When trying to switch network for MetaMask, the switch promise gets stuck
29
+ // if the switch got trigged once already, so we need to keep track of that
30
+ this._hasSwitchedNetwork = false;
31
+ this.name = opts.walletName;
32
+ this.projectId = opts.projectId;
33
+ this.deepLinkPreference = opts.deepLinkPreference || 'native';
34
+ this.preferredChains = opts.walletConnectPreferredChains || [];
35
+ this.hasSwitchedNetwork =
36
+ (_a = Boolean(localStorage.getItem(this.swicthedNetworkKey))) !== null && _a !== void 0 ? _a : false;
37
+ const lsCurrentChain = localStorage.getItem(this.currentChainKey);
38
+ this.currentChainId = lsCurrentChain
39
+ ? parseIntSafe(lsCurrentChain)
40
+ : undefined;
41
+ }
42
+ getMappedChains() {
43
+ return (this.evmNetworks
44
+ // Filters out palm that crashes Trust Wallet
45
+ .filter((network) => network.chainId !== 11297108109)
46
+ .map((network) => `eip155:${network.chainId}`));
47
+ }
48
+ getMappedChainsByPreferredOrder() {
49
+ const allChains = this.getMappedChains();
50
+ const reorderedChains = this.preferredChains.filter((chain) => allChains.includes(chain));
51
+ const remainingChains = allChains.filter((chain) => !this.preferredChains.includes(chain));
52
+ return [...reorderedChains, ...remainingChains];
53
+ }
54
+ initConnection() {
55
+ return __awaiter(this, void 0, void 0, function* () {
56
+ const { provider } = WalletConnect;
57
+ if (!provider) {
58
+ throw new DynamicError('No provider found (init connection)');
59
+ }
60
+ // this means there is already a connection in progress, so don't call connect again
61
+ if (provider === null || provider === void 0 ? void 0 : provider.uri) {
62
+ return;
63
+ }
64
+ const optionalNamespaces = {
65
+ eip155: {
66
+ chains: this.getMappedChainsByPreferredOrder(),
67
+ events: ['chainChanged', 'accountsChanged'],
68
+ methods: [
69
+ 'eth_chainId',
70
+ 'eth_signTypedData',
71
+ 'eth_signTransaction',
72
+ 'eth_sign',
73
+ 'personal_sign',
74
+ 'eth_sendTransaction',
75
+ 'eth_signTypedData_v4',
76
+ 'wallet_switchEthereumChain',
77
+ 'wallet_addEthereumChain',
78
+ ],
79
+ rpcMap: this.evmNetworkRpcMap(),
80
+ },
81
+ };
82
+ provider
83
+ .connect({
84
+ optionalNamespaces,
85
+ })
86
+ .catch((e) => {
87
+ logger.error(e);
88
+ ee.emit('walletconnect_connection_failed', e);
89
+ });
90
+ });
91
+ }
92
+ createInitProviderPromise() {
93
+ return __awaiter(this, void 0, void 0, function* () {
94
+ WalletConnect.provider = yield Provider.init({
95
+ logger: logger.logLevel.toLowerCase() === 'debug' ? 'debug' : undefined,
96
+ projectId: this.projectId,
97
+ });
98
+ this.teardownEventListeners();
99
+ this.setupEventListeners();
100
+ });
101
+ }
102
+ // We need to add a gate to this method since we will be calling it asynchronously
103
+ // from different places (such as setShowAuthFlow), which means there's a chance for
104
+ // a race condition to happen where createInitProviderPromise is called multiple times
105
+ initProvider() {
106
+ return __awaiter(this, void 0, void 0, function* () {
107
+ const { provider } = WalletConnect;
108
+ if (!provider) {
109
+ if (this.initializePromise === undefined) {
110
+ this.initializePromise = this.createInitProviderPromise();
111
+ }
112
+ yield this.initializePromise;
113
+ }
114
+ });
115
+ }
116
+ refreshSession() {
117
+ var _a, _b, _c, _d, _e;
118
+ if ((_b = (_a = WalletConnect.provider) === null || _a === void 0 ? void 0 : _a.session) === null || _b === void 0 ? void 0 : _b.topic) {
119
+ if (localStorage.getItem(this.sessionTopicKey) ===
120
+ ((_d = (_c = WalletConnect.provider) === null || _c === void 0 ? void 0 : _c.session) === null || _d === void 0 ? void 0 : _d.topic)) {
121
+ this.session = WalletConnect.provider.session;
122
+ this.activeAccount = ((_e = localStorage.getItem(this.activeAccountKey)) !== null && _e !== void 0 ? _e : undefined);
123
+ }
24
124
  }
25
- this.deepLinkPreference = props.deepLinkPreference || 'native';
26
125
  }
27
- getClient() {
28
- if (this.client) {
29
- return this.client;
126
+ init() {
127
+ return __awaiter(this, void 0, void 0, function* () {
128
+ yield this.initProvider();
129
+ yield this.initConnection();
130
+ this.isInitialized = true;
131
+ });
132
+ }
133
+ get sessionTopicKey() {
134
+ return sessionTopicKey(this.key);
135
+ }
136
+ get activeAccountKey() {
137
+ return activeAccountKey(this.key);
138
+ }
139
+ get swicthedNetworkKey() {
140
+ return swicthedNetworkKey(this.key);
141
+ }
142
+ get currentChainKey() {
143
+ return currentChainKey(this.key);
144
+ }
145
+ set currentChainId(value) {
146
+ this._currentChainId = value;
147
+ if (value) {
148
+ localStorage.setItem(this.currentChainKey, value.toString());
149
+ }
150
+ else {
151
+ localStorage.removeItem(this.currentChainKey);
30
152
  }
31
- this.client = initClient(this.key, this.bridge, this.clientOptions);
32
- return this.client;
33
153
  }
34
- supportsNetworkSwitching() {
35
- if (this.connectedChain === 'EVM') {
36
- return true;
154
+ get currentChainId() {
155
+ return this._currentChainId;
156
+ }
157
+ set hasSwitchedNetwork(value) {
158
+ this._hasSwitchedNetwork = value;
159
+ if (value) {
160
+ localStorage.setItem(this.swicthedNetworkKey, value.toString());
37
161
  }
38
162
  else {
39
- const client = this.getClient();
40
- return Boolean(client === null || client === void 0 ? void 0 : client.chainId);
163
+ localStorage.removeItem(this.swicthedNetworkKey);
41
164
  }
42
165
  }
166
+ get hasSwitchedNetwork() {
167
+ return this._hasSwitchedNetwork;
168
+ }
169
+ supportsNetworkSwitching() {
170
+ return true;
171
+ }
43
172
  setupEventListeners() {
44
- setupWalletConnectEventListeners(this, this.getClient());
173
+ if (!WalletConnect.provider) {
174
+ return;
175
+ }
176
+ WalletConnect.provider.client.on('session_event', ({ params }) => {
177
+ logger.debug('session_event was called', { params });
178
+ if (!params || !params.event) {
179
+ logger.debug('session_event was called without params or params.event');
180
+ return;
181
+ }
182
+ const { name, data } = params.event;
183
+ if (name === 'chainChanged') {
184
+ const chainId = parseIntSafe(data);
185
+ if (chainId === this.currentChainId) {
186
+ logger.debug(`ignoring chainChanged event with same chain id as current chain id: ${chainId}`);
187
+ return;
188
+ }
189
+ if (chainId === undefined) {
190
+ logger.debug(`received unexpected data for chainChanged: ${data} with type ${typeof data}}`);
191
+ return;
192
+ }
193
+ this.currentChainId = chainId;
194
+ this.emit('chainChange', { chain: String(chainId) });
195
+ // When a user switches network from their wallet, we need the provider to change network
196
+ // such that any future calls to `getNetwork` will return the correct network
197
+ this.switchNetwork({ networkChainId: chainId });
198
+ }
199
+ else if (name === 'accountsChanged') {
200
+ if (!Array.isArray(data)) {
201
+ logger.debug(`received unexpected data for accountsChanged: ${data} with type ${typeof data}}`);
202
+ return;
203
+ }
204
+ // eslint-disable-next-line prefer-destructuring
205
+ const account = data[0].split(':')[2];
206
+ this.setActiveAccount(account);
207
+ }
208
+ });
209
+ WalletConnect.provider.client.on('session_delete', () => __awaiter(this, void 0, void 0, function* () {
210
+ this.endSession();
211
+ this.emit('disconnect');
212
+ }));
45
213
  }
46
214
  teardownEventListeners() {
47
- teardownWalletConnectEventListeners(this.getClient());
48
- }
49
- getWalletClient() {
50
- const client = this.getClient();
51
- return client
52
- ? createWalletClient({
53
- transport: custom(new WalletConnectProvider({
54
- connector: client,
55
- infuraId: INFURA_ID,
56
- rpc: this.evmNetworkRpcMap(),
57
- })),
58
- })
59
- : undefined;
215
+ if (!WalletConnect.provider) {
216
+ return;
217
+ }
218
+ WalletConnect.provider.client.removeAllListeners('session_event');
219
+ WalletConnect.provider.client.removeAllListeners('session_delete');
220
+ }
221
+ getWalletClient(chainId) {
222
+ if (!WalletConnect.provider) {
223
+ return;
224
+ }
225
+ return createWalletClient({
226
+ account: this.activeAccount ? toAccount(this.activeAccount) : undefined,
227
+ chain: chainId ? chainsMap[chainId] : undefined,
228
+ transport: custom(WalletConnect.provider),
229
+ });
60
230
  }
61
- fetchPublicAddress(opts) {
231
+ getAddress(opts) {
232
+ var _a, _b;
62
233
  return __awaiter(this, void 0, void 0, function* () {
63
- return fetchWalletConnectEVMPublicAddress(getWalletBookWallet(this.walletBook, this.key), this.getClient(), this.deepLinkPreference, Object.assign(Object.assign({}, opts), { onConnect: (payload) => {
64
- var _a, _b;
65
- (_a = opts === null || opts === void 0 ? void 0 : opts.onConnect) === null || _a === void 0 ? void 0 : _a.call(opts, payload);
66
- this.connectedChain = payload.params[0].chainId ? 'EVM' : 'SOL';
67
- if ((_b = payload.params[0].accounts) === null || _b === void 0 ? void 0 : _b.length) {
68
- this.emit('accountChange', {
69
- accounts: payload.params[0].accounts,
70
- });
234
+ if (this.activeAccount) {
235
+ return this.activeAccount;
236
+ }
237
+ if (!WalletConnect.provider || !((_a = WalletConnect.provider) === null || _a === void 0 ? void 0 : _a.uri)) {
238
+ logger.debug('No WC2 provider found, re-initializing...');
239
+ yield this.endSession();
240
+ yield this.init();
241
+ // sleep 1 s to wait for connect call to finish
242
+ // the connect call isn't await-ed because it only resolves once
243
+ // the connection is established, but we need to wait for it to
244
+ // finish setting up the connection URI and making it available
245
+ // on the provider
246
+ yield sleep(1000);
247
+ if (!WalletConnect.provider || !((_b = WalletConnect.provider) === null || _b === void 0 ? void 0 : _b.uri)) {
248
+ logger.debug('No WC2 provider found, escaping and throwing error');
249
+ throw new DynamicError('No provider found');
250
+ }
251
+ }
252
+ const metadata = getWalletBookWallet(this.walletBook, this.key);
253
+ performPlatformSpecificConnectionMethod(WalletConnect.provider.uri, metadata, {
254
+ onDesktopUri: opts === null || opts === void 0 ? void 0 : opts.onDesktopUri,
255
+ onDisplayUri: opts === null || opts === void 0 ? void 0 : opts.onDisplayUri,
256
+ }, this.deepLinkPreference);
257
+ return new Promise((resolve, reject) => {
258
+ if (!WalletConnect.provider) {
259
+ reject(new DynamicError('No provider found'));
260
+ return;
261
+ }
262
+ const onFail = () => {
263
+ const error = new DynamicError('Connection rejected. Please try again.');
264
+ error.code = 'connection_rejected';
265
+ if (WalletConnect.provider) {
266
+ WalletConnect.provider.uri = undefined;
267
+ // this is needed for mobile to work when using universal links.
268
+ // if the user cancels the connection, we need to re-initialize the provider
269
+ // so that the async work is done ahead of time, before the user tries to connect again,
270
+ // otherwise they will trigger the iOS bug where they are redirected to the app store
271
+ this.init();
71
272
  }
72
- } }));
273
+ reject(error);
274
+ // We must clean up the onConnect and onFail listeners
275
+ // whenever the connection attempt either succeeds or fails
276
+ cleanupListeners();
277
+ };
278
+ const onConnect = ({ session }) => {
279
+ if (!session) {
280
+ reject(new DynamicError('No session found'));
281
+ }
282
+ this.setSession(session);
283
+ this.setActiveAccount(session.namespaces.eip155.accounts[0].split(':')[2]);
284
+ this.getNetwork().then((chainId) => {
285
+ this.currentChainId = chainId;
286
+ resolve(this.activeAccount);
287
+ });
288
+ // We must clean up the onConnect and onFail listeners
289
+ // whenever the connection attempt either succeeds or fails
290
+ cleanupListeners();
291
+ };
292
+ const cleanupListeners = () => {
293
+ var _a;
294
+ ee.off('walletconnect_connection_failed', onFail);
295
+ (_a = WalletConnect.provider) === null || _a === void 0 ? void 0 : _a.off('connect', onConnect);
296
+ };
297
+ ee.on('walletconnect_connection_failed', onFail);
298
+ WalletConnect.provider.on('connect', onConnect);
299
+ });
300
+ });
301
+ }
302
+ /**
303
+ * WalletConnect V2 will fail to send the sign message request if the chainId
304
+ * is not the same as the one in the session. This method will wait for the
305
+ * chainId to change and then retry the sign message request.
306
+ *
307
+ * Otherwise it will just return the result of the sign message request.
308
+ *
309
+ * @param signMessageFn - Function to sign message with provider
310
+ * @param messageToSign - Message to sign
311
+ * @returns
312
+ */
313
+ waitForSignMessage(signMessageFn, messageToSign) {
314
+ return __awaiter(this, void 0, void 0, function* () {
315
+ const raceConditionPromise = new Promise((resolve, reject) => {
316
+ // Create listener for chain change event
317
+ this.on('chainChange', () => resolve({ success: false }));
318
+ signMessageFn(messageToSign)
319
+ .then((result) => resolve({ signedMessage: result, success: true }))
320
+ .catch(reject);
321
+ });
322
+ const signedMessageResult = yield raceConditionPromise;
323
+ if (signedMessageResult.success === false) {
324
+ return signMessageFn(messageToSign);
325
+ }
326
+ return signedMessageResult.signedMessage;
73
327
  });
74
328
  }
75
329
  getDeepLink() {
76
330
  var _a;
77
- const wallet = getWalletBookWallet(this.walletBook, this.key);
78
- if (!isMobile() && !((_a = wallet.desktop) === null || _a === void 0 ? void 0 : _a.native)) {
79
- return undefined;
331
+ if (!this.session) {
332
+ return;
80
333
  }
81
- return getDeepLink({
82
- metadata: wallet,
334
+ const metadata = getWalletBookWallet(this.walletBook, this.key);
335
+ const deepLink = getDeepLink({
336
+ metadata,
83
337
  mode: 'regular',
84
338
  preference: this.deepLinkPreference,
85
- uri: this.getClient().uri,
339
+ uri: (_a = WalletConnect.provider) === null || _a === void 0 ? void 0 : _a.uri,
86
340
  });
341
+ if (!deepLink) {
342
+ return;
343
+ }
344
+ // we need to include the session topic here because it helps the wallet
345
+ // auto redirect back to the dapp after signing
346
+ return `${deepLink}?sessionTopic=${this.session.topic}`;
87
347
  }
88
348
  signMessage(messageToSign) {
89
349
  return __awaiter(this, void 0, void 0, function* () {
90
- return signWalletConnectPersonalMessage(messageToSign, getWalletBookWallet(this.walletBook, this.key), this.getClient(), this.deepLinkPreference,
91
- // don't call getPublicClient until we really need to
92
- () => __awaiter(this, void 0, void 0, function* () { return this.getPublicClient(); }));
350
+ if (!this.session) {
351
+ throw new DynamicError('no session');
352
+ }
353
+ const web3Provider = this.getWalletClient();
354
+ if (!web3Provider) {
355
+ throw new DynamicError('No WalletConnect provider found to handle signing');
356
+ }
357
+ const deepLink = this.getDeepLink();
358
+ if (isMobile() && deepLink) {
359
+ window.location.href = deepLink;
360
+ }
361
+ const signMessageFn = (messageToSign) => __awaiter(this, void 0, void 0, function* () {
362
+ const { activeAccount } = this;
363
+ if (!activeAccount) {
364
+ return;
365
+ }
366
+ return web3Provider.signMessage({
367
+ account: activeAccount,
368
+ message: messageToSign,
369
+ });
370
+ });
371
+ const response = yield this.waitForSignMessage(signMessageFn, messageToSign);
372
+ return response;
93
373
  });
94
374
  }
375
+ clearActiveAccount() {
376
+ localStorage.removeItem(this.activeAccountKey);
377
+ this.activeAccount = undefined;
378
+ }
379
+ clearSession() {
380
+ localStorage.removeItem(this.sessionTopicKey);
381
+ this.session = undefined;
382
+ }
383
+ setActiveAccount(account) {
384
+ localStorage.setItem(this.activeAccountKey, account);
385
+ this.activeAccount = account;
386
+ this.emit('accountChange', { accounts: [account] });
387
+ }
388
+ setSession(session) {
389
+ localStorage.setItem(this.sessionTopicKey, session.topic);
390
+ this.session = session;
391
+ }
95
392
  endSession() {
393
+ var _a;
394
+ return __awaiter(this, void 0, void 0, function* () {
395
+ this.clearActiveAccount();
396
+ this.clearSession();
397
+ this.hasSwitchedNetwork = false;
398
+ this.currentChainId = undefined;
399
+ if (!((_a = WalletConnect.provider) === null || _a === void 0 ? void 0 : _a.session)) {
400
+ return;
401
+ }
402
+ try {
403
+ yield WalletConnect.provider.disconnect();
404
+ // We must unset provider on logout so that a new session can be established
405
+ // If we don't then the provider will still have the old session and will hang
406
+ WalletConnect.provider = undefined;
407
+ }
408
+ catch (e) {
409
+ logger.debug(e);
410
+ }
411
+ });
412
+ }
413
+ getNetwork() {
414
+ const _super = Object.create(null, {
415
+ getNetwork: { get: () => super.getNetwork }
416
+ });
96
417
  return __awaiter(this, void 0, void 0, function* () {
97
- killWalletConnectSession(this.getClient());
418
+ if (this.currentChainId) {
419
+ return this.currentChainId;
420
+ }
421
+ yield this.initProvider();
422
+ return _super.getNetwork.call(this);
98
423
  });
99
424
  }
100
425
  providerSwitchNetwork({ network, provider, }) {
@@ -102,45 +427,67 @@ class WalletConnect extends EthWalletConnector {
102
427
  providerSwitchNetwork: { get: () => super.providerSwitchNetwork }
103
428
  });
104
429
  return __awaiter(this, void 0, void 0, function* () {
105
- const client = this.getClient();
106
430
  const currentNetworkId = yield this.getNetwork();
107
431
  if (currentNetworkId && currentNetworkId === network.chainId) {
108
432
  return;
109
433
  }
110
- if (this.switchNetworkOnlyFromWallet !== undefined &&
111
- this.switchNetworkOnlyFromWallet) {
434
+ if (this.switchNetworkOnlyFromWallet) {
112
435
  throw new DynamicError('Network switching is only supported through the wallet');
113
436
  }
114
437
  if (!this.supportsNetworkSwitching()) {
115
438
  throw new DynamicError('Network switching not supported');
116
439
  }
117
- if (!client) {
118
- throw new DynamicError('Client not found');
440
+ if (!provider) {
441
+ throw new DynamicError('Provider not found');
119
442
  }
120
- if (isMobile()) {
121
- const deepLink = getDeepLink({
122
- metadata: getWalletBookWallet(this.walletBook, this.key),
123
- mode: 'regular',
124
- preference: this.deepLinkPreference,
125
- uri: client.uri,
126
- });
127
- window.location.href = deepLink;
128
- }
129
- return _super.providerSwitchNetwork.call(this, { network, provider });
443
+ yield _super.providerSwitchNetwork.call(this, { network, provider });
444
+ this.currentChainId = network.chainId;
445
+ this.hasSwitchedNetwork = true;
446
+ this.emit('chainChange', { chain: String(network.chainId) });
130
447
  });
131
448
  }
132
449
  getConnectedAccounts() {
133
450
  return __awaiter(this, void 0, void 0, function* () {
134
- const client = this.getClient();
135
- if (!client.connected)
451
+ if (this.isInitialized === false) {
452
+ yield this.initProvider();
453
+ this.refreshSession();
454
+ this.isInitialized = true;
455
+ }
456
+ if (!this.activeAccount) {
136
457
  return [];
137
- return client.accounts;
458
+ }
459
+ return [this.activeAccount];
138
460
  });
139
461
  }
140
- getSession() {
462
+ isMetaMask() {
463
+ var _a, _b, _c, _d, _e;
464
+ return ((_e = (_d = (_c = (_b = (_a = this.session) === null || _a === void 0 ? void 0 : _a.peer) === null || _b === void 0 ? void 0 : _b.metadata) === null || _c === void 0 ? void 0 : _c.name) === null || _d === void 0 ? void 0 : _d.toLowerCase().startsWith('metamask')) !== null && _e !== void 0 ? _e : false);
465
+ }
466
+ getSupportedNetworks() {
141
467
  var _a;
142
468
  return __awaiter(this, void 0, void 0, function* () {
143
- return (_a = this.client) === null || _a === void 0 ? void 0 : _a.session;
469
+ // MM allows you to switch to any network the first time, even if it's not enabled in MM
470
+ // so we should consider all networks as supported if network switching hasn't been triggered yet
471
+ if (this.isMetaMask() && !this.hasSwitchedNetwork) {
472
+ return this.evmNetworks.map((network) => network.chainId.toString());
473
+ }
474
+ yield this.initProvider();
475
+ this.refreshSession();
476
+ if (!this.session) {
477
+ return [];
478
+ }
479
+ const chains = [];
480
+ // Some wallet (i.e ZenGo) use namespaces.account to list supported chains
481
+ // while others use keys within the namespaces object
482
+ Object.keys(this.session.namespaces).forEach((key) => {
483
+ if (key.startsWith('eip155:')) {
484
+ chains.push(key.split(':')[1]);
485
+ }
486
+ });
487
+ (_a = this.session.namespaces.eip155) === null || _a === void 0 ? void 0 : _a.accounts.forEach((account) => chains.push(account.split(':')[1]));
488
+ return chains.length
489
+ ? chains
490
+ : this.evmNetworks.map((network) => network.chainId.toString());
144
491
  });
145
492
  }
146
493
  }