@dynamic-labs/sdk-react-core 4.0.0-alpha.18 → 4.0.0-alpha.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.
Files changed (32) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/package.cjs +1 -1
  3. package/package.js +1 -1
  4. package/package.json +11 -11
  5. package/src/lib/components/WalletConnectorEvents/WalletConnectorEvents.cjs +4 -2
  6. package/src/lib/components/WalletConnectorEvents/WalletConnectorEvents.js +4 -2
  7. package/src/lib/locale/en/translation.cjs +7 -4
  8. package/src/lib/locale/en/translation.d.ts +4 -1
  9. package/src/lib/locale/en/translation.js +7 -4
  10. package/src/lib/styles/index.shadow.cjs +1 -1
  11. package/src/lib/styles/index.shadow.js +1 -1
  12. package/src/lib/utils/hooks/index.d.ts +1 -0
  13. package/src/lib/utils/hooks/useConnectWallet/useConnectWallet.cjs +6 -11
  14. package/src/lib/utils/hooks/useConnectWallet/useConnectWallet.js +6 -11
  15. package/src/lib/utils/hooks/useDebounce/index.d.ts +1 -0
  16. package/src/lib/utils/hooks/useDebounce/useDebounce.cjs +22 -0
  17. package/src/lib/utils/hooks/useDebounce/useDebounce.d.ts +1 -0
  18. package/src/lib/utils/hooks/useDebounce/useDebounce.js +18 -0
  19. package/src/lib/utils/hooks/useEmbeddedReveal/useEmbeddedReveal.cjs +5 -2
  20. package/src/lib/utils/hooks/useEmbeddedReveal/useEmbeddedReveal.d.ts +1 -1
  21. package/src/lib/utils/hooks/useEmbeddedReveal/useEmbeddedReveal.js +5 -2
  22. package/src/lib/utils/hooks/useEmbeddedWallet/useEmbeddedWallet.cjs +2 -0
  23. package/src/lib/utils/hooks/useEmbeddedWallet/useEmbeddedWallet.d.ts +1 -0
  24. package/src/lib/utils/hooks/useEmbeddedWallet/useEmbeddedWallet.js +2 -0
  25. package/src/lib/utils/hooks/useSyncEmbeddedWalletFlow/useSyncEmbeddedWalletFlow.cjs +58 -16
  26. package/src/lib/utils/hooks/useSyncEmbeddedWalletFlow/useSyncEmbeddedWalletFlow.d.ts +4 -1
  27. package/src/lib/utils/hooks/useSyncEmbeddedWalletFlow/useSyncEmbeddedWalletFlow.js +59 -17
  28. package/src/lib/utils/hooks/useUserAuth/useUserAuth.cjs +5 -4
  29. package/src/lib/utils/hooks/useUserAuth/useUserAuth.js +5 -4
  30. package/src/lib/views/EmbeddedReveal/EmbeddedRevealView/EmbeddedRevealView.cjs +23 -10
  31. package/src/lib/views/EmbeddedReveal/EmbeddedRevealView/EmbeddedRevealView.d.ts +1 -0
  32. package/src/lib/views/EmbeddedReveal/EmbeddedRevealView/EmbeddedRevealView.js +23 -10
@@ -67,3 +67,4 @@ export * from './useSmartWallets';
67
67
  export { useEmbeddedWalletSessionKeys } from './useEmbeddedWalletSessionKeys';
68
68
  export { useTelegramLogin } from './useTelegramLogin';
69
69
  export { useEndUserWarning } from './useEndUserWarning';
70
+ export { useDebounce } from './useDebounce';
@@ -31,6 +31,7 @@ require('../../../locale/locale.cjs');
31
31
  var getWalletProvider = require('../../functions/getWalletProvider/getWalletProvider.cjs');
32
32
  var isConnectOnly = require('../authenticationHooks/helpers/isConnectOnly.cjs');
33
33
  var getWalletConnectorForWallet = require('../../functions/getWalletConnectorForWallet/getWalletConnectorForWallet.cjs');
34
+ var useDebounce = require('../useDebounce/useDebounce.cjs');
34
35
  var updateUserWalletsFromConnectedWallets = require('./updateUserWalletsFromConnectedWallets/updateUserWalletsFromConnectedWallets.cjs');
35
36
 
