@dynamic-labs/sdk-react-core 4.65.0 → 4.67.0

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 (70) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/package.cjs +4 -4
  3. package/package.js +4 -4
  4. package/package.json +15 -15
  5. package/src/index.cjs +2 -0
  6. package/src/index.d.ts +2 -2
  7. package/src/index.js +1 -0
  8. package/src/lib/Main.cjs +1 -0
  9. package/src/lib/Main.js +1 -0
  10. package/src/lib/client/extension/functions/hasElevatedAccessToken/hasElevatedAccessToken.cjs +18 -0
  11. package/src/lib/client/extension/functions/hasElevatedAccessToken/hasElevatedAccessToken.d.ts +1 -0
  12. package/src/lib/client/extension/functions/hasElevatedAccessToken/hasElevatedAccessToken.js +14 -0
  13. package/src/lib/client/extension/functions/hasElevatedAccessToken/index.d.ts +1 -0
  14. package/src/lib/client/extension/index.d.ts +1 -0
  15. package/src/lib/context/DynamicContext/DynamicContext.cjs +20 -19
  16. package/src/lib/context/DynamicContext/DynamicContext.js +20 -19
  17. package/src/lib/context/DynamicContext/types/SettingsOverrides.d.ts +10 -0
  18. package/src/lib/styles/index.shadow.cjs +1 -1
  19. package/src/lib/styles/index.shadow.js +1 -1
  20. package/src/lib/utils/constants/values.cjs +2 -0
  21. package/src/lib/utils/constants/values.js +2 -0
  22. package/src/lib/utils/functions/compareChains/compareChains.cjs +1 -0
  23. package/src/lib/utils/functions/compareChains/compareChains.js +1 -0
  24. package/src/lib/utils/hooks/index.d.ts +2 -1
  25. package/src/lib/utils/hooks/useDynamicWaas/useDynamicWaas.cjs +7 -3
  26. package/src/lib/utils/hooks/useDynamicWaas/useDynamicWaas.d.ts +4 -1
  27. package/src/lib/utils/hooks/useDynamicWaas/useDynamicWaas.js +7 -3
  28. package/src/lib/utils/hooks/useNetworkConfigurationsFromProjectSettings/useNetworkConfigurationsFromProjectSettings.cjs +7 -2
  29. package/src/lib/utils/hooks/useNetworkConfigurationsFromProjectSettings/useNetworkConfigurationsFromProjectSettings.d.ts +2 -1
  30. package/src/lib/utils/hooks/useNetworkConfigurationsFromProjectSettings/useNetworkConfigurationsFromProjectSettings.js +7 -2
  31. package/src/lib/utils/hooks/useSignEip7702Authorization/index.d.ts +1 -0
  32. package/src/lib/utils/hooks/useSignEip7702Authorization/useSignEip7702Authorization.cjs +162 -0
  33. package/src/lib/utils/hooks/useSignEip7702Authorization/useSignEip7702Authorization.d.ts +78 -0
  34. package/src/lib/utils/hooks/useSignEip7702Authorization/useSignEip7702Authorization.js +158 -0
  35. package/src/lib/utils/hooks/useStepUpAuthentication/index.d.ts +1 -1
  36. package/src/lib/utils/hooks/useStepUpAuthentication/useStepUpAuthentication.cjs +102 -23
  37. package/src/lib/utils/hooks/useStepUpAuthentication/useStepUpAuthentication.d.ts +35 -15
  38. package/src/lib/utils/hooks/useStepUpAuthentication/useStepUpAuthentication.js +103 -24
  39. package/src/lib/utils/hooks/useSyncDynamicWaas/useSyncDynamicWaas.cjs +3 -1
  40. package/src/lib/utils/hooks/useSyncDynamicWaas/useSyncDynamicWaas.js +3 -1
  41. package/src/lib/utils/hooks/useWalletConnectorNetwork/useWalletConnectorNetwork.cjs +3 -2
  42. package/src/lib/utils/hooks/useWalletConnectorNetwork/useWalletConnectorNetwork.js +3 -2
  43. package/src/lib/utils/hooks/useWalletPassword/useWalletPassword.cjs +24 -2
  44. package/src/lib/utils/hooks/useWalletPassword/useWalletPassword.js +24 -2
  45. package/src/lib/views/CollectUserDataView/UserDataFields/UserPhoneField/UserPhoneField.cjs +10 -6
  46. package/src/lib/views/CollectUserDataView/UserDataFields/UserPhoneField/UserPhoneField.js +11 -7
  47. package/src/lib/views/MfaDisplayBackupCodesView/MfaDisplayBackupCodesView.cjs +1 -1
  48. package/src/lib/views/MfaDisplayBackupCodesView/MfaDisplayBackupCodesView.js +1 -1
  49. package/src/lib/views/ResetPasswordForSettingsView/ResetPasswordForSettingsView.cjs +5 -21
  50. package/src/lib/views/ResetPasswordForSettingsView/ResetPasswordForSettingsView.js +5 -21
  51. package/src/lib/views/SendBalanceView/SendBalanceView.cjs +1 -0
  52. package/src/lib/views/SendBalanceView/SendBalanceView.js +1 -0
  53. package/src/lib/views/SetupPasswordForWalletCreationView/SetupPasswordForWalletCreationView.cjs +9 -1
  54. package/src/lib/views/SetupPasswordForWalletCreationView/SetupPasswordForWalletCreationView.js +9 -1
  55. package/src/lib/views/TransactionConfirmationView/TransactionConfirmationView.cjs +21 -1
  56. package/src/lib/views/TransactionConfirmationView/TransactionConfirmationView.js +21 -1
  57. package/src/lib/views/WalletList/data.cjs +1 -0
  58. package/src/lib/views/WalletList/data.d.ts +1 -1
  59. package/src/lib/views/WalletList/data.js +1 -0
  60. package/src/lib/widgets/DynamicWidget/views/ResetPasswordView/ResetPasswordView.cjs +26 -5
  61. package/src/lib/widgets/DynamicWidget/views/ResetPasswordView/ResetPasswordView.js +26 -5
  62. package/src/lib/widgets/DynamicWidget/views/SetupPasswordConfirmView/SetupPasswordConfirmView.cjs +3 -2
  63. package/src/lib/widgets/DynamicWidget/views/SetupPasswordConfirmView/SetupPasswordConfirmView.d.ts +2 -0
  64. package/src/lib/widgets/DynamicWidget/views/SetupPasswordConfirmView/SetupPasswordConfirmView.js +3 -2
  65. package/src/lib/widgets/DynamicWidget/views/SetupPasswordKnowledgeCheckView/SetupPasswordKnowledgeCheckView.cjs +2 -2
  66. package/src/lib/widgets/DynamicWidget/views/SetupPasswordKnowledgeCheckView/SetupPasswordKnowledgeCheckView.d.ts +2 -0
  67. package/src/lib/widgets/DynamicWidget/views/SetupPasswordKnowledgeCheckView/SetupPasswordKnowledgeCheckView.js +2 -2
  68. package/src/lib/widgets/DynamicWidget/views/SetupPasswordView/SetupPasswordView.cjs +30 -22
  69. package/src/lib/widgets/DynamicWidget/views/SetupPasswordView/SetupPasswordView.d.ts +2 -1
  70. package/src/lib/widgets/DynamicWidget/views/SetupPasswordView/SetupPasswordView.js +30 -22
