@dynamic-labs/ethereum 0.17.18 → 0.17.20

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.
package/CHANGELOG.md CHANGED
@@ -1,4 +1,20 @@
1
1
 
2
+ ### [0.17.20](https://github.com/dynamic-labs/DynamicAuth/compare/v0.17.19...v0.17.20) (2023-07-03)
3
+
4
+
5
+ ### Bug Fixes
6
+
7
+ * persist chain to WalletConnect session when changed in wallet ([#2556](https://github.com/dynamic-labs/DynamicAuth/issues/2556)) ([#2562](https://github.com/dynamic-labs/DynamicAuth/issues/2562)) ([0415e6d](https://github.com/dynamic-labs/DynamicAuth/commit/0415e6d055e860ab63ebf0d249ca9cdd71dfdb83))
8
+
9
+ ### [0.17.19](https://github.com/dynamic-labs/DynamicAuth/compare/v0.17.18...v0.17.19) (2023-07-02)
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * log out if there's any session sync issue ([#2548](https://github.com/dynamic-labs/DynamicAuth/issues/2548)) ([3f92bab](https://github.com/dynamic-labs/DynamicAuth/commit/3f92bab1b6b317f4a024a68d4d220921bad3437c))
15
+ * WC2 sign-message on non-selected chain ([#2551](https://github.com/dynamic-labs/DynamicAuth/issues/2551)) ([c455e53](https://github.com/dynamic-labs/DynamicAuth/commit/c455e530c964b2865ffd29529546faddf2a57096)), closes [#2544](https://github.com/dynamic-labs/DynamicAuth/issues/2544) [#2552](https://github.com/dynamic-labs/DynamicAuth/issues/2552) [#2525](https://github.com/dynamic-labs/DynamicAuth/issues/2525) [#2500](https://github.com/dynamic-labs/DynamicAuth/issues/2500) [#2546](https://github.com/dynamic-labs/DynamicAuth/issues/2546)
16
+ * **wcv2:** don't force required chain to eth in case is not enabled ([#2538](https://github.com/dynamic-labs/DynamicAuth/issues/2538)) ([933dc20](https://github.com/dynamic-labs/DynamicAuth/commit/933dc20b300f0740a438810b9e65d693aae61689))
17
+
2
18
  ### [0.17.18](https://github.com/dynamic-labs/DynamicAuth/compare/v0.17.17...v0.17.18) (2023-06-29)
3
19
 
4
20
  ### [0.17.17](https://github.com/dynamic-labs/DynamicAuth/compare/v0.17.16...v0.17.17) (2023-06-29)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynamic-labs/ethereum",
3
- "version": "0.17.18",
3
+ "version": "0.17.20",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/dynamic-labs/DynamicAuth.git",
@@ -32,11 +32,11 @@
32
32
  "ethers": "5.7.2",
33
33
  "eventemitter3": "5.0.1",
34
34
  "buffer": "6.0.3",
35
- "@dynamic-labs/rpc-providers": "0.17.18",
36
- "@dynamic-labs/types": "0.17.18",
37
- "@dynamic-labs/utils": "0.17.18",
38
- "@dynamic-labs/wallet-book": "0.17.18",
39
- "@dynamic-labs/wallet-connector-core": "0.17.18"
35
+ "@dynamic-labs/rpc-providers": "0.17.20",
36
+ "@dynamic-labs/types": "0.17.20",
37
+ "@dynamic-labs/utils": "0.17.20",
38
+ "@dynamic-labs/wallet-book": "0.17.20",
39
+ "@dynamic-labs/wallet-connector-core": "0.17.20"
40
40
  },
41
41
  "peerDependencies": {}
42
42
  }
@@ -141,6 +141,12 @@ class WalletConnect extends EthWalletConnector.EthWalletConnector {
141
141
  return client.accounts;
142
142
  });
143
143
  }
144
+ getSession() {
145
+ var _a;
146
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
147
+ return (_a = this.client) === null || _a === void 0 ? void 0 : _a.session;
148
+ });
149
+ }
144
150
  }
145
151
 
146
152
  exports.WalletConnect = WalletConnect;
@@ -3,6 +3,19 @@ import { ethers } from 'ethers';
3
3
  import { Chain, FetchPublicAddressOpts, WalletEventListeners } from '@dynamic-labs/wallet-connector-core';
4
4
  import { EvmNetwork } from '@dynamic-labs/types';
5
5
  import { EthWalletConnector, EthWalletConnectorOpts } from '../EthWalletConnector';
