@dynamic-labs/sdk-react-core 4.75.0 → 4.77.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 (28) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/package.cjs +3 -3
  3. package/package.js +3 -3
  4. package/package.json +14 -14
  5. package/src/lib/context/ErrorContext/hooks/useErrorText/useErrorText.cjs +1 -0
  6. package/src/lib/context/ErrorContext/hooks/useErrorText/useErrorText.js +1 -0
  7. package/src/lib/data/api/email/email.cjs +3 -0
  8. package/src/lib/data/api/email/email.js +4 -1
  9. package/src/lib/data/api/oauth/oauth.cjs +6 -0
  10. package/src/lib/data/api/oauth/oauth.js +7 -1
  11. package/src/lib/data/api/sms/sms.cjs +6 -0
  12. package/src/lib/data/api/sms/sms.js +7 -1
  13. package/src/lib/data/api/wallets/wallets.cjs +6 -0
  14. package/src/lib/data/api/wallets/wallets.js +7 -1
  15. package/src/lib/utils/constants/values.cjs +2 -0
  16. package/src/lib/utils/constants/values.js +2 -0
  17. package/src/lib/utils/hooks/authenticationHooks/useConnectAndSign/useConnectAndSign.cjs +22 -0
  18. package/src/lib/utils/hooks/authenticationHooks/useConnectAndSign/useConnectAndSign.js +23 -1
  19. package/src/lib/utils/hooks/useSyncDynamicWaas/useSyncDynamicWaas.cjs +15 -9
  20. package/src/lib/utils/hooks/useSyncDynamicWaas/useSyncDynamicWaas.js +15 -9
  21. package/src/lib/utils/hooks/useTransition/useTransition.cjs +14 -3
  22. package/src/lib/utils/hooks/useTransition/useTransition.js +14 -3
  23. package/src/lib/utils/hooks/useUserAuth/useUserAuth.cjs +4 -0
  24. package/src/lib/utils/hooks/useUserAuth/useUserAuth.js +5 -1
  25. package/src/lib/utils/hooks/useVerifyWallet/useVerifyWallet.cjs +6 -0
  26. package/src/lib/utils/hooks/useVerifyWallet/useVerifyWallet.js +7 -1
  27. package/src/lib/utils/hooks/useWalletItemActions/useHandleWalletItem/useHandleWalletItem.cjs +9 -2
  28. package/src/lib/utils/hooks/useWalletItemActions/useHandleWalletItem/useHandleWalletItem.js +9 -2
package/CHANGELOG.md CHANGED
@@ -1,4 +1,34 @@
1
1
 
