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