6
+ type ConnectorSession = {
7
+ connected: boolean;
8
+ accounts: string[];
9
+ chainId: number;
10
+ bridge: string;
11
+ key: string;
12
+ clientId: string;
13
+ clientMeta: any;
14
+ peerId: string;
15
+ peerMeta: any;
16
+ handshakeId: number;
17
+ handshakeTopic: string;
18
+ };
6
19
  export type WalletConnectOpts = EthWalletConnectorOpts & {
7
20
  walletConnectV1Bridge: string;
8
21
  walletName: string;
@@ -32,4 +45,6 @@ export declare class WalletConnect extends EthWalletConnector {
32
45
  provider: ethers.providers.Web3Provider;
33
46
  }): Promise<void>;
34
47
  getConnectedAccounts(): Promise<string[]>;
48
+ getSession(): Promise<ConnectorSession | undefined>;
35
49
  }
50
+ export {};
@@ -133,6 +133,12 @@ class WalletConnect extends EthWalletConnector {
133
133
  return client.accounts;
134
134
  });
135
135
  }
136
+ getSession() {
137
+ var _a;
138
+ return __awaiter(this, void 0, void 0, function* () {
139
+ return (_a = this.client) === null || _a === void 0 ? void 0 : _a.session;
140
+ });
141
+ }
136
142
  }
137
143
 
138
144
  export { WalletConnect };
@@ -32,6 +32,7 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
32
32
  this.projectId = opts.projectId;
33
33
  }
34
34
  initConnection() {
35
+ var _a;
35
36
  return _tslib.__awaiter(this, void 0, void 0, function* () {
36
37
  const { provider } = WalletConnectV2;
37
38
  if (!provider) {
@@ -41,7 +42,9 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
41
42
  if (provider === null || provider === void 0 ? void 0 : provider.uri) {
42
43
  return;
43
44
  }
44
- const defaultChain = 1;
45
+ const defaultChain = ((_a = this.evmNetworks) === null || _a === void 0 ? void 0 : _a.length)
46
+ ? this.evmNetworks[0].chainId
47
+ : 1;
45
48
  provider
46
49
  .connect({
47
50
  namespaces: {
@@ -81,6 +84,7 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
81
84
  createInitProviderPromise() {
82
85
  return _tslib.__awaiter(this, void 0, void 0, function* () {
83
86
  const provider = yield Provider__default["default"].init({
87
+ logger: walletConnectorCore.logger.logLevel.toLowerCase() === 'debug' ? 'debug' : undefined,
84
88
  projectId: this.projectId,
85
89
  });
86
90
  WalletConnectV2.provider = provider;
@@ -142,6 +146,9 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
142
146
  return;
143
147
  }
144
148
  (_a = listeners.onChainChange) === null || _a === void 0 ? void 0 : _a.call(listeners, String(chainId));
149
+ // When a user switches network from their wallet, we need the provider to change network
150
+ // such that any future calls to `getNetwork` will return the correct network
151
+ this.switchNetwork({ networkChainId: chainId });
145
152
  }
146
153
  else if (name === 'accountsChanged') {
147
154
  if (!Array.isArray(data)) {
@@ -238,6 +245,35 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
238
245
  });
239
246
  });
240
247
  }
248
+ /**
249
+ * WalletConnect V2 will fail to send the sign message request if the chainId
250
+ * is not the same as the one in the session. This method will wait for the
251
+ * chainId to change and then retry the sign message request.
252
+ *
253
+ * Otherwise it will just return the result of the sign message request.
254
+ *
255
+ * @param signMessageFn - Function to sign message with provider
256
+ * @param messageToSign - Message to sign
257
+ * @returns
258
+ */
259
+ waitForSignMessage(signMessageFn, messageToSign) {
260
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
261
+ const raceConditionPromise = new Promise((resolve) => {
262
+ // Create listener for chain change event
263
+ this.setupEventListeners({
264
+ onChainChange: () => _tslib.__awaiter(this, void 0, void 0, function* () {
265
+ resolve({ success: false });
266
+ }),
267
+ });
268
+ signMessageFn(messageToSign).then((result) => resolve({ signedMessage: result, success: true }));
269
+ });
270
+ const signedMessageResult = yield raceConditionPromise;
271
+ if (signedMessageResult.success === false) {
272
+ return signMessageFn(messageToSign);
273
+ }
274
+ return signedMessageResult.signedMessage;
275
+ });
276
+ }
241
277
  signMessage(messageToSign) {
242
278
  return _tslib.__awaiter(this, void 0, void 0, function* () {
243
279
  if (!this.session) {
@@ -262,23 +298,13 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
262
298
  if (!web3Provider) {
263
299
  throw new utils.DynamicError('No web3 provider found');
264
300
  }
265
- const response = web3Provider.send('personal_sign', [
266
- walletConnectorCore.utf8ToHex(messageToSign, true),
267
- this.activeAccount,
268
- ]);
269
- try {
270
- // A terrible hack to get MM to sign the message when it is on the wrong chain
271
- // Since MM supports only one chain at a time, it just hangs when we call
272
- // to sign, and it is not on Mainnet. For some magical reason,
273
- // when we attempt to call again it just works.
274
- if (this.key === 'metamask') {
275
- yield this.promiseWithTimeout(7000, response);
276
- }
277
- }
278
- catch (e) {
279
- walletConnectorCore.logger.debug('metmask failed to sign message');
280
- throw e;
281
- }
301
+ const signMessageFn = (messageToSign) => _tslib.__awaiter(this, void 0, void 0, function* () {
302
+ return web3Provider.send('personal_sign', [
303
+ walletConnectorCore.utf8ToHex(messageToSign, true),
304
+ this.activeAccount,
305
+ ]);
306
+ });
307
+ const response = yield this.waitForSignMessage(signMessageFn, messageToSign);
282
308
  return response;
283
309
  });
284
310
  }
@@ -308,7 +334,9 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
308
334
  }
309
335
  try {
310
336
  yield WalletConnectV2.provider.disconnect();
311
- WalletConnectV2.provider.uri = undefined;
337
+ // We must unset provider on logout so that a new session can be established
338
+ // If we don't then the provider will still have the old session and will hang
339
+ WalletConnectV2.provider = undefined;
312
340
  }
313
341
  catch (e) {
314
342
  walletConnectorCore.logger.debug(e);
@@ -375,18 +403,6 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
375
403
  return chains.length ? chains : undefined;
376
404
  });
377
405
  }
378
- // a HACK for MM to sign message when the selected chain is not mainnet
379
- promiseWithTimeout(ms, promise) {
380
- // Create a promise that rejects in <ms> milliseconds
381
- const timeout = new Promise((_, reject) => {
382
- const id = setTimeout(() => {
383
- clearTimeout(id);
384
- reject(new utils.DynamicError(undefined, 'metamask_timeout'));
385
- }, ms);
386
- });
387
- // Returns a race between our timeout and the passed in promise
388
- return Promise.race([promise, timeout]);
389
- }
390
406
  }
