@dynamic-labs/sdk-react-core 3.0.0-alpha.46 → 3.0.0-alpha.48
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 +34 -0
- package/package.cjs +2 -2
- package/package.js +2 -2
- package/package.json +13 -13
- package/src/index.cjs +2 -2
- package/src/index.d.ts +1 -1
- package/src/index.js +1 -1
- package/src/lib/components/OTPVerificationView/OTPVerificationView.cjs +2 -2
- package/src/lib/components/OTPVerificationView/OTPVerificationView.d.ts +1 -0
- package/src/lib/components/OTPVerificationView/OTPVerificationView.js +2 -2
- package/src/lib/components/PinField/PinField.cjs +2 -2
- package/src/lib/components/PinField/PinField.d.ts +1 -1
- package/src/lib/components/PinField/PinField.js +2 -2
- package/src/lib/components/SendBalanceForm/SendBalanceForm.cjs +1 -1
- package/src/lib/components/SendBalanceForm/SendBalanceForm.js +1 -1
- package/src/lib/components/SendBalancePageLayout/SendBalancePageLayout.cjs +3 -3
- package/src/lib/components/SendBalancePageLayout/SendBalancePageLayout.js +3 -3
- package/src/lib/components/TransactionConfirmationPageLayout/TransactionConfirmationPageLayout.cjs +3 -3
- package/src/lib/components/TransactionConfirmationPageLayout/TransactionConfirmationPageLayout.js +3 -3
- package/src/lib/components/TransactionStatusLayout/TransactionStatusLayout.cjs +1 -1
- package/src/lib/components/TransactionStatusLayout/TransactionStatusLayout.js +1 -1
- package/src/lib/components/UserProfile/parts/UserProfileSocialAccount/UserProfileSocialAccount.cjs +1 -1
- package/src/lib/components/UserProfile/parts/UserProfileSocialAccount/UserProfileSocialAccount.js +1 -1
- package/src/lib/context/DynamicContext/useDynamicContext/useDynamicContext.cjs +1 -2
- package/src/lib/context/DynamicContext/useDynamicContext/useDynamicContext.d.ts +1 -1
- package/src/lib/context/DynamicContext/useDynamicContext/useDynamicContext.js +1 -2
- package/src/lib/data/api/mfa/mfa.cjs +5 -1
- package/src/lib/data/api/mfa/mfa.d.ts +2 -1
- package/src/lib/data/api/mfa/mfa.js +6 -2
- package/src/lib/locale/en/translation.cjs +3 -1
- package/src/lib/locale/en/translation.d.ts +2 -0
- package/src/lib/locale/en/translation.js +3 -1
- package/src/lib/shared/utils/functions/hasPendingRequirements/hasPendingRequirements.cjs +10 -0
- package/src/lib/shared/utils/functions/hasPendingRequirements/hasPendingRequirements.d.ts +2 -0
- package/src/lib/shared/utils/functions/hasPendingRequirements/hasPendingRequirements.js +6 -0
- package/src/lib/shared/utils/functions/hasPendingRequirements/index.d.ts +1 -0
- package/src/lib/shared/utils/functions/index.d.ts +1 -0
- package/src/lib/store/hooks/useUser/useUser.cjs +2 -4
- package/src/lib/store/hooks/useUser/useUser.js +2 -4
- package/src/lib/styles/index.shadow.cjs +1 -1
- package/src/lib/styles/index.shadow.js +1 -1
- package/src/lib/utils/functions/isCookieEnabled/isCookieEnabled.cjs +8 -1
- package/src/lib/utils/functions/isCookieEnabled/isCookieEnabled.js +8 -1
- package/src/lib/utils/hooks/index.d.ts +1 -1
- package/src/lib/utils/hooks/useExternalAuth/useExternalAuth.cjs +4 -1
- package/src/lib/utils/hooks/useExternalAuth/useExternalAuth.js +4 -1
- package/src/lib/utils/hooks/useMfa/useMfa.cjs +2 -1
- package/src/lib/utils/hooks/useMfa/useMfa.d.ts +1 -1
- package/src/lib/utils/hooks/useMfa/useMfa.js +2 -1
- package/src/lib/utils/hooks/useSocialAuth/useSocialAuth.cjs +7 -13
- package/src/lib/utils/hooks/useSocialAuth/useSocialAuth.js +7 -13
- package/src/lib/utils/hooks/useUserAuth/useUserAuth.cjs +2 -1
- package/src/lib/utils/hooks/useUserAuth/useUserAuth.js +3 -2
- package/src/lib/utils/hooks/useWalletOptions/index.d.ts +1 -0
- package/src/lib/utils/hooks/{useSelectWalletOption/useSelectWalletOption.cjs → useWalletOptions/useWalletOptions.cjs} +31 -4
- package/src/lib/utils/hooks/useWalletOptions/useWalletOptions.d.ts +9 -0
- package/src/lib/utils/hooks/{useSelectWalletOption/useSelectWalletOption.js → useWalletOptions/useWalletOptions.js} +32 -5
- package/src/lib/views/CollectUserDataView/CollectUserDataView.cjs +6 -5
- package/src/lib/views/CollectUserDataView/CollectUserDataView.js +6 -5
- package/src/lib/views/MfaVerificationView/MfaVerificationView.cjs +10 -3
- package/src/lib/views/MfaVerificationView/MfaVerificationView.js +11 -4
- package/src/lib/widgets/DynamicWidget/views/ManageMfaWidgetView/ManageMfaWidgetView.cjs +20 -6
- package/src/lib/widgets/DynamicWidget/views/ManageMfaWidgetView/ManageMfaWidgetView.js +21 -7
- package/src/lib/widgets/DynamicWidget/views/ManageMfaWidgetView/components/UserDeviceTile.cjs +3 -4
- package/src/lib/widgets/DynamicWidget/views/ManageMfaWidgetView/components/UserDeviceTile.d.ts +2 -1
- package/src/lib/widgets/DynamicWidget/views/ManageMfaWidgetView/components/UserDeviceTile.js +3 -4
- package/src/lib/widgets/DynamicWidget/views/ManageMfaWidgetView/components/utils/sort.cjs +2 -8
- package/src/lib/widgets/DynamicWidget/views/ManageMfaWidgetView/components/utils/sort.d.ts +1 -1
- package/src/lib/widgets/DynamicWidget/views/ManageMfaWidgetView/components/utils/sort.js +2 -8
- package/src/lib/utils/hooks/useSelectWalletOption/index.d.ts +0 -1
- package/src/lib/utils/hooks/useSelectWalletOption/useSelectWalletOption.d.ts +0 -3
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
5
|
|
|
6
6
|
var sdkApiCore = require('@dynamic-labs/sdk-api-core');
|
|
7
|
+
var utils = require('@dynamic-labs/utils');
|
|
7
8
|
require('@dynamic-labs/store');
|
|
8
9
|
require('../../constants/colors.cjs');
|
|
9
10
|
require('../../constants/values.cjs');
|
|
@@ -16,7 +17,6 @@ require('react');
|
|
|
16
17
|
require('@dynamic-labs/wallet-book');
|
|
17
18
|
require('../../../shared/utils/classes/storage/localStorage.cjs');
|
|
18
19
|
require('../../../shared/utils/classes/storage/sessionStorage.cjs');
|
|
19
|
-
require('@dynamic-labs/utils');
|
|
20
20
|
require('../../../shared/consts/index.cjs');
|
|
21
21
|
var projectSettingsActions = require('../../../store/actions/projectSettingsActions/projectSettingsActions.cjs');
|
|
22
22
|
require('../../../../../_virtual/_tslib.cjs');
|
|
@@ -91,6 +91,13 @@ require('../../../context/ReinitializeContext/ReinitializeContextProvider.cjs');
|
|
|
91
91
|
|
|
92
92
|
const isCookieEnabled = () => {
|
|
93
93
|
var _a, _b, _c, _d;
|
|
94
|
+
/**
|
|
95
|
+
* There is no cookie on native mobile applications
|
|
96
|
+
* so this feature must be disabled for native mobile
|
|
97
|
+
*/
|
|
98
|
+
if (utils.PlatformService.isNativeMobile) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
94
101
|
const securitySettings = (_b = (_a = projectSettingsActions.getProjectSettings()) === null || _a === void 0 ? void 0 : _a.settings) === null || _b === void 0 ? void 0 : _b.security;
|
|
95
102
|
if (!securitySettings)
|
|
96
103
|
return false;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
import { AuthStorageEnum } from '@dynamic-labs/sdk-api-core';
|
|
3
|
+
import { PlatformService } from '@dynamic-labs/utils';
|
|
3
4
|
import '@dynamic-labs/store';
|
|
4
5
|
import '../../constants/colors.js';
|
|
5
6
|
import '../../constants/values.js';
|
|
@@ -12,7 +13,6 @@ import 'react';
|
|
|
12
13
|
import '@dynamic-labs/wallet-book';
|
|
13
14
|
import '../../../shared/utils/classes/storage/localStorage.js';
|
|
14
15
|
import '../../../shared/utils/classes/storage/sessionStorage.js';
|
|
15
|
-
import '@dynamic-labs/utils';
|
|
16
16
|
import '../../../shared/consts/index.js';
|
|
17
17
|
import { getProjectSettings } from '../../../store/actions/projectSettingsActions/projectSettingsActions.js';
|
|
18
18
|
import '../../../../../_virtual/_tslib.js';
|
|
@@ -87,6 +87,13 @@ import '../../../context/ReinitializeContext/ReinitializeContextProvider.js';
|
|
|
87
87
|
|
|
88
88
|
const isCookieEnabled = () => {
|
|
89
89
|
var _a, _b, _c, _d;
|
|
90
|
+
/**
|
|
91
|
+
* There is no cookie on native mobile applications
|
|
92
|
+
* so this feature must be disabled for native mobile
|
|
93
|
+
*/
|
|
94
|
+
if (PlatformService.isNativeMobile) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
90
97
|
const securitySettings = (_b = (_a = getProjectSettings()) === null || _a === void 0 ? void 0 : _a.settings) === null || _b === void 0 ? void 0 : _b.security;
|
|
91
98
|
if (!securitySettings)
|
|
92
99
|
return false;
|
|
@@ -60,6 +60,6 @@ export { useSyncEmbeddedWalletFlow } from './useSyncEmbeddedWalletFlow';
|
|
|
60
60
|
export { useSyncOnboardingFlow } from './useSyncOnboardingFlow';
|
|
61
61
|
export { useExternalAuth } from './useExternalAuth';
|
|
62
62
|
export { useRefreshUser } from './useRefreshUser';
|
|
63
|
-
export {
|
|
63
|
+
export { useWalletOptions } from './useWalletOptions';
|
|
64
64
|
export { useResetCookieLocalStorage } from './useResetCookieLocalStorage';
|
|
65
65
|
export { useSyncMfaFlow } from './useSyncMfaFlow';
|
|
@@ -17,6 +17,7 @@ require('../../constants/colors.cjs');
|
|
|
17
17
|
require('../../constants/values.cjs');
|
|
18
18
|
require('../../../shared/utils/classes/storage/localStorage.cjs');
|
|
19
19
|
require('../../../shared/utils/classes/storage/sessionStorage.cjs');
|
|
20
|
+
var hasPendingRequirements = require('../../../shared/utils/functions/hasPendingRequirements/hasPendingRequirements.cjs');
|
|
20
21
|
require('../../../shared/consts/index.cjs');
|
|
21
22
|
require('../../../config/ApiEndpoint.cjs');
|
|
22
23
|
require('@dynamic-labs/multi-wallet');
|
|
@@ -109,7 +110,9 @@ const useExternalAuth = () => {
|
|
|
109
110
|
externalJwt,
|
|
110
111
|
});
|
|
111
112
|
setCallback('authSuccess');
|
|
112
|
-
|
|
113
|
+
if (userProfile && !hasPendingRequirements.hasPendingRequirements(userProfile)) {
|
|
114
|
+
setShowAuthFlow(false);
|
|
115
|
+
}
|
|
113
116
|
return userProfile;
|
|
114
117
|
}
|
|
115
118
|
catch (e) {
|
|
@@ -13,6 +13,7 @@ import '../../constants/colors.js';
|
|
|
13
13
|
import '../../constants/values.js';
|
|
14
14
|
import '../../../shared/utils/classes/storage/localStorage.js';
|
|
15
15
|
import '../../../shared/utils/classes/storage/sessionStorage.js';
|
|
16
|
+
import { hasPendingRequirements } from '../../../shared/utils/functions/hasPendingRequirements/hasPendingRequirements.js';
|
|
16
17
|
import '../../../shared/consts/index.js';
|
|
17
18
|
import '../../../config/ApiEndpoint.js';
|
|
18
19
|
import '@dynamic-labs/multi-wallet';
|
|
@@ -105,7 +106,9 @@ const useExternalAuth = () => {
|
|
|
105
106
|
externalJwt,
|
|
106
107
|
});
|
|
107
108
|
setCallback('authSuccess');
|
|
108
|
-
|
|
109
|
+
if (userProfile && !hasPendingRequirements(userProfile)) {
|
|
110
|
+
setShowAuthFlow(false);
|
|
111
|
+
}
|
|
109
112
|
return userProfile;
|
|
110
113
|
}
|
|
111
114
|
catch (e) {
|
|
@@ -112,12 +112,13 @@ const useMfa = () => {
|
|
|
112
112
|
mfaDeviceId: deviceId,
|
|
113
113
|
});
|
|
114
114
|
});
|
|
115
|
-
const deleteUserDevice = (deviceId) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
115
|
+
const deleteUserDevice = (deviceId, mfaAuthToken) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
116
116
|
if (!verifiedUser) {
|
|
117
117
|
throw new Error(errors.USER_NOT_LOGGED_IN);
|
|
118
118
|
}
|
|
119
119
|
yield mfa.deleteMfaDevice({
|
|
120
120
|
environmentId,
|
|
121
|
+
mfaAuthToken,
|
|
121
122
|
mfaDeviceId: deviceId,
|
|
122
123
|
});
|
|
123
124
|
});
|
|
@@ -7,7 +7,7 @@ export declare const useMfa: () => {
|
|
|
7
7
|
}>;
|
|
8
8
|
readonly authDevice: (code: string, type?: MFADeviceType, deviceId?: string) => Promise<boolean>;
|
|
9
9
|
readonly authRecoveryCode: (code: string) => Promise<boolean>;
|
|
10
|
-
readonly deleteUserDevice: (deviceId: string) => Promise<void>;
|
|
10
|
+
readonly deleteUserDevice: (deviceId: string, mfaAuthToken: string) => Promise<void>;
|
|
11
11
|
readonly getRecoveryCodes: (generateNewCodes?: boolean) => Promise<string[]>;
|
|
12
12
|
readonly getUserDevices: () => Promise<MFADevice[]>;
|
|
13
13
|
readonly updateUserDevice: (deviceId: string) => Promise<void>;
|
|
@@ -108,12 +108,13 @@ const useMfa = () => {
|
|
|
108
108
|
mfaDeviceId: deviceId,
|
|
109
109
|
});
|
|
110
110
|
});
|
|
111
|
-
const deleteUserDevice = (deviceId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
111
|
+
const deleteUserDevice = (deviceId, mfaAuthToken) => __awaiter(void 0, void 0, void 0, function* () {
|
|
112
112
|
if (!verifiedUser) {
|
|
113
113
|
throw new Error(USER_NOT_LOGGED_IN);
|
|
114
114
|
}
|
|
115
115
|
yield deleteMfaDevice({
|
|
116
116
|
environmentId,
|
|
117
|
+
mfaAuthToken,
|
|
117
118
|
mfaDeviceId: deviceId,
|
|
118
119
|
});
|
|
119
120
|
});
|
|
@@ -228,29 +228,23 @@ const useSocialAuth = ({ sessionTimeout, onSettled, onError, onFarcasterUrl, })
|
|
|
228
228
|
oauthLoginUrl.searchParams.set('code_challenge_method', 'S256');
|
|
229
229
|
}
|
|
230
230
|
const isMobile = utils.isMobile();
|
|
231
|
-
const effectiveRedirectUrl = redirectUrl !== null && redirectUrl !== void 0 ? redirectUrl : defaultRedirectUrl;
|
|
232
231
|
try {
|
|
233
232
|
const authCode = yield utils.Oauth2Service.getOauthCode({
|
|
234
233
|
apiProvider: getProviderByType.getProviderByType((_c = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers) !== null && _c !== void 0 ? _c : [], provider),
|
|
235
234
|
getOAuthResultFromApi: () => oauth.getOAuthResult(environmentId, provider, {
|
|
236
235
|
state,
|
|
237
236
|
}),
|
|
238
|
-
initWebAuth: () => {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
? removeDynamicOauthParamsFromUrl(mobileRedirectUrl)
|
|
245
|
-
: undefined,
|
|
246
|
-
state,
|
|
247
|
-
});
|
|
248
|
-
},
|
|
237
|
+
initWebAuth: ({ redirectUrl } = {}) => oauth.initAuth(environmentId, provider, {
|
|
238
|
+
redirectUrl: redirectUrl
|
|
239
|
+
? removeDynamicOauthParamsFromUrl(redirectUrl)
|
|
240
|
+
: undefined,
|
|
241
|
+
state,
|
|
242
|
+
}),
|
|
249
243
|
isMobile,
|
|
250
244
|
oauthLoginUrl,
|
|
251
245
|
onSettled,
|
|
252
246
|
provider,
|
|
253
|
-
redirectUrl:
|
|
247
|
+
redirectUrl: redirectUrl !== null && redirectUrl !== void 0 ? redirectUrl : defaultRedirectUrl,
|
|
254
248
|
sessionTimeout,
|
|
255
249
|
setIsProcessing,
|
|
256
250
|
state,
|
|
@@ -224,29 +224,23 @@ const useSocialAuth = ({ sessionTimeout, onSettled, onError, onFarcasterUrl, })
|
|
|
224
224
|
oauthLoginUrl.searchParams.set('code_challenge_method', 'S256');
|
|
225
225
|
}
|
|
226
226
|
const isMobile$1 = isMobile();
|
|
227
|
-
const effectiveRedirectUrl = redirectUrl !== null && redirectUrl !== void 0 ? redirectUrl : defaultRedirectUrl;
|
|
228
227
|
try {
|
|
229
228
|
const authCode = yield Oauth2Service.getOauthCode({
|
|
230
229
|
apiProvider: getProviderByType((_c = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers) !== null && _c !== void 0 ? _c : [], provider),
|
|
231
230
|
getOAuthResultFromApi: () => getOAuthResult(environmentId, provider, {
|
|
232
231
|
state,
|
|
233
232
|
}),
|
|
234
|
-
initWebAuth: () => {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
? removeDynamicOauthParamsFromUrl(mobileRedirectUrl)
|
|
241
|
-
: undefined,
|
|
242
|
-
state,
|
|
243
|
-
});
|
|
244
|
-
},
|
|
233
|
+
initWebAuth: ({ redirectUrl } = {}) => initAuth(environmentId, provider, {
|
|
234
|
+
redirectUrl: redirectUrl
|
|
235
|
+
? removeDynamicOauthParamsFromUrl(redirectUrl)
|
|
236
|
+
: undefined,
|
|
237
|
+
state,
|
|
238
|
+
}),
|
|
245
239
|
isMobile: isMobile$1,
|
|
246
240
|
oauthLoginUrl,
|
|
247
241
|
onSettled,
|
|
248
242
|
provider,
|
|
249
|
-
redirectUrl:
|
|
243
|
+
redirectUrl: redirectUrl !== null && redirectUrl !== void 0 ? redirectUrl : defaultRedirectUrl,
|
|
250
244
|
sessionTimeout,
|
|
251
245
|
setIsProcessing,
|
|
252
246
|
state,
|
|
@@ -166,7 +166,8 @@ const useUserAuth = ({ authMethod, }) => {
|
|
|
166
166
|
});
|
|
167
167
|
const handleAuthError = (error, { options = {}, onError, }) => {
|
|
168
168
|
var _a;
|
|
169
|
-
if (error instanceof utils.MfaInvalidOtpError
|
|
169
|
+
if (error instanceof utils.MfaInvalidOtpError ||
|
|
170
|
+
error instanceof utils.MfaRateLimitedError) {
|
|
170
171
|
throw error;
|
|
171
172
|
}
|
|
172
173
|
// these get caught in onboarding form and handled there
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
import { __awaiter } from '../../../../../_virtual/_tslib.js';
|
|
3
|
-
import { DynamicError, MfaInvalidOtpError, EmailAlreadyExistsError, CustomFieldNotUniqueError, UsernameAlreadyExistsError, TooManyEmailVerificationsError, InvalidPhoneNumberError, NoAccessError, AccountExistsError, SandboxMaximumThresholdReachedError, UserHasAccountWithEmailError, sleep } from '@dynamic-labs/utils';
|
|
3
|
+
import { DynamicError, MfaInvalidOtpError, MfaRateLimitedError, EmailAlreadyExistsError, CustomFieldNotUniqueError, UsernameAlreadyExistsError, TooManyEmailVerificationsError, InvalidPhoneNumberError, NoAccessError, AccountExistsError, SandboxMaximumThresholdReachedError, UserHasAccountWithEmailError, sleep } from '@dynamic-labs/utils';
|
|
4
4
|
import { MfaBackupCodeAcknowledgement } from '@dynamic-labs/sdk-api-core';
|
|
5
5
|
import { useAccountExistsContext } from '../../../context/AccountExistsContext/AccountExistsContext.js';
|
|
6
6
|
import 'react';
|
|
@@ -162,7 +162,8 @@ const useUserAuth = ({ authMethod, }) => {
|
|
|
162
162
|
});
|
|
163
163
|
const handleAuthError = (error, { options = {}, onError, }) => {
|
|
164
164
|
var _a;
|
|
165
|
-
if (error instanceof MfaInvalidOtpError
|
|
165
|
+
if (error instanceof MfaInvalidOtpError ||
|
|
166
|
+
error instanceof MfaRateLimitedError) {
|
|
166
167
|
throw error;
|
|
167
168
|
}
|
|
168
169
|
// these get caught in onboarding form and handled there
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useWalletOptions } from './useWalletOptions';
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
5
|
|
|
6
6
|
var _tslib = require('../../../../../_virtual/_tslib.cjs');
|
|
7
|
+
var React = require('react');
|
|
7
8
|
var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
|
|
8
9
|
var walletBook = require('@dynamic-labs/wallet-book');
|
|
9
10
|
var utils = require('@dynamic-labs/utils');
|
|
10
|
-
require('react');
|
|
11
11
|
require('../../../context/DynamicContext/DynamicContext.cjs');
|
|
12
12
|
require('@dynamic-labs/sdk-api-core');
|
|
13
13
|
require('../../../shared/logger.cjs');
|
|
@@ -93,16 +93,42 @@ require('../../../context/ConnectWithOtpContext/constants.cjs');
|
|
|
93
93
|
require('../../../context/ReinitializeContext/ReinitializeContextProvider.cjs');
|
|
94
94
|
var useInternalDynamicContext = require('../../../context/DynamicContext/useDynamicContext/useInternalDynamicContext.cjs');
|
|
95
95
|
|
|
96
|
-
const
|
|
96
|
+
const embeddedWalletsKeys = [
|
|
97
|
+
'magicemailotp',
|
|
98
|
+
'magiclink',
|
|
99
|
+
'magicsocial',
|
|
100
|
+
'turnkey',
|
|
101
|
+
'turnkeyhd',
|
|
102
|
+
'coinbasempc',
|
|
103
|
+
'zerodev',
|
|
104
|
+
];
|
|
105
|
+
const useWalletOptions = () => {
|
|
97
106
|
const { walletConnectorOptions, setShowAuthFlow } = useInternalDynamicContext.useInternalDynamicContext();
|
|
98
107
|
const { walletBook: walletBook$1 } = walletBook.useWalletBookContext();
|
|
99
108
|
const { setView } = ViewContext.useViewContext();
|
|
100
109
|
const { navigateToWalletGroup } = WalletGroupContext.useWalletGroupContext();
|
|
101
110
|
const { handleWalletItemClick } = useWalletItemActions.useWalletItemActions();
|
|
111
|
+
const walletOptions = React.useMemo(() => {
|
|
112
|
+
var _a;
|
|
113
|
+
return (_a = walletConnectorOptions === null || walletConnectorOptions === void 0 ? void 0 : walletConnectorOptions.filter((option) => !embeddedWalletsKeys.includes(option.walletConnector.key)).map((option) => {
|
|
114
|
+
const groupName = option.group
|
|
115
|
+
? walletBook.getWalletGroup(walletBook$1, option.group).name
|
|
116
|
+
: undefined;
|
|
117
|
+
return {
|
|
118
|
+
group: option.group,
|
|
119
|
+
groupName,
|
|
120
|
+
key: option.walletConnector.key,
|
|
121
|
+
name: option.name,
|
|
122
|
+
};
|
|
123
|
+
})) !== null && _a !== void 0 ? _a : [];
|
|
124
|
+
}, [walletBook$1, walletConnectorOptions]);
|
|
102
125
|
const selectWalletOption = (walletKey) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
103
126
|
const group = groupWalletOptions.groupWalletOptions(walletBook$1, walletConnectorOptions);
|
|
104
127
|
const walletOption = group.find((wallet) => wallet.key === walletKey);
|
|
105
|
-
logVerboseTroubleshootingMessage.logVerboseTroubleshootingMessage('[
|
|
128
|
+
logVerboseTroubleshootingMessage.logVerboseTroubleshootingMessage('[useWalletOptions] selectWalletOption', {
|
|
129
|
+
walletKey,
|
|
130
|
+
walletOption: walletOption === null || walletOption === void 0 ? void 0 : walletOption.key,
|
|
131
|
+
});
|
|
106
132
|
if (!walletOption) {
|
|
107
133
|
throw new utils.DynamicError('Invalid wallet option key provided.');
|
|
108
134
|
}
|
|
@@ -123,7 +149,8 @@ const useSelectWalletOption = () => {
|
|
|
123
149
|
});
|
|
124
150
|
return {
|
|
125
151
|
selectWalletOption,
|
|
152
|
+
walletOptions,
|
|
126
153
|
};
|
|
127
154
|
};
|
|
128
155
|
|
|
129
|
-
exports.
|
|
156
|
+
exports.useWalletOptions = useWalletOptions;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
import { __awaiter } from '../../../../../_virtual/_tslib.js';
|
|
3
|
+
import { useMemo } from 'react';
|
|
3
4
|
import { isHardwareWalletConnector } from '@dynamic-labs/wallet-connector-core';
|
|
4
|
-
import { useWalletBookContext } from '@dynamic-labs/wallet-book';
|
|
5
|
+
import { useWalletBookContext, getWalletGroup } from '@dynamic-labs/wallet-book';
|
|
5
6
|
import { DynamicError } from '@dynamic-labs/utils';
|
|
6
|
-
import 'react';
|
|
7
7
|
import '../../../context/DynamicContext/DynamicContext.js';
|
|
8
8
|
import '@dynamic-labs/sdk-api-core';
|
|
9
9
|
import '../../../shared/logger.js';
|
|
@@ -89,16 +89,42 @@ import '../../../context/ConnectWithOtpContext/constants.js';
|
|
|
89
89
|
import '../../../context/ReinitializeContext/ReinitializeContextProvider.js';
|
|
90
90
|
import { useInternalDynamicContext } from '../../../context/DynamicContext/useDynamicContext/useInternalDynamicContext.js';
|
|
91
91
|
|
|
92
|
-
const
|
|
92
|
+
const embeddedWalletsKeys = [
|
|
93
|
+
'magicemailotp',
|
|
94
|
+
'magiclink',
|
|
95
|
+
'magicsocial',
|
|
96
|
+
'turnkey',
|
|
97
|
+
'turnkeyhd',
|
|
98
|
+
'coinbasempc',
|
|
99
|
+
'zerodev',
|
|
100
|
+
];
|
|
101
|
+
const useWalletOptions = () => {
|
|
93
102
|
const { walletConnectorOptions, setShowAuthFlow } = useInternalDynamicContext();
|
|
94
103
|
const { walletBook } = useWalletBookContext();
|
|
95
104
|
const { setView } = useViewContext();
|
|
96
105
|
const { navigateToWalletGroup } = useWalletGroupContext();
|
|
97
106
|
const { handleWalletItemClick } = useWalletItemActions();
|
|
107
|
+
const walletOptions = useMemo(() => {
|
|
108
|
+
var _a;
|
|
109
|
+
return (_a = walletConnectorOptions === null || walletConnectorOptions === void 0 ? void 0 : walletConnectorOptions.filter((option) => !embeddedWalletsKeys.includes(option.walletConnector.key)).map((option) => {
|
|
110
|
+
const groupName = option.group
|
|
111
|
+
? getWalletGroup(walletBook, option.group).name
|
|
112
|
+
: undefined;
|
|
113
|
+
return {
|
|
114
|
+
group: option.group,
|
|
115
|
+
groupName,
|
|
116
|
+
key: option.walletConnector.key,
|
|
117
|
+
name: option.name,
|
|
118
|
+
};
|
|
119
|
+
})) !== null && _a !== void 0 ? _a : [];
|
|
120
|
+
}, [walletBook, walletConnectorOptions]);
|
|
98
121
|
const selectWalletOption = (walletKey) => __awaiter(void 0, void 0, void 0, function* () {
|
|
99
122
|
const group = groupWalletOptions(walletBook, walletConnectorOptions);
|
|
100
123
|
const walletOption = group.find((wallet) => wallet.key === walletKey);
|
|
101
|
-
logVerboseTroubleshootingMessage('[
|
|
124
|
+
logVerboseTroubleshootingMessage('[useWalletOptions] selectWalletOption', {
|
|
125
|
+
walletKey,
|
|
126
|
+
walletOption: walletOption === null || walletOption === void 0 ? void 0 : walletOption.key,
|
|
127
|
+
});
|
|
102
128
|
if (!walletOption) {
|
|
103
129
|
throw new DynamicError('Invalid wallet option key provided.');
|
|
104
130
|
}
|
|
@@ -119,7 +145,8 @@ const useSelectWalletOption = () => {
|
|
|
119
145
|
});
|
|
120
146
|
return {
|
|
121
147
|
selectWalletOption,
|
|
148
|
+
walletOptions,
|
|
122
149
|
};
|
|
123
150
|
};
|
|
124
151
|
|
|
125
|
-
export {
|
|
152
|
+
export { useWalletOptions };
|
|
@@ -107,15 +107,16 @@ const CollectUserDataView = () => {
|
|
|
107
107
|
const [isNetworkPickerOpen, setIsNetworkPickerOpen] = React.useState(false);
|
|
108
108
|
const nameService = useFetchNameService.useFetchNameService();
|
|
109
109
|
const { t } = reactI18next.useTranslation();
|
|
110
|
-
if (!
|
|
110
|
+
if (!userWithMissingInfo) {
|
|
111
111
|
return null;
|
|
112
112
|
}
|
|
113
|
-
const evmNetworks = walletConnector.evmNetworks || [];
|
|
113
|
+
const evmNetworks = (walletConnector === null || walletConnector === void 0 ? void 0 : walletConnector.evmNetworks) || [];
|
|
114
114
|
const _isSupportedNetwork = !network || isSupportedNetwork.isSupportedNetwork({ network, walletConnector });
|
|
115
|
+
const shouldDisplayWrongNetworkState = !_isSupportedNetwork && Boolean(walletConnector);
|
|
115
116
|
const walletAddress = (_a = userWithMissingInfo === null || userWithMissingInfo === void 0 ? void 0 : userWithMissingInfo.verifiedCredentials.find((verifiedCredential) => verifiedCredential.id === userWithMissingInfo.lastVerifiedCredentialId)) === null || _a === void 0 ? void 0 : _a.address;
|
|
116
|
-
return (jsxRuntime.jsxs("div", { className: 'collect-user-data', "data-testid": 'collect-user-data-view', children: [jsxRuntime.jsxs("div", { className: 'collect-user-data__network-container', children: [jsxRuntime.jsxs("div", { className: 'collect-user-data__img-container', children: [(nameService === null || nameService === void 0 ? void 0 : nameService.avatar) ? (jsxRuntime.jsx("img", { src: nameService.avatar, alt: '', className: 'collect-user-data__img collect-user-data__img--rounded' })) : (jsxRuntime.jsx(AuthProviderIcon.AuthProviderIcon, { iconSize: 28 })), jsxRuntime.jsx(Typography.Typography, { variant: 'body_normal', color: 'primary', weight: 'medium', className: 'collect-user-data__wallet-address', children: (nameService === null || nameService === void 0 ? void 0 : nameService.name) || shortenWalletAddress.shortenWalletAddress(walletAddress, 3, 3) })] }), jsxRuntime.jsx(NetworkPicker.NetworkPicker, { currentNetwork: network, evmNetworks: evmNetworks, connector: walletConnector, showNetworkName: true, isNetworkPickerOpen: isNetworkPickerOpen, setIsNetworkPickerOpen: setIsNetworkPickerOpen, buttonClassName: 'collect-user-data__network-picker-button', mainClassName: 'collect-user-data__network-picker' })] }), onboardingImageUrl && (jsxRuntime.jsx("img", { className: 'collect-user-data__main-img', src: onboardingImageUrl, alt: 'onboarding' })),
|
|
117
|
-
'collect-user-data__form--error':
|
|
118
|
-
}), children: [jsxRuntime.jsx("div", { className: 'collect-user-data__success-icon', children: jsxRuntime.jsx(Icon.Icon, { color: 'text-primary', size: 'large', children: jsxRuntime.jsx(checkConnection.ReactComponent, {}) }) }), jsxRuntime.jsx(OnboardingUserDataForm.OnboardingUserDataForm, { disableSubmit:
|
|
117
|
+
return (jsxRuntime.jsxs("div", { className: 'collect-user-data', "data-testid": 'collect-user-data-view', children: [jsxRuntime.jsxs("div", { className: 'collect-user-data__network-container', children: [jsxRuntime.jsxs("div", { className: 'collect-user-data__img-container', children: [(nameService === null || nameService === void 0 ? void 0 : nameService.avatar) ? (jsxRuntime.jsx("img", { src: nameService.avatar, alt: '', className: 'collect-user-data__img collect-user-data__img--rounded' })) : (jsxRuntime.jsx(AuthProviderIcon.AuthProviderIcon, { iconSize: 28 })), jsxRuntime.jsx(Typography.Typography, { variant: 'body_normal', color: 'primary', weight: 'medium', className: 'collect-user-data__wallet-address', children: (nameService === null || nameService === void 0 ? void 0 : nameService.name) || shortenWalletAddress.shortenWalletAddress(walletAddress, 3, 3) })] }), walletConnector && (jsxRuntime.jsx(NetworkPicker.NetworkPicker, { currentNetwork: network, evmNetworks: evmNetworks, connector: walletConnector, showNetworkName: true, isNetworkPickerOpen: isNetworkPickerOpen, setIsNetworkPickerOpen: setIsNetworkPickerOpen, buttonClassName: 'collect-user-data__network-picker-button', mainClassName: 'collect-user-data__network-picker' }))] }), onboardingImageUrl && (jsxRuntime.jsx("img", { className: 'collect-user-data__main-img', src: onboardingImageUrl, alt: 'onboarding' })), shouldDisplayWrongNetworkState && (jsxRuntime.jsx(ErrorContainer.ErrorContainer, { withIcon: false, className: 'collect-user-data__error--not-supported', copykey: 'dyn_collect_user_data.not_supported_network.error_message', children: t('dyn_collect_user_data.not_supported_network.error_message') })), jsxRuntime.jsxs("div", { className: classNames.classNames('collect-user-data__form', {
|
|
118
|
+
'collect-user-data__form--error': shouldDisplayWrongNetworkState,
|
|
119
|
+
}), children: [jsxRuntime.jsx("div", { className: 'collect-user-data__success-icon', children: jsxRuntime.jsx(Icon.Icon, { color: 'text-primary', size: 'large', children: jsxRuntime.jsx(checkConnection.ReactComponent, {}) }) }), jsxRuntime.jsx(OnboardingUserDataForm.OnboardingUserDataForm, { disableSubmit: shouldDisplayWrongNetworkState, userProfile: userWithMissingInfo, children: shouldDisplayWrongNetworkState ? (jsxRuntime.jsxs("div", { className: 'collect-user-data__welcome-container', children: [jsxRuntime.jsx(Typography.Typography, { variant: 'title', color: 'primary', className: 'collect-user-data__welcome-title', copykey: 'dyn_collect_user_data.not_supported_network.title', children: t('dyn_collect_user_data.not_supported_network.title') }), jsxRuntime.jsx(Typography.Typography, { variant: 'body_normal', weight: 'regular', color: 'secondary', copykey: 'dyn_collect_user_data.not_supported_network.description', children: t('dyn_collect_user_data.not_supported_network.description') })] })) : (jsxRuntime.jsxs("div", { className: 'collect-user-data__welcome-container', children: [jsxRuntime.jsx(Typography.Typography, { variant: 'title', color: 'primary', className: 'collect-user-data__welcome-title', copykey: 'dyn_collect_user_data.greeting', children: (projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.general.collectUserDataWelcomeHeader) ||
|
|
119
120
|
t('dyn_collect_user_data.greeting', { appName }) }), jsxRuntime.jsx(Typography.Typography, { variant: 'body_normal', weight: 'regular', color: 'secondary', copykey: 'dyn_collect_user_data.description', children: (projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.general.collectUserDataWelcomeMessage) ||
|
|
120
121
|
t('dyn_collect_user_data.description') })] })) }), jsxRuntime.jsx(TextButton.TextButton, { className: 'collect-user-data__log-out', onClick: handleLogOut, copykey: 'dyn_collect_user_data.log_out_button', children: t('dyn_collect_user_data.log_out_button') })] })] }));
|
|
121
122
|
};
|
|
@@ -103,15 +103,16 @@ const CollectUserDataView = () => {
|
|
|
103
103
|
const [isNetworkPickerOpen, setIsNetworkPickerOpen] = useState(false);
|
|
104
104
|
const nameService = useFetchNameService();
|
|
105
105
|
const { t } = useTranslation();
|
|
106
|
-
if (!
|
|
106
|
+
if (!userWithMissingInfo) {
|
|
107
107
|
return null;
|
|
108
108
|
}
|
|
109
|
-
const evmNetworks = walletConnector.evmNetworks || [];
|
|
109
|
+
const evmNetworks = (walletConnector === null || walletConnector === void 0 ? void 0 : walletConnector.evmNetworks) || [];
|
|
110
110
|
const _isSupportedNetwork = !network || isSupportedNetwork({ network, walletConnector });
|
|
111
|
+
const shouldDisplayWrongNetworkState = !_isSupportedNetwork && Boolean(walletConnector);
|
|
111
112
|
const walletAddress = (_a = userWithMissingInfo === null || userWithMissingInfo === void 0 ? void 0 : userWithMissingInfo.verifiedCredentials.find((verifiedCredential) => verifiedCredential.id === userWithMissingInfo.lastVerifiedCredentialId)) === null || _a === void 0 ? void 0 : _a.address;
|
|
112
|
-
return (jsxs("div", { className: 'collect-user-data', "data-testid": 'collect-user-data-view', children: [jsxs("div", { className: 'collect-user-data__network-container', children: [jsxs("div", { className: 'collect-user-data__img-container', children: [(nameService === null || nameService === void 0 ? void 0 : nameService.avatar) ? (jsx("img", { src: nameService.avatar, alt: '', className: 'collect-user-data__img collect-user-data__img--rounded' })) : (jsx(AuthProviderIcon, { iconSize: 28 })), jsx(Typography, { variant: 'body_normal', color: 'primary', weight: 'medium', className: 'collect-user-data__wallet-address', children: (nameService === null || nameService === void 0 ? void 0 : nameService.name) || shortenWalletAddress(walletAddress, 3, 3) })] }), jsx(NetworkPicker, { currentNetwork: network, evmNetworks: evmNetworks, connector: walletConnector, showNetworkName: true, isNetworkPickerOpen: isNetworkPickerOpen, setIsNetworkPickerOpen: setIsNetworkPickerOpen, buttonClassName: 'collect-user-data__network-picker-button', mainClassName: 'collect-user-data__network-picker' })] }), onboardingImageUrl && (jsx("img", { className: 'collect-user-data__main-img', src: onboardingImageUrl, alt: 'onboarding' })),
|
|
113
|
-
'collect-user-data__form--error':
|
|
114
|
-
}), children: [jsx("div", { className: 'collect-user-data__success-icon', children: jsx(Icon, { color: 'text-primary', size: 'large', children: jsx(SvgCheckConnection, {}) }) }), jsx(OnboardingUserDataForm, { disableSubmit:
|
|
113
|
+
return (jsxs("div", { className: 'collect-user-data', "data-testid": 'collect-user-data-view', children: [jsxs("div", { className: 'collect-user-data__network-container', children: [jsxs("div", { className: 'collect-user-data__img-container', children: [(nameService === null || nameService === void 0 ? void 0 : nameService.avatar) ? (jsx("img", { src: nameService.avatar, alt: '', className: 'collect-user-data__img collect-user-data__img--rounded' })) : (jsx(AuthProviderIcon, { iconSize: 28 })), jsx(Typography, { variant: 'body_normal', color: 'primary', weight: 'medium', className: 'collect-user-data__wallet-address', children: (nameService === null || nameService === void 0 ? void 0 : nameService.name) || shortenWalletAddress(walletAddress, 3, 3) })] }), walletConnector && (jsx(NetworkPicker, { currentNetwork: network, evmNetworks: evmNetworks, connector: walletConnector, showNetworkName: true, isNetworkPickerOpen: isNetworkPickerOpen, setIsNetworkPickerOpen: setIsNetworkPickerOpen, buttonClassName: 'collect-user-data__network-picker-button', mainClassName: 'collect-user-data__network-picker' }))] }), onboardingImageUrl && (jsx("img", { className: 'collect-user-data__main-img', src: onboardingImageUrl, alt: 'onboarding' })), shouldDisplayWrongNetworkState && (jsx(ErrorContainer, { withIcon: false, className: 'collect-user-data__error--not-supported', copykey: 'dyn_collect_user_data.not_supported_network.error_message', children: t('dyn_collect_user_data.not_supported_network.error_message') })), jsxs("div", { className: classNames('collect-user-data__form', {
|
|
114
|
+
'collect-user-data__form--error': shouldDisplayWrongNetworkState,
|
|
115
|
+
}), children: [jsx("div", { className: 'collect-user-data__success-icon', children: jsx(Icon, { color: 'text-primary', size: 'large', children: jsx(SvgCheckConnection, {}) }) }), jsx(OnboardingUserDataForm, { disableSubmit: shouldDisplayWrongNetworkState, userProfile: userWithMissingInfo, children: shouldDisplayWrongNetworkState ? (jsxs("div", { className: 'collect-user-data__welcome-container', children: [jsx(Typography, { variant: 'title', color: 'primary', className: 'collect-user-data__welcome-title', copykey: 'dyn_collect_user_data.not_supported_network.title', children: t('dyn_collect_user_data.not_supported_network.title') }), jsx(Typography, { variant: 'body_normal', weight: 'regular', color: 'secondary', copykey: 'dyn_collect_user_data.not_supported_network.description', children: t('dyn_collect_user_data.not_supported_network.description') })] })) : (jsxs("div", { className: 'collect-user-data__welcome-container', children: [jsx(Typography, { variant: 'title', color: 'primary', className: 'collect-user-data__welcome-title', copykey: 'dyn_collect_user_data.greeting', children: (projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.general.collectUserDataWelcomeHeader) ||
|
|
115
116
|
t('dyn_collect_user_data.greeting', { appName }) }), jsx(Typography, { variant: 'body_normal', weight: 'regular', color: 'secondary', copykey: 'dyn_collect_user_data.description', children: (projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.general.collectUserDataWelcomeMessage) ||
|
|
116
117
|
t('dyn_collect_user_data.description') })] })) }), jsx(TextButton, { className: 'collect-user-data__log-out', onClick: handleLogOut, copykey: 'dyn_collect_user_data.log_out_button', children: t('dyn_collect_user_data.log_out_button') })] })] }));
|
|
117
118
|
};
|
|
@@ -100,11 +100,18 @@ const MfaVerificationView = ({ type, isInitialSetup = false, showBackButton = fa
|
|
|
100
100
|
const { authDevice } = useMfa.useMfa();
|
|
101
101
|
const [code, setCode] = React.useState('');
|
|
102
102
|
const [error, setError] = React.useState();
|
|
103
|
+
const [isRateLimited, setIsRateLimited] = React.useState(false);
|
|
103
104
|
const { data: isValid, isLoading } = usePromise.usePromise(() => authDevice(code, type, deviceId), {
|
|
104
105
|
deps: [code],
|
|
105
106
|
enabled: (code === null || code === void 0 ? void 0 : code.length) === 6,
|
|
106
|
-
onReject: () => {
|
|
107
|
-
|
|
107
|
+
onReject: (err) => {
|
|
108
|
+
if (err instanceof utils.MfaRateLimitedError) {
|
|
109
|
+
setIsRateLimited(true);
|
|
110
|
+
setError(new utils.DynamicError(t('dyn_mfa.otp_verification_view.rate_limit_error')));
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
setError(new utils.DynamicError(t('dyn_mfa.otp_verification_view.error')));
|
|
114
|
+
}
|
|
108
115
|
},
|
|
109
116
|
onResolve: () => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
110
117
|
const user = userActions.getUser();
|
|
@@ -128,7 +135,7 @@ const MfaVerificationView = ({ type, isInitialSetup = false, showBackButton = fa
|
|
|
128
135
|
}
|
|
129
136
|
setView('mfa-secure-device', { isInitialSetup, type });
|
|
130
137
|
};
|
|
131
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(OTPVerificationView.OTPVerificationView, { MainIcon: passwordHero.ReactComponent, error: error, isLoading: isLoading, onPinComplete: onSubmit, isValid: Boolean(isValid), onPinChange: onCodeChange, description: t('dyn_mfa.otp_verification_view.body'), onClickBack: showBackButton ? onClickBack : undefined }), !isInitialSetup && (jsxRuntime.jsx("div", { className: 'mfa-verification-view__choose-another-method', children: jsxRuntime.jsx(TextButton.TextButton, { className: 'mfa-verification-view__choose-another-method-button', onClick: () => setView('mfa-choose-device', { isInitialSetup }), copykey: 'dyn_mfa.otp_verification_view.choose_another_method', children: t('dyn_mfa.otp_verification_view.choose_another_method') }) }))] }));
|
|
138
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(OTPVerificationView.OTPVerificationView, { MainIcon: passwordHero.ReactComponent, error: error, isLoading: isLoading, onPinComplete: onSubmit, isValid: Boolean(isValid), onPinChange: onCodeChange, description: t('dyn_mfa.otp_verification_view.body'), onClickBack: showBackButton ? onClickBack : undefined, disabled: isRateLimited }), !isInitialSetup && (jsxRuntime.jsx("div", { className: 'mfa-verification-view__choose-another-method', children: jsxRuntime.jsx(TextButton.TextButton, { className: 'mfa-verification-view__choose-another-method-button', onClick: () => setView('mfa-choose-device', { isInitialSetup }), copykey: 'dyn_mfa.otp_verification_view.choose_another_method', children: t('dyn_mfa.otp_verification_view.choose_another_method') }) }))] }));
|
|
132
139
|
};
|
|
133
140
|
|
|
134
141
|
exports.MfaVerificationView = MfaVerificationView;
|
|
@@ -3,7 +3,7 @@ import { __awaiter } from '../../../../_virtual/_tslib.js';
|
|
|
3
3
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
4
4
|
import { useState } from 'react';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
|
-
import { DynamicError } from '@dynamic-labs/utils';
|
|
6
|
+
import { MfaRateLimitedError, DynamicError } from '@dynamic-labs/utils';
|
|
7
7
|
import { MfaBackupCodeAcknowledgement } from '@dynamic-labs/sdk-api-core';
|
|
8
8
|
import '@dynamic-labs/store';
|
|
9
9
|
import '../../utils/constants/colors.js';
|
|
@@ -96,11 +96,18 @@ const MfaVerificationView = ({ type, isInitialSetup = false, showBackButton = fa
|
|
|
96
96
|
const { authDevice } = useMfa();
|
|
97
97
|
const [code, setCode] = useState('');
|
|
98
98
|
const [error, setError] = useState();
|
|
99
|
+
const [isRateLimited, setIsRateLimited] = useState(false);
|
|
99
100
|
const { data: isValid, isLoading } = usePromise(() => authDevice(code, type, deviceId), {
|
|
100
101
|
deps: [code],
|
|
101
102
|
enabled: (code === null || code === void 0 ? void 0 : code.length) === 6,
|
|
102
|
-
onReject: () => {
|
|
103
|
-
|
|
103
|
+
onReject: (err) => {
|
|
104
|
+
if (err instanceof MfaRateLimitedError) {
|
|
105
|
+
setIsRateLimited(true);
|
|
106
|
+
setError(new DynamicError(t('dyn_mfa.otp_verification_view.rate_limit_error')));
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
setError(new DynamicError(t('dyn_mfa.otp_verification_view.error')));
|
|
110
|
+
}
|
|
104
111
|
},
|
|
105
112
|
onResolve: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
106
113
|
const user = getUser();
|
|
@@ -124,7 +131,7 @@ const MfaVerificationView = ({ type, isInitialSetup = false, showBackButton = fa
|
|
|
124
131
|
}
|
|
125
132
|
setView('mfa-secure-device', { isInitialSetup, type });
|
|
126
133
|
};
|
|
127
|
-
return (jsxs(Fragment, { children: [jsx(OTPVerificationView, { MainIcon: SvgPasswordHero, error: error, isLoading: isLoading, onPinComplete: onSubmit, isValid: Boolean(isValid), onPinChange: onCodeChange, description: t('dyn_mfa.otp_verification_view.body'), onClickBack: showBackButton ? onClickBack : undefined }), !isInitialSetup && (jsx("div", { className: 'mfa-verification-view__choose-another-method', children: jsx(TextButton, { className: 'mfa-verification-view__choose-another-method-button', onClick: () => setView('mfa-choose-device', { isInitialSetup }), copykey: 'dyn_mfa.otp_verification_view.choose_another_method', children: t('dyn_mfa.otp_verification_view.choose_another_method') }) }))] }));
|
|
134
|
+
return (jsxs(Fragment, { children: [jsx(OTPVerificationView, { MainIcon: SvgPasswordHero, error: error, isLoading: isLoading, onPinComplete: onSubmit, isValid: Boolean(isValid), onPinChange: onCodeChange, description: t('dyn_mfa.otp_verification_view.body'), onClickBack: showBackButton ? onClickBack : undefined, disabled: isRateLimited }), !isInitialSetup && (jsx("div", { className: 'mfa-verification-view__choose-another-method', children: jsx(TextButton, { className: 'mfa-verification-view__choose-another-method-button', onClick: () => setView('mfa-choose-device', { isInitialSetup }), copykey: 'dyn_mfa.otp_verification_view.choose_another_method', children: t('dyn_mfa.otp_verification_view.choose_another_method') }) }))] }));
|
|
128
135
|
};
|
|
129
136
|
|
|
130
137
|
export { MfaVerificationView };
|
|
@@ -27,6 +27,7 @@ require('../../../../shared/utils/classes/storage/localStorage.cjs');
|
|
|
27
27
|
require('../../../../shared/utils/classes/storage/sessionStorage.cjs');
|
|
28
28
|
var useEffectOnce = require('../../../../shared/utils/hooks/useEffectOnce/useEffectOnce.cjs');
|
|
29
29
|
require('../../../../shared/consts/index.cjs');
|
|
30
|
+
var useInternalDynamicContext = require('../../../../context/DynamicContext/useDynamicContext/useInternalDynamicContext.cjs');
|
|
30
31
|
require('../../../../context/CaptchaContext/CaptchaContext.cjs');
|
|
31
32
|
require('../../../../context/ErrorContext/ErrorContext.cjs');
|
|
32
33
|
require('@dynamic-labs/multi-wallet');
|
|
@@ -101,32 +102,45 @@ require('../../../../components/InlineWidget/InlineWidget.cjs');
|
|
|
101
102
|
require('qrcode');
|
|
102
103
|
|
|
103
104
|
const ManageMfaWidgetView = () => {
|
|
105
|
+
var _a;
|
|
104
106
|
const [userDevices, setUserDevices] = React.useState([]);
|
|
107
|
+
const [mfaMethod, setMfaMethod] = React.useState();
|
|
105
108
|
const [loading, setLoading] = React.useState(false);
|
|
106
109
|
const { setDynamicWidgetView } = DynamicWidgetContext.useWidgetContext();
|
|
107
|
-
const { setShowMfaQRCode } = useDynamicModals.useDynamicModals();
|
|
110
|
+
const { setShowMfaQRCode, setShowOTPVerification } = useDynamicModals.useDynamicModals();
|
|
108
111
|
const { getUserDevices, deleteUserDevice } = useMfa.useMfa();
|
|
109
112
|
const { t } = reactI18next.useTranslation();
|
|
113
|
+
const { projectSettings } = useInternalDynamicContext.useInternalDynamicContext();
|
|
114
|
+
const isMfaRequired = Boolean((_a = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.security.mfa) === null || _a === void 0 ? void 0 : _a.required);
|
|
110
115
|
const getDevices = React.useCallback(() => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
111
116
|
setLoading(true);
|
|
112
117
|
const devices = yield getUserDevices();
|
|
113
118
|
// set the user devices with the default device first
|
|
114
|
-
setUserDevices(sort.
|
|
119
|
+
setUserDevices(sort.sortDevices(devices));
|
|
115
120
|
setLoading(false);
|
|
116
121
|
}), [getUserDevices]);
|
|
117
122
|
// re-fetch devices when a new device is added
|
|
118
|
-
useDynamicEvents.useDynamicEvents('mfaCompletionSuccess', () =>
|
|
123
|
+
useDynamicEvents.useDynamicEvents('mfaCompletionSuccess', (_b) => _tslib.__awaiter(void 0, [_b], void 0, function* ({ mfaToken }) {
|
|
124
|
+
if (mfaToken) {
|
|
125
|
+
// we now require an MFA token to delete a device which is an async operation
|
|
126
|
+
if ((mfaMethod === null || mfaMethod === void 0 ? void 0 : mfaMethod.action) === 'remove') {
|
|
127
|
+
yield deleteUserDevice(mfaMethod.params.deviceId, mfaToken);
|
|
128
|
+
setMfaMethod(undefined);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
getDevices();
|
|
132
|
+
}));
|
|
119
133
|
// delete device and then re-fetch devices
|
|
120
134
|
const deleteDevice = (id) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
121
|
-
|
|
122
|
-
|
|
135
|
+
setMfaMethod({ action: 'remove', params: { deviceId: id } });
|
|
136
|
+
setShowOTPVerification(true);
|
|
123
137
|
});
|
|
124
138
|
// load devices on initial page load
|
|
125
139
|
useEffectOnce.useEffectOnce(() => {
|
|
126
140
|
getDevices();
|
|
127
141
|
});
|
|
128
142
|
const backButton = (jsxRuntime.jsx(IconButton.IconButton, { type: 'button', onClick: () => setDynamicWidgetView('settings'), "data-testid": 'back-button', children: jsxRuntime.jsx(chevronLeft.ReactComponent, {}) }));
|
|
129
|
-
return (jsxRuntime.jsxs("div", { className: 'manage-mfa-widget-view', children: [jsxRuntime.jsx(ModalHeader.ModalHeader, { leading: backButton, children: jsxRuntime.jsx("div", { className: 'send-balance-page-layout__header-content', children: jsxRuntime.jsx(Typography.Typography, { variant: 'title', color: 'primary', copykey: 'dyn_manage_mfa.title', children: t('dyn_manage_mfa.title') }) }) }), jsxRuntime.jsxs("div", { className: 'manage-mfa-widget-view__scroll-container', children: [loading && jsxRuntime.jsx(MfaDeviceTileSkeleton.MfaDeviceTileSkeleton, {}), !loading && userDevices.length === 0 && (jsxRuntime.jsx(Typography.Typography, { className: 'manage-mfa-widget-view__no-devices', variant: 'body_normal', color: 'secondary', copykey: 'dyn_manage_mfa.no_devices', children: t('dyn_manage_mfa.no_devices') })), userDevices.map((device, index) => (jsxRuntime.jsx(UserDeviceTile.UserDeviceTile, { userDevice: device, index: index, deleteDevice: deleteDevice }, device.id)))] }), userDevices.length > 0 || (jsxRuntime.jsx("div", { className: 'manage-mfa-widget-view__add-mfa-button-container', children: jsxRuntime.jsx(TypographyButton.TypographyButton, { buttonClassName: 'manage-mfa-widget-view__add-mfa-button-container__button', onClick: () => setShowMfaQRCode(true), copykey: 'dyn_manage_mfa.add_mfa_button', startSlot: jsxRuntime.jsx(add.ReactComponent, {}), children: t('dyn_manage_mfa.add_mfa_button') }) }))] }));
|
|
143
|
+
return (jsxRuntime.jsxs("div", { className: 'manage-mfa-widget-view', children: [jsxRuntime.jsx(ModalHeader.ModalHeader, { leading: backButton, children: jsxRuntime.jsx("div", { className: 'send-balance-page-layout__header-content', children: jsxRuntime.jsx(Typography.Typography, { variant: 'title', color: 'primary', copykey: 'dyn_manage_mfa.title', children: t('dyn_manage_mfa.title') }) }) }), jsxRuntime.jsxs("div", { className: 'manage-mfa-widget-view__scroll-container', children: [loading && jsxRuntime.jsx(MfaDeviceTileSkeleton.MfaDeviceTileSkeleton, {}), !loading && userDevices.length === 0 && (jsxRuntime.jsx(Typography.Typography, { className: 'manage-mfa-widget-view__no-devices', variant: 'body_normal', color: 'secondary', copykey: 'dyn_manage_mfa.no_devices', children: t('dyn_manage_mfa.no_devices') })), userDevices.map((device, index) => (jsxRuntime.jsx(UserDeviceTile.UserDeviceTile, { isMfaRequired: isMfaRequired, userDevice: device, index: index, deleteDevice: deleteDevice }, device.id)))] }), userDevices.length > 0 || (jsxRuntime.jsx("div", { className: 'manage-mfa-widget-view__add-mfa-button-container', children: jsxRuntime.jsx(TypographyButton.TypographyButton, { buttonClassName: 'manage-mfa-widget-view__add-mfa-button-container__button', onClick: () => setShowMfaQRCode(true), copykey: 'dyn_manage_mfa.add_mfa_button', startSlot: jsxRuntime.jsx(add.ReactComponent, {}), children: t('dyn_manage_mfa.add_mfa_button') }) }))] }));
|
|
130
144
|
};
|
|
131
145
|
|
|
132
146
|
exports.ManageMfaWidgetView = ManageMfaWidgetView;
|