@dynamic-labs/ethereum 0.18.0-RC.8 → 0.18.0-RC.9

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,25 @@
1
1
 
2
+ ## [0.18.0-RC.9](https://github.com/dynamic-labs/DynamicAuth/compare/v0.18.0-RC.8...v0.18.0-RC.9) (2023-07-04)
3
+
4
+
5
+ ### Features
6
+
7
+ * add Network Not Supported prompt to connect-only & show prompt before sign in connect-sign mode ([#2474](https://github.com/dynamic-labs/DynamicAuth/issues/2474)) ([8d5bfa9](https://github.com/dynamic-labs/DynamicAuth/commit/8d5bfa97ca4da50e06ce258a38a63e7407a795f6))
8
+ * **DYN-2602:** add ability to unlink connected wallet ([#2494](https://github.com/dynamic-labs/DynamicAuth/issues/2494)) ([389861b](https://github.com/dynamic-labs/DynamicAuth/commit/389861bc0281baec379b1593e529cef3467f3326))
9
+ * **DYN-2604:** add chainId property to walletsByChain object ([#2405](https://github.com/dynamic-labs/DynamicAuth/issues/2405)) ([d9b42f7](https://github.com/dynamic-labs/DynamicAuth/commit/d9b42f7b1d53dac1ed0228ecb5e56a44c6abd8d2))
10
+ * **DynamicAuthLayout:** show connected wallet progress ([#2567](https://github.com/dynamic-labs/DynamicAuth/issues/2567)) ([a20ff6f](https://github.com/dynamic-labs/DynamicAuth/commit/a20ff6f32b360ccc699d2a271c7a96751ae87d29))
11
+ * **DynamicBridgeFlow:** add bridge flow ([#2543](https://github.com/dynamic-labs/DynamicAuth/issues/2543)) ([79c4c87](https://github.com/dynamic-labs/DynamicAuth/commit/79c4c870d47a0c853c292a8d913bd9be9e209a15))
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * don't force required chain to eth in case is not enabled ([#2537](https://github.com/dynamic-labs/DynamicAuth/issues/2537)) ([b01d6c9](https://github.com/dynamic-labs/DynamicAuth/commit/b01d6c9e91e9971e82739c5a2c900de4768f977c))
17
+ * log out if there's any session sync issue ([#2545](https://github.com/dynamic-labs/DynamicAuth/issues/2545)) ([29972fa](https://github.com/dynamic-labs/DynamicAuth/commit/29972fad1067f5550a61f6e2cd9adcaf811fd268))
18
+ * persist chain to WalletConnect session when changed in wallet ([#2556](https://github.com/dynamic-labs/DynamicAuth/issues/2556)) ([fc9ec35](https://github.com/dynamic-labs/DynamicAuth/commit/fc9ec3501de1e3235adee4df95b296dc22cce23e))
19
+ * WC2 sign-message on non-selected chain ([#2544](https://github.com/dynamic-labs/DynamicAuth/issues/2544)) ([48a4384](https://github.com/dynamic-labs/DynamicAuth/commit/48a4384f77c29775e0c28ed335956cfbd6f89ca3))
20
+ * **wcv2:** add eth_signTypedData_v4 to optional methods ([#2527](https://github.com/dynamic-labs/DynamicAuth/issues/2527)) ([b99474b](https://github.com/dynamic-labs/DynamicAuth/commit/b99474b81b083134762be0fe9554a6f049b3edda))
21
+ * **wcv2:** allow getWeb3Provider to wait to provider init ([#2523](https://github.com/dynamic-labs/DynamicAuth/issues/2523)) ([d9c7fee](https://github.com/dynamic-labs/DynamicAuth/commit/d9c7fee10d2a6c766043515e19829fd7e3d5b2ef))
22
+
2
23
  ## [0.18.0-RC.8](https://github.com/dynamic-labs/DynamicAuth/compare/v0.18.0-RC.7...v0.18.0-RC.8) (2023-06-29)
3
24
 
4
25
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynamic-labs/ethereum",
3
- "version": "0.18.0-RC.8",
3
+ "version": "0.18.0-RC.9",
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.18.0-RC.8",
36
- "@dynamic-labs/types": "0.18.0-RC.8",
37
- "@dynamic-labs/utils": "0.18.0-RC.8",
38
- "@dynamic-labs/wallet-book": "0.18.0-RC.8",
39
- "@dynamic-labs/wallet-connector-core": "0.18.0-RC.8"
35
+ "@dynamic-labs/rpc-providers": "0.18.0-RC.9",
36
+ "@dynamic-labs/types": "0.18.0-RC.9",
37
+ "@dynamic-labs/utils": "0.18.0-RC.9",
38
+ "@dynamic-labs/wallet-book": "0.18.0-RC.9",
39
+ "@dynamic-labs/wallet-connector-core": "0.18.0-RC.9"
40
40
  },
41
41
  "peerDependencies": {}
42
42
  }
@@ -139,6 +139,12 @@ class WalletConnect extends EthWalletConnector.EthWalletConnector {
139
139
  return client.accounts;
140
140
  });
141
141
  }
142
+ getSession() {
143
+ var _a;
144
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
145
+ return (_a = this.client) === null || _a === void 0 ? void 0 : _a.session;
146
+ });
147
+ }
142
148
  }
143
149
 
144
150
  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 {};
@@ -131,6 +131,12 @@ class WalletConnect extends EthWalletConnector {
131
131
  return client.accounts;
132
132
  });
133
133
  }
134
+ getSession() {
135
+ var _a;
136
+ return __awaiter(this, void 0, void 0, function* () {
137
+ return (_a = this.client) === null || _a === void 0 ? void 0 : _a.session;
138
+ });
139
+ }
134
140
  }
135
141
 
136
142
  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: {
@@ -66,6 +69,7 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
66
69
  'eth_sign',
67
70
  'personal_sign',
68
71
  'eth_sendTransaction',
72
+ 'eth_signTypedData_v4',
69
73
  ],
70
74
  rpcMap: this.evmNetworkRpcMap(),
71
75
  },
@@ -80,6 +84,7 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
80
84
  createInitProviderPromise() {
81
85
  return _tslib.__awaiter(this, void 0, void 0, function* () {
82
86
  const provider = yield Provider__default["default"].init({
87
+ logger: walletConnectorCore.logger.logLevel.toLowerCase() === 'debug' ? 'debug' : undefined,
83
88
  projectId: this.projectId,
84
89
  });
85
90
  WalletConnectV2.provider = provider;
@@ -141,6 +146,9 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
141
146
  return;
142
147
  }
143
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 });
144
152
  }
145
153
  else if (name === 'accountsChanged') {
146
154
  if (!Array.isArray(data)) {
@@ -168,7 +176,7 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
168
176
  }
169
177
  getWeb3Provider() {
170
178
  if (!WalletConnectV2.provider) {
171
- throw new Error('No provider found');
179
+ return;
172
180
  }
173
181
  return new ethers.ethers.providers.Web3Provider(WalletConnectV2.provider, 'any');
174
182
  }
@@ -222,6 +230,35 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
222
230
  });
223
231
  });
224
232
  }
233
+ /**
234
+ * WalletConnect V2 will fail to send the sign message request if the chainId
235
+ * is not the same as the one in the session. This method will wait for the
236
+ * chainId to change and then retry the sign message request.
237
+ *
238
+ * Otherwise it will just return the result of the sign message request.
239
+ *
240
+ * @param signMessageFn - Function to sign message with provider
241
+ * @param messageToSign - Message to sign
242
+ * @returns
243
+ */
244
+ waitForSignMessage(signMessageFn, messageToSign) {
245
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
246
+ const raceConditionPromise = new Promise((resolve) => {
247
+ // Create listener for chain change event
248
+ this.setupEventListeners({
249
+ onChainChange: () => _tslib.__awaiter(this, void 0, void 0, function* () {
250
+ resolve({ success: false });
251
+ }),
252
+ });
253
+ signMessageFn(messageToSign).then((result) => resolve({ signedMessage: result, success: true }));
254
+ });
255
+ const signedMessageResult = yield raceConditionPromise;
256
+ if (signedMessageResult.success === false) {
257
+ return signMessageFn(messageToSign);
258
+ }
259
+ return signedMessageResult.signedMessage;
260
+ });
261
+ }
225
262
  signMessage(messageToSign) {
226
263
  var _a, _b;
227
264
  return _tslib.__awaiter(this, void 0, void 0, function* () {
@@ -237,23 +274,16 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
237
274
  window.location.href = deepLink;
238
275
  }
239
276
  const web3Provider = this.getWeb3Provider();
240
- const response = web3Provider.send('personal_sign', [
241
- walletConnectorCore.utf8ToHex(messageToSign, true),
242
- this.activeAccount,
243
- ]);
244
- try {
245
- // A terrible hack to get MM to sign the message when it is on the wrong chain
246
- // Since MM supports only one chain at a time, it just hangs when we call
247
- // to sign, and it is not on Mainnet. For some magical reason,
248
- // when we attempt to call again it just works.
249
- if (this.key === 'metamask') {
250
- yield this.promiseWithTimeout(7000, response);
251
- }
252
- }
253
- catch (e) {
254
- walletConnectorCore.logger.debug('metmask failed to sign message');
255
- throw e;
277
+ if (!web3Provider) {
278
+ throw new utils.DynamicError('No web3 provider found');
256
279
  }
280
+ const signMessageFn = (messageToSign) => _tslib.__awaiter(this, void 0, void 0, function* () {
281
+ return web3Provider.send('personal_sign', [
282
+ walletConnectorCore.utf8ToHex(messageToSign, true),
283
+ this.activeAccount,
284
+ ]);
285
+ });
286
+ const response = yield this.waitForSignMessage(signMessageFn, messageToSign);
257
287
  return response;
258
288
  });
259
289
  }
