@dynamic-labs/ethereum 0.17.18 → 0.17.19

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,13 @@
1
1
 
2
+ ### [0.17.19](https://github.com/dynamic-labs/DynamicAuth/compare/v0.17.18...v0.17.19) (2023-07-02)
3
+
4
+
5
+ ### Bug Fixes
6
+
7
+ * 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))
8
+ * 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)
9
+ * **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))
10
+
2
11
  ### [0.17.18](https://github.com/dynamic-labs/DynamicAuth/compare/v0.17.17...v0.17.18) (2023-06-29)
3
12
 
4
13
  ### [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.19",
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.19",
36
+ "@dynamic-labs/types": "0.17.19",
37
+ "@dynamic-labs/utils": "0.17.19",
38
+ "@dynamic-labs/wallet-book": "0.17.19",
39
+ "@dynamic-labs/wallet-connector-core": "0.17.19"
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;
@@ -238,6 +242,35 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
238
242
  });
239
243
  });
240
244
  }
245
+ /**
246
+ * WalletConnect V2 will fail to send the sign message request if the chainId
247
+ * is not the same as the one in the session. This method will wait for the
248
+ * chainId to change and then retry the sign message request.
249
+ *
250
+ * Otherwise it will just return the result of the sign message request.
251
+ *
252
+ * @param signMessageFn - Function to sign message with provider
253
+ * @param messageToSign - Message to sign
254
+ * @returns
255
+ */
256
+ waitForSignMessage(signMessageFn, messageToSign) {
257
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
258
+ const raceConditionPromise = new Promise((resolve) => {
259
+ // Create listener for chain change event
260
+ this.setupEventListeners({
261
+ onChainChange: () => _tslib.__awaiter(this, void 0, void 0, function* () {
262
+ resolve({ success: false });
263
+ }),
264
+ });
265
+ signMessageFn(messageToSign).then((result) => resolve({ signedMessage: result, success: true }));
266
+ });
267
+ const signedMessageResult = yield raceConditionPromise;
268
+ if (signedMessageResult.success === false) {
269
+ return signMessageFn(messageToSign);
270
+ }
271
+ return signedMessageResult.signedMessage;
272
+ });
273
+ }
241
274
  signMessage(messageToSign) {
242
275
  return _tslib.__awaiter(this, void 0, void 0, function* () {
243
276
  if (!this.session) {
@@ -262,23 +295,13 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
262
295
  if (!web3Provider) {
263
296
  throw new utils.DynamicError('No web3 provider found');
264
297
  }
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
- }
298
+ const signMessageFn = (messageToSign) => _tslib.__awaiter(this, void 0, void 0, function* () {
299
+ return web3Provider.send('personal_sign', [
300
+ walletConnectorCore.utf8ToHex(messageToSign, true),
301
+ this.activeAccount,
302
+ ]);
303
+ });
304
+ const response = yield this.waitForSignMessage(signMessageFn, messageToSign);
282
305
  return response;
283
306
  });
284
307
  }
@@ -308,7 +331,9 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
308
331
  }
309
332
  try {
310
333
  yield WalletConnectV2.provider.disconnect();
311
- WalletConnectV2.provider.uri = undefined;
334
+ // We must unset provider on logout so that a new session can be established
335
+ // If we don't then the provider will still have the old session and will hang
336
+ WalletConnectV2.provider = undefined;
312
337
  }
313
338
  catch (e) {
314
339
  walletConnectorCore.logger.debug(e);
@@ -375,18 +400,6 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
375
400
  return chains.length ? chains : undefined;
376
401
  });
377
402
  }
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
403
  }
391
404
 
392
405
  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;
@@ -229,6 +233,35 @@ class WalletConnectV2 extends EthWalletConnector {
229
233
  });
230
234
  });
231
235
  }
236
+ /**
237
+ * WalletConnect V2 will fail to send the sign message request if the chainId
238
+ * is not the same as the one in the session. This method will wait for the
239
+ * chainId to change and then retry the sign message request.
240
+ *
241
+ * Otherwise it will just return the result of the sign message request.
242
+ *
243
+ * @param signMessageFn - Function to sign message with provider
244
+ * @param messageToSign - Message to sign
245
+ * @returns
246
+ */
247
+ waitForSignMessage(signMessageFn, messageToSign) {
248
+ return __awaiter(this, void 0, void 0, function* () {
249
+ const raceConditionPromise = new Promise((resolve) => {
250
+ // Create listener for chain change event
251
+ this.setupEventListeners({
252
+ onChainChange: () => __awaiter(this, void 0, void 0, function* () {
253
+ resolve({ success: false });
254
+ }),
255
+ });
256
+ signMessageFn(messageToSign).then((result) => resolve({ signedMessage: result, success: true }));
257
+ });
258
+ const signedMessageResult = yield raceConditionPromise;
259
+ if (signedMessageResult.success === false) {
260
+ return signMessageFn(messageToSign);
261
+ }
262
+ return signedMessageResult.signedMessage;
263
+ });
264
+ }
232
265
  signMessage(messageToSign) {
233
266
  return __awaiter(this, void 0, void 0, function* () {
234
267
  if (!this.session) {
@@ -253,23 +286,13 @@ class WalletConnectV2 extends EthWalletConnector {
253
286
  if (!web3Provider) {
254
287
  throw new DynamicError('No web3 provider found');
255
288
  }
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
- }
289
+ const signMessageFn = (messageToSign) => __awaiter(this, void 0, void 0, function* () {
290
+ return web3Provider.send('personal_sign', [
291
+ utf8ToHex(messageToSign, true),
292
+ this.activeAccount,
293
+ ]);
294
+ });
295
+ const response = yield this.waitForSignMessage(signMessageFn, messageToSign);
273
296
  return response;
274
297
  });
275
298
  }
@@ -299,7 +322,9 @@ class WalletConnectV2 extends EthWalletConnector {
299
322
  }
300
323
  try {
301
324
  yield WalletConnectV2.provider.disconnect();
302
- WalletConnectV2.provider.uri = undefined;
325
+ // We must unset provider on logout so that a new session can be established
326
+ // If we don't then the provider will still have the old session and will hang
327
+ WalletConnectV2.provider = undefined;
303
328
  }
304
329
  catch (e) {
305
330
  logger.debug(e);
@@ -366,18 +391,6 @@ class WalletConnectV2 extends EthWalletConnector {
366
391
  return chains.length ? chains : undefined;
367
392
  });
368
393
  }
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
394
  }
382
395
 
383
396
  export { WalletConnectV2 };