2
+ ## [4.77.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.76.0...v4.77.0) (2026-04-10)
3
+
4
+
5
+ ### Features
6
+
7
+ * **midnight:** add types and chain constants ([#10851](https://github.com/dynamic-labs/dynamic-auth/issues/10851)) ([91620d2](https://github.com/dynamic-labs/dynamic-auth/commit/91620d21596c525d8d51ddb0c0ba7df456e3eb64))
8
+
9
+
10
+ ### Bug Fixes
11
+
12
+ * issue when linking new wallet via qr code when there's no active session ([#10878](https://github.com/dynamic-labs/dynamic-auth/issues/10878)) ([53cbae0](https://github.com/dynamic-labs/dynamic-auth/commit/53cbae0806665371e9214663e72e2f1fb7e1ac3f))
13
+ * **lint-staged:** exclude Playwright specs from jest pre-commit hook [DYNT-496] ([#10880](https://github.com/dynamic-labs/dynamic-auth/issues/10880)) ([d3c8a9a](https://github.com/dynamic-labs/dynamic-auth/commit/d3c8a9a59c855bb834dcedf2e18a2bd0eabcb420))
14
+ * **react-core:** exclude password setup cancellations from wallet creation failure metrics ([#10868](https://github.com/dynamic-labs/dynamic-auth/issues/10868)) ([685de16](https://github.com/dynamic-labs/dynamic-auth/commit/685de16f004f282e1b24114c3a18d8c02b7e48aa))
15
+ * **react-native:** adds eip7702 authorization ([#10904](https://github.com/dynamic-labs/dynamic-auth/issues/10904)) ([fa3e41f](https://github.com/dynamic-labs/dynamic-auth/commit/fa3e41f18aeca309c199003781e569bb425dda5d))
16
+ * **react-native:** remove crypto dependency ([#10871](https://github.com/dynamic-labs/dynamic-auth/issues/10871)) ([de4faa5](https://github.com/dynamic-labs/dynamic-auth/commit/de4faa5bd8bbb8fc321ed65f8b6ccfbaff1d00d3))
17
+ * **react-native:** unify session storage ([#10870](https://github.com/dynamic-labs/dynamic-auth/issues/10870)) ([0536ea0](https://github.com/dynamic-labs/dynamic-auth/commit/0536ea0a78f69b9952b21eec38b4868276215b46))
18
+
19
+ ## [4.76.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.75.0...v4.76.0) (2026-04-06)
20
+
21
+
22
+ ### Features
23
+
24
+ * handle credential_not_enabled_for_sign_in error across all sign-in methods ([#10819](https://github.com/dynamic-labs/dynamic-auth/issues/10819)) ([f694b85](https://github.com/dynamic-labs/dynamic-auth/commit/f694b857eab9d377626078d290473ca369652331))
25
+
26
+
27
+ ### Bug Fixes
28
+
29
+ * modal transition race condition (opacity stuck at 0) ([#10857](https://github.com/dynamic-labs/dynamic-auth/issues/10857)) ([6e9ec68](https://github.com/dynamic-labs/dynamic-auth/commit/6e9ec68040776cc5be333ad20ad0096374947b74))
30
+ * **react-native:** ensure session is correctly mapped ([#10860](https://github.com/dynamic-labs/dynamic-auth/issues/10860)) ([117b013](https://github.com/dynamic-labs/dynamic-auth/commit/117b013faf9a0d4bc6b8429a36d8e88dba546889))
31
+
2
32
  ## [4.75.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.74.1...v4.75.0) (2026-04-03)
3
33
 
4
34
 
package/package.cjs CHANGED
@@ -3,10 +3,10 @@
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
- var version = "4.75.0";
6
+ var version = "4.77.0";
7
7
  var dependencies = {
8
- "@dynamic-labs/sdk-api-core": "0.0.923",
9
- "@dynamic-labs-sdk/client": "0.23.2",
8
+ "@dynamic-labs/sdk-api-core": "0.0.927",
9
+ "@dynamic-labs-sdk/client": "0.24.0",
10
10
  "@dynamic-labs-wallet/browser-wallet-client": "0.0.314",
11
11
  "@hcaptcha/react-hcaptcha": "1.4.4",
12
12
  "@thumbmarkjs/thumbmarkjs": "0.16.0",
package/package.js CHANGED
@@ -1,8 +1,8 @@
1
1
  'use client'
2
- var version = "4.75.0";
2
+ var version = "4.77.0";
3
3
  var dependencies = {
4
- "@dynamic-labs/sdk-api-core": "0.0.923",
5
- "@dynamic-labs-sdk/client": "0.23.2",
4
+ "@dynamic-labs/sdk-api-core": "0.0.927",
5
+ "@dynamic-labs-sdk/client": "0.24.0",
6
6
  "@dynamic-labs-wallet/browser-wallet-client": "0.0.314",
7
7
  "@hcaptcha/react-hcaptcha": "1.4.4",
8
8
  "@thumbmarkjs/thumbmarkjs": "0.16.0",
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@dynamic-labs/sdk-react-core",
3
- "version": "4.75.0",
3
+ "version": "4.77.0",
4
4
  "dependencies": {
5
- "@dynamic-labs/sdk-api-core": "0.0.923",
6
- "@dynamic-labs-sdk/client": "0.23.2",
5
+ "@dynamic-labs/sdk-api-core": "0.0.927",
6
+ "@dynamic-labs-sdk/client": "0.24.0",
7
7
  "@dynamic-labs-wallet/browser-wallet-client": "0.0.314",
8
8
  "@hcaptcha/react-hcaptcha": "1.4.4",
9
9
  "@thumbmarkjs/thumbmarkjs": "0.16.0",
@@ -16,17 +16,17 @@
16
16
  "yup": "0.32.11",
17
17
  "react-international-phone": "4.5.0",
18
18
  "bs58": "5.0.0",
19
- "@dynamic-labs/assert-package-version": "4.75.0",
20
- "@dynamic-labs/iconic": "4.75.0",
21
- "@dynamic-labs/locale": "4.75.0",
22
- "@dynamic-labs/logger": "4.75.0",
23
- "@dynamic-labs/multi-wallet": "4.75.0",
24
- "@dynamic-labs/rpc-providers": "4.75.0",
25
- "@dynamic-labs/store": "4.75.0",
26
- "@dynamic-labs/types": "4.75.0",
27
- "@dynamic-labs/utils": "4.75.0",
28
- "@dynamic-labs/wallet-book": "4.75.0",
29
- "@dynamic-labs/wallet-connector-core": "4.75.0",
19
+ "@dynamic-labs/assert-package-version": "4.77.0",
20
+ "@dynamic-labs/iconic": "4.77.0",
21
+ "@dynamic-labs/locale": "4.77.0",
22
+ "@dynamic-labs/logger": "4.77.0",
23
+ "@dynamic-labs/multi-wallet": "4.77.0",
24
+ "@dynamic-labs/rpc-providers": "4.77.0",
25
+ "@dynamic-labs/store": "4.77.0",
26
+ "@dynamic-labs/types": "4.77.0",
27
+ "@dynamic-labs/utils": "4.77.0",
28
+ "@dynamic-labs/wallet-book": "4.77.0",
29
+ "@dynamic-labs/wallet-connector-core": "4.77.0",
30
30
  "eventemitter3": "5.0.1"
31
31
  },
32
32
  "devDependencies": {
@@ -20,6 +20,7 @@ const mapErrorCodeToTranslation = {
20
20
  [utils.ErrorCode.CONNECTION_REJECTED]: 'dyn_error.connection_rejected',
21
21
  [utils.ErrorCode.MISSING_PUBLIC_ADDRESS]: 'dyn_error.missing_public_address',
22
22
  [utils.ErrorCode.CONNECTION_PROPOSAL_EXPIRED]: 'dyn_error.connection_proposal_expired',
23
+ [utils.ErrorCode.CREDENTIAL_NOT_ENABLED_FOR_SIGN_IN]: 'dyn_error.credential_not_enabled_for_sign_in',
23
24
  [utils.ErrorCode.SEI_NOT_ENABLED_IN_KEPLR_WALLET]: 'dyn_error.sei_not_enabled_in_keplr_wallet',
24
25
  [utils.RATE_LIMIT_ERROR_CODE]: 'dyn_error.rate_limit_error',
25
26
  };
@@ -16,6 +16,7 @@ const mapErrorCodeToTranslation = {
16
16
  [ErrorCode.CONNECTION_REJECTED]: 'dyn_error.connection_rejected',
17
17
  [ErrorCode.MISSING_PUBLIC_ADDRESS]: 'dyn_error.missing_public_address',
18
18
  [ErrorCode.CONNECTION_PROPOSAL_EXPIRED]: 'dyn_error.connection_proposal_expired',
19
+ [ErrorCode.CREDENTIAL_NOT_ENABLED_FOR_SIGN_IN]: 'dyn_error.credential_not_enabled_for_sign_in',
19
20
  [ErrorCode.SEI_NOT_ENABLED_IN_KEPLR_WALLET]: 'dyn_error.sei_not_enabled_in_keplr_wallet',
20
21
  [RATE_LIMIT_ERROR_CODE]: 'dyn_error.rate_limit_error',
21
22
  };
@@ -45,6 +45,9 @@ const signInWithEmailVerification = (_b) => _tslib.__awaiter(void 0, [_b], void
45
45
  if (data.error.code === 'missing_from_list') {
46
46
  throw new utils$1.NoAccessError({ email: data.payload.email });
47
47
  }
48
+ if (data.code === 'credential_not_enabled_for_sign_in') {
49
+ throw new utils$1.DynamicError(data.error, utils$1.ErrorCode.CREDENTIAL_NOT_ENABLED_FOR_SIGN_IN);
50
+ }
48
51
  if (data.code === 'email_associated_with_different_provider') {
49
52
  throw new utils$1.AccountExistsError(data.error, data.payload);
50
53
  }
@@ -1,7 +1,7 @@
1
1
  'use client'
2
2
  import { __awaiter } from '../../../../../_virtual/_tslib.js';
3
3
  import { getElevatedAccessToken } from '@dynamic-labs-sdk/client';
4
- import { NoAccessError, AccountExistsError, SandboxMaximumThresholdReachedError, EmailVerificationError, UserHasAccountWithEmailError } from '@dynamic-labs/utils';
4
+ import { NoAccessError, DynamicError, ErrorCode, AccountExistsError, SandboxMaximumThresholdReachedError, EmailVerificationError, UserHasAccountWithEmailError } from '@dynamic-labs/utils';
5
5
  import { TokenScope, UnprocessableEntityErrorCode } from '@dynamic-labs/sdk-api-core';
6
6
  import { sdkApi } from '../api.js';
7
7
  import { ELEVATED_ACCESS_TOKEN_HEADER } from '../constants.js';
@@ -41,6 +41,9 @@ const signInWithEmailVerification = (_b) => __awaiter(void 0, [_b], void 0, func
41
41
  if (data.error.code === 'missing_from_list') {
42
42
  throw new NoAccessError({ email: data.payload.email });
43
43
  }
44
+ if (data.code === 'credential_not_enabled_for_sign_in') {
45
+ throw new DynamicError(data.error, ErrorCode.CREDENTIAL_NOT_ENABLED_FOR_SIGN_IN);
46
+ }
44
47
  if (data.code === 'email_associated_with_different_provider') {
45
48
  throw new AccountExistsError(data.error, data.payload);
46
49
  }
@@ -211,6 +211,9 @@ const telegramVerify = (environmentId, oauthResultRequest) => _tslib.__awaiter(v
211
211
  });
212
212
  const handleVerifyError = (e) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
213
213
  const data = yield utils.logResponseError(e, 'error verifying social');
214
+ if (data.code === 'credential_not_enabled_for_sign_in') {
215
+ throw new utils$1.DynamicError(data.error, utils$1.ErrorCode.CREDENTIAL_NOT_ENABLED_FOR_SIGN_IN);
216
+ }
214
217
  if (data.code === 'social_account_already_exists') {
215
218
  throw new utils$1.SocialAccountAlreadyExistsError();
216
219
  }
@@ -222,6 +225,9 @@ const handleVerifyError = (e) => _tslib.__awaiter(void 0, void 0, void 0, functi
222
225
  const handleSignInError = (e) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
223
226
  var _f, _g, _h;
224
227
  const data = yield utils.logResponseError(e, 'error signin social');
228
+ if (data.code === 'credential_not_enabled_for_sign_in') {
229
+ throw new utils$1.DynamicError(data.error, utils$1.ErrorCode.CREDENTIAL_NOT_ENABLED_FOR_SIGN_IN);
230
+ }
225
231
  if (data.error.code === 'gate_blocked') {
226
232
  throw new utils$1.GateBlockedError(data.payload.walletPublicKey);
227
233
  }
@@ -2,7 +2,7 @@
2
2
  import { __awaiter } from '../../../../../_virtual/_tslib.js';
3
3
  import { getElevatedAccessToken } from '@dynamic-labs-sdk/client';
4
4
  import { TokenScope } from '@dynamic-labs/sdk-api-core';
5
- import { SocialAccountAlreadyExistsError, SandboxMaximumThresholdReachedError, GateBlockedError, NoAccessError, AccountExistsError } from '@dynamic-labs/utils';
5
+ import { DynamicError, ErrorCode, SocialAccountAlreadyExistsError, SandboxMaximumThresholdReachedError, GateBlockedError, NoAccessError, AccountExistsError } from '@dynamic-labs/utils';
6
6
  import '@dynamic-labs-sdk/client/core';
7
7
  import '../../../client/client.js';
8
8
  import 'react';
@@ -207,6 +207,9 @@ const telegramVerify = (environmentId, oauthResultRequest) => __awaiter(void 0,
207
207
  });
208
208
  const handleVerifyError = (e) => __awaiter(void 0, void 0, void 0, function* () {
209
209
  const data = yield logResponseError(e, 'error verifying social');
210
+ if (data.code === 'credential_not_enabled_for_sign_in') {
211
+ throw new DynamicError(data.error, ErrorCode.CREDENTIAL_NOT_ENABLED_FOR_SIGN_IN);
212
+ }
210
213
  if (data.code === 'social_account_already_exists') {
211
214
  throw new SocialAccountAlreadyExistsError();
212
215
  }
@@ -218,6 +221,9 @@ const handleVerifyError = (e) => __awaiter(void 0, void 0, void 0, function* ()
218
221
  const handleSignInError = (e) => __awaiter(void 0, void 0, void 0, function* () {
219
222
  var _f, _g, _h;
220
223
  const data = yield logResponseError(e, 'error signin social');
224
+ if (data.code === 'credential_not_enabled_for_sign_in') {
225
+ throw new DynamicError(data.error, ErrorCode.CREDENTIAL_NOT_ENABLED_FOR_SIGN_IN);
226
+ }
221
227
  if (data.error.code === 'gate_blocked') {
222
228
  throw new GateBlockedError(data.payload.walletPublicKey);
223
229
  }
@@ -54,6 +54,9 @@ const signInWithSmsVerification = (_b) => _tslib.__awaiter(void 0, [_b], void 0,
54
54
  }
55
55
  catch (e) {
56
56
  const data = yield utils.logResponseError(e, 'Error signin phone number');
57
+ if (data.code === 'credential_not_enabled_for_sign_in') {
58
+ throw new utils$1.DynamicError(data.error, utils$1.ErrorCode.CREDENTIAL_NOT_ENABLED_FOR_SIGN_IN);
59
+ }
57
60
  if (((_c = data.error) === null || _c === void 0 ? void 0 : _c.code) === 'missing_from_list') {
58
61
  throw new utils$1.NoAccessError({ phoneNumber: data.payload.phoneNumber });
59
62
  }
@@ -103,6 +106,9 @@ const verifySms = (_e) => _tslib.__awaiter(void 0, [_e], void 0, function* ({ ve
103
106
  catch (e) {
104
107
  const data = yield utils.logResponseError(e, 'Error verifying phone number');
105
108
  logger.logger.error(data.error);
109
+ if (data.code === 'credential_not_enabled_for_sign_in') {
110
+ throw new utils$1.DynamicError(data.error, utils$1.ErrorCode.CREDENTIAL_NOT_ENABLED_FOR_SIGN_IN);
111
+ }
106
112
  if (data.error.code === 'sandbox_maximum_threshold_reached') {
107
113
  throw new utils$1.SandboxMaximumThresholdReachedError(data.error.message);
108
114
  }
@@ -1,7 +1,7 @@
1
1
  'use client'
2
2
  import { __awaiter } from '../../../../../_virtual/_tslib.js';
3
3
  import { getElevatedAccessToken } from '@dynamic-labs-sdk/client';
4
- import { NoAccessError, SmsVerificationError, SandboxMaximumThresholdReachedError } from '@dynamic-labs/utils';
4
+ import { DynamicError, ErrorCode, NoAccessError, SmsVerificationError, SandboxMaximumThresholdReachedError } from '@dynamic-labs/utils';
5
5
  import { TokenScope } from '@dynamic-labs/sdk-api-core';
6
6
  import { Locale } from '@dynamic-labs/locale';
7
7
  import '@dynamic-labs/iconic';
@@ -50,6 +50,9 @@ const signInWithSmsVerification = (_b) => __awaiter(void 0, [_b], void 0, functi
50
50
  }
51
51
  catch (e) {
52
52
  const data = yield logResponseError(e, 'Error signin phone number');
53
+ if (data.code === 'credential_not_enabled_for_sign_in') {
54
+ throw new DynamicError(data.error, ErrorCode.CREDENTIAL_NOT_ENABLED_FOR_SIGN_IN);
55
+ }
53
56
  if (((_c = data.error) === null || _c === void 0 ? void 0 : _c.code) === 'missing_from_list') {
54
57
  throw new NoAccessError({ phoneNumber: data.payload.phoneNumber });
55
58
  }
@@ -99,6 +102,9 @@ const verifySms = (_e) => __awaiter(void 0, [_e], void 0, function* ({ verificat
99
102
  catch (e) {
100
103
  const data = yield logResponseError(e, 'Error verifying phone number');
101
104
  logger.error(data.error);
105
+ if (data.code === 'credential_not_enabled_for_sign_in') {
106
+ throw new DynamicError(data.error, ErrorCode.CREDENTIAL_NOT_ENABLED_FOR_SIGN_IN);
107
+ }
102
108
  if (data.error.code === 'sandbox_maximum_threshold_reached') {
103
109
  throw new SandboxMaximumThresholdReachedError(data.error.message);
104
110
  }
@@ -189,6 +189,9 @@ const verifyWallet = (environmentId_3, _f) => _tslib.__awaiter(void 0, [environm
189
189
  walletPublicKey: data.payload.walletPublicKey,
190
190
  });
191
191
  }
192
+ if (data.code === 'credential_not_enabled_for_sign_in') {
193
+ throw new utils$1.DynamicError(data.error, utils$1.ErrorCode.CREDENTIAL_NOT_ENABLED_FOR_SIGN_IN);
194
+ }
192
195
  if (data.code === 'email_associated_with_different_provider') {
193
196
  throw new utils$1.AccountExistsError(data.error, data.payload);
194
197
  }
@@ -237,6 +240,9 @@ const walletsVerify = (environmentId_4, _l) => _tslib.__awaiter(void 0, [environ
237
240
  walletPublicKey: data.payload.walletPublicKey,
238
241
  });
239
242
  }
243
+ if (data.code === 'credential_not_enabled_for_sign_in') {
244
+ throw new utils$1.DynamicError(data.error, utils$1.ErrorCode.CREDENTIAL_NOT_ENABLED_FOR_SIGN_IN);
245
+ }
240
246
  if (data.code === 'email_associated_with_different_provider') {
241
247
  throw new utils$1.AccountExistsError(data.error, data.payload);
242
248
  }
@@ -2,7 +2,7 @@
2
2
  import { __awaiter } from '../../../../../_virtual/_tslib.js';
3
3
  import { getElevatedAccessToken } from '@dynamic-labs-sdk/client';
4
4
  import { TokenScope, VerifyRequestFromJSON } from '@dynamic-labs/sdk-api-core';
5
- import { DynamicError, EmbeddedWalletExistsError, WalletUsedError, MergeAccountsConfirmationError, SandboxMaximumThresholdReachedError, WalletNotDeployedError, ChainalysisError, GateBlockedError, NoAccessError, AccountExistsError } from '@dynamic-labs/utils';
5
+ import { DynamicError, EmbeddedWalletExistsError, WalletUsedError, MergeAccountsConfirmationError, SandboxMaximumThresholdReachedError, WalletNotDeployedError, ChainalysisError, GateBlockedError, NoAccessError, ErrorCode, AccountExistsError } from '@dynamic-labs/utils';
6
6
  import '@dynamic-labs-sdk/client/core';
7
7
  import '../../../client/client.js';
8
8
  import 'react';
@@ -185,6 +185,9 @@ const verifyWallet = (environmentId_3, _f) => __awaiter(void 0, [environmentId_3
185
185
  walletPublicKey: data.payload.walletPublicKey,
186
186
  });
187
187
  }
188
+ if (data.code === 'credential_not_enabled_for_sign_in') {
189
+ throw new DynamicError(data.error, ErrorCode.CREDENTIAL_NOT_ENABLED_FOR_SIGN_IN);
190
+ }
188
191
  if (data.code === 'email_associated_with_different_provider') {
189
192
  throw new AccountExistsError(data.error, data.payload);
190
193
  }
@@ -233,6 +236,9 @@ const walletsVerify = (environmentId_4, _l) => __awaiter(void 0, [environmentId_
233
236
  walletPublicKey: data.payload.walletPublicKey,
234
237
  });
235
238
  }
239
+ if (data.code === 'credential_not_enabled_for_sign_in') {
240
+ throw new DynamicError(data.error, ErrorCode.CREDENTIAL_NOT_ENABLED_FOR_SIGN_IN);
241
+ }
236
242
  if (data.code === 'email_associated_with_different_provider') {
237
243
  throw new AccountExistsError(data.error, data.payload);
238
244
  }
@@ -18,6 +18,7 @@ const ChainEnumToVerifiedCredentialName = {
18
18
  ETH: 'eip155',
19
19
  EVM: 'eip155',
20
20
  FLOW: 'flow',
21
+ MIDNIGHT: 'midnight',
21
22
  SOL: 'solana',
22
23
  STARK: 'starknet',
23
24
  STELLAR: 'stellar',
@@ -34,6 +35,7 @@ const VerifiedCredentialNameToChainEnum = {
34
35
  cosmos: sdkApiCore.ChainEnum.Cosmos,
35
36
  eip155: sdkApiCore.ChainEnum.Evm,
36
37
  flow: sdkApiCore.ChainEnum.Flow,
38
+ midnight: sdkApiCore.ChainEnum.Midnight,
37
39
  solana: sdkApiCore.ChainEnum.Sol,
38
40
  starknet: sdkApiCore.ChainEnum.Stark,
39
41
  stellar: sdkApiCore.ChainEnum.Stellar,
@@ -14,6 +14,7 @@ const ChainEnumToVerifiedCredentialName = {
14
14
  ETH: 'eip155',
15
15
  EVM: 'eip155',
16
16
  FLOW: 'flow',
17
+ MIDNIGHT: 'midnight',
17
18
  SOL: 'solana',
18
19
  STARK: 'starknet',
19
20
  STELLAR: 'stellar',
@@ -30,6 +31,7 @@ const VerifiedCredentialNameToChainEnum = {
30
31
  cosmos: ChainEnum.Cosmos,
31
32
  eip155: ChainEnum.Evm,
32
33
  flow: ChainEnum.Flow,
34
+ midnight: ChainEnum.Midnight,
33
35
  solana: ChainEnum.Sol,
34
36
  starknet: ChainEnum.Stark,
35
37
  stellar: ChainEnum.Stellar,
@@ -31,6 +31,7 @@ require('@dynamic-labs-sdk/client/core');
31
31
  require('../../../../client/client.cjs');
32
32
  require('@dynamic-labs-sdk/client');
33
33
  require('../../../../config/ApiEndpoint.cjs');
34
+ var getUserProfile = require('../../../../client/extension/user/getUserProfile/getUserProfile.cjs');
34
35
  require('@dynamic-labs/locale');
35
36
  require('../../../../store/state/dynamicContextProps/dynamicContextProps.cjs');
36
37
  require('../../../../store/state/primaryWalletId/primaryWalletId.cjs');
@@ -213,6 +214,10 @@ const useConnectAndSign = ({ shouldUpdateWallets = true, shouldCallCallback = tr
213
214
  return;
214
215
  }
215
216
  const { address } = connectionResult;
217
+ logger.logger.logVerboseTroubleshootingMessage('[useConnectAndSign] connection result', {
218
+ address,
219
+ walletConnectorKey: walletConnector.key,
220
+ });
216
221
  const walletNetwork = yield walletConnector.getNetwork(true);
217
222
  const usesSupportedNetwork = isSupportedNetwork.isSupportedNetwork({
218
223
  network: walletNetwork,
@@ -226,6 +231,23 @@ const useConnectAndSign = ({ shouldUpdateWallets = true, shouldCallCallback = tr
226
231
  }
227
232
  return pushView('network-not-supported');
228
233
  }
234
+ const user = getUserProfile.getUserProfile();
235
+ const isAlreadyVerified = Boolean(user === null || user === void 0 ? void 0 : user.verifiedCredentials.find((vc) => vc.walletProvider === walletConnectorCore.getWalletProvider(walletConnector) &&
236
+ vc.walletName === walletConnector.key &&
237
+ vc.address &&
238
+ walletConnectorCore.isSameAddress(vc.address, address, walletConnector.connectedChain)));
239
+ logger.logger.logVerboseTroubleshootingMessage('[useConnectAndSign] isAlreadyVerified', {
240
+ isAlreadyVerified,
241
+ userVerifiedCredentials: user === null || user === void 0 ? void 0 : user.verifiedCredentials,
242
+ });
243
+ // this is in case the user is trying to link a wallet that is already verified/linked
244
+ // this flow mainly happens when trying to link a WalletConnect or MM wallet through qr code
245
+ // skip this check when requestedScopes is present, as that indicates a step-up auth flow
246
+ // where the user must re-sign with an already-verified wallet to authorize a sensitive action
247
+ if (isAlreadyVerified && !(requestedScopes === null || requestedScopes === void 0 ? void 0 : requestedScopes.length)) {
248
+ setShowAuthFlow(false);
249
+ return;
250
+ }
229
251
  if (isConnectOnly.isConnectOnly()) {
230
252
  utils.StorageService.setItem(localStorage.LAST_USED_WALLET, walletConnector.key);
231
253
  if (shouldUpdateWallets) {
@@ -1,7 +1,7 @@
1
1
  'use client'
2
2
  import { __awaiter } from '../../../../../../_virtual/_tslib.js';
3
3
  import { DeferredPromise, StorageService, CustomError, GetAddressCancelledError } from '@dynamic-labs/utils';
4
- import { isEmailWalletConnector, isEmailOTPWalletConnector, isBloctoConnector } from '@dynamic-labs/wallet-connector-core';
4
+ import { isEmailWalletConnector, isEmailOTPWalletConnector, isBloctoConnector, getWalletProvider, isSameAddress } from '@dynamic-labs/wallet-connector-core';
5
5
  import { useCaptchaContext } from '../../../../context/CaptchaContext/CaptchaContext.js';
6
6
  import 'react';
7
7
  import '../../../../context/DynamicContext/DynamicContext.js';
@@ -27,6 +27,7 @@ import '@dynamic-labs-sdk/client/core';
27
27
  import '../../../../client/client.js';
28
28
  import '@dynamic-labs-sdk/client';
29
29
  import '../../../../config/ApiEndpoint.js';
30
+ import { getUserProfile } from '../../../../client/extension/user/getUserProfile/getUserProfile.js';
30
31
  import '@dynamic-labs/locale';
31
32
  import '../../../../store/state/dynamicContextProps/dynamicContextProps.js';
32
33
  import '../../../../store/state/primaryWalletId/primaryWalletId.js';
@@ -209,6 +210,10 @@ const useConnectAndSign = ({ shouldUpdateWallets = true, shouldCallCallback = tr
209
210
  return;
210
211
  }
211
212
  const { address } = connectionResult;
213
+ logger.logVerboseTroubleshootingMessage('[useConnectAndSign] connection result', {
214
+ address,
215
+ walletConnectorKey: walletConnector.key,
216
+ });
212
217
  const walletNetwork = yield walletConnector.getNetwork(true);
213
218
  const usesSupportedNetwork = isSupportedNetwork({
214
219
  network: walletNetwork,
@@ -222,6 +227,23 @@ const useConnectAndSign = ({ shouldUpdateWallets = true, shouldCallCallback = tr
222
227
  }
223
228
  return pushView('network-not-supported');
224
229
  }
230
+ const user = getUserProfile();
231
+ const isAlreadyVerified = Boolean(user === null || user === void 0 ? void 0 : user.verifiedCredentials.find((vc) => vc.walletProvider === getWalletProvider(walletConnector) &&
232
+ vc.walletName === walletConnector.key &&
233
+ vc.address &&
234
+ isSameAddress(vc.address, address, walletConnector.connectedChain)));
235
+ logger.logVerboseTroubleshootingMessage('[useConnectAndSign] isAlreadyVerified', {
236
+ isAlreadyVerified,
237
+ userVerifiedCredentials: user === null || user === void 0 ? void 0 : user.verifiedCredentials,
238
+ });
239
+ // this is in case the user is trying to link a wallet that is already verified/linked
240
+ // this flow mainly happens when trying to link a WalletConnect or MM wallet through qr code
241
+ // skip this check when requestedScopes is present, as that indicates a step-up auth flow
242
+ // where the user must re-sign with an already-verified wallet to authorize a sensitive action
243
+ if (isAlreadyVerified && !(requestedScopes === null || requestedScopes === void 0 ? void 0 : requestedScopes.length)) {
244
+ setShowAuthFlow(false);
245
+ return;
246
+ }
225
247
  if (isConnectOnly()) {
226
248
  StorageService.setItem(LAST_USED_WALLET, walletConnector.key);
227
249
  if (shouldUpdateWallets) {
@@ -179,15 +179,21 @@ const useWalletCreation = () => {
179
179
  }
180
180
  catch (error) {
181
181
  const duration = Date.now() - startTime;
182
- logger.logger.instrument('Auto wallet creation failed', {
183
- chainCount: requirements.length,
184
- chains: chainsString,
185
- environmentId,
186
- error: error instanceof Error ? error.message : 'Unknown error',
187
- key: 'auto_wallet_creation_failed',
188
- time: duration,
189
- userId: user === null || user === void 0 ? void 0 : user.id,
190
- });
182
+ // Don't count password setup cancellations as failures — they're intentional
183
+ // user actions, not errors. The onFailure handler already suppresses the error
184
+ // UI for this case; the metric should be consistent with that intent.
185
+ if (!(error instanceof Error &&
186
+ error.message === useSetupPassword.PASSWORD_SETUP_CANCELLED_ERROR)) {
187
+ logger.logger.instrument('Auto wallet creation failed', {
188
+ chainCount: requirements.length,
189
+ chains: chainsString,
190
+ environmentId,
191
+ error: error instanceof Error ? error.message : 'Unknown error',
192
+ key: 'auto_wallet_creation_failed',
193
+ time: duration,
194
+ userId: user === null || user === void 0 ? void 0 : user.id,
195
+ });
196
+ }
191
197
  throw error;
192
198
  }
193
199
  }), {
@@ -175,15 +175,21 @@ const useWalletCreation = () => {
175
175
  }
176
176
  catch (error) {
177
177
  const duration = Date.now() - startTime;
178
- logger.instrument('Auto wallet creation failed', {
179
- chainCount: requirements.length,
180
- chains: chainsString,
181
- environmentId,
182
- error: error instanceof Error ? error.message : 'Unknown error',
183
- key: 'auto_wallet_creation_failed',
184
- time: duration,
185
- userId: user === null || user === void 0 ? void 0 : user.id,
186
- });
178
+ // Don't count password setup cancellations as failures — they're intentional
179
+ // user actions, not errors. The onFailure handler already suppresses the error
180
+ // UI for this case; the metric should be consistent with that intent.
181
+ if (!(error instanceof Error &&
182
+ error.message === PASSWORD_SETUP_CANCELLED_ERROR)) {
183
+ logger.instrument('Auto wallet creation failed', {
184
+ chainCount: requirements.length,
185
+ chains: chainsString,
186
+ environmentId,
187
+ error: error instanceof Error ? error.message : 'Unknown error',
188
+ key: 'auto_wallet_creation_failed',
189
+ time: duration,
190
+ userId: user === null || user === void 0 ? void 0 : user.id,
191
+ });
192
+ }
187
193
  throw error;
188
194
  }
189
195
  }), {
@@ -18,6 +18,11 @@ const useTransition = (_a) => {
18
18
  const [stage, setStage] = React.useState(initialStage);
19
19
  const [mount, setMount] = React.useState(!animateOnMount);
20
20
  const [currentDuration, setCurrentDuration] = React.useState(duration);
21
+ // Track current stage in a ref so the transition effect doesn't need `stage`
22
+ // as a dependency. This prevents the effect's cleanup from cancelling an
23
+ // in-flight rAF every time stage changes (the race condition).
24
+ const stageRef = React.useRef(initialStage);
25
+ stageRef.current = stage;
21
26
  const performTransition = (runTransition, transitionDelay) => {
22
27
  if (transitionDelay) {
23
28
  timeoutIdRef.current = animationFrameTimeout.animationFrameTimeout(runTransition, transitionDelay);
@@ -45,11 +50,14 @@ const useTransition = (_a) => {
45
50
  }, animationDuration);
46
51
  }, [duration, outDuration]);
47
52
  React.useEffect(() => {
48
- if (isShown && stage !== 'ENTERED') {
53
+ const currentStage = stageRef.current;
54
+ if (isShown && currentStage !== 'ENTERED' && currentStage !== 'ENTERING') {
49
55
  const enterDelay = inDelay || delay;
50
56
  performTransition(performEnter, enterDelay);
51
57
  }
52
- else if (!isShown && stage !== 'UNMOUNT') {
58
+ else if (!isShown &&
59
+ currentStage !== 'UNMOUNT' &&
60
+ currentStage !== 'EXITING') {
53
61
  const exitDelay = outDelay || delay;
54
62
  performTransition(performExit, exitDelay);
55
63
  }
@@ -57,7 +65,10 @@ const useTransition = (_a) => {
57
65
  animationFrameTimeout.clearAnimationFrameTimeout(animationFrameTimeoutIdRef.current);
58
66
  animationFrameTimeout.clearAnimationFrameTimeout(timeoutIdRef.current);
59
67
  };
60
- }, [inDelay, outDelay, performEnter, performExit, isShown, delay, stage]);
68
+ // `stage` is intentionally excluded from deps — we read it via stageRef to
69
+ // prevent the cleanup from cancelling an in-flight rAF on every stage change.
70
+ // eslint-disable-next-line react-hooks/exhaustive-deps
71
+ }, [inDelay, outDelay, performEnter, performExit, isShown, delay]);
61
72
  useTransitionEvents.useTransitionEvents(stage, events);
62
73
  return { currentDuration, mount, stage };
63
74
  };
@@ -14,6 +14,11 @@ const useTransition = (_a) => {
14
14
  const [stage, setStage] = useState(initialStage);
15
15
  const [mount, setMount] = useState(!animateOnMount);
16
16
  const [currentDuration, setCurrentDuration] = useState(duration);
17
+ // Track current stage in a ref so the transition effect doesn't need `stage`
18
+ // as a dependency. This prevents the effect's cleanup from cancelling an
19
+ // in-flight rAF every time stage changes (the race condition).
20
+ const stageRef = useRef(initialStage);
21
+ stageRef.current = stage;
17
22
  const performTransition = (runTransition, transitionDelay) => {
18
23
  if (transitionDelay) {
19
24
  timeoutIdRef.current = animationFrameTimeout(runTransition, transitionDelay);
@@ -41,11 +46,14 @@ const useTransition = (_a) => {
41
46
  }, animationDuration);
42
47
  }, [duration, outDuration]);
43
48
  useEffect(() => {
44
- if (isShown && stage !== 'ENTERED') {
49
+ const currentStage = stageRef.current;
50
+ if (isShown && currentStage !== 'ENTERED' && currentStage !== 'ENTERING') {
45
51
  const enterDelay = inDelay || delay;
46
52
  performTransition(performEnter, enterDelay);
47
53
  }
48
- else if (!isShown && stage !== 'UNMOUNT') {
54
+ else if (!isShown &&
55
+ currentStage !== 'UNMOUNT' &&
56
+ currentStage !== 'EXITING') {
49
57
  const exitDelay = outDelay || delay;
50
58
  performTransition(performExit, exitDelay);
51
59
  }
@@ -53,7 +61,10 @@ const useTransition = (_a) => {
53
61
  clearAnimationFrameTimeout(animationFrameTimeoutIdRef.current);
54
62
  clearAnimationFrameTimeout(timeoutIdRef.current);
55
63
  };
56
- }, [inDelay, outDelay, performEnter, performExit, isShown, delay, stage]);
64
+ // `stage` is intentionally excluded from deps — we read it via stageRef to
65
+ // prevent the cleanup from cancelling an in-flight rAF on every stage change.
66
+ // eslint-disable-next-line react-hooks/exhaustive-deps
67
+ }, [inDelay, outDelay, performEnter, performExit, isShown, delay]);
57
68
  useTransitionEvents(stage, events);
58
69
  return { currentDuration, mount, stage };
59
70
  };
@@ -186,6 +186,10 @@ const useUserAuth = ({ authMethod, }) => {
186
186
  (error === null || error === void 0 ? void 0 : error.code) === 'ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED') {
187
187
  throw error;
188
188
  }
189
+ if (error.code === utils.ErrorCode.CREDENTIAL_NOT_ENABLED_FOR_SIGN_IN) {
190
+ setError(error.message, error.code);
191
+ return;
192
+ }
189
193
  if (onError) {
190
194
  onError === null || onError === void 0 ? void 0 : onError(error);
191
195
  return;
@@ -3,7 +3,7 @@ import { __awaiter } from '../../../../../_virtual/_tslib.js';
3
3
  import { useCallback } from 'react';
4
4
  import { MfaInvalidOtpError, MfaRateLimitedError, SandboxMaximumThresholdReachedError as SandboxMaximumThresholdReachedError$1 } from '@dynamic-labs-sdk/client';
5
5
  import { WalletProviderEnum, EmbeddedWalletVersionEnum, MfaBackupCodeAcknowledgement } from '@dynamic-labs/sdk-api-core';
6
- import { EmailAlreadyExistsError, CustomFieldNotUniqueError, UsernameAlreadyExistsError, TooManyEmailVerificationsError, InvalidPhoneNumberError, NoAccessError, AccountExistsError, SandboxMaximumThresholdReachedError, UserHasAccountWithEmailError, DynamicError, sleep } from '@dynamic-labs/utils';
6
+ import { EmailAlreadyExistsError, CustomFieldNotUniqueError, UsernameAlreadyExistsError, TooManyEmailVerificationsError, InvalidPhoneNumberError, NoAccessError, AccountExistsError, SandboxMaximumThresholdReachedError, UserHasAccountWithEmailError, ErrorCode, DynamicError, sleep } from '@dynamic-labs/utils';
7
7
  import '@dynamic-labs-sdk/client/core';
8
8
  import '../../../client/client.js';
9
9
  import '../../../config/ApiEndpoint.js';
@@ -182,6 +182,10 @@ const useUserAuth = ({ authMethod, }) => {
182
182
  (error === null || error === void 0 ? void 0 : error.code) === 'ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED') {
183
183
  throw error;
184
184
  }
185
+ if (error.code === ErrorCode.CREDENTIAL_NOT_ENABLED_FOR_SIGN_IN) {
186
+ setError(error.message, error.code);
187
+ return;
188
+ }
185
189
  if (onError) {
186
190
  onError === null || onError === void 0 ? void 0 : onError(error);
187
191
  return;
@@ -266,6 +266,12 @@ const useVerifyWallet = ({ displaySiweStatement, environmentId, projectSettings,
266
266
  pushView('account-exists');
267
267
  return;
268
268
  }
269
+ if (e.code === utils.ErrorCode.CREDENTIAL_NOT_ENABLED_FOR_SIGN_IN) {
270
+ handleDisconnectWallet({ walletConnector });
271
+ clearStackAndPushInitialView();
272
+ setError(e.message, e.code);
273
+ return;
274
+ }
269
275
  const authMode$1 = authMode.getAuthMode();
270
276
  if (connectedWallets.length && authMode$1 === 'connect-only') {
271
277
  throw new utils.DynamicError(e.message);
@@ -1,6 +1,6 @@
1
1
  'use client'
2
2
  import { __awaiter } from '../../../../../_virtual/_tslib.js';
3
- import { DynamicError, StorageService, EmbeddedWalletExistsError, WalletUsedError, MergeAccountsConfirmationError, ChainalysisError, GateBlockedError, SandboxMaximumThresholdReachedError, NoAccessError, AccountExistsError } from '@dynamic-labs/utils';
3
+ import { DynamicError, StorageService, EmbeddedWalletExistsError, WalletUsedError, MergeAccountsConfirmationError, ChainalysisError, GateBlockedError, SandboxMaximumThresholdReachedError, NoAccessError, AccountExistsError, ErrorCode } from '@dynamic-labs/utils';
4
4
  import { getWalletProvider, isSocialWalletConnector } from '@dynamic-labs/wallet-connector-core';
5
5
  import 'react';
6
6
  import { dynamicEvents } from '../../../events/dynamicEvents.js';
@@ -262,6 +262,12 @@ const useVerifyWallet = ({ displaySiweStatement, environmentId, projectSettings,
262
262
  pushView('account-exists');
263
263
  return;
264
264
  }
265
+ if (e.code === ErrorCode.CREDENTIAL_NOT_ENABLED_FOR_SIGN_IN) {
266
+ handleDisconnectWallet({ walletConnector });
267
+ clearStackAndPushInitialView();
268
+ setError(e.message, e.code);
269
+ return;
270
+ }
265
271
  const authMode = getAuthMode();
266
272
  if (connectedWallets.length && authMode === 'connect-only') {
267
273
  throw new DynamicError(e.message);
@@ -289,11 +289,18 @@ const useHandleWalletItem = ({ allowAlreadyConnectedWallet, onQrCodeConnect, onC
289
289
  }
290
290
  }
291
291
  const supportsMultiAccount = walletConnectorCore.connectorRequiresDisconnectionForNewConnection(walletConnector);
292
+ const isNotInstalledWithQrCodeSupport = walletConnector.isWalletConnect ||
293
+ (!walletConnector.isInstalledOnBrowser() &&
294
+ walletConnector.canConnectViaQrCode);
295
+ logger.logger.logVerboseTroubleshootingMessage('[handleWalletItemClick] isNotInstalledWithQrCodeSupport', {
296
+ isNotInstalledWithQrCodeSupport,
297
+ walletConnectorKey: walletConnector.key,
298
+ });
292
299
  if (!allowAlreadyConnectedWallet &&
293
300
  isSelectedWalletAlreadyConnected.isSelectedWalletAlreadyConnected(linkedWallets, walletConnector, user) &&
294
301
  walletConnector.connectedChain !== 'FLOW' &&
295
- !walletConnector.isWalletConnect &&
296
- !supportsMultiAccount) {
302
+ !supportsMultiAccount &&
303
+ !isNotInstalledWithQrCodeSupport) {
297
304
  handleAlreadyConnectedWallet(walletConnector);
298
305
  }
299
306
  else if (walletConnector.canConnectViaCustodialService) {
@@ -285,11 +285,18 @@ const useHandleWalletItem = ({ allowAlreadyConnectedWallet, onQrCodeConnect, onC
285
285
  }
286
286
  }
287
287
  const supportsMultiAccount = connectorRequiresDisconnectionForNewConnection(walletConnector);
288
+ const isNotInstalledWithQrCodeSupport = walletConnector.isWalletConnect ||
289
+ (!walletConnector.isInstalledOnBrowser() &&
290
+ walletConnector.canConnectViaQrCode);
291
+ logger.logVerboseTroubleshootingMessage('[handleWalletItemClick] isNotInstalledWithQrCodeSupport', {
292
+ isNotInstalledWithQrCodeSupport,
293
+ walletConnectorKey: walletConnector.key,
294
+ });
288
295
  if (!allowAlreadyConnectedWallet &&
289
296
  isSelectedWalletAlreadyConnected(linkedWallets, walletConnector, user) &&
290
297
  walletConnector.connectedChain !== 'FLOW' &&
291
- !walletConnector.isWalletConnect &&
292
- !supportsMultiAccount) {
298
+ !supportsMultiAccount &&
299
+ !isNotInstalledWithQrCodeSupport) {
293
300
  handleAlreadyConnectedWallet(walletConnector);
294
301
  }
295
302
  else if (walletConnector.canConnectViaCustodialService) {