@@ -0,0 +1,158 @@
1
+ 'use client'
2
+ import { __awaiter } from '../../../../../_virtual/_tslib.js';
3
+ import { useCallback } from 'react';
4
+ import { DynamicError } from '@dynamic-labs/utils';
5
+ import '../../../context/DynamicContext/DynamicContext.js';
6
+ import '../../../store/state/loadingAndLifecycle/loadingAndLifecycle.js';
7
+ import '@dynamic-labs/iconic';
8
+ import '@dynamic-labs/wallet-connector-core';
9
+ import 'react/jsx-runtime';
10
+ import '../../../context/ViewContext/ViewContext.js';
11
+ import '../../../shared/logger.js';
12
+ import '@dynamic-labs/wallet-book';
13
+ import '../../constants/colors.js';
14
+ import '../../constants/values.js';
15
+ import '@dynamic-labs/sdk-api-core';
16
+ import '../../../shared/consts/index.js';
17
+ import '../../../events/dynamicEvents.js';
18
+ import '../../../context/CaptchaContext/CaptchaContext.js';
19
+ import '../../../context/ErrorContext/ErrorContext.js';
20
+ import '@dynamic-labs/multi-wallet';
21
+ import 'react-international-phone';
22
+ import '../../../store/state/nonce/nonce.js';
23
+ import '@dynamic-labs-sdk/client/core';
24
+ import '../../../client/client.js';
25
+ import '@dynamic-labs-sdk/client';
26
+ import '../../../config/ApiEndpoint.js';
27
+ import '@dynamic-labs/locale';
28
+ import '../../../store/state/dynamicContextProps/dynamicContextProps.js';
29
+ import '../../../store/state/primaryWalletId/primaryWalletId.js';
30
+ import '../../../store/state/connectedWalletsInfo/connectedWalletsInfo.js';
31
+ import '../../functions/getWaasAddressTypeLabel/getWaasAddressTypeLabel.js';
32
+ import '../../../context/AccessDeniedContext/AccessDeniedContext.js';
33
+ import '../../../context/AccountExistsContext/AccountExistsContext.js';
34
+ import '../../../context/UserWalletsContext/UserWalletsContext.js';
35
+ import '../../../store/state/authMode/authMode.js';
36
+ import '../../../context/VerificationContext/VerificationContext.js';
37
+ import 'react-dom';
38
+ import '../../functions/compareChains/compareChains.js';
39
+ import '../../../views/Passkey/utils/findPrimaryEmbeddedChain/findPrimaryEmbeddedChain.js';
40
+ import '../../../context/ThemeContext/ThemeContext.js';
41
+ import '../useUserUpdateRequest/useUpdateUser/userFieldsSchema.js';
42
+ import 'bs58';
43
+ import '@dynamic-labs/types';
44
+ import '../../../context/SocialRedirectContext/SocialRedirectContext.js';
45
+ import '../../../context/LoadingContext/LoadingContext.js';
46
+ import '../../../context/WalletContext/WalletContext.js';
47
+ import '../useEmbeddedWallet/useSecureEnclaveEmbeddedWallet/constants.js';
48
+ import 'yup';
49
+ import '../../../context/MockContext/MockContext.js';
50
+ import '../../../views/CollectUserDataView/useFields.js';
51
+ import '../../../context/FieldsStateContext/FieldsStateContext.js';
52
+ import '../../../context/UserFieldEditorContext/UserFieldEditorContext.js';
53
+ import '@dynamic-labs/rpc-providers';
54
+ import '../../../store/state/walletOptions/walletOptions.js';
55
+ import 'react-i18next';
56
+ import '../../../components/Accordion/components/AccordionItem/AccordionItem.js';
57
+ import '../../../components/Alert/Alert.js';
58
+ import '../../../components/ShadowDOM/ShadowDOM.js';
59
+ import '../../../components/IconButton/IconButton.js';
60
+ import '../../../components/InlineWidget/InlineWidget.js';
61
+ import '../../../components/Input/Input.js';
62
+ import '../../../components/IsBrowser/IsBrowser.js';
63
+ import '../../../components/MenuList/Dropdown/Dropdown.js';
64
+ import '../../../components/OverlayCard/OverlayCard.js';
65
+ import '../../../components/Transition/ZoomTransition/ZoomTransition.js';
66
+ import '../../../components/Transition/SlideInUpTransition/SlideInUpTransition.js';
67
+ import '../../../components/Transition/OpacityTransition/OpacityTransition.js';
68
+ import '../../../components/PasskeyCreatedSuccessBanner/PasskeyCreatedSuccessBanner.js';
69
+ import '../../../components/Popper/Popper/Popper.js';
70
+ import '../../../components/Popper/PopperContext/PopperContext.js';
71
+ import 'react-focus-lock';
72
+ import 'qrcode';
73
+ import 'formik';
74
+ import '../useSubdomainCheck/useSubdomainCheck.js';
75
+ import '../../../context/WalletGroupContext/WalletGroupContext.js';
76
+ import '../../../widgets/DynamicWidget/context/DynamicWidgetContext.js';
77
+ import '../useWalletBackup/useWalletBackup.js';
78
+ import '../useWalletBackup/types.js';
79
+ import '../useWalletBackup/cloudProviders.js';
80
+ import '../../../context/IpConfigurationContext/IpConfigurationContext.js';
81
+ import '../../../context/ConnectWithOtpContext/ConnectWithOtpContext.js';
82
+ import '../../../widgets/DynamicBridgeWidget/views/WalletsView/components/SecondaryWallets/SecondaryWallets.js';
83
+ import '@hcaptcha/react-hcaptcha';
84
+ import '../../../widgets/DynamicWidget/helpers/convertExchangeKeyAndProviderEnum.js';
85
+ import '../../../views/ExchangeWhitelistWarning/ExchangeWhitelistWarning.js';
86
+ import '../../../context/ErrorContext/hooks/useErrorText/useErrorText.js';
87
+ import '../../../context/FooterAnimationContext/index.js';
88
+ import '../../../views/MfaChooseDeviceView/useGetMfaOptions/useGetMfaOptions.js';
89
+ import '../../../context/PasskeyContext/PasskeyContext.js';
90
+ import '../../../context/OnrampContext/OnrampContext.js';
91
+ import '../../../store/state/sendBalances.js';
92
+ import '../../../store/state/connectorsInitializing/connectorsInitializing.js';
93
+ import '../../../components/OverlayCardBase/OverlayCardTarget/OverlayCardTarget.js';
94
+ import '../../../widgets/DynamicWidget/components/DynamicWidgetHeader/DynamicWidgetHeader.js';
95
+ import '../../../views/TransactionConfirmationView/TransactionConfirmationView.js';
96
+ import '../../../widgets/DynamicWidget/components/PasskeyCard/PasskeyCard.js';
97
+ import '../../../widgets/DynamicWidget/views/CryptoComOnramp/CryptoComOnramp.js';
98
+ import '../../../../index.js';
99
+ import '../../../widgets/DynamicWidget/views/ReceiveWalletFunds/ReceiveWalletFunds.js';
100
+ import '../../../store/state/tokenBalances.js';
101
+ import '../../../store/state/multichainBalances.js';
102
+ import '../../../shared/utils/functions/getInitialUrl/getInitialUrl.js';
103
+ import { useInternalDynamicContext } from '../../../context/DynamicContext/useDynamicContext/useInternalDynamicContext/useInternalDynamicContext.js';
104
+
105
+ /**
106
+ * Hook for signing EIP-7702 authorizations for ZeroDev kernel delegation.
107
+ *
108
+ * This hook provides a way to sign EIP-7702 authorizations that enable
109
+ * single-use MFA flows where the authorization signing step is separated
110
+ * from the transaction execution step.
111
+ *
112
+ * The signed authorization can be passed to kernel account client creation
113
+ * functions like `createEcdsaKernelAccountClientWith7702`.
114
+ *
115
+ * @returns An object containing the `signEip7702Authorization` function
116
+ *
117
+ * @example
118
+ * ```tsx
119
+ * import { useSignEip7702Authorization } from '@dynamic-labs/sdk-react-core';
120
+ *
121
+ * function MyComponent() {
122
+ * const { signEip7702Authorization } = useSignEip7702Authorization();
123
+ *
124
+ * const handleSign = async () => {
125
+ * try {
126
+ * const auth = await signEip7702Authorization();
127
+ * console.log('Signed authorization:', auth);
128
+ * // Use auth with kernel client creation
129
+ * } catch (error) {
130
+ * console.error('Failed to sign authorization:', error);
131
+ * }
132
+ * };
133
+ *
134
+ * return <button onClick={handleSign}>Sign Authorization</button>;
135
+ * }
136
+ * ```
137
+ */
138
+ const useSignEip7702Authorization = () => {
139
+ const { primaryWallet } = useInternalDynamicContext();
140
+ const signEip7702Auth = useCallback((params) => __awaiter(void 0, void 0, void 0, function* () {
141
+ var _a;
142
+ const { wallet: providedWallet, chainId: providedChainId } = params !== null && params !== void 0 ? params : {};
143
+ // Use provided wallet or fallback to primary wallet
144
+ const wallet = providedWallet !== null && providedWallet !== void 0 ? providedWallet : primaryWallet;
145
+ if (!wallet) {
146
+ throw new DynamicError('No wallet available. Please connect a wallet first.');
147
+ }
148
+ if (((_a = wallet.connector) === null || _a === void 0 ? void 0 : _a.key) !== 'zerodev') {
149
+ throw new DynamicError('The wallet connector must be a ZeroDev connector to sign EIP-7702 authorizations.');
150
+ }
151
+ return wallet.connector.signEip7702PreAuth(providedChainId);
152
+ }), [primaryWallet]);
153
+ return {
154
+ signEip7702Authorization: signEip7702Auth,
155
+ };
156
+ };
157
+
158
+ export { useSignEip7702Authorization };
@@ -1,2 +1,2 @@
1
1
  export { useStepUpAuthentication } from './useStepUpAuthentication';