@@ -283,7 +313,9 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
283
313
  }
284
314
  try {
285
315
  yield WalletConnectV2.provider.disconnect();
286
- WalletConnectV2.provider.uri = undefined;
316
+ // We must unset provider on logout so that a new session can be established
317
+ // If we don't then the provider will still have the old session and will hang
318
+ WalletConnectV2.provider = undefined;
287
319
  }
288
320
  catch (e) {
289
321
  walletConnectorCore.logger.debug(e);
@@ -350,18 +382,6 @@ class WalletConnectV2 extends EthWalletConnector.EthWalletConnector {
350
382
  return chains.length ? chains : undefined;
351
383
  });
352
384
  }
353
- // a HACK for MM to sign message when the selected chain is not mainnet
354
- promiseWithTimeout(ms, promise) {
355
- // Create a promise that rejects in <ms> milliseconds
356
- const timeout = new Promise((_, reject) => {
357
- const id = setTimeout(() => {
358
- clearTimeout(id);
359
- reject(new utils.DynamicError(undefined, 'metamask_timeout'));
360
- }, ms);
361
- });
362
- // Returns a race between our timeout and the passed in promise
363
- return Promise.race([promise, timeout]);
364
- }
365
385
  }
366
386
 
367
387
  exports.WalletConnectV2 = WalletConnectV2;