391
407
 
392
408
  exports.WalletConnectV2 = WalletConnectV2;
@@ -33,6 +33,18 @@ export declare class WalletConnectV2 extends EthWalletConnector {
33
33
  getDeepLink(): string | undefined;
34
34
  getWeb3Provider(): ethers.providers.Web3Provider | undefined;
35
35
  fetchPublicAddress(opts?: FetchPublicAddressOpts): Promise<string | undefined>;
36
+ /**
37
+ * WalletConnect V2 will fail to send the sign message request if the chainId
38
+ * is not the same as the one in the session. This method will wait for the
39
+ * chainId to change and then retry the sign message request.
40
+ *
41
+ * Otherwise it will just return the result of the sign message request.
42
+ *
43
+ * @param signMessageFn - Function to sign message with provider
44
+ * @param messageToSign - Message to sign
45
+ * @returns
46
+ */
47
+ protected waitForSignMessage(signMessageFn: (messageToSign: string) => Promise<string | undefined>, messageToSign: string): Promise<string | undefined>;
36
48
  signMessage(messageToSign: string): Promise<string | undefined>;
37
49
  private clearActiveAccount;
38
50
  private clearSession;
@@ -46,5 +58,4 @@ export declare class WalletConnectV2 extends EthWalletConnector {
46
58
  }): Promise<void>;
47
59
  getConnectedAccounts(): Promise<string[]>;
48
60
  getSupportedNetworks(): Promise<string[] | undefined>;
49
- private promiseWithTimeout;
50
61
  }
@@ -23,6 +23,7 @@ class WalletConnectV2 extends EthWalletConnector {
23
23
  this.projectId = opts.projectId;
24
24
  }
