@dynamic-labs/wagmi-connector 4.79.0 → 4.79.2

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,22 @@
1
1
 
2
+ ### [4.79.2](https://github.com/dynamic-labs/dynamic-auth/compare/v4.79.1...v4.79.2) (2026-05-04)
3
+
4
+
5
+ ### Bug Fixes
6
+
7
+ * **react-native:** remove extra react-native turbo modules instructions ([#11126](https://github.com/dynamic-labs/dynamic-auth/issues/11126))
8
+
9
+ ### [4.79.1](https://github.com/dynamic-labs/dynamic-auth/compare/v4.79.0...v4.79.1) (2026-05-01)
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * **playwright:** tolerate confirm-only transfer wallet modal ([#11081](https://github.com/dynamic-labs/dynamic-auth/issues/11081)) ([f4f2b85](https://github.com/dynamic-labs/dynamic-auth/commit/f4f2b85e515a3dfb7f54bd1dd697fa8fddea74f0))
15
+ * **sdk-react-core:** replace rAF polling with setTimeout in animationFrameTimeout ([#11086](https://github.com/dynamic-labs/dynamic-auth/issues/11086)) ([73cad2a](https://github.com/dynamic-labs/dynamic-auth/commit/73cad2a1be0a331b7504aca2b6dcb1ef770a6b37))
16
+ * **wagmi-connector:** emit change on wallet-internal MM account switch DYNT-549 ([#11044](https://github.com/dynamic-labs/dynamic-auth/issues/11044)) ([4345aa2](https://github.com/dynamic-labs/dynamic-auth/commit/4345aa2a96bc0fac5a5c8280875e6ab122391b98)), closes [#11043](https://github.com/dynamic-labs/dynamic-auth/issues/11043) [#11045](https://github.com/dynamic-labs/dynamic-auth/issues/11045) [#10945](https://github.com/dynamic-labs/dynamic-auth/issues/10945) [#10945](https://github.com/dynamic-labs/dynamic-auth/issues/10945)
17
+ * **wagmi-connector:** fix accountChange listener leak DYNT-549 ([#11043](https://github.com/dynamic-labs/dynamic-auth/issues/11043)) ([e4652aa](https://github.com/dynamic-labs/dynamic-auth/commit/e4652aa3b3c586bd4648deda4a0406ca555f3481)), closes [#11044](https://github.com/dynamic-labs/dynamic-auth/issues/11044) [#11045](https://github.com/dynamic-labs/dynamic-auth/issues/11045)
18
+ * **wagmi-connector:** use accountChange event payload as authoritative address in SyncDynamicWagmi DYNT-549 ([#11045](https://github.com/dynamic-labs/dynamic-auth/issues/11045)) ([77a300b](https://github.com/dynamic-labs/dynamic-auth/commit/77a300be77d90dc3c1aefe02a2074764d89a1cb7)), closes [#11043](https://github.com/dynamic-labs/dynamic-auth/issues/11043) [#11044](https://github.com/dynamic-labs/dynamic-auth/issues/11044) [#11044](https://github.com/dynamic-labs/dynamic-auth/issues/11044)
19
+
2
20
  ## [4.79.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.78.1...v4.79.0) (2026-04-30)
3
21
 
4
22
 
package/package.js CHANGED
@@ -1,4 +1,4 @@
1
1
  'use client'
2
- var version = "4.79.0";
2
+ var version = "4.79.2";
3
3
 
4
4
  export { version };
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@dynamic-labs/wagmi-connector",
3
- "version": "4.79.0",
3
+ "version": "4.79.2",
4
4
  "peerDependencies": {
5
5
  "@wagmi/core": "^2.6.4",
6
6
  "react": ">=18.0.0 <20.0.0",
7
7
  "viem": "^2.45.3",
8
8
  "wagmi": "^2.14.11",
9
- "@dynamic-labs/assert-package-version": "4.79.0",
10
- "@dynamic-labs/ethereum-core": "4.79.0",
11
- "@dynamic-labs/logger": "4.79.0",
12
- "@dynamic-labs/rpc-providers": "4.79.0",
13
- "@dynamic-labs/sdk-react-core": "4.79.0",
14
- "@dynamic-labs/types": "4.79.0",
15
- "@dynamic-labs/wallet-connector-core": "4.79.0",
9
+ "@dynamic-labs/assert-package-version": "4.79.2",
10
+ "@dynamic-labs/ethereum-core": "4.79.2",
11
+ "@dynamic-labs/logger": "4.79.2",
12
+ "@dynamic-labs/rpc-providers": "4.79.2",
13
+ "@dynamic-labs/sdk-react-core": "4.79.2",
14
+ "@dynamic-labs/types": "4.79.2",
15
+ "@dynamic-labs/wallet-connector-core": "4.79.2",
16
16
  "eventemitter3": "5.0.1"
17
17
  },
18
18
  "license": "MIT",
@@ -6,14 +6,25 @@ import { logger } from '@dynamic-labs/wallet-connector-core';
6
6
 
7
7
  /* eslint-disable prefer-arrow/prefer-arrow-functions */
8
8
  const getCreateConnectorFn = ({ connectorId, wallet, }) => createConnector((config) => ({
9
+ // Bound listener refs are stored once in connect() and reused in disconnect()
10
+ // so wallet.connector.off() actually unsubscribes what wallet.connector.on()
11
+ // registered. Calling .bind(this) at each call site returned a fresh function
12
+ // each time, so off() never matched on() and listeners accumulated across
13
+ // every connect/disconnect cycle. (DYNT-549)
14
+ _listeners: undefined,
9
15
  connect() {
10
16
  return __awaiter(this, void 0, void 0, function* () {
11
17
  if (!wallet.connector) {
12
18
  throw new Error('WalletConnector is not defined');
13
19
  }
14
- wallet.connector.on('accountChange', this.handleAccountsChange.bind(this));
15
- wallet.connector.on('chainChange', this.handleChainChange.bind(this));
16
- wallet.connector.on('disconnect', this.onDisconnect.bind(this));
20
+ this._listeners = {
21
+ accountChange: this.handleAccountsChange.bind(this),
22
+ chainChange: this.handleChainChange.bind(this),
23
+ disconnect: this.onDisconnect.bind(this),
24
+ };
25
+ wallet.connector.on('accountChange', this._listeners.accountChange);
26
+ wallet.connector.on('chainChange', this._listeners.chainChange);
27
+ wallet.connector.on('disconnect', this._listeners.disconnect);
17
28
  const accounts = yield this.getAccounts();
18
29
  return {
19
30
  accounts,
@@ -23,9 +34,12 @@ const getCreateConnectorFn = ({ connectorId, wallet, }) => createConnector((conf
23
34
  },
24
35
  disconnect() {
25
36
  return __awaiter(this, void 0, void 0, function* () {
26
- wallet.connector.off('accountChange', this.handleAccountsChange.bind(this));
27
- wallet.connector.off('chainChange', this.handleChainChange.bind(this));
28
- wallet.connector.off('disconnect', this.onDisconnect.bind(this));
37
+ if (!this._listeners)
38
+ return;
39
+ wallet.connector.off('accountChange', this._listeners.accountChange);
40
+ wallet.connector.off('chainChange', this._listeners.chainChange);
41
+ wallet.connector.off('disconnect', this._listeners.disconnect);
42
+ this._listeners = undefined;
29
43
  });
30
44
  },
31
45
  getAccounts() {
@@ -77,12 +91,24 @@ const getCreateConnectorFn = ({ connectorId, wallet, }) => createConnector((conf
77
91
  },
78
92
  name: 'Dynamic',
79
93
  onAccountsChanged(accounts) {
80
- // Intentionally does NOT emit `change` on the wagmi emitter. Dynamic keeps
81
- // wagmi's active account aligned with the primary wallet via
82
- // SyncDynamicWagmi, and emitting here risks double-sync races. DYNT-549
83
- // tracks customer reports where wagmi stays one account behind the primary
84
- // wallet after a MetaMask account switch log context so we can correlate
85
- // repro cases with the no-op path taken here.
94
+ var _a, _b;
95
+ const next = (_a = accounts[0]) === null || _a === void 0 ? void 0 : _a.toLowerCase();
96
+ const bound = (_b = wallet === null || wallet === void 0 ? void 0 : wallet.address) === null || _b === void 0 ? void 0 : _b.toLowerCase();
97
+ // Wallet-internal switch (e.g. user toggled accounts inside the MetaMask
98
+ // extension while the Dynamic primary wallet is still bound to this
99
+ // connector). Tell wagmi directly so it doesn't lag a step behind. Safe
100
+ // against SyncDynamicWagmi races because the synthetic newId
101
+ // (`${connector.id}-${wallet.address}`) is unchanged in this branch, so
102
+ // SyncDynamicWagmi.sync() returns early instead of fighting us. DYNT-549.
103
+ if (next && bound && next === bound) {
104
+ config.emitter.emit('change', {
105
+ accounts: accounts.map((a) => getAddress(a)),
106
+ });
107
+ return;
108
+ }
109
+ // Primary-wallet swap (or empty accounts). Leave wagmi state to
110
+ // SyncDynamicWagmi's disconnect/reconnect dance and log so we can
111
+ // correlate stuck-state customer reports with the path taken.
86
112
  logger.instrument('[DynamicWagmiConnector] onAccountsChanged (no-op)', {
87
113
  accounts: accounts.map((a) => getAddress(a)),
88
114
  connectorId,
@@ -37,31 +37,37 @@ const SyncDynamicWagmi = ({ children, connector, wallet, }) => {
37
37
  lastConnectedWalletId.current = newId;
38
38
  connect({ connector });
39
39
  }, [connect, clientStatus]);
40
- const sync = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
40
+ const sync = useCallback((overrideAddress) => __awaiter(void 0, void 0, void 0, function* () {
41
+ // overrideAddress lets the accountChange handler pass the authoritative
42
+ // address from the event payload; the live ref read for prevConnection
43
+ // makes a sync triggered before any re-render still see the post-
44
+ // initial-connect ref state. (DYNT-549 defense-in-depth)
45
+ const address = overrideAddress !== null && overrideAddress !== void 0 ? overrideAddress : wallet === null || wallet === void 0 ? void 0 : wallet.address;
46
+ const prevConnection = Boolean(lastConnectedWalletId.current);
41
47
  logger.logVerboseTroubleshootingMessage('[SyncDynamicWagmi] sync', {
48
+ address,
42
49
  connectorKey: connector === null || connector === void 0 ? void 0 : connector.key,
43
- hasPreviousConnection,
50
+ hasPreviousConnection: prevConnection,
44
51
  lastConnectedWalletId: lastConnectedWalletId.current,
45
- wallet: wallet === null || wallet === void 0 ? void 0 : wallet.address,
46
52
  });
47
53
  // if there's no connector, disconnect wagmi
48
- if (!connector || !(wallet === null || wallet === void 0 ? void 0 : wallet.address)) {
54
+ if (!connector || !address) {
49
55
  disconnectWagmi();
50
56
  return;
51
57
  }
52
- const newId = `${connector.id}-${wallet.address}`;
58
+ const newId = `${connector.id}-${address}`;
53
59
  // if the connector hasn't changed since the last connection, do nothing
54
60
  if (newId === lastConnectedWalletId.current) {
55
61
  return;
56
62
  }
57
63
  // if has a previous connection, disconnect wagmi
58
- if (hasPreviousConnection) {
64
+ if (prevConnection) {
59
65
  disconnectWagmi();
60
66
  }
61
67
  // and then (re)connect wagmi
62
68
  // force reconnect if has disconnected in the preivous step
63
69
  // in case the clientStatus takes a while to update
64
- connectWagmi(connector, newId, hasPreviousConnection);
70
+ connectWagmi(connector, newId, prevConnection);
65
71
  }), [
66
72
  connectWagmi,
67
73
  connector,
@@ -71,14 +77,15 @@ const SyncDynamicWagmi = ({ children, connector, wallet, }) => {
71
77
  ]);
72
78
  // this is for handling the scenario where the user unlocks the wallet,
73
79
  // as well as changes to a linked wallet
74
- useWalletConnectorEvent(wallet === null || wallet === void 0 ? void 0 : wallet.connector, 'accountChange', () => {
80
+ useWalletConnectorEvent(wallet === null || wallet === void 0 ? void 0 : wallet.connector, 'accountChange', ({ accounts }) => {
75
81
  var _a;
76
82
  logger.logVerboseTroubleshootingMessage('[SyncDynamicWagmi] accountChange', {
83
+ accounts,
77
84
  clientStatus,
78
85
  connectorKey: (_a = wallet === null || wallet === void 0 ? void 0 : wallet.connector) === null || _a === void 0 ? void 0 : _a.key,
79
86
  lastConnectedWalletId: lastConnectedWalletId.current,
80
87
  });
81
- sync();
88
+ sync(accounts === null || accounts === void 0 ? void 0 : accounts[0]);
82
89
  });
83
90
  useEffect(() => {
84
91
  logger.logVerboseTroubleshootingMessage('[SyncDynamicWagmi] useEffect', {