2
- export type { StepUpAuthenticationState, UseStepUpAuthenticationParams, UseStepUpAuthenticationReturn, VerifyOtpParams, VerifyWalletParams, } from './useStepUpAuthentication';
2
+ export type { IsStepUpRequiredParams, StepUpAuthenticationState, UseStepUpAuthenticationParams, UseStepUpAuthenticationReturn, VerifyOtpParams, VerifyPasskeyMfaParams, VerifyTotpMfaParams, VerifyWalletParams, } from './useStepUpAuthentication';
@@ -24,12 +24,13 @@ require('@dynamic-labs/multi-wallet');
24
24
  require('react-international-phone');
25
25
  require('../../../store/state/nonce/nonce.cjs');
26
26
  require('@dynamic-labs/locale');
27
- require('../../../store/state/dynamicContextProps/dynamicContextProps.cjs');
27
+ var dynamicContextProps = require('../../../store/state/dynamicContextProps/dynamicContextProps.cjs');
28
28
  require('../../../store/state/primaryWalletId/primaryWalletId.cjs');
29
29
  require('../../../store/state/connectedWalletsInfo/connectedWalletsInfo.cjs');
30
30
  require('../../functions/getWaasAddressTypeLabel/getWaasAddressTypeLabel.cjs');
31
31
  require('../../../events/dynamicEvents.cjs');