@@ -30,8 +30,20 @@ export declare class WalletConnectV2 extends EthWalletConnector {
30
30
  supportsNetworkSwitching(): boolean;
31
31
  setupEventListeners(listeners: WalletEventListeners): void;
32
32
  teardownEventListeners(): void;
33
- getWeb3Provider(): ethers.providers.Web3Provider;
33
+ getWeb3Provider(): ethers.providers.Web3Provider | undefined;
34
34
  fetchPublicAddress(opts?: FetchPublicAddressOpts): Promise<string | undefined>;
35
+ /**
36
+ * WalletConnect V2 will fail to send the sign message request if the chainId
37
+ * is not the same as the one in the session. This method will wait for the
38
+ * chainId to change and then retry the sign message request.
39
+ *
40
+ * Otherwise it will just return the result of the sign message request.
41
+ *
42
+ * @param signMessageFn - Function to sign message with provider
43
+ * @param messageToSign - Message to sign
44
+ * @returns
45
+ */
46
+ protected waitForSignMessage(signMessageFn: (messageToSign: string) => Promise<string | undefined>, messageToSign: string): Promise<string | undefined>;
35
47
  signMessage(messageToSign: string): Promise<string | undefined>;
36
48
  private clearActiveAccount;
37
49
  private clearSession;
@@ -45,5 +57,4 @@ export declare class WalletConnectV2 extends EthWalletConnector {
45
57
  }): Promise<void>;
46
58
  getConnectedAccounts(): Promise<string[]>;
47
59
  getSupportedNetworks(): Promise<string[] | undefined>;
48
- private promiseWithTimeout;
49
60
  }
@@ -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: {
@@ -57,6 +60,7 @@ class WalletConnectV2 extends EthWalletConnector {
57
60
  'eth_sign',
58
61
  'personal_sign',
59
62
  'eth_sendTransaction',
63
+ 'eth_signTypedData_v4',
60
64
  ],
61
65
  rpcMap: this.evmNetworkRpcMap(),
62
66
  },
@@ -71,6 +75,7 @@ class WalletConnectV2 extends EthWalletConnector {
71
75
  createInitProviderPromise() {
72
76
  return __awaiter(this, void 0, void 0, function* () {
73
77
  const provider = yield Provider.init({
78
+ logger: logger.logLevel.toLowerCase() === 'debug' ? 'debug' : undefined,
74
79
  projectId: this.projectId,
75
80
  });
76
81
  WalletConnectV2.provider = provider;
@@ -132,6 +137,9 @@ class WalletConnectV2 extends EthWalletConnector {
132
137
  return;
133
138
  }
134
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 });
135
143
  }
136
144
  else if (name === 'accountsChanged') {
137
145
  if (!Array.isArray(data)) {
@@ -159,7 +167,7 @@ class WalletConnectV2 extends EthWalletConnector {
159
167
  }
160
168
  getWeb3Provider() {
161
169
  if (!WalletConnectV2.provider) {
162
- throw new Error('No provider found');
170
+ return;
163
171
  }
164
172
  return new ethers.providers.Web3Provider(WalletConnectV2.provider, 'any');
165
173
  }
@@ -213,6 +221,35 @@ class WalletConnectV2 extends EthWalletConnector {
213
221
  });
214
222
  });