25
25
  initConnection() {
26
+ var _a;
26
27
  return __awaiter(this, void 0, void 0, function* () {
27
28
  const { provider } = WalletConnectV2;
28
29
  if (!provider) {
@@ -32,7 +33,9 @@ class WalletConnectV2 extends EthWalletConnector {
32
33
  if (provider === null || provider === void 0 ? void 0 : provider.uri) {
33
34
  return;
34
35
  }
35
- const defaultChain = 1;
36
+ const defaultChain = ((_a = this.evmNetworks) === null || _a === void 0 ? void 0 : _a.length)
37
+ ? this.evmNetworks[0].chainId
38
+ : 1;
36
39
  provider
37
40
  .connect({
38
41
  namespaces: {
@@ -72,6 +75,7 @@ class WalletConnectV2 extends EthWalletConnector {
72
75
  createInitProviderPromise() {
73
76
  return __awaiter(this, void 0, void 0, function* () {
74
77
  const provider = yield Provider.init({
78
+ logger: logger.logLevel.toLowerCase() === 'debug' ? 'debug' : undefined,
75
79
  projectId: this.projectId,
76
80
  });
77
81
  WalletConnectV2.provider = provider;
@@ -133,6 +137,9 @@ class WalletConnectV2 extends EthWalletConnector {
133
137
  return;
134
138
  }
135
139
  (_a = listeners.onChainChange) === null || _a === void 0 ? void 0 : _a.call(listeners, String(chainId));
140
+ // When a user switches network from their wallet, we need the provider to change network
141
+ // such that any future calls to `getNetwork` will return the correct network
142
+ this.switchNetwork({ networkChainId: chainId });
136
143
  }
137
144
  else if (name === 'accountsChanged') {
138
145
  if (!Array.isArray(data)) {
@@ -229,6 +236,35 @@ class WalletConnectV2 extends EthWalletConnector {
229
236
  });
230
237
  });
231
238
  }
239
+ /**
240
+ * WalletConnect V2 will fail to send the sign message request if the chainId
241
+ * is not the same as the one in the session. This method will wait for the
242
+ * chainId to change and then retry the sign message request.
243
+ *
244
+ * Otherwise it will just return the result of the sign message request.
245
+ *
246
+ * @param signMessageFn - Function to sign message with provider
247
+ * @param messageToSign - Message to sign
248
+ * @returns
249
+ */
250
+ waitForSignMessage(signMessageFn, messageToSign) {
251
+ return __awaiter(this, void 0, void 0, function* () {
252
+ const raceConditionPromise = new Promise((resolve) => {
253
+ // Create listener for chain change event
254
+ this.setupEventListeners({
255
+ onChainChange: () => __awaiter(this, void 0, void 0, function* () {
256
+ resolve({ success: false });
257
+ }),
258
+ });
259
+ signMessageFn(messageToSign).then((result) => resolve({ signedMessage: result, success: true }));
260
+ });
261
+ const signedMessageResult = yield raceConditionPromise;
262
+ if (signedMessageResult.success === false) {
263
+ return signMessageFn(messageToSign);
264
+ }
265
+ return signedMessageResult.signedMessage;
266
+ });
267
+ }
232
268
  signMessage(messageToSign) {
233
269
  return __awaiter(this, void 0, void 0, function* () {
234
270
  if (!this.session) {
@@ -253,23 +289,13 @@ class WalletConnectV2 extends EthWalletConnector {
253
289
  if (!web3Provider) {
254
290
  throw new DynamicError('No web3 provider found');
255
291
  }
256
- const response = web3Provider.send('personal_sign', [
257
- utf8ToHex(messageToSign, true),
258
- this.activeAccount,
259
- ]);
260
- try {
261
- // A terrible hack to get MM to sign the message when it is on the wrong chain
262
- // Since MM supports only one chain at a time, it just hangs when we call
263
- // to sign, and it is not on Mainnet. For some magical reason,
264
- // when we attempt to call again it just works.
265
- if (this.key === 'metamask') {
266
- yield this.promiseWithTimeout(7000, response);
267
- }
268
- }
269
- catch (e) {
270
- logger.debug('metmask failed to sign message');
271
- throw e;
272
- }
292
+ const signMessageFn = (messageToSign) => __awaiter(this, void 0, void 0, function* () {
293
+ return web3Provider.send('personal_sign', [
294
+ utf8ToHex(messageToSign, true),
295
+ this.activeAccount,
296
+ ]);
297
+ });
298
+ const response = yield this.waitForSignMessage(signMessageFn, messageToSign);
273
299
  return response;
274
300
  });
275
301
  }
@@ -299,7 +325,9 @@ class WalletConnectV2 extends EthWalletConnector {
299
325
  }
300
326
  try {
301
327
  yield WalletConnectV2.provider.disconnect();
302
- WalletConnectV2.provider.uri = undefined;
328
+ // We must unset provider on logout so that a new session can be established
329
+ // If we don't then the provider will still have the old session and will hang
330
+ WalletConnectV2.provider = undefined;
303
331
  }
304
332
  catch (e) {
305
333
  logger.debug(e);
@@ -366,18 +394,6 @@ class WalletConnectV2 extends EthWalletConnector {
366
394
  return chains.length ? chains : undefined;
367
395
  });
368
396
  }
369
- // a HACK for MM to sign message when the selected chain is not mainnet
370
- promiseWithTimeout(ms, promise) {
371
- // Create a promise that rejects in <ms> milliseconds
372
- const timeout = new Promise((_, reject) => {
373
- const id = setTimeout(() => {
374
- clearTimeout(id);
375
- reject(new DynamicError(undefined, 'metamask_timeout'));
376
- }, ms);
377
- });
378
- // Returns a race between our timeout and the passed in promise
379
- return Promise.race([promise, timeout]);
380
- }
381
397
  }
382
398
 
383
399
  export { WalletConnectV2 };