32
32
  var useUser = require('../../../client/extension/user/useUser/useUser.cjs');
33
+ var hasElevatedAccessToken = require('../../../client/extension/functions/hasElevatedAccessToken/hasElevatedAccessToken.cjs');
33
34
  var useConnectAndSign = require('../authenticationHooks/useConnectAndSign/useConnectAndSign.cjs');
34
35
  var UserWalletsContext = require('../../../context/UserWalletsContext/UserWalletsContext.cjs');
35
36
 
@@ -72,47 +73,55 @@ const dispatchOtp = (credential) => _tslib.__awaiter(void 0, void 0, void 0, fun
72
73
  : sendSmsOtp(credential);
73
74
  });
74
75
  /**
75
- * Perform step-up authentication for an already-authenticated user via OTP.
76
+ * Perform step-up authentication for an already-authenticated user.
76
77
  *
77
- * Automatically selects the first sign-in enabled email or SMS credential on
78
- * the user, or targets a specific credential when `credentialId` is provided.
78
+ * Supports multiple verification methods:
79
+ * - **OTP** (email/SMS): `sendOtp()` then `verifyOtp()`
80
+ * - **Wallet**: `verifyWallet()` for wallet signature verification
81
+ * - **Passkey MFA**: `verifyPasskeyMfa()` for passkey-based MFA
82
+ * - **TOTP MFA**: `verifyTotpMfa()` for authenticator app codes
79
83
  *
80
- * @param params.credentialId - Optional id of a specific verified credential to
81
- * use. Must be an email or SMS credential. Defaults to the first sign-in
82
- * enabled email or SMS credential on the authenticated user.
84
+ * For OTP and wallet methods, automatically selects the first sign-in enabled
85
+ * credential, or targets a specific one when `credentialId` is provided.
83
86
  *
84
- * @returns `sendOtp` sends the OTP to the resolved credential.
85
- * @returns `verifyOtp` verifies the OTP code supplied by the user.
86
- * @returns `state` current loading / error / otpVerification state.
87
- * @returns `resetState` – resets state back to its initial value.
87
+ * @param params.credentialId - Optional id of a specific verified credential or
88
+ * wallet to use. For OTP, must be an email or SMS credential. Defaults to the
89
+ * first sign-in enabled email or SMS credential on the authenticated user.
88
90
  *
89
91
  * @example
90
92
  * ```tsx
91
- * const { sendOtp, verifyOtp, state } = useStepUpAuthentication();
92
- *
93
- * // Step 1: send OTP
93
+ * // OTP flow
94
+ * const { sendOtp, verifyOtp } = useStepUpAuthentication();
94
95
  * await sendOtp();
96
+ * const result = await verifyOtp({ verificationToken: '123456', requestedScopes: ['wallet:export'] });
97
+ *
98
+ * // Passkey MFA flow
99
+ * const { verifyPasskeyMfa } = useStepUpAuthentication();
100
+ * const result = await verifyPasskeyMfa({ requestedScopes: ['wallet:export'] });
95
101
  *
96
- * // Step 2: after the user enters the code
97
- * const result = await verifyOtp({ verificationToken: '123456' });
102
+ * // TOTP MFA flow
103
+ * const { verifyTotpMfa } = useStepUpAuthentication();
104
+ * const result = await verifyTotpMfa({ code: '123456', requestedScopes: ['wallet:export'] });
98
105
  * ```
99
106
  */
