@dynamic-labs/sdk-react-core 0.18.0-beta.29 → 0.18.0-beta.30

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,10 @@
1
1
 
2
+ ## [0.18.0-beta.30](https://github.com/dynamic-labs/DynamicAuth/compare/v0.18.0-beta.29...v0.18.0-beta.30) (2023-08-04)
3
+
4
+ ### Bug Fixes
5
+
6
+ * add improves to wallet events handling
7
+
2
8
  ## [0.18.0-beta.29](https://github.com/dynamic-labs/DynamicAuth/compare/v0.18.0-beta.28...v0.18.0-beta.29) (2023-08-03)
3
9
 
4
10
 
package/package.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var version = "0.18.0-beta.29";
5
+ var version = "0.18.0-beta.30";
6
6
  var dependencies = {
7
7
  "react-focus-lock": "2.9.2",
8
8
  "@dynamic-labs/iconic": "0.1.23",
package/package.js CHANGED
@@ -1,4 +1,4 @@
1
- var version = "0.18.0-beta.29";
1
+ var version = "0.18.0-beta.30";
2
2
  var dependencies = {
3
3
  "react-focus-lock": "2.9.2",
4
4
  "@dynamic-labs/iconic": "0.1.23",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynamic-labs/sdk-react-core",
3
- "version": "0.18.0-beta.29",
3
+ "version": "0.18.0-beta.30",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/dynamic-labs/DynamicAuth.git",
@@ -16,13 +16,14 @@
16
16
  "formik": "2.2.9",
17
17
  "qrcode": "1.5.1",
18
18
  "ethers": "5.7.2",
19
- "@dynamic-labs/logger": "0.18.0-beta.29",
20
- "@dynamic-labs/multi-wallet": "0.18.0-beta.29",
21
- "@dynamic-labs/rpc-providers": "0.18.0-beta.29",
22
- "@dynamic-labs/types": "0.18.0-beta.29",
23
- "@dynamic-labs/utils": "0.18.0-beta.29",
24
- "@dynamic-labs/wallet-book": "0.18.0-beta.29",
25
- "@dynamic-labs/wallet-connector-core": "0.18.0-beta.29"
19
+ "@dynamic-labs/logger": "0.18.0-beta.30",
20
+ "@dynamic-labs/multi-wallet": "0.18.0-beta.30",
21
+ "@dynamic-labs/rpc-providers": "0.18.0-beta.30",
22
+ "@dynamic-labs/types": "0.18.0-beta.30",
23
+ "@dynamic-labs/utils": "0.18.0-beta.30",
24
+ "@dynamic-labs/wallet-book": "0.18.0-beta.30",
25
+ "@dynamic-labs/wallet-connector-core": "0.18.0-beta.30",
26
+ "eventemitter3": "5.0.1"
26
27
  },
27
28
  "devDependencies": {
28
29
  "semver": "7.3.8"
@@ -30,3 +30,4 @@ export { useInterval } from './useInterval/useInterval';
30
30
  export { useCountdown } from './useCountdown/useCountdown';
31
31
  export { useValidateSession } from './useValidateSession';
32
32
  export { useEventListener } from './useEventListener';
33
+ export { useWalletConnectorEvent } from './useWalletConnectorEvent';
@@ -0,0 +1 @@
1
+ export { useWalletConnectorEvent } from './useWalletConnectorEvent';
@@ -0,0 +1,42 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var React = require('react');
6
+ var useIsomorphicLayoutEffect = require('../useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.cjs');
7
+
8
+ const useWalletConnectorEvent = (eventEmitters, eventName, handler) => {
9
+ const callbackRef = React.useRef(handler);
10
+ useIsomorphicLayoutEffect.useIsomorphicLayoutEffect(() => {
11
+ callbackRef.current = handler;
12
+ }, [handler]);
13
+ React.useEffect(() => {
14
+ if (!eventEmitters)
15
+ return;
16
+ const eventEmittersArray = Array.isArray(eventEmitters)
17
+ ? eventEmitters
18
+ : [eventEmitters];
19
+ /**
20
+ * Initialize the event listeners for the wallet connectors
21
+ * to ensure they were initialized before listening to events
22
+ *
23
+ * This will be removed when all wallets are migrated to
24
+ * use the event emitter "emit" method
25
+ *
26
+ * Ticket todo - QNTM-88
27
+ */
28
+ eventEmittersArray.forEach((connector) => connector.initEventListener());
29
+ const uniqueEventEmitters = Array.from(new Set(eventEmittersArray));
30
+ const unsubscribeCallbacks = uniqueEventEmitters.map((emitter) => {
31
+ const callback = (...args) => {
32
+ callbackRef.current(emitter, ...args);
33
+ };
34
+ emitter.on(eventName, callback);
35
+ return () => emitter.off(eventName, callback);
36
+ });
37
+ return () => unsubscribeCallbacks.forEach((unsubscribe) => unsubscribe());
38
+ // eslint-disable-next-line react-hooks/exhaustive-deps
39
+ }, [eventEmitters, eventName]);
40
+ };
41
+
42
+ exports.useWalletConnectorEvent = useWalletConnectorEvent;
@@ -0,0 +1,12 @@
1
+ import { WalletConnector, WalletConnectorEventTypes } from '@dynamic-labs/wallet-connector-core';
2
+ /**
3
+ * This type is a copy of the ArgumentMap type from eventemitter3 package.
4
+ * Is used extract the arguments from a event type.
5
+ * Then we can use the arguments to reconstruct the callback we want
6
+ */
7
+ type ArgumentMap<T extends object> = {
8
+ [K in keyof T]: T[K] extends (...args: any[]) => void ? Parameters<T[K]> : T[K] extends any[] ? T[K] : any[];
9
+ };
10
+ type EventArg<Event extends keyof WalletConnectorEventTypes> = ArgumentMap<WalletConnectorEventTypes>[Extract<Event, keyof WalletConnectorEventTypes>];
11
+ export declare const useWalletConnectorEvent: <Event_1 extends keyof WalletConnectorEventTypes = keyof WalletConnectorEventTypes>(eventEmitters: WalletConnector | WalletConnector[] | undefined, eventName: Event_1, handler: (connector: WalletConnector, ...args: EventArg<Event_1>) => void) => void;
12
+ export {};
@@ -0,0 +1,38 @@
1
+ import { useRef, useEffect } from 'react';
2
+ import { useIsomorphicLayoutEffect } from '../useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.js';
3
+
4
+ const useWalletConnectorEvent = (eventEmitters, eventName, handler) => {
5
+ const callbackRef = useRef(handler);
6
+ useIsomorphicLayoutEffect(() => {
7
+ callbackRef.current = handler;
8
+ }, [handler]);
9
+ useEffect(() => {
10
+ if (!eventEmitters)
11
+ return;
12
+ const eventEmittersArray = Array.isArray(eventEmitters)
13
+ ? eventEmitters
14
+ : [eventEmitters];
15
+ /**
16
+ * Initialize the event listeners for the wallet connectors
17
+ * to ensure they were initialized before listening to events
18
+ *
19
+ * This will be removed when all wallets are migrated to
20
+ * use the event emitter "emit" method
21
+ *
22
+ * Ticket todo - QNTM-88
23
+ */
24
+ eventEmittersArray.forEach((connector) => connector.initEventListener());
25
+ const uniqueEventEmitters = Array.from(new Set(eventEmittersArray));
26
+ const unsubscribeCallbacks = uniqueEventEmitters.map((emitter) => {
27
+ const callback = (...args) => {
28
+ callbackRef.current(emitter, ...args);
29
+ };
30
+ emitter.on(eventName, callback);
31
+ return () => emitter.off(eventName, callback);
32
+ });
33
+ return () => unsubscribeCallbacks.forEach((unsubscribe) => unsubscribe());
34
+ // eslint-disable-next-line react-hooks/exhaustive-deps
35
+ }, [eventEmitters, eventName]);
36
+ };
37
+
38
+ export { useWalletConnectorEvent };
@@ -44,6 +44,18 @@ const useWalletConnectors = ({ authMode, authToken, connectedWallets, wallets: a
44
44
  }
45
45
  return connectedWallets;
46
46
  }, [authMode, connectedWallets, linkedWallets, user, onboardingOnlyJwt]);
47
+ /**
48
+ * This useEffect is temporary.
49
+ * While the wallet connectors don't use the event emitter, we need to manually
50
+ * initialize the bridge between the old event listeners and the new event emitter.
51
+ * When the wallet connectors are migrated to the new event emitter, there will be no
52
+ * need to initialize or teardown event listeners, then we can remove this useEffect.
53
+ * @todo remove this useEffect
54
+ * Ticket todo - QNTM-88
55
+ */
56
+ React.useEffect(() => walletsBasedOnAuthMode.forEach((wallet) => {
57
+ wallet.connector.initEventListener();
58
+ }), [walletsBasedOnAuthMode]);
47
59
  const { connectedWalletMap, computeConnectedStateForWallets, didConnectedStateLoad, } = useWalletsConnectionState.useWalletsConnectionState(walletsBasedOnAuthMode);
48
60
  const wallets = React.useMemo(() => walletsBasedOnAuthMode.map((wallet) => (Object.assign(Object.assign({}, wallet), { connected: Boolean(connectedWalletMap[wallet.id]) }))), [connectedWalletMap, walletsBasedOnAuthMode]);
49
61
  React.useEffect(() => {
@@ -40,6 +40,18 @@ const useWalletConnectors = ({ authMode, authToken, connectedWallets, wallets: a
40
40
  }
41
41
  return connectedWallets;
42
42
  }, [authMode, connectedWallets, linkedWallets, user, onboardingOnlyJwt]);
43
+ /**
44
+ * This useEffect is temporary.
45
+ * While the wallet connectors don't use the event emitter, we need to manually
46
+ * initialize the bridge between the old event listeners and the new event emitter.
47
+ * When the wallet connectors are migrated to the new event emitter, there will be no
48
+ * need to initialize or teardown event listeners, then we can remove this useEffect.
49
+ * @todo remove this useEffect
50
+ * Ticket todo - QNTM-88
51
+ */
52
+ useEffect(() => walletsBasedOnAuthMode.forEach((wallet) => {
53
+ wallet.connector.initEventListener();
54
+ }), [walletsBasedOnAuthMode]);
43
55
  const { connectedWalletMap, computeConnectedStateForWallets, didConnectedStateLoad, } = useWalletsConnectionState(walletsBasedOnAuthMode);
44
56
  const wallets = useMemo(() => walletsBasedOnAuthMode.map((wallet) => (Object.assign(Object.assign({}, wallet), { connected: Boolean(connectedWalletMap[wallet.id]) }))), [connectedWalletMap, walletsBasedOnAuthMode]);
45
57
  useEffect(() => {
@@ -16,12 +16,11 @@ require('../../constants/colors.cjs');
16
16
  require('../../../shared/utils/classes/storage/localStorage.cjs');
17
17
  require('ethers');
18
18
  require('../../../shared/consts/index.cjs');
19
+ var useWalletConnectorEvent = require('../useWalletConnectorEvent/useWalletConnectorEvent.cjs');
19
20
 
20
- const orderedSecondaryWalletAddresses = (wallets) => wallets.map((wallet) => wallet.address).sort();
21
21
  const useWalletEventListeners = ({ computeConnectedStateForWallets, handleLogOut, multiWallet, multiWalletWidgetState, primaryWallet, secondaryWallets, selectedWalletConnector, selectedWalletWithAction, setSelectedWalletConnector, setSelectedWalletWithAction, setMultiWalletWidgetState, user, setPrimaryWalletId, authMode, refreshConnectedWallet, }) => {
22
22
  const [loadingNetwork, setLoadingNetwork] = React.useState(true);
23
23
  const [network, setNetwork] = React.useState(undefined);
24
- const seen = new Set();
25
24
  React.useEffect(() => {
26
25
  const fetchNetwork = () => _tslib.__awaiter(void 0, void 0, void 0, function* () {
27
26
  try {
@@ -40,36 +39,100 @@ const useWalletEventListeners = ({ computeConnectedStateForWallets, handleLogOut
40
39
  });
41
40
  fetchNetwork();
42
41
  }, [primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.id]);
43
- React.useEffect(() => {
42
+ useWalletConnectorEvent.useWalletConnectorEvent(primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector, 'disconnect', () => {
43
+ logger.logger.debug('primary wallet disconnect');
44
+ handleLogOut();
45
+ });
46
+ useWalletConnectorEvent.useWalletConnectorEvent(primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector, 'chainChange', (_, { chain }) => {
47
+ logger.logger.debug('primary wallet chain change', { chain });
44
48
  if (!primaryWallet) {
45
49
  return;
46
50
  }
47
- addPrimaryWalletEventListeners(seen);
48
- return () => {
49
- primaryWallet.connector.teardownEventListeners();
50
- };
51
- // justification: we don't want to setup event listeners more than needed
52
- // eslint-disable-next-line react-hooks/exhaustive-deps
53
- }, [
54
- user,
55
- primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.address,
56
- primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.id,
57
- multiWalletWidgetState,
58
- // eslint-disable-next-line react-hooks/exhaustive-deps
59
- selectedWalletConnector === null || selectedWalletConnector === void 0 ? void 0 : selectedWalletConnector.name,
60
- primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector.isInitialized,
61
- ]);
62
- React.useEffect(() => {
63
- addSecondaryWalletEventListeners(seen);
64
- return () => {
65
- for (const wallet of secondaryWallets) {
66
- wallet.connector.teardownEventListeners();
51
+ refreshConnectedWallet(primaryWallet.id, primaryWallet.connector);
52
+ // https://linear.app/dynamic-labs/issue/QNTM-84/breaking-change-rename-network-to-primarywalletnetwork
53
+ if (primaryWallet.chain === 'starknet') {
54
+ setNetwork(chain);
55
+ }
56
+ else {
57
+ setNetwork(parseInt(chain));
58
+ }
59
+ });
60
+ useWalletConnectorEvent.useWalletConnectorEvent(primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector, 'accountChange', (_, { accounts }) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
61
+ logger.logger.debug('primary wallet account change', {
62
+ accounts,
63
+ });
64
+ // change the api here
65
+ if (!primaryWallet)
66
+ return;
67
+ const [newAddress] = accounts;
68
+ const newWallet = secondaryWallets.find((wallet) => walletConnectorCore.isSameAddress(wallet.address, newAddress, wallet.chain));
69
+ if (authMode === 'connect-only') {
70
+ refreshConnectedWallet(primaryWallet.id, primaryWallet.connector);
71
+ return;
72
+ }
73
+ if (walletConnectorCore.isSameAddress(newAddress, primaryWallet.address, primaryWallet.chain)) {
74
+ setMultiWalletWidgetState('idle');
75
+ }
76
+ else if (!multiWallet) {
77
+ yield handleLogOut();
78
+ return;
79
+ }
80
+ else if (multiWalletWidgetState === 'awaiting_account_switch') {
81
+ handleAccountChangeWhenAwaitingAccountSwitch(true, newAddress);
82
+ }
83
+ else if (multiWalletWidgetState === 'idle' && newWallet) {
84
+ setPrimaryWalletId(newWallet.id);
85
+ }
86
+ else if (multiWalletWidgetState === 'idle' && !newWallet) {
87
+ if (user) {
88
+ setMultiWalletWidgetState('detected_new_wallet');
89
+ setSelectedWalletConnector(primaryWallet.connector);
90
+ yield computeConnectedStateForWallets();
91
+ return;
67
92
  }
68
- };
69
- }, [
70
- multiWalletWidgetState,
71
- orderedSecondaryWalletAddresses(secondaryWallets).join(),
72
- ]);
93
+ }
94
+ else {
95
+ logger.logger.error(`Unexpected multiWalletWidgetState (${multiWalletWidgetState}) and onAccountChange combination. Resetting state to idle.`);
96
+ setMultiWalletWidgetState('idle');
97
+ }
98
+ yield computeConnectedStateForWallets();
99
+ }));
100
+ const uniqueNonPrimaryWallets = React.useMemo(() => {
101
+ const primaryConnector = primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector;
102
+ const secondaryConnectors = secondaryWallets.map(({ connector }) => connector);
103
+ const allWalletConnectors = new Set([
104
+ ...secondaryConnectors,
105
+ primaryConnector,
106
+ selectedWalletConnector,
107
+ ].filter((connector) => Boolean(connector)));
108
+ if (primaryConnector) {
109
+ allWalletConnectors.delete(primaryConnector);
110
+ }
111
+ return Array.from(allWalletConnectors);
112
+ }, [secondaryWallets, selectedWalletConnector, primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector]);
113
+ useWalletConnectorEvent.useWalletConnectorEvent(uniqueNonPrimaryWallets, 'accountChange', () => _tslib.__awaiter(void 0, void 0, void 0, function* () {
114
+ logger.logger.debug('secondary wallet account change');
115
+ if (authMode === 'connect-only' && secondaryWallets.length) {
116
+ refreshConnectedWallet(secondaryWallets[0].id, secondaryWallets[0].connector);
117
+ return;
118
+ }
119
+ if (multiWalletWidgetState === 'awaiting_account_switch') {
120
+ handleAccountChangeWhenAwaitingAccountSwitch(false, (selectedWalletWithAction === null || selectedWalletWithAction === void 0 ? void 0 : selectedWalletWithAction.wallet.address) || '');
121
+ }
122
+ yield computeConnectedStateForWallets();
123
+ }));
124
+ useWalletConnectorEvent.useWalletConnectorEvent(uniqueNonPrimaryWallets, 'chainChange', () => _tslib.__awaiter(void 0, void 0, void 0, function* () {
125
+ logger.logger.debug('secondary wallet chain change');
126
+ // We should pass the proper walletId here
127
+ if (!secondaryWallets.length) {
128
+ return;
129
+ }
130
+ refreshConnectedWallet(secondaryWallets[0].id, secondaryWallets[0].connector);
131
+ }));
132
+ useWalletConnectorEvent.useWalletConnectorEvent(uniqueNonPrimaryWallets, 'disconnect', () => {
133
+ logger.logger.debug('secondary wallet disconnect');
134
+ computeConnectedStateForWallets();
135
+ });
73
136
  const handleAccountChangeWhenAwaitingAccountSwitch = React.useCallback((isPrimaryWallet, newAddress) => {
74
137
  const linkedSecondaryWallet = secondaryWallets.find((wallet) => walletConnectorCore.isSameAddress(wallet.address, newAddress, wallet.chain));
75
138
  // this means the user is linking a new account, so we need proof of ownership...
@@ -92,120 +155,6 @@ const useWalletEventListeners = ({ computeConnectedStateForWallets, handleLogOut
92
155
  setSelectedWalletWithAction,
93
156
  setPrimaryWalletId,
94
157
  ]);
95
- const addPrimaryWalletEventListeners = React.useCallback((seen) => {
96
- if (!primaryWallet) {
97
- return;
98
- }
99
- seen.add(primaryWallet.connector.name);
100
- primaryWallet.connector.setupEventListeners({
101
- onAccountChange: (accounts) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
102
- const [newAddress] = accounts;
103
- const newWallet = secondaryWallets.find((wallet) => walletConnectorCore.isSameAddress(wallet.address, newAddress, wallet.chain));
104
- if (authMode === 'connect-only') {
105
- refreshConnectedWallet(primaryWallet.id, primaryWallet.connector);
106
- return;
107
- }
108
- if (walletConnectorCore.isSameAddress(newAddress, primaryWallet.address, primaryWallet.chain)) {
109
- setMultiWalletWidgetState('idle');
110
- }
111
- else if (!multiWallet) {
112
- yield handleLogOut();
113
- return;
114
- }
115
- else if (multiWalletWidgetState === 'awaiting_account_switch') {
116
- handleAccountChangeWhenAwaitingAccountSwitch(true, newAddress);
117
- }
118
- else if (multiWalletWidgetState === 'idle' && newWallet) {
119
- setPrimaryWalletId(newWallet.id);
120
- }
121
- else if (multiWalletWidgetState === 'idle' && !newWallet) {
122
- if (user) {
123
- setMultiWalletWidgetState('detected_new_wallet');
124
- setSelectedWalletConnector(primaryWallet.connector);
125
- yield computeConnectedStateForWallets();
126
- return;
127
- }
128
- }
129
- else {
130
- logger.logger.error(`Unexpected multiWalletWidgetState (${multiWalletWidgetState}) and onAccountChange combination. Resetting state to idle.`);
131
- setMultiWalletWidgetState('idle');
132
- }
133
- yield computeConnectedStateForWallets();
134
- }),
135
- onChainChange: (chain) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
136
- if (!primaryWallet) {
137
- return;
138
- }
139
- refreshConnectedWallet(primaryWallet.id, primaryWallet.connector);
140
- // https://linear.app/dynamic-labs/issue/QNTM-84/breaking-change-rename-network-to-primarywalletnetwork
141
- if (primaryWallet.chain === 'starknet') {
142
- setNetwork(chain);
143
- }
144
- else {
145
- setNetwork(parseInt(chain));
146
- }
147
- }),
148
- onDisconnect: handleLogOut,
149
- });
150
- }, [
151
- authMode,
152
- primaryWallet,
153
- setMultiWalletWidgetState,
154
- multiWallet,
155
- user,
156
- computeConnectedStateForWallets,
157
- handleLogOut,
158
- multiWalletWidgetState,
159
- secondaryWallets,
160
- setSelectedWalletConnector,
161
- handleAccountChangeWhenAwaitingAccountSwitch,
162
- setPrimaryWalletId,
163
- refreshConnectedWallet,
164
- ]);
165
- const addSecondaryWalletEventListeners = React.useCallback((seen) => {
166
- const secondaryListeners = {
167
- onAccountChange: () => _tslib.__awaiter(void 0, void 0, void 0, function* () {
168
- if (authMode === 'connect-only' && secondaryWallets.length) {
169
- refreshConnectedWallet(secondaryWallets[0].id, secondaryWallets[0].connector);
170
- return;
171
- }
172
- if (multiWalletWidgetState === 'awaiting_account_switch') {
173
- handleAccountChangeWhenAwaitingAccountSwitch(false, (selectedWalletWithAction === null || selectedWalletWithAction === void 0 ? void 0 : selectedWalletWithAction.wallet.address) || '');
174
- }
175
- yield computeConnectedStateForWallets();
176
- }),
177
- onChainChange: () => _tslib.__awaiter(void 0, void 0, void 0, function* () {
178
- // We should pass the proper walletId here
179
- if (!secondaryWallets.length) {
180
- return;
181
- }
182
- refreshConnectedWallet(secondaryWallets[0].id, secondaryWallets[0].connector);
183
- }),
184
- onDisconnect: () => _tslib.__awaiter(void 0, void 0, void 0, function* () {
185
- yield computeConnectedStateForWallets();
186
- }),
187
- };
188
- if (selectedWalletConnector && !seen.has(selectedWalletConnector.name)) {
189
- seen.add(selectedWalletConnector.name);
190
- selectedWalletConnector.setupEventListeners(secondaryListeners);
191
- }
192
- for (const wallet of secondaryWallets) {
193
- if (seen.has(wallet.connector.name)) {
194
- continue;
195
- }
196
- seen.add(wallet.connector.name);
197
- wallet.connector.setupEventListeners(secondaryListeners);
198
- }
199
- }, [
200
- authMode,
201
- computeConnectedStateForWallets,
202
- selectedWalletConnector,
203
- selectedWalletWithAction,
204
- handleAccountChangeWhenAwaitingAccountSwitch,
205
- multiWalletWidgetState,
206
- secondaryWallets,
207
- refreshConnectedWallet,
208
- ]);
209
158
  return {
210
159
  loadingNetwork,
211
160
  network,
@@ -1,5 +1,5 @@
1
1
  import { __awaiter } from '../../../../../_virtual/_tslib.js';
2
- import { useState, useEffect, useCallback } from 'react';
2
+ import { useState, useEffect, useMemo, useCallback } from 'react';
3
3
  import { isSameAddress } from '@dynamic-labs/wallet-connector-core';
4
4
  import '@dynamic-labs/sdk-api';
5
5
  import { logger } from '../../../shared/logger.js';
@@ -12,12 +12,11 @@ import '../../constants/colors.js';
12
12
  import '../../../shared/utils/classes/storage/localStorage.js';
13
13
  import 'ethers';
14
14
  import '../../../shared/consts/index.js';
15
+ import { useWalletConnectorEvent } from '../useWalletConnectorEvent/useWalletConnectorEvent.js';
15
16
 
16
- const orderedSecondaryWalletAddresses = (wallets) => wallets.map((wallet) => wallet.address).sort();
17
17
  const useWalletEventListeners = ({ computeConnectedStateForWallets, handleLogOut, multiWallet, multiWalletWidgetState, primaryWallet, secondaryWallets, selectedWalletConnector, selectedWalletWithAction, setSelectedWalletConnector, setSelectedWalletWithAction, setMultiWalletWidgetState, user, setPrimaryWalletId, authMode, refreshConnectedWallet, }) => {
18
18
  const [loadingNetwork, setLoadingNetwork] = useState(true);
19
19
  const [network, setNetwork] = useState(undefined);
20
- const seen = new Set();
21
20
  useEffect(() => {
22
21
  const fetchNetwork = () => __awaiter(void 0, void 0, void 0, function* () {
23
22
  try {
@@ -36,36 +35,100 @@ const useWalletEventListeners = ({ computeConnectedStateForWallets, handleLogOut
36
35
  });
37
36
  fetchNetwork();
38
37
  }, [primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.id]);
39
- useEffect(() => {
38
+ useWalletConnectorEvent(primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector, 'disconnect', () => {
39
+ logger.debug('primary wallet disconnect');
40
+ handleLogOut();
41
+ });
42
+ useWalletConnectorEvent(primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector, 'chainChange', (_, { chain }) => {
43
+ logger.debug('primary wallet chain change', { chain });
40
44
  if (!primaryWallet) {
41
45
  return;
42
46
  }
43
- addPrimaryWalletEventListeners(seen);
44
- return () => {
45
- primaryWallet.connector.teardownEventListeners();
46
- };
47
- // justification: we don't want to setup event listeners more than needed
48
- // eslint-disable-next-line react-hooks/exhaustive-deps
49
- }, [
50
- user,
51
- primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.address,
52
- primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.id,
53
- multiWalletWidgetState,
54
- // eslint-disable-next-line react-hooks/exhaustive-deps
55
- selectedWalletConnector === null || selectedWalletConnector === void 0 ? void 0 : selectedWalletConnector.name,
56
- primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector.isInitialized,
57
- ]);
58
- useEffect(() => {
59
- addSecondaryWalletEventListeners(seen);
60
- return () => {
61
- for (const wallet of secondaryWallets) {
62
- wallet.connector.teardownEventListeners();
47
+ refreshConnectedWallet(primaryWallet.id, primaryWallet.connector);
48
+ // https://linear.app/dynamic-labs/issue/QNTM-84/breaking-change-rename-network-to-primarywalletnetwork
49
+ if (primaryWallet.chain === 'starknet') {
50
+ setNetwork(chain);
51
+ }
52
+ else {
53
+ setNetwork(parseInt(chain));
54
+ }
55
+ });
56
+ useWalletConnectorEvent(primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector, 'accountChange', (_, { accounts }) => __awaiter(void 0, void 0, void 0, function* () {
57
+ logger.debug('primary wallet account change', {
58
+ accounts,
59
+ });
60
+ // change the api here
61
+ if (!primaryWallet)
62
+ return;
63
+ const [newAddress] = accounts;
64
+ const newWallet = secondaryWallets.find((wallet) => isSameAddress(wallet.address, newAddress, wallet.chain));
65
+ if (authMode === 'connect-only') {
66
+ refreshConnectedWallet(primaryWallet.id, primaryWallet.connector);
67
+ return;
68
+ }
69
+ if (isSameAddress(newAddress, primaryWallet.address, primaryWallet.chain)) {
70
+ setMultiWalletWidgetState('idle');
71
+ }
72
+ else if (!multiWallet) {
73
+ yield handleLogOut();
74
+ return;
75
+ }
76
+ else if (multiWalletWidgetState === 'awaiting_account_switch') {
77
+ handleAccountChangeWhenAwaitingAccountSwitch(true, newAddress);
78
+ }
79
+ else if (multiWalletWidgetState === 'idle' && newWallet) {
80
+ setPrimaryWalletId(newWallet.id);
81
+ }
82
+ else if (multiWalletWidgetState === 'idle' && !newWallet) {
83
+ if (user) {
84
+ setMultiWalletWidgetState('detected_new_wallet');
85
+ setSelectedWalletConnector(primaryWallet.connector);
86
+ yield computeConnectedStateForWallets();
87
+ return;
63
88
  }
64
- };
65
- }, [
66
- multiWalletWidgetState,
67
- orderedSecondaryWalletAddresses(secondaryWallets).join(),
68
- ]);
89
+ }
90
+ else {
91
+ logger.error(`Unexpected multiWalletWidgetState (${multiWalletWidgetState}) and onAccountChange combination. Resetting state to idle.`);
92
+ setMultiWalletWidgetState('idle');
93
+ }
94
+ yield computeConnectedStateForWallets();
95
+ }));
96
+ const uniqueNonPrimaryWallets = useMemo(() => {
97
+ const primaryConnector = primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector;
98
+ const secondaryConnectors = secondaryWallets.map(({ connector }) => connector);
99
+ const allWalletConnectors = new Set([
100
+ ...secondaryConnectors,
101
+ primaryConnector,
102
+ selectedWalletConnector,
103
+ ].filter((connector) => Boolean(connector)));
104
+ if (primaryConnector) {
105
+ allWalletConnectors.delete(primaryConnector);
106
+ }
107
+ return Array.from(allWalletConnectors);
108
+ }, [secondaryWallets, selectedWalletConnector, primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector]);
109
+ useWalletConnectorEvent(uniqueNonPrimaryWallets, 'accountChange', () => __awaiter(void 0, void 0, void 0, function* () {
110
+ logger.debug('secondary wallet account change');
111
+ if (authMode === 'connect-only' && secondaryWallets.length) {
112
+ refreshConnectedWallet(secondaryWallets[0].id, secondaryWallets[0].connector);
113
+ return;
114
+ }
115
+ if (multiWalletWidgetState === 'awaiting_account_switch') {
116
+ handleAccountChangeWhenAwaitingAccountSwitch(false, (selectedWalletWithAction === null || selectedWalletWithAction === void 0 ? void 0 : selectedWalletWithAction.wallet.address) || '');
117
+ }
118
+ yield computeConnectedStateForWallets();
119
+ }));
120
+ useWalletConnectorEvent(uniqueNonPrimaryWallets, 'chainChange', () => __awaiter(void 0, void 0, void 0, function* () {
121
+ logger.debug('secondary wallet chain change');
122
+ // We should pass the proper walletId here
123
+ if (!secondaryWallets.length) {
124
+ return;
125
+ }
126
+ refreshConnectedWallet(secondaryWallets[0].id, secondaryWallets[0].connector);
127
+ }));
128
+ useWalletConnectorEvent(uniqueNonPrimaryWallets, 'disconnect', () => {
129
+ logger.debug('secondary wallet disconnect');
130
+ computeConnectedStateForWallets();
131
+ });
69
132
  const handleAccountChangeWhenAwaitingAccountSwitch = useCallback((isPrimaryWallet, newAddress) => {
70
133
  const linkedSecondaryWallet = secondaryWallets.find((wallet) => isSameAddress(wallet.address, newAddress, wallet.chain));
71
134
  // this means the user is linking a new account, so we need proof of ownership...
@@ -88,120 +151,6 @@ const useWalletEventListeners = ({ computeConnectedStateForWallets, handleLogOut
88
151
  setSelectedWalletWithAction,
89
152
  setPrimaryWalletId,
90
153
  ]);
91
- const addPrimaryWalletEventListeners = useCallback((seen) => {
92
- if (!primaryWallet) {
93
- return;
94
- }
95
- seen.add(primaryWallet.connector.name);
96
- primaryWallet.connector.setupEventListeners({
97
- onAccountChange: (accounts) => __awaiter(void 0, void 0, void 0, function* () {
98
- const [newAddress] = accounts;
99
- const newWallet = secondaryWallets.find((wallet) => isSameAddress(wallet.address, newAddress, wallet.chain));
100
- if (authMode === 'connect-only') {
101
- refreshConnectedWallet(primaryWallet.id, primaryWallet.connector);
102
- return;
103
- }
104
- if (isSameAddress(newAddress, primaryWallet.address, primaryWallet.chain)) {
105
- setMultiWalletWidgetState('idle');
106
- }
107
- else if (!multiWallet) {
108
- yield handleLogOut();
109
- return;
110
- }
111
- else if (multiWalletWidgetState === 'awaiting_account_switch') {
112
- handleAccountChangeWhenAwaitingAccountSwitch(true, newAddress);
113
- }
114
- else if (multiWalletWidgetState === 'idle' && newWallet) {
115
- setPrimaryWalletId(newWallet.id);
116
- }
117
- else if (multiWalletWidgetState === 'idle' && !newWallet) {
118
- if (user) {
119
- setMultiWalletWidgetState('detected_new_wallet');
120
- setSelectedWalletConnector(primaryWallet.connector);
121
- yield computeConnectedStateForWallets();
122
- return;
123
- }
124
- }
125
- else {
126
- logger.error(`Unexpected multiWalletWidgetState (${multiWalletWidgetState}) and onAccountChange combination. Resetting state to idle.`);
127
- setMultiWalletWidgetState('idle');
128
- }
129
- yield computeConnectedStateForWallets();
130
- }),
131
- onChainChange: (chain) => __awaiter(void 0, void 0, void 0, function* () {
132
- if (!primaryWallet) {
133
- return;
134
- }
135
- refreshConnectedWallet(primaryWallet.id, primaryWallet.connector);
136
- // https://linear.app/dynamic-labs/issue/QNTM-84/breaking-change-rename-network-to-primarywalletnetwork
137
- if (primaryWallet.chain === 'starknet') {
138
- setNetwork(chain);
139
- }
140
- else {
141
- setNetwork(parseInt(chain));
142
- }
143
- }),
144
- onDisconnect: handleLogOut,
145
- });
146
- }, [
147
- authMode,
148
- primaryWallet,
149
- setMultiWalletWidgetState,
150
- multiWallet,
151
- user,
152
- computeConnectedStateForWallets,
153
- handleLogOut,
154
- multiWalletWidgetState,
155
- secondaryWallets,
156
- setSelectedWalletConnector,
157
- handleAccountChangeWhenAwaitingAccountSwitch,
158
- setPrimaryWalletId,
159
- refreshConnectedWallet,
160
- ]);
161
- const addSecondaryWalletEventListeners = useCallback((seen) => {
162
- const secondaryListeners = {
163
- onAccountChange: () => __awaiter(void 0, void 0, void 0, function* () {
164
- if (authMode === 'connect-only' && secondaryWallets.length) {
165
- refreshConnectedWallet(secondaryWallets[0].id, secondaryWallets[0].connector);
166
- return;
167
- }
168
- if (multiWalletWidgetState === 'awaiting_account_switch') {
169
- handleAccountChangeWhenAwaitingAccountSwitch(false, (selectedWalletWithAction === null || selectedWalletWithAction === void 0 ? void 0 : selectedWalletWithAction.wallet.address) || '');
170
- }
171
- yield computeConnectedStateForWallets();
172
- }),
173
- onChainChange: () => __awaiter(void 0, void 0, void 0, function* () {
174
- // We should pass the proper walletId here
175
- if (!secondaryWallets.length) {
176
- return;
177
- }
178
- refreshConnectedWallet(secondaryWallets[0].id, secondaryWallets[0].connector);
179
- }),
180
- onDisconnect: () => __awaiter(void 0, void 0, void 0, function* () {
181
- yield computeConnectedStateForWallets();
182
- }),
183
- };
184
- if (selectedWalletConnector && !seen.has(selectedWalletConnector.name)) {
185
- seen.add(selectedWalletConnector.name);
186
- selectedWalletConnector.setupEventListeners(secondaryListeners);
187
- }
188
- for (const wallet of secondaryWallets) {
189
- if (seen.has(wallet.connector.name)) {
190
- continue;
191
- }
192
- seen.add(wallet.connector.name);
193
- wallet.connector.setupEventListeners(secondaryListeners);
194
- }
195
- }, [
196
- authMode,
197
- computeConnectedStateForWallets,
198
- selectedWalletConnector,
199
- selectedWalletWithAction,
200
- handleAccountChangeWhenAwaitingAccountSwitch,
201
- multiWalletWidgetState,
202
- secondaryWallets,
203
- refreshConnectedWallet,
204
- ]);
205
154
  return {
206
155
  loadingNetwork,
207
156
  network,