36
37
  const useConnectWallet = ({ authMode, clearPrimaryWalletId, enableVisitTrackingOnConnectOnly, environmentId, primaryWalletId, setPrimaryWalletId, walletConnectorOptions, handleConnectedWallet, setShowAuthFlow, isBridgeFlow, user, }) => {
@@ -69,11 +70,10 @@ const useConnectWallet = ({ authMode, clearPrimaryWalletId, enableVisitTrackingO
69
70
  setPrimaryWalletId,
70
71
  ]);
71
72
  // The function to update and define the connectedWallets list.
72
- // It uses walletConnector to get the current wallet address and network
73
- // The address and network in the runtime are updated by the event listeners
74
- // The event listeners are updating `connectedWallets` list.
75
- // It should be called on the first render and when connectedWalletsInfo updates
76
- const updateConnectedWalletsList = React.useCallback(() => _tslib.__awaiter(void 0, void 0, void 0, function* () {
73
+ // It should be called on the first render, when connectedWalletsInfo updates and when walletConnectorOptions updates.
74
+ // To avoid unnecessary updates that are causing issues with connectors added asynchronously,
75
+ // we're debouncing this function
76
+ const updateConnectedWalletsList = useDebounce.useDebounce(() => _tslib.__awaiter(void 0, void 0, void 0, function* () {
77
77
  const walletConnectors = walletConnectorOptions.map((wallet) => wallet.walletConnector);
78
78
  if (!walletConnectors.length) {
79
79
  return;
@@ -110,12 +110,7 @@ const useConnectWallet = ({ authMode, clearPrimaryWalletId, enableVisitTrackingO
110
110
  return walletObject;
111
111
  })))).filter((wallet) => Boolean(wallet));
112
112
  setConnectedWallets(updatedConnectedWallets);
113
- }), [
114
- connectedWalletsInfo,
115
- disconnectWallet,
116
- setConnectedWallets,
117
- walletConnectorOptions,
118
- ]);
113
+ }), 300);
119
114
  // Generate the connectedWallets list when connectedWalletsInfo (localStorage) or memoized wallet connector updates
120
115
  React.useEffect(() => {
121
116
  updateConnectedWalletsList();
@@ -27,6 +27,7 @@ import '../../../locale/locale.js';
27
27
  import { getWalletProvider } from '../../functions/getWalletProvider/getWalletProvider.js';
28
28
  import { isConnectOnly } from '../authenticationHooks/helpers/isConnectOnly.js';
29
29
  import { getWalletConnectorForWallet } from '../../functions/getWalletConnectorForWallet/getWalletConnectorForWallet.js';
30
+ import { useDebounce } from '../useDebounce/useDebounce.js';
30
31
  import { updateUserWalletsFromConnectedWallets } from './updateUserWalletsFromConnectedWallets/updateUserWalletsFromConnectedWallets.js';
31
32
 
32
33
  const useConnectWallet = ({ authMode, clearPrimaryWalletId, enableVisitTrackingOnConnectOnly, environmentId, primaryWalletId, setPrimaryWalletId, walletConnectorOptions, handleConnectedWallet, setShowAuthFlow, isBridgeFlow, user, }) => {
@@ -65,11 +66,10 @@ const useConnectWallet = ({ authMode, clearPrimaryWalletId, enableVisitTrackingO
65
66
  setPrimaryWalletId,
66
67
  ]);
67
68
  // The function to update and define the connectedWallets list.
68
- // It uses walletConnector to get the current wallet address and network
69
- // The address and network in the runtime are updated by the event listeners
70
- // The event listeners are updating `connectedWallets` list.
71
- // It should be called on the first render and when connectedWalletsInfo updates
72
- const updateConnectedWalletsList = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
69
+ // It should be called on the first render, when connectedWalletsInfo updates and when walletConnectorOptions updates.
70
+ // To avoid unnecessary updates that are causing issues with connectors added asynchronously,
71
+ // we're debouncing this function
72
+ const updateConnectedWalletsList = useDebounce(() => __awaiter(void 0, void 0, void 0, function* () {
73
73
  const walletConnectors = walletConnectorOptions.map((wallet) => wallet.walletConnector);
74
74
  if (!walletConnectors.length) {
75
75
  return;
@@ -106,12 +106,7 @@ const useConnectWallet = ({ authMode, clearPrimaryWalletId, enableVisitTrackingO
106
106
  return walletObject;
107
107
  })))).filter((wallet) => Boolean(wallet));
108
108
  setConnectedWallets(updatedConnectedWallets);
109
- }), [
110
- connectedWalletsInfo,
111
- disconnectWallet,
112
- setConnectedWallets,
113
- walletConnectorOptions,
114
- ]);
109
+ }), 300);
115
110
  // Generate the connectedWallets list when connectedWalletsInfo (localStorage) or memoized wallet connector updates