100
107
  const useStepUpAuthentication = ({ credentialId, } = {}) => {
101
108
  const user = useUser.useUser();
109
+ const environmentId = dynamicContextProps.useEnvironmentId();
102
110
  const [state, setState] = React.useState(INITIAL_STATE);
103
111
  const connectAndSign = useConnectAndSign.useConnectAndSign();
104
112
  const { userWallets } = UserWalletsContext.useInternalUserWallets();
105
113
  // Ref keeps the latest otpVerification available inside the verifyOtp
106
114
  // callback without creating a stale closure over state.
107
115
  const otpVerificationRef = React.useRef(null);
116
+ const isStepUpRequired = React.useCallback(({ scope }) => !hasElevatedAccessToken.hasElevatedAccessToken(scope), []);
108
117
  const resetState = React.useCallback(() => {
109
118
  otpVerificationRef.current = null;
110
119
  setState(INITIAL_STATE);
111
120
  }, []);
112
121
  const setError = React.useCallback((errorMessage) => {
113
122
  setState((prev) => (Object.assign(Object.assign({}, prev), { error: errorMessage, isLoading: false })));
114
- logger.logger.error(errorMessage);
115
- }, []);
123
+ logger.logger.error(errorMessage, { environmentId, userId: user === null || user === void 0 ? void 0 : user.id });
124
+ }, [environmentId, user === null || user === void 0 ? void 0 : user.id]);
116
125
  const sendOtp = React.useCallback(() => _tslib.__awaiter(void 0, void 0, void 0, function* () {
117
126
  const credentials = user === null || user === void 0 ? void 0 : user.verifiedCredentials;
118
127
  if (!(credentials === null || credentials === void 0 ? void 0 : credentials.length)) {
@@ -138,10 +147,20 @@ const useStepUpAuthentication = ({ credentialId, } = {}) => {
138
147
  catch (error) {
139
148
  const errorMessage = error instanceof Error ? error.message : 'Failed to send OTP';
140
149
  setState((prev) => (Object.assign(Object.assign({}, prev), { error: errorMessage, isLoading: false })));
141
- logger.logger.error('Failed to send OTP for step-up authentication', { error });
150
+ logger.logger.error('Failed to send OTP for step-up authentication', {
151
+ environmentId,
152
+ error,
153
+ userId: user === null || user === void 0 ? void 0 : user.id,
154
+ });
142
155
  return null;
143
156
  }
144
- }), [credentialId, setError, user === null || user === void 0 ? void 0 : user.verifiedCredentials]);
157
+ }), [
158
+ credentialId,
159
+ environmentId,
160
+ setError,
161
+ user === null || user === void 0 ? void 0 : user.id,
162
+ user === null || user === void 0 ? void 0 : user.verifiedCredentials,
163
+ ]);
145
164
  const verifyOtp = React.useCallback((_a) => _tslib.__awaiter(void 0, [_a], void 0, function* ({ requestedScopes, verificationToken, }) {
146
165
  const otpVerification = otpVerificationRef.current;
147
166
  if (!otpVerification) {
@@ -162,11 +181,13 @@ const useStepUpAuthentication = ({ credentialId, } = {}) => {
162
181
  const errorMessage = error instanceof Error ? error.message : 'Failed to verify OTP';
163
182
  setState((prev) => (Object.assign(Object.assign({}, prev), { error: errorMessage, isLoading: false })));
164
183
  logger.logger.error('Failed to verify OTP for step-up authentication', {
184
+ environmentId,
165
185
  error,
186
+ userId: user === null || user === void 0 ? void 0 : user.id,
166
187
  });
167
188
  return null;
168
189
  }
169
- }), [setError]);
190
+ }), [environmentId, setError, user === null || user === void 0 ? void 0 : user.id]);
170
191
  const verifyWallet = React.useCallback((_b) => _tslib.__awaiter(void 0, [_b], void 0, function* ({ requestedScopes }) {
171
192
  setState((prev) => (Object.assign(Object.assign({}, prev), { error: null, isLoading: true })));
172
193
  const wallet = userWallets.find((w) => w.id === credentialId);
@@ -187,11 +208,69 @@ const useStepUpAuthentication = ({ credentialId, } = {}) => {
187
208
  : 'Failed to verify wallet for step-up authentication';
188
209
  setState((prev) => (Object.assign(Object.assign({}, prev), { error: errorMessage, isLoading: false })));
189
210
  logger.logger.error('Failed to verify wallet for step-up authentication', {
211
+ environmentId,
190
212
  error,
213
+ userId: user === null || user === void 0 ? void 0 : user.id,
214
+ });
215
+ }
216
+ }), [
217
+ connectAndSign,
218
+ credentialId,
219
+ environmentId,
220
+ setError,
221
+ user === null || user === void 0 ? void 0 : user.id,
222
+ userWallets,
223
+ ]);
224
+ const verifyPasskeyMfa = React.useCallback((_c) => _tslib.__awaiter(void 0, [_c], void 0, function* ({ requestedScopes, }) {
225
+ setState((prev) => (Object.assign(Object.assign({}, prev), { error: null, isLoading: true })));
226
+ try {
227
+ // requestedScopes is available in @dynamic-labs-sdk/client >= 0.14.0
228
+ const response = yield client.authenticatePasskeyMFA({
229
+ requestedScopes,
191
230
  });
231
+ setState((prev) => (Object.assign(Object.assign({}, prev), { error: null, isLoading: false })));
232
+ return response;
233
+ }
234
+ catch (error) {
235
+ const errorMessage = error instanceof Error
236
+ ? error.message
237
+ : 'Failed to authenticate passkey for step-up authentication';
238
+ setState((prev) => (Object.assign(Object.assign({}, prev), { error: errorMessage, isLoading: false })));
239
+ logger.logger.error('Failed to authenticate passkey for step-up authentication', { environmentId, error, userId: user === null || user === void 0 ? void 0 : user.id });
240
+ return null;
241
+ }
242
+ }), [environmentId, user === null || user === void 0 ? void 0 : user.id]);
243
+ const verifyTotpMfa = React.useCallback((_d) => _tslib.__awaiter(void 0, [_d], void 0, function* ({ code, deviceId, requestedScopes, }) {
244
+ setState((prev) => (Object.assign(Object.assign({}, prev), { error: null, isLoading: true })));
245
+ try {
246
+ // requestedScopes is available in @dynamic-labs-sdk/client >= 0.14.0
247
+ const response = yield client.authenticateTotpMfaDevice({
248
+ code,
249
+ deviceId,
250
+ requestedScopes,
251
+ });
252
+ setState((prev) => (Object.assign(Object.assign({}, prev), { error: null, isLoading: false })));
253
+ return response;
254
+ }
255
+ catch (error) {
256
+ const errorMessage = error instanceof Error
257
+ ? error.message
258
+ : 'Failed to authenticate TOTP device for step-up authentication';
259
+ setState((prev) => (Object.assign(Object.assign({}, prev), { error: errorMessage, isLoading: false })));
260
+ logger.logger.error('Failed to authenticate TOTP device for step-up authentication', { environmentId, error, userId: user === null || user === void 0 ? void 0 : user.id });
261
+ return null;
192
262
  }
193
- }), [connectAndSign, credentialId, setError, userWallets]);
194
- return { resetState, sendOtp, state, verifyOtp, verifyWallet };
263
+ }), [environmentId, user === null || user === void 0 ? void 0 : user.id]);
264
+ return {
265
+ isStepUpRequired,
266
+ resetState,
267
+ sendOtp,
268
+ state,
269
+ verifyOtp,
270
+ verifyPasskeyMfa,
271
+ verifyTotpMfa,
272
+ verifyWallet,
273
+ };
195
274
  };
