@dynamic-labs/ethereum 4.32.1-preview.0 → 4.32.1

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,10 +1,18 @@
1
1
 
2
- ### [4.32.1-preview.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.32.0...v4.32.1-preview.0) (2025-09-19)
2
+ ### [4.32.1](https://github.com/dynamic-labs/dynamic-auth/compare/v4.32.0...v4.32.1) (2025-09-25)
3
+
4
+
5
+ ### Features
6
+
7
+ * allow connecting multiple WC wallets ([#9493](https://github.com/dynamic-labs/dynamic-auth/issues/9493)) ([350c53c](https://github.com/dynamic-labs/dynamic-auth/commit/350c53cfc2198a565e9a324d9d65c3e57883d772))
8
+ * always use redirect inside MM IAB ([#9535](https://github.com/dynamic-labs/dynamic-auth/issues/9535)) ([8aca796](https://github.com/dynamic-labs/dynamic-auth/commit/8aca7968dfa0ef0f3caee043b415f9f76187112e))
3
9
 
4
10
 
5
11
  ### Bug Fixes
6
12
 
7
13
  * correct naming ([#9513](https://github.com/dynamic-labs/dynamic-auth/issues/9513)) ([5b4e31b](https://github.com/dynamic-labs/dynamic-auth/commit/5b4e31b9bbf2401d377201a4cd12edf79eaef75f))
14
+ * correct Safe Wallet App Store ID to prevent misdirect ([#9531](https://github.com/dynamic-labs/dynamic-auth/issues/9531)) ([b58adc5](https://github.com/dynamic-labs/dynamic-auth/commit/b58adc54de8018bf25011b205b94977da9676c2d))
15
+ * prevent social login popup in headless scenarios ([#9541](https://github.com/dynamic-labs/dynamic-auth/issues/9541)) ([a91c0b0](https://github.com/dynamic-labs/dynamic-auth/commit/a91c0b0d1d09210fa149cae80abab6978f4ae998))
8
16
 
9
17
  ## [4.32.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.31.4...v4.32.0) (2025-09-17)
10
18
 
package/package.cjs CHANGED
@@ -3,6 +3,6 @@
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
- var version = "4.32.1-preview.0";
6
+ var version = "4.32.1";
7
7
 
8
8
  exports.version = version;
package/package.js CHANGED
@@ -1,4 +1,4 @@
1
1
  'use client'
2
- var version = "4.32.1-preview.0";
2
+ var version = "4.32.1";
3
3
 
4
4
  export { version };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynamic-labs/ethereum",
3
- "version": "4.32.1-preview.0",
3
+ "version": "4.32.1",
4
4
  "description": "A React SDK for implementing wallet web3 authentication and authorization to your website.",
5
5
  "author": "Dynamic Labs, Inc.",
6
6
  "license": "MIT",
@@ -24,16 +24,16 @@
24
24
  "eventemitter3": "5.0.1",
25
25
  "buffer": "6.0.3",
26
26
  "@metamask/sdk": "0.33.0",
27
- "@dynamic-labs/assert-package-version": "4.32.1-preview.0",
28
- "@dynamic-labs/embedded-wallet-evm": "4.32.1-preview.0",
29
- "@dynamic-labs/ethereum-core": "4.32.1-preview.0",
30
- "@dynamic-labs/logger": "4.32.1-preview.0",
31
- "@dynamic-labs/rpc-providers": "4.32.1-preview.0",
32
- "@dynamic-labs/types": "4.32.1-preview.0",
33
- "@dynamic-labs/utils": "4.32.1-preview.0",
34
- "@dynamic-labs/waas-evm": "4.32.1-preview.0",
35
- "@dynamic-labs/wallet-book": "4.32.1-preview.0",
36
- "@dynamic-labs/wallet-connector-core": "4.32.1-preview.0"
27
+ "@dynamic-labs/assert-package-version": "4.32.1",
28
+ "@dynamic-labs/embedded-wallet-evm": "4.32.1",
29
+ "@dynamic-labs/ethereum-core": "4.32.1",
30
+ "@dynamic-labs/logger": "4.32.1",
31
+ "@dynamic-labs/rpc-providers": "4.32.1",
32
+ "@dynamic-labs/types": "4.32.1",
33
+ "@dynamic-labs/utils": "4.32.1",
34
+ "@dynamic-labs/waas-evm": "4.32.1",
35
+ "@dynamic-labs/wallet-book": "4.32.1",
36
+ "@dynamic-labs/wallet-connector-core": "4.32.1"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "viem": "^2.28.4"
@@ -414,31 +414,25 @@ class MetaMaskConnector extends InjectedWalletBase.InjectedWalletBase {
414
414
  }
415
415
  shouldDeepLinkToMetaMaskInAppBrowser() {
416
416
  // Not in an in-app browser
417
- console.log('In in-app browser - isInAppBrowser', this.isInAppBrowser);
418
417
  if (this.isInAppBrowser) {
419
418
  return false;
420
419
  }
421
- console.log('In in-app browser - isMobile', utils.isMobile());
422
420
  // Not a mobile device
423
421
  if (!utils.isMobile()) {
424
422
  return false;
425
423
  }
426
- console.log('In in-app browser - mobileExperience', this.mobileExperience);
427
424
  // SDK is configured to use the in-app browser
428
425
  if (this.mobileExperience !== 'in-app-browser') {
429
426
  return false;
430
427
  }
431
- console.log('In in-app browser - metadata.inAppBrowserUrl', this.metadata.inAppBrowserUrl);
432
428
  // Wallet does not have an in-app browser link
433
429
  if (!this.metadata.inAppBrowserUrl) {
434
430
  return false;
435
431
  }
436
- console.log('In in-app browser - navigator.userAgent', navigator.userAgent);
437
432
  // We don't want to deep link to the in-app browser when already in the in-app browser
438
433
  if (navigator.userAgent.match(/metamaskmobile/i)) {
439
434
  return false;
440
435
  }
441
- console.log('In in-app browser - returning true to use deeplink');
442
436
  return true;
443
437
  }
444
438
  getConnectionUri() {
@@ -410,31 +410,25 @@ class MetaMaskConnector extends InjectedWalletBase {
410
410
  }
411
411
  shouldDeepLinkToMetaMaskInAppBrowser() {
412
412
  // Not in an in-app browser
413
- console.log('In in-app browser - isInAppBrowser', this.isInAppBrowser);
414
413
  if (this.isInAppBrowser) {
415
414
  return false;
416
415
  }
417
- console.log('In in-app browser - isMobile', isMobile());
418
416
  // Not a mobile device
419
417
  if (!isMobile()) {
420
418
  return false;
421
419
  }
422
- console.log('In in-app browser - mobileExperience', this.mobileExperience);
423
420
  // SDK is configured to use the in-app browser
424
421
  if (this.mobileExperience !== 'in-app-browser') {
425
422
  return false;
426
423
  }
427
- console.log('In in-app browser - metadata.inAppBrowserUrl', this.metadata.inAppBrowserUrl);
428
424
  // Wallet does not have an in-app browser link
429
425
  if (!this.metadata.inAppBrowserUrl) {
430
426
  return false;
431
427
  }
432
- console.log('In in-app browser - navigator.userAgent', navigator.userAgent);
433
428
  // We don't want to deep link to the in-app browser when already in the in-app browser
434
429
  if (navigator.userAgent.match(/metamaskmobile/i)) {
435
430
  return false;
436
431
  }
437
- console.log('In in-app browser - returning true to use deeplink');
438
432
  return true;
439
433
  }
440
434
  getConnectionUri() {
@@ -236,6 +236,7 @@ class WalletConnectConnector extends ethereumCore.EthereumWalletConnector {
236
236
  network,
237
237
  switchNetworkOnlyFromWallet: this.switchNetworkOnlyFromWallet,
238
238
  });
239
+ yield this.reconnectIfRequired();
239
240
  const currentNetworkId = yield this.getNetwork();
240
241
  walletConnectorCore.logger.logVerboseTroubleshootingMessage('[WalletConnect] providerSwitchNetwork - currentNetworkId', currentNetworkId);
241
242
  if (currentNetworkId && currentNetworkId === network.chainId) {
@@ -258,22 +259,22 @@ class WalletConnectConnector extends ethereumCore.EthereumWalletConnector {
258
259
  getSupportedNetworks() {
259
260
  return _tslib.__awaiter(this, void 0, void 0, function* () {
260
261
  var _a;
262
+ const enabledNetworks = this.evmNetworks.map((network) => network.chainId.toString());
261
263
  const provider = yield WalletConnectProvider.WalletConnectProvider.awaitAndGetProvider();
264
+ // if there is no session to determine supported networks, we need to return the enabled networks
262
265
  if (!(provider === null || provider === void 0 ? void 0 : provider.session)) {
263
- return [];
266
+ return enabledNetworks;
264
267
  }
265
- const chains = [];
268
+ const sessionNetworks = [];
266
269
  // Some wallet (i.e ZenGo) use namespaces.account to list supported chains
267
270
  // while others use keys within the namespaces object
268
271
  Object.keys(provider === null || provider === void 0 ? void 0 : provider.session.namespaces).forEach((key) => {
269
272
  if (key.startsWith('eip155:')) {
270
- chains.push(key.split(':')[1]);
273
+ sessionNetworks.push(key.split(':')[1]);
271
274
  }
272
275
  });
273
- (_a = provider === null || provider === void 0 ? void 0 : provider.session.namespaces.eip155) === null || _a === void 0 ? void 0 : _a.accounts.forEach((account) => chains.push(account.split(':')[1]));
274
- return chains.length
275
- ? chains
276
- : this.evmNetworks.map((network) => network.chainId.toString());
276
+ (_a = provider === null || provider === void 0 ? void 0 : provider.session.namespaces.eip155) === null || _a === void 0 ? void 0 : _a.accounts.forEach((account) => sessionNetworks.push(account.split(':')[1]));
277
+ return sessionNetworks.length ? sessionNetworks : enabledNetworks;
277
278
  });
278
279
  }
279
280
  getDeepLink() {
@@ -304,6 +305,42 @@ class WalletConnectConnector extends ethereumCore.EthereumWalletConnector {
304
305
  getConnectionUri() {
305
306
  return WalletConnectProvider.WalletConnectProvider.getConnectionUri();
306
307
  }
308
+ validateActiveWallet(expectedAddress) {
309
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
310
+ walletConnectorCore.logger.debug('[WalletConnect] validateActiveWallet - validating wallet', expectedAddress);
311
+ const [activeAddress] = yield this.getConnectedAccounts();
312
+ const isWalletActive = activeAddress &&
313
+ walletConnectorCore.isSameAddress(activeAddress, expectedAddress, this.connectedChain);
314
+ if (isWalletActive) {
315
+ walletConnectorCore.logger.debug('[WalletConnect] validateActiveWallet - wallet is active');
316
+ return;
317
+ }
318
+ // if the was an existing session, we need to end it before prompting the user to connect
319
+ // with the wallet they want to use
320
+ if (activeAddress) {
321
+ walletConnectorCore.logger.debug('[WalletConnect] validateActiveWallet - ending existing WC session');
322
+ yield this.endSession();
323
+ }
324
+ walletConnectorCore.logger.debug('[WalletConnect] validateActiveWallet - trying to reconnect WalletConnect wallet...');
325
+ return this.handleWalletNotActive({
326
+ activeAddress,
327
+ expectedAddress,
328
+ });
329
+ });
330
+ }
331
+ reconnectIfRequired() {
332
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
333
+ var _a, _b;
334
+ const wcProvider = yield WalletConnectProvider.WalletConnectProvider.awaitAndGetProvider();
335
+ if (wcProvider === null || wcProvider === void 0 ? void 0 : wcProvider.session) {
336
+ return;
337
+ }
338
+ // we don't really need the address in the WC reconnect view
339
+ yield this.handleWalletNotActive({
340
+ expectedAddress: (_b = (_a = this.getActiveAccount()) === null || _a === void 0 ? void 0 : _a.address) !== null && _b !== void 0 ? _b : '',
341
+ });
342
+ });
343
+ }
307
344
  }
308
345
 
309
346
  exports.WalletConnectConnector = WalletConnectConnector;
@@ -7777,4 +7777,6 @@ export declare class WalletConnectConnector extends EthereumWalletConnector impl
7777
7777
  getSupportedNetworks(): Promise<string[]>;
7778
7778
  getDeepLink(): string | undefined;
7779
7779
  getConnectionUri(): string | undefined;
7780
+ validateActiveWallet(expectedAddress: string): Promise<void>;
7781
+ reconnectIfRequired(): Promise<void>;
7780
7782
  }
@@ -4,7 +4,7 @@ import { createWalletClient, custom } from 'viem';
4
4
  import { toAccount } from 'viem/accounts';
5
5
  import { EthereumWalletConnector, chainsMap, normalizeRpcError } from '@dynamic-labs/ethereum-core';
6
6
  import { StorageService, parseIntSafe, DynamicError, isMobile, template, PlatformService } from '@dynamic-labs/utils';
7
- import { logger, getDeepLink } from '@dynamic-labs/wallet-connector-core';
7
+ import { logger, getDeepLink, isSameAddress } from '@dynamic-labs/wallet-connector-core';
8
8
  import { WalletConnectProvider } from '../WalletConnectProvider/WalletConnectProvider.js';
9
9
 
10
10
  const WC_CURRENT_CHAIN_KEY = 'dynamic-wc2-current-chain';
@@ -232,6 +232,7 @@ class WalletConnectConnector extends EthereumWalletConnector {
232
232
  network,
233
233
  switchNetworkOnlyFromWallet: this.switchNetworkOnlyFromWallet,
234
234
  });
235
+ yield this.reconnectIfRequired();
235
236
  const currentNetworkId = yield this.getNetwork();
236
237
  logger.logVerboseTroubleshootingMessage('[WalletConnect] providerSwitchNetwork - currentNetworkId', currentNetworkId);
237
238
  if (currentNetworkId && currentNetworkId === network.chainId) {
@@ -254,22 +255,22 @@ class WalletConnectConnector extends EthereumWalletConnector {
254
255
  getSupportedNetworks() {
255
256
  return __awaiter(this, void 0, void 0, function* () {
256
257
  var _a;
258
+ const enabledNetworks = this.evmNetworks.map((network) => network.chainId.toString());
257
259
  const provider = yield WalletConnectProvider.awaitAndGetProvider();
260
+ // if there is no session to determine supported networks, we need to return the enabled networks
258
261
  if (!(provider === null || provider === void 0 ? void 0 : provider.session)) {
259
- return [];
262
+ return enabledNetworks;
260
263
  }
261
- const chains = [];
264
+ const sessionNetworks = [];
262
265
  // Some wallet (i.e ZenGo) use namespaces.account to list supported chains
263
266
  // while others use keys within the namespaces object
264
267
  Object.keys(provider === null || provider === void 0 ? void 0 : provider.session.namespaces).forEach((key) => {
265
268
  if (key.startsWith('eip155:')) {
266
- chains.push(key.split(':')[1]);
269
+ sessionNetworks.push(key.split(':')[1]);
267
270
  }
268
271
  });
269
- (_a = provider === null || provider === void 0 ? void 0 : provider.session.namespaces.eip155) === null || _a === void 0 ? void 0 : _a.accounts.forEach((account) => chains.push(account.split(':')[1]));
270
- return chains.length
271
- ? chains
272
- : this.evmNetworks.map((network) => network.chainId.toString());
272
+ (_a = provider === null || provider === void 0 ? void 0 : provider.session.namespaces.eip155) === null || _a === void 0 ? void 0 : _a.accounts.forEach((account) => sessionNetworks.push(account.split(':')[1]));
273
+ return sessionNetworks.length ? sessionNetworks : enabledNetworks;
273
274
  });
274
275
  }
275
276
  getDeepLink() {
@@ -300,6 +301,42 @@ class WalletConnectConnector extends EthereumWalletConnector {
300
301
  getConnectionUri() {
301
302
  return WalletConnectProvider.getConnectionUri();
302
303
  }
304
+ validateActiveWallet(expectedAddress) {
305
+ return __awaiter(this, void 0, void 0, function* () {
306
+ logger.debug('[WalletConnect] validateActiveWallet - validating wallet', expectedAddress);
307
+ const [activeAddress] = yield this.getConnectedAccounts();
308
+ const isWalletActive = activeAddress &&
309
+ isSameAddress(activeAddress, expectedAddress, this.connectedChain);
310
+ if (isWalletActive) {
311
+ logger.debug('[WalletConnect] validateActiveWallet - wallet is active');
312
+ return;
313
+ }
314
+ // if the was an existing session, we need to end it before prompting the user to connect
315
+ // with the wallet they want to use
316
+ if (activeAddress) {
317
+ logger.debug('[WalletConnect] validateActiveWallet - ending existing WC session');
318
+ yield this.endSession();
319
+ }
320
+ logger.debug('[WalletConnect] validateActiveWallet - trying to reconnect WalletConnect wallet...');
321
+ return this.handleWalletNotActive({
322
+ activeAddress,
323
+ expectedAddress,
324
+ });
325
+ });
326
+ }
327
+ reconnectIfRequired() {
328
+ return __awaiter(this, void 0, void 0, function* () {
329
+ var _a, _b;
330
+ const wcProvider = yield WalletConnectProvider.awaitAndGetProvider();
331
+ if (wcProvider === null || wcProvider === void 0 ? void 0 : wcProvider.session) {
332
+ return;
333
+ }
334
+ // we don't really need the address in the WC reconnect view
335
+ yield this.handleWalletNotActive({
336
+ expectedAddress: (_b = (_a = this.getActiveAccount()) === null || _a === void 0 ? void 0 : _a.address) !== null && _b !== void 0 ? _b : '',
337
+ });
338
+ });
339
+ }
303
340
  }
304
341
 
305
342
  export { WalletConnectConnector };