116
111
  useEffect(() => {
117
112
  updateConnectedWalletsList();
@@ -0,0 +1 @@
1
+ export { useDebounce } from './useDebounce';
@@ -0,0 +1,22 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var React = require('react');
7
+
8
+ const useDebounce = (callback, timeout) => {
9
+ const timeoutId = React.useRef(null);
10
+ const callbackRef = React.useRef(callback);
11
+ callbackRef.current = callback;
12
+ return React.useCallback(((...params) => {
13
+ if (timeoutId.current) {
14
+ clearTimeout(timeoutId.current);
15
+ }
16
+ timeoutId.current = window.setTimeout(() => {
17
+ callbackRef.current(...params);
18
+ }, timeout);
19
+ }), [timeout]);
20
+ };
21
+
22
+ exports.useDebounce = useDebounce;
@@ -0,0 +1 @@
1
+ export declare const useDebounce: <C extends (...params: any[]) => void>(callback: C, timeout: number) => C;
@@ -0,0 +1,18 @@
1
+ 'use client'
2
+ import { useRef, useCallback } from 'react';
3
+
4
+ const useDebounce = (callback, timeout) => {
5
+ const timeoutId = useRef(null);
6
+ const callbackRef = useRef(callback);
7
+ callbackRef.current = callback;
8
+ return useCallback(((...params) => {
9
+ if (timeoutId.current) {
10
+ clearTimeout(timeoutId.current);
11
+ }
12
+ timeoutId.current = window.setTimeout(() => {
13
+ callbackRef.current(...params);
14
+ }, timeout);
15
+ }), [timeout]);
16
+ };
17
+
18
+ export { useDebounce };
@@ -115,7 +115,7 @@ const useEmbeddedReveal = () => {
115
115
  throw new Error('Coinbase MPC wallet not found');
116
116
  }
117
117
  };
118
- const initExportProcess = React.useCallback((...args_1) => _tslib.__awaiter(void 0, [...args_1], void 0, function* (recoveryPhrase = false) {
118
+ const initExportProcess = React.useCallback((...args_1) => _tslib.__awaiter(void 0, [...args_1], void 0, function* (recoveryPhrase = false, isPromptForExport = false) {
119
119
  if (!primaryWallet) {
120
120
  throw new Error('No primary wallet');
121
121
  }
@@ -135,7 +135,10 @@ const useEmbeddedReveal = () => {
135
135
  ignoreIfIsEmbeddedWidget: false,
136
136
  performMultiWalletChecks: false,
137
137
  });
138
- setView('embedded-reveal-view', { exportPrivateKey: !recoveryPhrase });
138
+ setView('embedded-reveal-view', {
139
+ exportPrivateKey: !recoveryPhrase,
140
+ isPromptForExport,
141
+ });
139
142
  return new Promise((resolve, reject) => {
140
143
  dynamicEvents.dynamicEvents.once('embeddedWalletRevealCompleted', (wallet) => resolve(wallet));
141
144
  dynamicEvents.dynamicEvents.once('embeddedWalletRevealFailed', (error) => reject(error));
@@ -1,4 +1,4 @@
1
1
  import { Wallet } from '../../../shared';
2
2
  export declare const useEmbeddedReveal: () => {
3
- readonly initExportProcess: (recoveryPhrase?: boolean) => Promise<Wallet>;
3
+ readonly initExportProcess: (recoveryPhrase?: boolean, isPromptForExport?: boolean) => Promise<Wallet>;
4
4
  };
@@ -111,7 +111,7 @@ const useEmbeddedReveal = () => {
111
111
  throw new Error('Coinbase MPC wallet not found');
112
112
  }
113
113
  };
114
- const initExportProcess = useCallback((...args_1) => __awaiter(void 0, [...args_1], void 0, function* (recoveryPhrase = false) {
114
+ const initExportProcess = useCallback((...args_1) => __awaiter(void 0, [...args_1], void 0, function* (recoveryPhrase = false, isPromptForExport = false) {
115
115
  if (!primaryWallet) {
116
116
  throw new Error('No primary wallet');
117
117
  }
@@ -131,7 +131,10 @@ const useEmbeddedReveal = () => {
131
131
  ignoreIfIsEmbeddedWidget: false,
132
132
  performMultiWalletChecks: false,
133
133
  });
134
- setView('embedded-reveal-view', { exportPrivateKey: !recoveryPhrase });
134
+ setView('embedded-reveal-view', {
135
+ exportPrivateKey: !recoveryPhrase,
136
+ isPromptForExport,
137
+ });
135
138
  return new Promise((resolve, reject) => {
136
139
  dynamicEvents.once('embeddedWalletRevealCompleted', (wallet) => resolve(wallet));
137
140
  dynamicEvents.once('embeddedWalletRevealFailed', (error) => reject(error));
@@ -157,6 +157,7 @@ const useEmbeddedWallet = () => {
157
157
  }
158
158
  return revealCoinbaseMPCEmbeddedWalletKey();
159
159
  });
160
+ const shouldPromptForKeyExport = React.useCallback(() => { var _a; return Boolean((_a = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk.embeddedWallets) === null || _a === void 0 ? void 0 : _a.promptForKeyExport); }, [projectSettings]);
160
161
  const shouldAutoCreateEmbeddedWallet = React.useCallback((verifiedUser) => {
161
162
  var _a, _b, _c, _d, _e;
162
163
  const hasEmbeddedWalletProviderEnabled = isTurnkeyEnabled.isTurnkeyEnabled(projectSettings) ||
@@ -202,6 +203,7 @@ const useEmbeddedWallet = () => {
202
203
  revealWalletKey,
203
204
  sendOneTimeCode,
204
205
  shouldAutoCreateEmbeddedWallet,
206
+ shouldPromptForKeyExport,
205
207
  userHasEmbeddedWallet,
206
208
  };
207
209
  };
@@ -39,5 +39,6 @@ export declare const useEmbeddedWallet: () => {
39
39
  } | undefined) => Promise<boolean>;
40
40
  readonly sendOneTimeCode: () => Promise<string>;
41
41
  readonly shouldAutoCreateEmbeddedWallet: (verifiedUser?: UserProfile) => boolean;
42
+ readonly shouldPromptForKeyExport: () => boolean;
42
43
  readonly userHasEmbeddedWallet: () => boolean;
43
44
  };
@@ -153,6 +153,7 @@ const useEmbeddedWallet = () => {
153
153
  }
154
154
  return revealCoinbaseMPCEmbeddedWalletKey();
155
155
  });
156
+ const shouldPromptForKeyExport = useCallback(() => { var _a; return Boolean((_a = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk.embeddedWallets) === null || _a === void 0 ? void 0 : _a.promptForKeyExport); }, [projectSettings]);
156
157
  const shouldAutoCreateEmbeddedWallet = useCallback((verifiedUser) => {
157
158
  var _a, _b, _c, _d, _e;
158
159
  const hasEmbeddedWalletProviderEnabled = isTurnkeyEnabled(projectSettings) ||
@@ -198,6 +199,7 @@ const useEmbeddedWallet = () => {
198
199
  revealWalletKey,
199
200
  sendOneTimeCode,
200
201
  shouldAutoCreateEmbeddedWallet,
202
+ shouldPromptForKeyExport,
201
203
  userHasEmbeddedWallet,
202
204
  };
203
205
  };
@@ -18,10 +18,12 @@ require('@dynamic-labs/wallet-book');
18
18
  require('../../constants/colors.cjs');
19
19
  require('../../constants/values.cjs');
20
20
  require('../../../store/state/loadingAndLifecycle.cjs');
21
+ var useLocalStorage = require('../../../shared/utils/hooks/useLocalStorage/useLocalStorage.cjs');
21
22
  require('../../../shared/consts/index.cjs');
22
23
  var useDynamicEvents = require('../events/useDynamicEvents/useDynamicEvents.cjs');
23
24
  require('../../../context/CaptchaContext/CaptchaContext.cjs');
24
25
  require('../../../context/ErrorContext/ErrorContext.cjs');
26
+ var findEmbeddedWalletFromVerifiedCredentials = require('../../functions/findEmbeddedWalletFromVerifiedCredentials/findEmbeddedWalletFromVerifiedCredentials.cjs');
25
27
  require('@dynamic-labs/multi-wallet');
26
28
  require('react-international-phone');
27
29
  require('../../../config/ApiEndpoint.cjs');
@@ -78,53 +80,83 @@ require('../../../store/state/sendBalances.cjs');
78
80
  require('../../../widgets/DynamicWidget/components/DynamicWidgetHeader/DynamicWidgetHeader.cjs');
79
81
  require('../../../views/TransactionConfirmationView/helpers/transactionErrorMessage.cjs');
80
82
  require('../../../widgets/DynamicWidget/views/ManagePasskeysWidgetView/PasskeyCard/PasskeyCard.cjs');
83
+ var useEmbeddedReveal = require('../useEmbeddedReveal/useEmbeddedReveal.cjs');
81
84
  require('../../../../index.cjs');
82
85
  require('../../../store/state/tokenBalances.cjs');
83
86
  require('../../../shared/utils/functions/getInitialUrl/getInitialUrl.cjs');
84
87
  var useInternalDynamicContext = require('../../../context/DynamicContext/useDynamicContext/useInternalDynamicContext.cjs');
85
88
  require('../useEmbeddedWallet/useSecureEnclaveEmbeddedWallet/constants.cjs');
86
89
 
90
+ let acknowledgedExportPrompt = false;
87
91
  const useSyncEmbeddedWalletFlow = () => {
88
- const { projectSettings, user, primaryWalletId, walletConnectorOptions, setShowAuthFlow, } = useInternalDynamicContext.useInternalDynamicContext();
92
+ const { projectSettings, user, primaryWalletId, walletConnectorOptions, primaryWallet, setShowAuthFlow, } = useInternalDynamicContext.useInternalDynamicContext();
89
93
  const { isLoadingEmbeddedWallet } = WalletContext.useWalletContext();
90
94
  const { loading: globalLoading } = LoadingContext.useLoadingContext();
91
- const { createEmbeddedWallet, shouldAutoCreateEmbeddedWallet } = useEmbeddedWallet.useEmbeddedWallet();
95
+ const { initExportProcess } = useEmbeddedReveal.useEmbeddedReveal();
96
+ const [wasShownExportPrompt, setWasShownExportPrompt] = useLocalStorage.useLocalStorage(`dynamic_export_prompt-${user === null || user === void 0 ? void 0 : user.userId}`, false, (data) => Boolean(data));
97
+ const { createEmbeddedWallet, shouldAutoCreateEmbeddedWallet, shouldPromptForKeyExport, } = useEmbeddedWallet.useEmbeddedWallet();
92
98
  const triggeredCreate = React.useRef(false);
99
+ const handleAcknowledgeExportPrompt = React.useCallback((value = true) => {
100
+ acknowledgedExportPrompt = value;
101
+ setWasShownExportPrompt(value);
102
+ }, [setWasShownExportPrompt]);
93
103
  useDynamicEvents.useInternalDynamicEvents('logout', () => {
94
104
  triggeredCreate.current = false;
105
+ acknowledgedExportPrompt = false;
95
106
  });
96
107
  // this is used to trigger createEmbeddedWallet
97
108
  // when user didn't create a passkey after login,
98
109
  // we force them to created it before they can use the app
99
110
  // ** It must be an useEffect because some of the dependencies are async
100
111
  React.useEffect(() => {
101
- const createWallet = () => _tslib.__awaiter(void 0, void 0, void 0, function* () {
102
- triggeredCreate.current = true;
103
- try {
104
- yield createEmbeddedWallet();
112
+ const syncEmbeddedWallet = () => _tslib.__awaiter(void 0, void 0, void 0, function* () {
113
+ const isNewUser = user === null || user === void 0 ? void 0 : user.newUser;
114
+ if (shouldSyncCreateWallet) {
115
+ triggeredCreate.current = true;
116
+ try {
117
+ yield createEmbeddedWallet();
118
+ }
119
+ catch (error) {
120
+ if (error instanceof utils.EmbeddedWalletException) {
121
+ logger.logger.debug('Error creating embedded wallet', error);
122
+ }
123
+ else {
124
+ logger.logger.error('Error creating embedded wallet', error);
125
+ }
126
+ setShowAuthFlow(false);
127
+ }
105
128
  }
106
- catch (error) {
107
- if (error instanceof utils.EmbeddedWalletException) {
108
- logger.logger.debug('Error creating embedded wallet', error);
129
+ if (shouldSyncPromptKeyExport &&
130
+ isNewUser &&
131
+ findEmbeddedWalletFromVerifiedCredentials.findEmbeddedWalletFromVerifiedCredentials(user) &&
132
+ primaryWallet) {
133
+ try {
134
+ setShowAuthFlow(true);
135
+ yield initExportProcess(true, true);
109
136
  }
110
- else {
111
- logger.logger.error('Error creating embedded wallet', error);
137
+ catch (error) {
138
+ logger.logger.error('Error initializing embedded wallet export', error);
139
+ setShowAuthFlow(false);
112
140
  }
113
- setShowAuthFlow(false);
114
141
  }
115
142
  });
116
143
  const shouldCreateWallet = shouldAutoCreateEmbeddedWallet();
117
- if (!shouldCreateWallet ||
144
+ const shouldSyncCreateWallet = shouldCreateWallet && !triggeredCreate.current;
145
+ if (wasShownExportPrompt && !acknowledgedExportPrompt)
146
+ acknowledgedExportPrompt = true;
147
+ const shouldPromptKeyExport = shouldPromptForKeyExport();
148
+ const shouldSyncPromptKeyExport = shouldPromptKeyExport && !acknowledgedExportPrompt;
149
+ const shouldSyncEmbeddedWallet = shouldSyncCreateWallet || shouldSyncPromptKeyExport;
150
+ if (!shouldSyncEmbeddedWallet ||
118
151
  !user ||
119
152
  !projectSettings ||
120
153
  !walletConnectorOptions.length || // no connectors to use for the embedded wallet
121
154
  isLoadingEmbeddedWallet || // already has a wallet
122
- globalLoading || // this will be true if auth is in progress
123
- triggeredCreate.current // already triggered
155
+ globalLoading // this will be true if auth is in progress
124
156
  ) {
125
157
  return;
126
158
  }
127
- createWallet();
159
+ syncEmbeddedWallet();
128
160
  }, [
129
161
  user,
130
162
  projectSettings,
@@ -135,7 +167,17 @@ const useSyncEmbeddedWalletFlow = () => {
135
167
  globalLoading,
136
168
  shouldAutoCreateEmbeddedWallet,
137
169
  setShowAuthFlow,
170
+ initExportProcess,
171
+ primaryWallet,
172
+ shouldPromptForKeyExport,
173
+ setWasShownExportPrompt,
174
+ handleAcknowledgeExportPrompt,
175
+ wasShownExportPrompt,
138
176
  ]);
177
+ return {
178
+ acknowledgedExportPrompt,
179
+ handleAcknowledgeExportPrompt,
180
+ };
139
181
  };
140
182
 
141
183
  exports.useSyncEmbeddedWalletFlow = useSyncEmbeddedWalletFlow;
@@ -1 +1,4 @@
1
- export declare const useSyncEmbeddedWalletFlow: () => void;
1
+ export declare const useSyncEmbeddedWalletFlow: () => {
2
+ acknowledgedExportPrompt: boolean;
3
+ handleAcknowledgeExportPrompt: (value?: boolean) => void;
4
+ };
@@ -1,6 +1,6 @@
1
1
  'use client'
2
2
  import { __awaiter } from '../../../../../_virtual/_tslib.js';
3
- import { useRef, useEffect } from 'react';
3
+ import { useRef, useCallback, useEffect } from 'react';
4
4
  import { EmbeddedWalletException } from '@dynamic-labs/utils';
5
5
  import { useEmbeddedWallet } from '../useEmbeddedWallet/useEmbeddedWallet.js';
6
6
  import '@dynamic-labs/sdk-api-core';
@@ -14,10 +14,12 @@ import '@dynamic-labs/wallet-book';
14
14
  import '../../constants/colors.js';
15
15
  import '../../constants/values.js';
16
16
  import '../../../store/state/loadingAndLifecycle.js';
17
+ import { useLocalStorage } from '../../../shared/utils/hooks/useLocalStorage/useLocalStorage.js';
17
18
  import '../../../shared/consts/index.js';
18
19
  import { useInternalDynamicEvents } from '../events/useDynamicEvents/useDynamicEvents.js';
19
20
  import '../../../context/CaptchaContext/CaptchaContext.js';
20
21
  import '../../../context/ErrorContext/ErrorContext.js';
22
+ import { findEmbeddedWalletFromVerifiedCredentials } from '../../functions/findEmbeddedWalletFromVerifiedCredentials/findEmbeddedWalletFromVerifiedCredentials.js';
21
23
  import '@dynamic-labs/multi-wallet';
22
24
  import 'react-international-phone';
23
25
  import '../../../config/ApiEndpoint.js';
@@ -74,53 +76,83 @@ import '../../../store/state/sendBalances.js';
74
76
  import '../../../widgets/DynamicWidget/components/DynamicWidgetHeader/DynamicWidgetHeader.js';
75
77
  import '../../../views/TransactionConfirmationView/helpers/transactionErrorMessage.js';
76
78
  import '../../../widgets/DynamicWidget/views/ManagePasskeysWidgetView/PasskeyCard/PasskeyCard.js';
79
+ import { useEmbeddedReveal } from '../useEmbeddedReveal/useEmbeddedReveal.js';
77
80
  import '../../../../index.js';
78
81
  import '../../../store/state/tokenBalances.js';
79
82
  import '../../../shared/utils/functions/getInitialUrl/getInitialUrl.js';
80
83
  import { useInternalDynamicContext } from '../../../context/DynamicContext/useDynamicContext/useInternalDynamicContext.js';
81
84
  import '../useEmbeddedWallet/useSecureEnclaveEmbeddedWallet/constants.js';
82
85
 
86
+ let acknowledgedExportPrompt = false;
83
87
  const useSyncEmbeddedWalletFlow = () => {
84
- const { projectSettings, user, primaryWalletId, walletConnectorOptions, setShowAuthFlow, } = useInternalDynamicContext();
88
+ const { projectSettings, user, primaryWalletId, walletConnectorOptions, primaryWallet, setShowAuthFlow, } = useInternalDynamicContext();
85
89
  const { isLoadingEmbeddedWallet } = useWalletContext();
86
90
  const { loading: globalLoading } = useLoadingContext();
87
- const { createEmbeddedWallet, shouldAutoCreateEmbeddedWallet } = useEmbeddedWallet();
91
+ const { initExportProcess } = useEmbeddedReveal();
92
+ const [wasShownExportPrompt, setWasShownExportPrompt] = useLocalStorage(`dynamic_export_prompt-${user === null || user === void 0 ? void 0 : user.userId}`, false, (data) => Boolean(data));
93
+ const { createEmbeddedWallet, shouldAutoCreateEmbeddedWallet, shouldPromptForKeyExport, } = useEmbeddedWallet();
88
94
  const triggeredCreate = useRef(false);
95
+ const handleAcknowledgeExportPrompt = useCallback((value = true) => {
96
+ acknowledgedExportPrompt = value;
97
+ setWasShownExportPrompt(value);
98
+ }, [setWasShownExportPrompt]);
89
99
  useInternalDynamicEvents('logout', () => {
90
100
  triggeredCreate.current = false;
101
+ acknowledgedExportPrompt = false;
91
102
  });
92
103
  // this is used to trigger createEmbeddedWallet
93
104
  // when user didn't create a passkey after login,
94
105
  // we force them to created it before they can use the app
95
106
  // ** It must be an useEffect because some of the dependencies are async
96
107
  useEffect(() => {
97
- const createWallet = () => __awaiter(void 0, void 0, void 0, function* () {
98
- triggeredCreate.current = true;
99
- try {
100
- yield createEmbeddedWallet();
108
+ const syncEmbeddedWallet = () => __awaiter(void 0, void 0, void 0, function* () {
109
+ const isNewUser = user === null || user === void 0 ? void 0 : user.newUser;
110
+ if (shouldSyncCreateWallet) {
111
+ triggeredCreate.current = true;
112
+ try {
113
+ yield createEmbeddedWallet();
114
+ }
115
+ catch (error) {
116
+ if (error instanceof EmbeddedWalletException) {
117
+ logger.debug('Error creating embedded wallet', error);
118
+ }
119
+ else {
120
+ logger.error('Error creating embedded wallet', error);
121
+ }
122
+ setShowAuthFlow(false);
123
+ }
101
124
  }
102
- catch (error) {
103
- if (error instanceof EmbeddedWalletException) {
104
- logger.debug('Error creating embedded wallet', error);
125
+ if (shouldSyncPromptKeyExport &&
126
+ isNewUser &&
127
+ findEmbeddedWalletFromVerifiedCredentials(user) &&
128
+ primaryWallet) {
129
+ try {
130
+ setShowAuthFlow(true);
131
+ yield initExportProcess(true, true);
105
132
  }
106
- else {
107
- logger.error('Error creating embedded wallet', error);
133
+ catch (error) {
134
+ logger.error('Error initializing embedded wallet export', error);
135
+ setShowAuthFlow(false);
108
136
  }
109
- setShowAuthFlow(false);
110
137
  }
111
138
  });
112
139
  const shouldCreateWallet = shouldAutoCreateEmbeddedWallet();
113
- if (!shouldCreateWallet ||
140
+ const shouldSyncCreateWallet = shouldCreateWallet && !triggeredCreate.current;
141
+ if (wasShownExportPrompt && !acknowledgedExportPrompt)
142
+ acknowledgedExportPrompt = true;
143
+ const shouldPromptKeyExport = shouldPromptForKeyExport();
144
+ const shouldSyncPromptKeyExport = shouldPromptKeyExport && !acknowledgedExportPrompt;
145
+ const shouldSyncEmbeddedWallet = shouldSyncCreateWallet || shouldSyncPromptKeyExport;
146
+ if (!shouldSyncEmbeddedWallet ||
114
147
  !user ||
115
148
  !projectSettings ||
116
149
  !walletConnectorOptions.length || // no connectors to use for the embedded wallet
117
150
  isLoadingEmbeddedWallet || // already has a wallet
118
- globalLoading || // this will be true if auth is in progress
119
- triggeredCreate.current // already triggered
151
+ globalLoading // this will be true if auth is in progress
120
152
  ) {
121
153
  return;
122
154
  }
123
- createWallet();
155
+ syncEmbeddedWallet();
124
156
  }, [
125
157
  user,
126
158
  projectSettings,
@@ -131,7 +163,17 @@ const useSyncEmbeddedWalletFlow = () => {
131
163
  globalLoading,
132
164
  shouldAutoCreateEmbeddedWallet,
133
165
  setShowAuthFlow,
166
+ initExportProcess,
167
+ primaryWallet,
168
+ shouldPromptForKeyExport,
169
+ setWasShownExportPrompt,
170
+ handleAcknowledgeExportPrompt,
171
+ wasShownExportPrompt,
134
172
  ]);
173
+ return {
174
+ acknowledgedExportPrompt,
175
+ handleAcknowledgeExportPrompt,
176
+ };
135
177
  };
136
178
 
137
179
  export { useSyncEmbeddedWalletFlow };
@@ -95,7 +95,7 @@ const useUserAuth = ({ authMethod, }) => {
95
95
  const { setErrorMessage, setError } = ErrorContext.useErrorContext();
96
96
  const { setExistentAccountData } = AccountExistsContext.useAccountExistsContext();
97
97
  const handleAuthenticatedUser = useHandleAuthenticatedUser.useHandleAuthenticatedUser();
98
- const { shouldAutoCreateEmbeddedWallet } = useEmbeddedWallet.useEmbeddedWallet();
98
+ const { shouldAutoCreateEmbeddedWallet, shouldPromptForKeyExport } = useEmbeddedWallet.useEmbeddedWallet();
99
99
  const isVerifyResponse = (response) => response.user;
100
100
  const initAuth = (_a) => _tslib.__awaiter(void 0, [_a], void 0, function* ({ isSignIn = true, verifyFunction, onVerifySuccess, onSettled, onError, showSuccessMessage = false, skipDefaultErrorHandling = false, }) {
101
101
  var _b;
@@ -129,9 +129,10 @@ const useUserAuth = ({ authMethod, }) => {
129
129
  }
130
130
  setMultiWalletWidgetState('idle');
131
131
  yield handleAuthenticatedUser(verifiedUser);
132
- // we should only close auth flow if no wallet is going to be created,
133
- // otherwise there will be a glitch with auth flow closing and then reopening for passkeys
132
+ // we should only close auth flow if no wallet is going to be created or there is no key export
133
+ // otherwise there will be a glitch with auth flow closing and then reopening for passkeys or export
134
134
  const shouldCreateWallet = shouldAutoCreateEmbeddedWallet(verifiedUser);
135
+ const shouldPromptExport = shouldPromptForKeyExport();
135
136
  if (showSuccessMessage) {
136
137
  // this timeout is set to make sure that the user will see success message
137
138
  yield sleepToShowSuccessMessage();
@@ -139,7 +140,7 @@ const useUserAuth = ({ authMethod, }) => {
139
140
  if (isSignIn) {
140
141
  setCallback('authSuccess');
141
142
  }
142
- if (!shouldCreateWallet) {
143
+ if (!shouldCreateWallet && !shouldPromptExport) {
143
144
  setShowAuthFlow(false);
144
145
  }
145
146
  onSettled === null || onSettled === void 0 ? void 0 : onSettled();
@@ -91,7 +91,7 @@ const useUserAuth = ({ authMethod, }) => {
91
91
  const { setErrorMessage, setError } = useErrorContext();
92
92
  const { setExistentAccountData } = useAccountExistsContext();
93
93
  const handleAuthenticatedUser = useHandleAuthenticatedUser();
94
- const { shouldAutoCreateEmbeddedWallet } = useEmbeddedWallet();
94
+ const { shouldAutoCreateEmbeddedWallet, shouldPromptForKeyExport } = useEmbeddedWallet();
95
95
  const isVerifyResponse = (response) => response.user;
96
96
  const initAuth = (_a) => __awaiter(void 0, [_a], void 0, function* ({ isSignIn = true, verifyFunction, onVerifySuccess, onSettled, onError, showSuccessMessage = false, skipDefaultErrorHandling = false, }) {
97
97
  var _b;
@@ -125,9 +125,10 @@ const useUserAuth = ({ authMethod, }) => {
125
125
  }
126
126
  setMultiWalletWidgetState('idle');
127
127
  yield handleAuthenticatedUser(verifiedUser);
128
- // we should only close auth flow if no wallet is going to be created,
129
- // otherwise there will be a glitch with auth flow closing and then reopening for passkeys
128
+ // we should only close auth flow if no wallet is going to be created or there is no key export
129
+ // otherwise there will be a glitch with auth flow closing and then reopening for passkeys or export
130
130
  const shouldCreateWallet = shouldAutoCreateEmbeddedWallet(verifiedUser);
131
+ const shouldPromptExport = shouldPromptForKeyExport();
131
132
  if (showSuccessMessage) {
132
133
  // this timeout is set to make sure that the user will see success message
133
134
  yield sleepToShowSuccessMessage();
@@ -135,7 +136,7 @@ const useUserAuth = ({ authMethod, }) => {
135
136
  if (isSignIn) {
136
137
  setCallback('authSuccess');
137
138
  }
138
- if (!shouldCreateWallet) {
139
+ if (!shouldCreateWallet && !shouldPromptExport) {
139
140
  setShowAuthFlow(false);
140
141
  }
141
142
  onSettled === null || onSettled === void 0 ? void 0 : onSettled();