196
275
 
197
276
  exports.useStepUpAuthentication = useStepUpAuthentication;
@@ -12,40 +12,60 @@ export type VerifyOtpParams = {
12
12
  export type VerifyWalletParams = {
13
13
  requestedScopes?: TokenScope[];
14
14
  };
15
+ export type VerifyPasskeyMfaParams = {
16
+ requestedScopes?: TokenScope[];
17
+ };
18
+ export type VerifyTotpMfaParams = {
19
+ code: string;
20
+ deviceId?: string;
21
+ requestedScopes?: TokenScope[];
22
+ };
23
+ export type IsStepUpRequiredParams = {
24
+ scope: TokenScope;
25
+ };
15
26
  export type UseStepUpAuthenticationParams = {
16
27
  credentialId?: string;
17
28
  };
18
29
  export type UseStepUpAuthenticationReturn = {
30
+ isStepUpRequired: (params: IsStepUpRequiredParams) => boolean;
19
31
  resetState: () => void;
20
32
  sendOtp: () => Promise<OTPVerification | null>;
21
33
  state: StepUpAuthenticationState;
22
34
  verifyOtp: (params: VerifyOtpParams) => Promise<VerifyResponse | null>;
35
+ verifyPasskeyMfa: (params: VerifyPasskeyMfaParams) => Promise<VerifyResponse | null>;
36
+ verifyTotpMfa: (params: VerifyTotpMfaParams) => Promise<VerifyResponse | null>;
23
37
  verifyWallet: (params: VerifyWalletParams) => Promise<void>;
24
38
  };
25
39
  /**
26
- * Perform step-up authentication for an already-authenticated user via OTP.
40
+ * Perform step-up authentication for an already-authenticated user.
27
41
  *
28
- * Automatically selects the first sign-in enabled email or SMS credential on
29
- * the user, or targets a specific credential when `credentialId` is provided.
42
+ * Supports multiple verification methods:
43
+ * - **OTP** (email/SMS): `sendOtp()` then `verifyOtp()`
44
+ * - **Wallet**: `verifyWallet()` for wallet signature verification
45
+ * - **Passkey MFA**: `verifyPasskeyMfa()` for passkey-based MFA
46
+ * - **TOTP MFA**: `verifyTotpMfa()` for authenticator app codes
30
47
  *
31
- * @param params.credentialId - Optional id of a specific verified credential to
32
- * use. Must be an email or SMS credential. Defaults to the first sign-in
33
- * enabled email or SMS credential on the authenticated user.
48
+ * For OTP and wallet methods, automatically selects the first sign-in enabled
49
+ * credential, or targets a specific one when `credentialId` is provided.
34
50
  *
35
- * @returns `sendOtp` sends the OTP to the resolved credential.
36
- * @returns `verifyOtp` verifies the OTP code supplied by the user.
37
- * @returns `state` current loading / error / otpVerification state.
38
- * @returns `resetState` – resets state back to its initial value.
51
+ * @param params.credentialId - Optional id of a specific verified credential or
52
+ * wallet to use. For OTP, must be an email or SMS credential. Defaults to the
53
+ * first sign-in enabled email or SMS credential on the authenticated user.
39
54
  *
40
55
  * @example
41
56
  * ```tsx
42
- * const { sendOtp, verifyOtp, state } = useStepUpAuthentication();
43
- *
44
- * // Step 1: send OTP
57
+ * // OTP flow
58
+ * const { sendOtp, verifyOtp } = useStepUpAuthentication();
45
59
  * await sendOtp();
60
+ * const result = await verifyOtp({ verificationToken: '123456', requestedScopes: ['wallet:export'] });
61
+ *
62
+ * // Passkey MFA flow
63
+ * const { verifyPasskeyMfa } = useStepUpAuthentication();
64
+ * const result = await verifyPasskeyMfa({ requestedScopes: ['wallet:export'] });
46
65
  *
47
- * // Step 2: after the user enters the code
48
- * const result = await verifyOtp({ verificationToken: '123456' });
66
+ * // TOTP MFA flow
67
+ * const { verifyTotpMfa } = useStepUpAuthentication();
68
+ * const result = await verifyTotpMfa({ code: '123456', requestedScopes: ['wallet:export'] });
49
69
  * ```
50
70
  */
51
71
  export declare const useStepUpAuthentication: ({ credentialId, }?: UseStepUpAuthenticationParams) => UseStepUpAuthenticationReturn;
@@ -1,7 +1,7 @@
1
1
  'use client'
2
2
  import { __awaiter } from '../../../../../_virtual/_tslib.js';
3
3
  import { useState, useRef, useCallback } from 'react';
4
- import { verifyOTP, sendEmailOTP, supportedCountries, sendSmsOTP } from '@dynamic-labs-sdk/client';
4
+ import { verifyOTP, authenticatePasskeyMFA, authenticateTotpMfaDevice, sendEmailOTP, supportedCountries, sendSmsOTP } from '@dynamic-labs-sdk/client';
5
5
  import { JwtVerifiedCredentialFormatEnum } from '@dynamic-labs/sdk-api-core';
6
6
  import '@dynamic-labs-sdk/client/core';
7
7
  import '../../../client/client.js';
@@ -20,12 +20,13 @@ import '@dynamic-labs/multi-wallet';
20
20
  import 'react-international-phone';
21
21
  import '../../../store/state/nonce/nonce.js';
22
22
  import '@dynamic-labs/locale';
23
- import '../../../store/state/dynamicContextProps/dynamicContextProps.js';
23
+ import { useEnvironmentId } from '../../../store/state/dynamicContextProps/dynamicContextProps.js';
24
24
  import '../../../store/state/primaryWalletId/primaryWalletId.js';
25
25
  import '../../../store/state/connectedWalletsInfo/connectedWalletsInfo.js';
26
26
  import '../../functions/getWaasAddressTypeLabel/getWaasAddressTypeLabel.js';
27
27
  import '../../../events/dynamicEvents.js';
28
28
  import { useUser } from '../../../client/extension/user/useUser/useUser.js';
29
+ import { hasElevatedAccessToken } from '../../../client/extension/functions/hasElevatedAccessToken/hasElevatedAccessToken.js';
29
30
  import { useConnectAndSign } from '../authenticationHooks/useConnectAndSign/useConnectAndSign.js';
30
31
  import { useInternalUserWallets } from '../../../context/UserWalletsContext/UserWalletsContext.js';
31
32
 
@@ -68,47 +69,55 @@ const dispatchOtp = (credential) => __awaiter(void 0, void 0, void 0, function*
68
69
  : sendSmsOtp(credential);
69
70
  });