215
223
  }
224
+ /**
225
+ * WalletConnect V2 will fail to send the sign message request if the chainId
226
+ * is not the same as the one in the session. This method will wait for the
227
+ * chainId to change and then retry the sign message request.
228
+ *
229
+ * Otherwise it will just return the result of the sign message request.
230
+ *
231
+ * @param signMessageFn - Function to sign message with provider
232
+ * @param messageToSign - Message to sign
233
+ * @returns
234
+ */
235
+ waitForSignMessage(signMessageFn, messageToSign) {
236
+ return __awaiter(this, void 0, void 0, function* () {
237
+ const raceConditionPromise = new Promise((resolve) => {
238
+ // Create listener for chain change event
239
+ this.setupEventListeners({
240
+ onChainChange: () => __awaiter(this, void 0, void 0, function* () {
241
+ resolve({ success: false });
242
+ }),
243
+ });
244
+ signMessageFn(messageToSign).then((result) => resolve({ signedMessage: result, success: true }));
245
+ });
246
+ const signedMessageResult = yield raceConditionPromise;
247
+ if (signedMessageResult.success === false) {
248
+ return signMessageFn(messageToSign);
249
+ }
250
+ return signedMessageResult.signedMessage;
251
+ });
252
+ }
216
253
  signMessage(messageToSign) {
217
254
  var _a, _b;
218
255
  return __awaiter(this, void 0, void 0, function* () {
@@ -228,23 +265,16 @@ class WalletConnectV2 extends EthWalletConnector {
228
265
  window.location.href = deepLink;
229
266
  }
230
267
  const web3Provider = this.getWeb3Provider();
231
- const response = web3Provider.send('personal_sign', [
232
- utf8ToHex(messageToSign, true),
233
- this.activeAccount,
234
- ]);
235
- try {
236
- // A terrible hack to get MM to sign the message when it is on the wrong chain
237
- // Since MM supports only one chain at a time, it just hangs when we call
238
- // to sign, and it is not on Mainnet. For some magical reason,
239
- // when we attempt to call again it just works.
240
- if (this.key === 'metamask') {
241
- yield this.promiseWithTimeout(7000, response);
242
- }
243
- }
244
- catch (e) {
245
- logger.debug('metmask failed to sign message');
246
- throw e;
268
+ if (!web3Provider) {
269
+ throw new DynamicError('No web3 provider found');
247
270
  }
271
+ const signMessageFn = (messageToSign) => __awaiter(this, void 0, void 0, function* () {
272
+ return web3Provider.send('personal_sign', [
273
+ utf8ToHex(messageToSign, true),
274
+ this.activeAccount,
275
+ ]);
276
+ });
277
+ const response = yield this.waitForSignMessage(signMessageFn, messageToSign);
248
278
  return response;
249
279
  });
250
280
  }
@@ -274,7 +304,9 @@ class WalletConnectV2 extends EthWalletConnector {
274
304
  }
275
305
  try {
276
306
  yield WalletConnectV2.provider.disconnect();
277
- WalletConnectV2.provider.uri = undefined;
307
+ // We must unset provider on logout so that a new session can be established
308
+ // If we don't then the provider will still have the old session and will hang
309
+ WalletConnectV2.provider = undefined;
278
310
  }
279
311
  catch (e) {
280
312
  logger.debug(e);
@@ -341,18 +373,6 @@ class WalletConnectV2 extends EthWalletConnector {
341
373
  return chains.length ? chains : undefined;
342
374
  });
343
375
  }
344
- // a HACK for MM to sign message when the selected chain is not mainnet
345
- promiseWithTimeout(ms, promise) {
346
- // Create a promise that rejects in <ms> milliseconds
347
- const timeout = new Promise((_, reject) => {
348
- const id = setTimeout(() => {
349
- clearTimeout(id);
350
- reject(new DynamicError(undefined, 'metamask_timeout'));
351
- }, ms);
352
- });
353
- // Returns a race between our timeout and the passed in promise
354
- return Promise.race([promise, timeout]);
355
- }
356
376
  }
357
377
 
358
378
  export { WalletConnectV2 };