70
71
  /**
71
- * Perform step-up authentication for an already-authenticated user via OTP.
72
+ * Perform step-up authentication for an already-authenticated user.
72
73
  *
73
- * Automatically selects the first sign-in enabled email or SMS credential on
74
- * the user, or targets a specific credential when `credentialId` is provided.
74
+ * Supports multiple verification methods:
75
+ * - **OTP** (email/SMS): `sendOtp()` then `verifyOtp()`
76
+ * - **Wallet**: `verifyWallet()` for wallet signature verification
77
+ * - **Passkey MFA**: `verifyPasskeyMfa()` for passkey-based MFA
78
+ * - **TOTP MFA**: `verifyTotpMfa()` for authenticator app codes
75
79
  *
76
- * @param params.credentialId - Optional id of a specific verified credential to
77
- * use. Must be an email or SMS credential. Defaults to the first sign-in
78
- * enabled email or SMS credential on the authenticated user.
80
+ * For OTP and wallet methods, automatically selects the first sign-in enabled
81
+ * credential, or targets a specific one when `credentialId` is provided.
79
82
  *
80
- * @returns `sendOtp` sends the OTP to the resolved credential.
81
- * @returns `verifyOtp` verifies the OTP code supplied by the user.
82
- * @returns `state` current loading / error / otpVerification state.
83
- * @returns `resetState` – resets state back to its initial value.
83
+ * @param params.credentialId - Optional id of a specific verified credential or
84
+ * wallet to use. For OTP, must be an email or SMS credential. Defaults to the
85
+ * first sign-in enabled email or SMS credential on the authenticated user.
84
86
  *
85
87
  * @example
86
88
  * ```tsx
87
- * const { sendOtp, verifyOtp, state } = useStepUpAuthentication();
88
- *
89
- * // Step 1: send OTP
89
+ * // OTP flow
90
+ * const { sendOtp, verifyOtp } = useStepUpAuthentication();
90
91
  * await sendOtp();
92
+ * const result = await verifyOtp({ verificationToken: '123456', requestedScopes: ['wallet:export'] });
93
+ *
94
+ * // Passkey MFA flow
95
+ * const { verifyPasskeyMfa } = useStepUpAuthentication();
96
+ * const result = await verifyPasskeyMfa({ requestedScopes: ['wallet:export'] });
91
97
  *
92
- * // Step 2: after the user enters the code
93
- * const result = await verifyOtp({ verificationToken: '123456' });
98
+ * // TOTP MFA flow
99
+ * const { verifyTotpMfa } = useStepUpAuthentication();
100
+ * const result = await verifyTotpMfa({ code: '123456', requestedScopes: ['wallet:export'] });
94
101
  * ```
95
102
  */
96
103
  const useStepUpAuthentication = ({ credentialId, } = {}) => {
97
104
  const user = useUser();
105
+ const environmentId = useEnvironmentId();
98
106
  const [state, setState] = useState(INITIAL_STATE);
99
107
  const connectAndSign = useConnectAndSign();
100
108
  const { userWallets } = useInternalUserWallets();
101
109
  // Ref keeps the latest otpVerification available inside the verifyOtp
102
110
  // callback without creating a stale closure over state.
103
111
  const otpVerificationRef = useRef(null);
112
+ const isStepUpRequired = useCallback(({ scope }) => !hasElevatedAccessToken(scope), []);
104
113
  const resetState = useCallback(() => {
105
114
  otpVerificationRef.current = null;
106
115
  setState(INITIAL_STATE);
107
116
  }, []);
108
117
  const setError = useCallback((errorMessage) => {
109
118
  setState((prev) => (Object.assign(Object.assign({}, prev), { error: errorMessage, isLoading: false })));
110
- logger.error(errorMessage);
111
- }, []);
119
+ logger.error(errorMessage, { environmentId, userId: user === null || user === void 0 ? void 0 : user.id });
120
+ }, [environmentId, user === null || user === void 0 ? void 0 : user.id]);
112
121
  const sendOtp = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
113
122
  const credentials = user === null || user === void 0 ? void 0 : user.verifiedCredentials;
114
123
  if (!(credentials === null || credentials === void 0 ? void 0 : credentials.length)) {
@@ -134,10 +143,20 @@ const useStepUpAuthentication = ({ credentialId, } = {}) => {
134
143
  catch (error) {
135
144
  const errorMessage = error instanceof Error ? error.message : 'Failed to send OTP';
136
145
  setState((prev) => (Object.assign(Object.assign({}, prev), { error: errorMessage, isLoading: false })));
137
- logger.error('Failed to send OTP for step-up authentication', { error });
146
+ logger.error('Failed to send OTP for step-up authentication', {
147
+ environmentId,
148
+ error,
149
+ userId: user === null || user === void 0 ? void 0 : user.id,
150
+ });
138
151
  return null;
139
152
  }
140
- }), [credentialId, setError, user === null || user === void 0 ? void 0 : user.verifiedCredentials]);
153
+ }), [
154
+ credentialId,
155
+ environmentId,
156
+ setError,
157
+ user === null || user === void 0 ? void 0 : user.id,
158
+ user === null || user === void 0 ? void 0 : user.verifiedCredentials,
159
+ ]);
141
160
  const verifyOtp = useCallback((_a) => __awaiter(void 0, [_a], void 0, function* ({ requestedScopes, verificationToken, }) {
142
161
  const otpVerification = otpVerificationRef.current;
143
162
  if (!otpVerification) {
@@ -158,11 +177,13 @@ const useStepUpAuthentication = ({ credentialId, } = {}) => {
158
177
  const errorMessage = error instanceof Error ? error.message : 'Failed to verify OTP';
159
178
  setState((prev) => (Object.assign(Object.assign({}, prev), { error: errorMessage, isLoading: false })));
160
179
  logger.error('Failed to verify OTP for step-up authentication', {
180
+ environmentId,
161
181
  error,
182
+ userId: user === null || user === void 0 ? void 0 : user.id,
162
183
  });
163
184
  return null;
164
185
  }
165
- }), [setError]);
186
+ }), [environmentId, setError, user === null || user === void 0 ? void 0 : user.id]);
166
187
  const verifyWallet = useCallback((_b) => __awaiter(void 0, [_b], void 0, function* ({ requestedScopes }) {
167
188
  setState((prev) => (Object.assign(Object.assign({}, prev), { error: null, isLoading: true })));
168
189
  const wallet = userWallets.find((w) => w.id === credentialId);
@@ -183,11 +204,69 @@ const useStepUpAuthentication = ({ credentialId, } = {}) => {
183
204
  : 'Failed to verify wallet for step-up authentication';
184
205
  setState((prev) => (Object.assign(Object.assign({}, prev), { error: errorMessage, isLoading: false })));
185
206
  logger.error('Failed to verify wallet for step-up authentication', {
207
+ environmentId,
186
208
  error,
209
+ userId: user === null || user === void 0 ? void 0 : user.id,
210
+ });
211
+ }
212
+ }), [
213
+ connectAndSign,
214
+ credentialId,
215
+ environmentId,
216
+ setError,
217
+ user === null || user === void 0 ? void 0 : user.id,
218
+ userWallets,
219
+ ]);
220
+ const verifyPasskeyMfa = useCallback((_c) => __awaiter(void 0, [_c], void 0, function* ({ requestedScopes, }) {
221
+ setState((prev) => (Object.assign(Object.assign({}, prev), { error: null, isLoading: true })));
222
+ try {
223
+ // requestedScopes is available in @dynamic-labs-sdk/client >= 0.14.0
224
+ const response = yield authenticatePasskeyMFA({
225
+ requestedScopes,
187
226
  });
227
+ setState((prev) => (Object.assign(Object.assign({}, prev), { error: null, isLoading: false })));
228
+ return response;
229
+ }
230
+ catch (error) {
231
+ const errorMessage = error instanceof Error
232
+ ? error.message
233
+ : 'Failed to authenticate passkey for step-up authentication';
234
+ setState((prev) => (Object.assign(Object.assign({}, prev), { error: errorMessage, isLoading: false })));
235
+ logger.error('Failed to authenticate passkey for step-up authentication', { environmentId, error, userId: user === null || user === void 0 ? void 0 : user.id });
236
+ return null;
237
+ }
238
+ }), [environmentId, user === null || user === void 0 ? void 0 : user.id]);
239
+ const verifyTotpMfa = useCallback((_d) => __awaiter(void 0, [_d], void 0, function* ({ code, deviceId, requestedScopes, }) {
240
+ setState((prev) => (Object.assign(Object.assign({}, prev), { error: null, isLoading: true })));
241
+ try {
242
+ // requestedScopes is available in @dynamic-labs-sdk/client >= 0.14.0
243
+ const response = yield authenticateTotpMfaDevice({
244
+ code,
245
+ deviceId,
246
+ requestedScopes,
247
+ });
248
+ setState((prev) => (Object.assign(Object.assign({}, prev), { error: null, isLoading: false })));
249
+ return response;
250
+ }
251
+ catch (error) {
252
+ const errorMessage = error instanceof Error
253
+ ? error.message
254
+ : 'Failed to authenticate TOTP device for step-up authentication';
255
+ setState((prev) => (Object.assign(Object.assign({}, prev), { error: errorMessage, isLoading: false })));
256
+ logger.error('Failed to authenticate TOTP device for step-up authentication', { environmentId, error, userId: user === null || user === void 0 ? void 0 : user.id });
257
+ return null;
188
258
  }
189
- }), [connectAndSign, credentialId, setError, userWallets]);
190
- return { resetState, sendOtp, state, verifyOtp, verifyWallet };
259
+ }), [environmentId, user === null || user === void 0 ? void 0 : user.id]);
260
+ return {
261
+ isStepUpRequired,
262
+ resetState,
263
+ sendOtp,
264
+ state,
265
+ verifyOtp,
266
+ verifyPasskeyMfa,
267
+ verifyTotpMfa,
268
+ verifyWallet,
269
+ };
191
270
  };
192
271
 
193
272
  export { useStepUpAuthentication };