@dynamic-labs/sdk-react-core 5.2.0 → 5.3.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 (33) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/package.cjs +3 -3
  3. package/package.js +3 -3
  4. package/package.json +15 -15
  5. package/src/index.d.ts +1 -1
  6. package/src/lib/client/extension/functions/getSessionIdFromMinToken/getSessionIdFromMinToken.cjs +30 -0
  7. package/src/lib/client/extension/functions/getSessionIdFromMinToken/getSessionIdFromMinToken.d.ts +5 -0
  8. package/src/lib/client/extension/functions/getSessionIdFromMinToken/getSessionIdFromMinToken.js +26 -0
  9. package/src/lib/client/extension/functions/getSessionIdFromMinToken/index.d.ts +1 -0
  10. package/src/lib/client/extension/index.d.ts +1 -0
  11. package/src/lib/context/DynamicContext/DynamicContext.cjs +2 -0
  12. package/src/lib/context/DynamicContext/DynamicContext.js +2 -0
  13. package/src/lib/context/ErrorContext/hooks/useErrorText/useErrorText.cjs +1 -0
  14. package/src/lib/context/ErrorContext/hooks/useErrorText/useErrorText.js +2 -1
  15. package/src/lib/data/api/transactions/index.d.ts +1 -0
  16. package/src/lib/data/api/transactions/screenTransaction.cjs +107 -0
  17. package/src/lib/data/api/transactions/screenTransaction.d.ts +12 -0
  18. package/src/lib/data/api/transactions/screenTransaction.js +101 -0
  19. package/src/lib/data/api/user/user.cjs +3 -0
  20. package/src/lib/data/api/user/user.js +4 -1
  21. package/src/lib/utils/functions/updatePrimaryWalletId/updatePrimaryWalletId.cjs +1 -1
  22. package/src/lib/utils/functions/updatePrimaryWalletId/updatePrimaryWalletId.js +1 -1
  23. package/src/lib/utils/hooks/useCreateWalletConnectorOptions/useCreateWalletConnectorOptions.d.ts +2 -1
  24. package/src/lib/utils/hooks/useMfa/useMfa.cjs +1 -1
  25. package/src/lib/utils/hooks/useMfa/useMfa.js +1 -1
  26. package/src/lib/utils/hooks/useSyncDynamicWaas/useSyncDynamicWaas.cjs +18 -7
  27. package/src/lib/utils/hooks/useSyncDynamicWaas/useSyncDynamicWaas.js +18 -7
  28. package/src/lib/utils/hooks/useUserAuth/useUserAuth.cjs +1 -0
  29. package/src/lib/utils/hooks/useUserAuth/useUserAuth.js +2 -1
  30. package/src/lib/utils/hooks/useUserDataForm/useUserDataForm.cjs +3 -0
  31. package/src/lib/utils/hooks/useUserDataForm/useUserDataForm.js +4 -1
  32. package/src/lib/views/MergeUserAccountsWithSameEmailView/MergeUserAccountsWithSameEmailView.cjs +1 -1
  33. package/src/lib/views/MergeUserAccountsWithSameEmailView/MergeUserAccountsWithSameEmailView.js +1 -1
package/CHANGELOG.md CHANGED
@@ -1,4 +1,23 @@
1
1
 
2
+ ## [5.3.0](https://github.com/dynamic-labs/dynamic-auth/compare/v5.2.0...v5.3.0) (2026-08-12)
3
+
4
+
5
+ ### Features
6
+
7
+ * **screening:** add transaction-screening service, types, and connector wiring (DYNT-1663) ([#12160](https://github.com/dynamic-labs/dynamic-auth/issues/12160)) ([d8df6a1](https://github.com/dynamic-labs/dynamic-auth/commit/d8df6a1fccbb6370c140454d9297eabd97699e35)), closes [#12172](https://github.com/dynamic-labs/dynamic-auth/issues/12172) [#12167](https://github.com/dynamic-labs/dynamic-auth/issues/12167) [#12168](https://github.com/dynamic-labs/dynamic-auth/issues/12168) [#12169](https://github.com/dynamic-labs/dynamic-auth/issues/12169)
8
+ * **screening:** screen Bitcoin connected-wallet transactions (DYNT-1663) ([#12169](https://github.com/dynamic-labs/dynamic-auth/issues/12169)) ([f34d1c3](https://github.com/dynamic-labs/dynamic-auth/commit/f34d1c31fe10d0cb02b4f7462dd4900d0256604a))
9
+ * **screening:** screen EVM connected-wallet sends (DYNT-1663) ([#12167](https://github.com/dynamic-labs/dynamic-auth/issues/12167)) ([1b72b24](https://github.com/dynamic-labs/dynamic-auth/commit/1b72b24393a49153d74ce715a44d262e8e48ddc7))
10
+ * **screening:** screen Solana connected-wallet transactions (DYNT-1663) ([#12168](https://github.com/dynamic-labs/dynamic-auth/issues/12168)) ([000eb18](https://github.com/dynamic-labs/dynamic-auth/commit/000eb180aca8349804953ff7738c0ba984a2fa21))
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * add PhoneNumberAlreadyLinkedError and map duplicate-phone backend code ([#12145](https://github.com/dynamic-labs/dynamic-auth/issues/12145)) ([9d13b5f](https://github.com/dynamic-labs/dynamic-auth/commit/9d13b5f8b22716b4c9ce206ee870aab5bd745b8b))
16
+ * **react-native-extension:** throw clear error when react-native-keychain native module is missing ([#12197](https://github.com/dynamic-labs/dynamic-auth/issues/12197)) ([b9983e1](https://github.com/dynamic-labs/dynamic-auth/commit/b9983e1f1aefa9a9bbdc1435f706a05e64f34f1c))
17
+ * security updates ([#12187](https://github.com/dynamic-labs/dynamic-auth/issues/12187)) ([d3a31e2](https://github.com/dynamic-labs/dynamic-auth/commit/d3a31e23533b6b7739851a3b747d62ba13d318b2))
18
+ * security updates ([#12208](https://github.com/dynamic-labs/dynamic-auth/issues/12208)) ([9e9472a](https://github.com/dynamic-labs/dynamic-auth/commit/9e9472acfbe01f7ac9e160829cc10e53c65f91e7))
19
+ * **sdk-react-core:** avoid spurious WaaS client rebuild on transient user sessionId churn ([#12182](https://github.com/dynamic-labs/dynamic-auth/issues/12182)) ([480b2ec](https://github.com/dynamic-labs/dynamic-auth/commit/480b2ecc87486a852e75e8814a76fb59ffe40c5d))
20
+
2
21
  ## [5.2.0](https://github.com/dynamic-labs/dynamic-auth/compare/v5.1.0...v5.2.0) (2026-08-06)
3
22
 
4
23
 
package/package.cjs CHANGED
@@ -3,10 +3,10 @@
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
- var version = "5.2.0";
6
+ var version = "5.3.0";
7
7
  var dependencies = {
8
- "@dynamic-labs/sdk-api-core": "0.0.1093",
9
- "@dynamic-labs-sdk/client": "1.25.0",
8
+ "@dynamic-labs/sdk-api-core": "0.0.1118",
9
+ "@dynamic-labs-sdk/client": "1.27.1",
10
10
  "@dynamic-labs-wallet/browser-wallet-client": "1.0.92",
11
11
  "@dynamic-labs-wallet/forward-mpc-client": "1.0.1",
12
12
  "@hcaptcha/react-hcaptcha": "1.4.4",
package/package.js CHANGED
@@ -1,8 +1,8 @@
1
1
  'use client'
2
- var version = "5.2.0";
2
+ var version = "5.3.0";
3
3
  var dependencies = {
4
- "@dynamic-labs/sdk-api-core": "0.0.1093",
5
- "@dynamic-labs-sdk/client": "1.25.0",
4
+ "@dynamic-labs/sdk-api-core": "0.0.1118",
5
+ "@dynamic-labs-sdk/client": "1.27.1",
6
6
  "@dynamic-labs-wallet/browser-wallet-client": "1.0.92",
7
7
  "@dynamic-labs-wallet/forward-mpc-client": "1.0.1",
8
8
  "@hcaptcha/react-hcaptcha": "1.4.4",
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@dynamic-labs/sdk-react-core",
3
- "version": "5.2.0",
3
+ "version": "5.3.0",
4
4
  "dependencies": {
5
- "@dynamic-labs/sdk-api-core": "0.0.1093",
6
- "@dynamic-labs-sdk/client": "1.25.0",
5
+ "@dynamic-labs/sdk-api-core": "0.0.1118",
6
+ "@dynamic-labs-sdk/client": "1.27.1",
7
7
  "@dynamic-labs-wallet/browser-wallet-client": "1.0.92",
8
8
  "@dynamic-labs-wallet/forward-mpc-client": "1.0.1",
9
9
  "@hcaptcha/react-hcaptcha": "1.4.4",
@@ -18,18 +18,18 @@
18
18
  "react-i18next": "13.5.0",
19
19
  "react-international-phone": "4.5.0",
20
20
  "yup": "0.32.11",
21
- "@dynamic-labs/assert-package-version": "5.2.0",
22
- "@dynamic-labs/iconic": "5.2.0",
23
- "@dynamic-labs/legacy-client": "5.2.0",
24
- "@dynamic-labs/locale": "5.2.0",
25
- "@dynamic-labs/logger": "5.2.0",
26
- "@dynamic-labs/multi-wallet": "5.2.0",
27
- "@dynamic-labs/rpc-providers": "5.2.0",
28
- "@dynamic-labs/store": "5.2.0",
29
- "@dynamic-labs/types": "5.2.0",
30
- "@dynamic-labs/utils": "5.2.0",
31
- "@dynamic-labs/wallet-book": "5.2.0",
32
- "@dynamic-labs/wallet-connector-core": "5.2.0",
21
+ "@dynamic-labs/assert-package-version": "5.3.0",
22
+ "@dynamic-labs/iconic": "5.3.0",
23
+ "@dynamic-labs/legacy-client": "5.3.0",
24
+ "@dynamic-labs/locale": "5.3.0",
25
+ "@dynamic-labs/logger": "5.3.0",
26
+ "@dynamic-labs/multi-wallet": "5.3.0",
27
+ "@dynamic-labs/rpc-providers": "5.3.0",
28
+ "@dynamic-labs/store": "5.3.0",
29
+ "@dynamic-labs/types": "5.3.0",
30
+ "@dynamic-labs/utils": "5.3.0",
31
+ "@dynamic-labs/wallet-book": "5.3.0",
32
+ "@dynamic-labs/wallet-connector-core": "5.3.0",
33
33
  "eventemitter3": "5.0.1"
34
34
  },
35
35
  "devDependencies": {
package/src/index.d.ts CHANGED
@@ -104,7 +104,7 @@ export { getDefaultColor, getThemeConfig, themesData, } from './lib/context/Them
104
104
  export type {
105
105
  /** @deprecated */
106
106
  ViewType, } from './lib/context/ViewContext';
107
- export type { NotSupportedError, SandboxMaximumThresholdReachedError, NoAccessError, ChainalysisError, EmailAlreadyExistsError, UsernameAlreadyExistsError, SocialAccountAlreadyExistsError, WalletNotDeployedError, WalletUsedError, EmailVerificationError, AccountExistsError, InvalidPhoneNumberError, RateLimitError, } from '@dynamic-labs/utils';
107
+ export type { NotSupportedError, SandboxMaximumThresholdReachedError, NoAccessError, ChainalysisError, EmailAlreadyExistsError, UsernameAlreadyExistsError, SocialAccountAlreadyExistsError, WalletNotDeployedError, WalletUsedError, EmailVerificationError, AccountExistsError, InvalidPhoneNumberError, PhoneNumberAlreadyLinkedError, RateLimitError, } from '@dynamic-labs/utils';
108
108
  export type { WalletConnector, Chain, } from '@dynamic-labs/wallet-connector-core';
109
109
  export type { EvmNetwork, PhoneData, OtpDestination, UserProfile,
110
110
  /** @deprecated use AuthOptions instead */
@@ -0,0 +1,30 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var sdkApiCore = require('@dynamic-labs/sdk-api-core');
7
+ var parseToken = require('../../../../shared/utils/functions/parseToken/parseToken.cjs');
8
+ var getMinAuthToken = require('../getMinAuthToken/getMinAuthToken.cjs');
9
+
10
+ /**
11
+ * Reads the session id (`sid` claim) from the current min JWT claims.
12
+ * Returns `undefined` when no token, decode fails, or the claim is missing.
13
+ */
14
+ const getSessionIdFromMinToken = () => {
15
+ const token = getMinAuthToken.getMinAuthToken();
16
+ if (!token)
17
+ return undefined;
18
+ const payload = parseToken.parseToken(token);
19
+ if (!payload || typeof payload !== 'object')
20
+ return undefined;
21
+ try {
22
+ const minJwt = sdkApiCore.MinifiedDynamicJwtFromJSON(payload);
23
+ return minJwt.sid;
24
+ }
25
+ catch (_a) {
26
+ return undefined;
27
+ }
28
+ };
29
+
30
+ exports.getSessionIdFromMinToken = getSessionIdFromMinToken;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Reads the session id (`sid` claim) from the current min JWT claims.
3
+ * Returns `undefined` when no token, decode fails, or the claim is missing.
4
+ */
5
+ export declare const getSessionIdFromMinToken: () => string | undefined;
@@ -0,0 +1,26 @@
1
+ 'use client'
2
+ import { MinifiedDynamicJwtFromJSON } from '@dynamic-labs/sdk-api-core';
3
+ import { parseToken } from '../../../../shared/utils/functions/parseToken/parseToken.js';
4
+ import { getMinAuthToken } from '../getMinAuthToken/getMinAuthToken.js';
5
+
6
+ /**
7
+ * Reads the session id (`sid` claim) from the current min JWT claims.
8
+ * Returns `undefined` when no token, decode fails, or the claim is missing.
9
+ */
10
+ const getSessionIdFromMinToken = () => {
11
+ const token = getMinAuthToken();
12
+ if (!token)
13
+ return undefined;
14
+ const payload = parseToken(token);
15
+ if (!payload || typeof payload !== 'object')
16
+ return undefined;
17
+ try {
18
+ const minJwt = MinifiedDynamicJwtFromJSON(payload);
19
+ return minJwt.sid;
20
+ }
21
+ catch (_a) {
22
+ return undefined;
23
+ }
24
+ };
25
+
26
+ export { getSessionIdFromMinToken };
@@ -0,0 +1 @@
1
+ export { getSessionIdFromMinToken } from './getSessionIdFromMinToken';
@@ -13,6 +13,7 @@ export { useRefetchProjectSettings } from './projectSettings/useRefetchProjectSe
13
13
  export { isCookieEnabled } from './functions/isCookieEnabled';
14
14
  export { getMinAuthToken } from './functions/getMinAuthToken';
15
15
  export { getSignInCredentialIdFromMinToken } from './functions/getSignInCredentialIdFromMinToken';
16
+ export { getSessionIdFromMinToken } from './functions/getSessionIdFromMinToken';
16
17
  export { getAuthToken } from './functions/getAuthToken';
17
18
  export { getExpiresAt } from './functions/getExpiresAt';
18
19
  export { hasElevatedAccessToken } from './functions/hasElevatedAccessToken';
@@ -34,6 +34,7 @@ var nonce = require('../../store/state/nonce/nonce.cjs');
34
34
  require('@dynamic-labs-wallet/browser-wallet-client');
35
35
  var ApiEndpoint = require('../../config/ApiEndpoint.cjs');
36
36
  var settings = require('../../data/api/settings/settings.cjs');
37
+ var screenTransaction = require('../../data/api/transactions/screenTransaction.cjs');
37
38
  var dynamicContextProps = require('../../store/state/dynamicContextProps/dynamicContextProps.cjs');
38
39
  var primaryWalletId = require('../../store/state/primaryWalletId/primaryWalletId.cjs');
39
40
  var connectedWalletsInfo = require('../../store/state/connectedWalletsInfo/connectedWalletsInfo.cjs');
@@ -302,6 +303,7 @@ const InnerDynamicContextProvider = (props) => {
302
303
  mobileExperience,
303
304
  networkConfigurations: serverNetworkConfigurations,
304
305
  projectSettings,
306
+ transactionScreening: screenTransaction.transactionScreeningService,
305
307
  useMetamaskSdk,
306
308
  walletBook: walletBook$1,
307
309
  walletConnectPreferredChains,
@@ -30,6 +30,7 @@ import { useFetchNonce, useNonce } from '../../store/state/nonce/nonce.js';
30
30
  import '@dynamic-labs-wallet/browser-wallet-client';
31
31
  import ApiEndpoint from '../../config/ApiEndpoint.js';
32
32
  import { sendDynamicProps } from '../../data/api/settings/settings.js';
33
+ import { transactionScreeningService } from '../../data/api/transactions/screenTransaction.js';
33
34
  import { useSyncDynamicContextProps } from '../../store/state/dynamicContextProps/dynamicContextProps.js';
34
35
  import { usePrimaryWalletId } from '../../store/state/primaryWalletId/primaryWalletId.js';
35
36
  import { resetConnectedWalletsInfo } from '../../store/state/connectedWalletsInfo/connectedWalletsInfo.js';
@@ -298,6 +299,7 @@ const InnerDynamicContextProvider = (props) => {
298
299
  mobileExperience,
299
300
  networkConfigurations: serverNetworkConfigurations,
300
301
  projectSettings,
302
+ transactionScreening: transactionScreeningService,
301
303
  useMetamaskSdk,
302
304
  walletBook,
303
305
  walletConnectPreferredChains,
@@ -23,6 +23,7 @@ const mapErrorCodeToTranslation = {
23
23
  [utils.ErrorCode.CREDENTIAL_NOT_ENABLED_FOR_SIGN_IN]: 'dyn_error.credential_not_enabled_for_sign_in',
24
24
  [utils.ErrorCode.SEI_NOT_ENABLED_IN_KEPLR_WALLET]: 'dyn_error.sei_not_enabled_in_keplr_wallet',
25
25
  [utils.RATE_LIMIT_ERROR_CODE]: 'dyn_error.rate_limit_error',
26
+ [utils.TRANSACTION_SCREENING_BLOCKED_ERROR_CODE]: 'dyn_error.transaction_screening_blocked',
26
27
  };
27
28
  /** A hook that listens to the error context and returns a translated value */
28
29
  const useErrorText = () => {
@@ -1,7 +1,7 @@
1
1
  'use client'
2
2
  import { useMemo } from 'react';
3
3
  import { useTranslation } from 'react-i18next';
4
- import { ErrorCode, RATE_LIMIT_ERROR_CODE } from '@dynamic-labs/utils';
4
+ import { ErrorCode, RATE_LIMIT_ERROR_CODE, TRANSACTION_SCREENING_BLOCKED_ERROR_CODE } from '@dynamic-labs/utils';
5
5
  import { useErrorContext } from '../../ErrorContext.js';
6
6
 
7
7
  const mapErrorCodeToTranslation = {
@@ -19,6 +19,7 @@ const mapErrorCodeToTranslation = {
19
19
  [ErrorCode.CREDENTIAL_NOT_ENABLED_FOR_SIGN_IN]: 'dyn_error.credential_not_enabled_for_sign_in',
20
20
  [ErrorCode.SEI_NOT_ENABLED_IN_KEPLR_WALLET]: 'dyn_error.sei_not_enabled_in_keplr_wallet',
21
21
  [RATE_LIMIT_ERROR_CODE]: 'dyn_error.rate_limit_error',
22
+ [TRANSACTION_SCREENING_BLOCKED_ERROR_CODE]: 'dyn_error.transaction_screening_blocked',
22
23
  };
23
24
  /** A hook that listens to the error context and returns a translated value */
24
25
  const useErrorText = () => {
@@ -1 +1,2 @@
1
1
  export * from './blockaid';
2
+ export * from './screenTransaction';
@@ -0,0 +1,107 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var _tslib = require('../../../../../_virtual/_tslib.cjs');
7
+ var sdkApiCore = require('@dynamic-labs/sdk-api-core');
8
+ var utils = require('@dynamic-labs/utils');
9
+ var api = require('../api.cjs');
10
+ require('@dynamic-labs/iconic');
11
+ require('@dynamic-labs/wallet-connector-core');
12
+ require('react');
13
+ require('react/jsx-runtime');
14
+ require('../../../context/ViewContext/ViewContext.cjs');
15
+ var logger = require('../../../shared/logger.cjs');
16
+ require('@dynamic-labs/wallet-book');
17
+ require('../../../utils/constants/colors.cjs');
18
+ require('../../../utils/constants/values.cjs');
19
+ require('../../../shared/consts/index.cjs');
20
+ var dynamicContextProps = require('../../../store/state/dynamicContextProps/dynamicContextProps.cjs');
21
+ require('@dynamic-labs-sdk/client/core');
22
+ require('eventemitter3');
23
+ require('@dynamic-labs-sdk/client');
24
+ require('../../../config/ApiEndpoint.cjs');
25
+ require('@dynamic-labs/multi-wallet');
26
+ require('react-international-phone');
27
+ require('../../../store/state/nonce/nonce.cjs');
28
+ require('@dynamic-labs-wallet/browser-wallet-client');
29
+ require('@dynamic-labs/locale');
30
+ require('../../../store/state/primaryWalletId/primaryWalletId.cjs');
31
+ require('../../../store/state/connectedWalletsInfo/connectedWalletsInfo.cjs');
32
+ require('../../../utils/functions/getWaasAddressTypeLabel/getWaasAddressTypeLabel.cjs');
33
+ require('../../../events/dynamicEvents.cjs');
34
+ var getProjectSettings = require('../../../client/extension/projectSettings/getProjectSettings/getProjectSettings.cjs');
35
+
36
+ // The SDK-internal chain union (shared across connector packages) is decoupled
37
+ // from the wire-level enum; this is the one place that needs to know both.
38
+ // Resolved per call rather than as a module-scope map, as is the block decision
39
+ // at the bottom of this file: reading an enum member at module scope resolves it
40
+ // the moment anything in this barrel's import graph loads, which takes down every
41
+ // spec that partially mocks sdk-api-core before a single test can run.
42
+ const chainEnumFor = (chain) => {
43
+ const chainEnumByScreeningChain = {
44
+ BTC: sdkApiCore.ChainEnum.Btc,
45
+ EVM: sdkApiCore.ChainEnum.Evm,
46
+ SOL: sdkApiCore.ChainEnum.Sol,
47
+ };
48
+ return chainEnumByScreeningChain[chain];
49
+ };
50
+ // A human is waiting on this call: it sits between "send" and the wallet
51
+ // prompt, so an unbounded fetch would stall the prompt indefinitely on a
52
+ // redcoast outage. Matches the enclave hook's 2000 ms wall-clock bound
53
+ // (SANCTIONS_SCREENING_TIMEOUT_MS) so both screening paths degrade alike.
54
+ const SCREENING_TIMEOUT_MS = 2000;
55
+ const isScreeningEnabled = () => {
56
+ var _a, _b, _c;
57
+ return Boolean((_c = (_b = (_a = getProjectSettings.getProjectSettings()) === null || _a === void 0 ? void 0 : _a.sdk) === null || _b === void 0 ? void 0 : _b.featureFlags) === null || _c === void 0 ? void 0 : _c.enableExternalWalletOnTransactionSanctions);
58
+ };
59
+ /**
60
+ * Screens a connected-wallet transaction against the environment's sanctions
61
+ * providers before the wallet is prompted. Best-effort by construction:
62
+ * resolves on allow and on any screening failure (fail-open — signing must
63
+ * never hard-fail on a screening outage), and throws
64
+ * TransactionScreeningBlockedError only on an explicit block decision. A
65
+ * screen that outlives SCREENING_TIMEOUT_MS is one of those failures.
66
+ */
67
+ const screenTransaction = (args) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
68
+ let abortTimer;
69
+ let response;
70
+ try {
71
+ // Reading settings can itself throw (e.g. the client store isn't
72
+ // initialized yet), which must fail open like everything else here.
73
+ if (!isScreeningEnabled())
74
+ return;
75
+ // The signal cancels the in-flight request so a hung endpoint can't tie up
76
+ // the browser's connections to the API; the race is what actually bounds the
77
+ // wait, since a host-supplied FetchService implementation need not honour it.
78
+ const abortController = new AbortController();
79
+ abortTimer = setTimeout(() => abortController.abort(), SCREENING_TIMEOUT_MS);
80
+ response = yield utils.promiseWithTimeout(api.sdkApi().screenTransaction({
81
+ environmentId: dynamicContextProps.getEnvironmentId(),
82
+ screenTransactionRequest: Object.assign(Object.assign({}, args), { chain: chainEnumFor(args.chain) }),
83
+ }, { signal: abortController.signal }), SCREENING_TIMEOUT_MS, { timeoutMessage: 'screenTransaction timed out' });
84
+ }
85
+ catch (_a) {
86
+ // Not the raw error: it can carry internal details (endpoint paths,
87
+ // server-side messages) that shouldn't cross the logger's broadcast
88
+ // boundary to whatever a host app has subscribed to its log events.
89
+ logger.logger.warn('screenTransaction error', {
90
+ message: 'Transaction screening failed',
91
+ });
92
+ return;
93
+ }
94
+ finally {
95
+ clearTimeout(abortTimer);
96
+ }
97
+ if ((response === null || response === void 0 ? void 0 : response.decision) === sdkApiCore.ScreenTransactionResponseDecisionEnum.Block) {
98
+ throw new utils.TransactionScreeningBlockedError(response.blockedAddresses);
99
+ }
100
+ });
101
+ const transactionScreeningService = {
102
+ screenTransaction,
103
+ };
104
+
105
+ exports.SCREENING_TIMEOUT_MS = SCREENING_TIMEOUT_MS;
106
+ exports.screenTransaction = screenTransaction;
107
+ exports.transactionScreeningService = transactionScreeningService;
@@ -0,0 +1,12 @@
1
+ import { ScreenTransactionArgs, TransactionScreeningService } from '@dynamic-labs/types';
2
+ export declare const SCREENING_TIMEOUT_MS = 2000;
3
+ /**
4
+ * Screens a connected-wallet transaction against the environment's sanctions
5
+ * providers before the wallet is prompted. Best-effort by construction:
6
+ * resolves on allow and on any screening failure (fail-open — signing must
7
+ * never hard-fail on a screening outage), and throws
8
+ * TransactionScreeningBlockedError only on an explicit block decision. A
9
+ * screen that outlives SCREENING_TIMEOUT_MS is one of those failures.
10
+ */
11
+ export declare const screenTransaction: (args: ScreenTransactionArgs) => Promise<void>;
12
+ export declare const transactionScreeningService: TransactionScreeningService;
@@ -0,0 +1,101 @@
1
+ 'use client'
2
+ import { __awaiter } from '../../../../../_virtual/_tslib.js';
3
+ import { ScreenTransactionResponseDecisionEnum, ChainEnum } from '@dynamic-labs/sdk-api-core';
4
+ import { promiseWithTimeout, TransactionScreeningBlockedError } from '@dynamic-labs/utils';
5
+ import { sdkApi } from '../api.js';
6
+ import '@dynamic-labs/iconic';
7
+ import '@dynamic-labs/wallet-connector-core';
8
+ import 'react';
9
+ import 'react/jsx-runtime';
10
+ import '../../../context/ViewContext/ViewContext.js';
11
+ import { logger } from '../../../shared/logger.js';
12
+ import '@dynamic-labs/wallet-book';
13
+ import '../../../utils/constants/colors.js';
14
+ import '../../../utils/constants/values.js';
15
+ import '../../../shared/consts/index.js';
16
+ import { getEnvironmentId } from '../../../store/state/dynamicContextProps/dynamicContextProps.js';
17
+ import '@dynamic-labs-sdk/client/core';
18
+ import 'eventemitter3';
19
+ import '@dynamic-labs-sdk/client';
20
+ import '../../../config/ApiEndpoint.js';
21
+ import '@dynamic-labs/multi-wallet';
22
+ import 'react-international-phone';
23
+ import '../../../store/state/nonce/nonce.js';
24
+ import '@dynamic-labs-wallet/browser-wallet-client';
25
+ import '@dynamic-labs/locale';
26
+ import '../../../store/state/primaryWalletId/primaryWalletId.js';
27
+ import '../../../store/state/connectedWalletsInfo/connectedWalletsInfo.js';
28
+ import '../../../utils/functions/getWaasAddressTypeLabel/getWaasAddressTypeLabel.js';
29
+ import '../../../events/dynamicEvents.js';
30
+ import { getProjectSettings } from '../../../client/extension/projectSettings/getProjectSettings/getProjectSettings.js';
31
+
32
+ // The SDK-internal chain union (shared across connector packages) is decoupled
33
+ // from the wire-level enum; this is the one place that needs to know both.
34
+ // Resolved per call rather than as a module-scope map, as is the block decision
35
+ // at the bottom of this file: reading an enum member at module scope resolves it
36
+ // the moment anything in this barrel's import graph loads, which takes down every
37
+ // spec that partially mocks sdk-api-core before a single test can run.
38
+ const chainEnumFor = (chain) => {
39
+ const chainEnumByScreeningChain = {
40
+ BTC: ChainEnum.Btc,
41
+ EVM: ChainEnum.Evm,
42
+ SOL: ChainEnum.Sol,
43
+ };
44
+ return chainEnumByScreeningChain[chain];
45
+ };
46
+ // A human is waiting on this call: it sits between "send" and the wallet
47
+ // prompt, so an unbounded fetch would stall the prompt indefinitely on a
48
+ // redcoast outage. Matches the enclave hook's 2000 ms wall-clock bound
49
+ // (SANCTIONS_SCREENING_TIMEOUT_MS) so both screening paths degrade alike.
50
+ const SCREENING_TIMEOUT_MS = 2000;
51
+ const isScreeningEnabled = () => {
52
+ var _a, _b, _c;
53
+ return Boolean((_c = (_b = (_a = getProjectSettings()) === null || _a === void 0 ? void 0 : _a.sdk) === null || _b === void 0 ? void 0 : _b.featureFlags) === null || _c === void 0 ? void 0 : _c.enableExternalWalletOnTransactionSanctions);
54
+ };
55
+ /**
56
+ * Screens a connected-wallet transaction against the environment's sanctions
57
+ * providers before the wallet is prompted. Best-effort by construction:
58
+ * resolves on allow and on any screening failure (fail-open — signing must
59
+ * never hard-fail on a screening outage), and throws
60
+ * TransactionScreeningBlockedError only on an explicit block decision. A
61
+ * screen that outlives SCREENING_TIMEOUT_MS is one of those failures.
62
+ */
63
+ const screenTransaction = (args) => __awaiter(void 0, void 0, void 0, function* () {
64
+ let abortTimer;
65
+ let response;
66
+ try {
67
+ // Reading settings can itself throw (e.g. the client store isn't
68
+ // initialized yet), which must fail open like everything else here.
69
+ if (!isScreeningEnabled())
70
+ return;
71
+ // The signal cancels the in-flight request so a hung endpoint can't tie up
72
+ // the browser's connections to the API; the race is what actually bounds the
73
+ // wait, since a host-supplied FetchService implementation need not honour it.
74
+ const abortController = new AbortController();
75
+ abortTimer = setTimeout(() => abortController.abort(), SCREENING_TIMEOUT_MS);
76
+ response = yield promiseWithTimeout(sdkApi().screenTransaction({
77
+ environmentId: getEnvironmentId(),
78
+ screenTransactionRequest: Object.assign(Object.assign({}, args), { chain: chainEnumFor(args.chain) }),
79
+ }, { signal: abortController.signal }), SCREENING_TIMEOUT_MS, { timeoutMessage: 'screenTransaction timed out' });
80
+ }
81
+ catch (_a) {
82
+ // Not the raw error: it can carry internal details (endpoint paths,
83
+ // server-side messages) that shouldn't cross the logger's broadcast
84
+ // boundary to whatever a host app has subscribed to its log events.
85
+ logger.warn('screenTransaction error', {
86
+ message: 'Transaction screening failed',
87
+ });
88
+ return;
89
+ }
90
+ finally {
91
+ clearTimeout(abortTimer);
92
+ }
93
+ if ((response === null || response === void 0 ? void 0 : response.decision) === ScreenTransactionResponseDecisionEnum.Block) {
94
+ throw new TransactionScreeningBlockedError(response.blockedAddresses);
95
+ }
96
+ });
97
+ const transactionScreeningService = {
98
+ screenTransaction,
99
+ };
100
+
101
+ export { SCREENING_TIMEOUT_MS, screenTransaction, transactionScreeningService };
@@ -59,6 +59,9 @@ const updateUserProfileFields = (environmentId, fields) => _tslib.__awaiter(void
59
59
  else if (error.code === 'too_many_verification_attempts') {
60
60
  throw new utils$1.TooManyEmailVerificationsError(error.error, error.code);
61
61
  }
62
+ else if (error.code === 'user_has_already_account_with_phone_number') {
63
+ throw new utils$1.PhoneNumberAlreadyLinkedError(error.error, error.code);
64
+ }
62
65
  else if (error.code === 'invalid_phone' ||
63
66
  error.code === 'invalid_sms_verification') {
64
67
  throw new utils$1.InvalidPhoneNumberError(error.error, error.code);
@@ -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 { EmailAlreadyExistsError, CustomFieldNotUniqueError, UsernameAlreadyExistsError, TooManyEmailVerificationsError, InvalidPhoneNumberError } from '@dynamic-labs/utils';
5
+ import { EmailAlreadyExistsError, CustomFieldNotUniqueError, UsernameAlreadyExistsError, TooManyEmailVerificationsError, PhoneNumberAlreadyLinkedError, InvalidPhoneNumberError } from '@dynamic-labs/utils';
6
6
  import '@dynamic-labs-sdk/client/core';
7
7
  import 'react';
8
8
  import 'eventemitter3';
@@ -55,6 +55,9 @@ const updateUserProfileFields = (environmentId, fields) => __awaiter(void 0, voi
55
55
  else if (error.code === 'too_many_verification_attempts') {
56
56
  throw new TooManyEmailVerificationsError(error.error, error.code);
57
57
  }
58
+ else if (error.code === 'user_has_already_account_with_phone_number') {
59
+ throw new PhoneNumberAlreadyLinkedError(error.error, error.code);
60
+ }
58
61
  else if (error.code === 'invalid_phone' ||
59
62
  error.code === 'invalid_sms_verification') {
60
63
  throw new InvalidPhoneNumberError(error.error, error.code);
@@ -25,8 +25,8 @@ require('react-international-phone');
25
25
  require('../../../store/state/nonce/nonce.cjs');
26
26
  require('@dynamic-labs-wallet/browser-wallet-client');
27
27
  require('@dynamic-labs/locale');
28
- var wallets = require('../../../data/api/wallets/wallets.cjs');
29
28
  var dynamicContextProps = require('../../../store/state/dynamicContextProps/dynamicContextProps.cjs');
29
+ var wallets = require('../../../data/api/wallets/wallets.cjs');
30
30
  var primaryWalletId = require('../../../store/state/primaryWalletId/primaryWalletId.cjs');
31
31
  require('../../../store/state/connectedWalletsInfo/connectedWalletsInfo.cjs');
32
32
  require('../getWaasAddressTypeLabel/getWaasAddressTypeLabel.cjs');
@@ -21,8 +21,8 @@ import 'react-international-phone';
21
21
  import '../../../store/state/nonce/nonce.js';
22
22
  import '@dynamic-labs-wallet/browser-wallet-client';
23
23
  import '@dynamic-labs/locale';
24
- import { storeSelectedWallet } from '../../../data/api/wallets/wallets.js';
25
24
  import { getEnvironmentId } from '../../../store/state/dynamicContextProps/dynamicContextProps.js';
25
+ import { storeSelectedWallet } from '../../../data/api/wallets/wallets.js';
26
26
  import { setPrimaryWalletId } from '../../../store/state/primaryWalletId/primaryWalletId.js';
27
27
  import '../../../store/state/connectedWalletsInfo/connectedWalletsInfo.js';
28
28
  import '../getWaasAddressTypeLabel/getWaasAddressTypeLabel.js';
@@ -1,5 +1,5 @@
1
1
  import { ProjectSettings } from '@dynamic-labs/sdk-api-core';
2
- import { type MobileExperience, type CoinbaseWalletPreference, type NetworkConfigurationMap, type WalletUiUtils } from '@dynamic-labs/types';
2
+ import { type MobileExperience, type CoinbaseWalletPreference, type NetworkConfigurationMap, type TransactionScreeningService, type WalletUiUtils } from '@dynamic-labs/types';
3
3
  import { DeepLinkVariant, InternalWalletConnector, WalletConnectorExtension, WalletConnectorsMethod } from '@dynamic-labs/wallet-connector-core';
4
4
  import { WalletBookSchema } from '@dynamic-labs/wallet-book';
5
5
  export type WalletConnectorProps = {
@@ -11,6 +11,7 @@ export type WalletConnectorProps = {
11
11
  mobileExperience?: MobileExperience;
12
12
  networkConfigurations: NetworkConfigurationMap | undefined;
13
13
  projectSettings: ProjectSettings | undefined;
14
+ transactionScreening?: TransactionScreeningService;
14
15
  walletBook: WalletBookSchema;
15
16
  walletConnectPreferredChains?: `eip155:${number}`[];
16
17
  walletConnectorsProp?: WalletConnectorsMethod[];
@@ -26,8 +26,8 @@ require('react-international-phone');
26
26
  require('../../../store/state/nonce/nonce.cjs');
27
27
  require('@dynamic-labs-wallet/browser-wallet-client');
28
28
  require('@dynamic-labs/locale');
29
- var user = require('../../../data/api/user/user.cjs');
30
29
  var dynamicContextProps = require('../../../store/state/dynamicContextProps/dynamicContextProps.cjs');
30
+ var user = require('../../../data/api/user/user.cjs');
31
31
  require('../../../store/state/primaryWalletId/primaryWalletId.cjs');
32
32
  require('../../../store/state/connectedWalletsInfo/connectedWalletsInfo.cjs');
33
33
  require('../../functions/getWaasAddressTypeLabel/getWaasAddressTypeLabel.cjs');
@@ -22,8 +22,8 @@ import 'react-international-phone';
22
22
  import '../../../store/state/nonce/nonce.js';
23
23
  import '@dynamic-labs-wallet/browser-wallet-client';
24
24
  import '@dynamic-labs/locale';
25
- import { refreshUserJwt } from '../../../data/api/user/user.js';
26
25
  import { getEnvironmentId } from '../../../store/state/dynamicContextProps/dynamicContextProps.js';
26
+ import { refreshUserJwt } from '../../../data/api/user/user.js';
27
27
  import '../../../store/state/primaryWalletId/primaryWalletId.js';
28
28
  import '../../../store/state/connectedWalletsInfo/connectedWalletsInfo.js';
29
29
  import '../../functions/getWaasAddressTypeLabel/getWaasAddressTypeLabel.js';
@@ -32,6 +32,7 @@ require('../../functions/getWaasAddressTypeLabel/getWaasAddressTypeLabel.cjs');
32
32
  require('../../../events/dynamicEvents.cjs');
33
33
  var useOnboardingCompleteUser = require('../../../client/extension/user/useOnboardingCompleteUser/useOnboardingCompleteUser.cjs');
34
34
  var useProjectSettings = require('../../../client/extension/projectSettings/useProjectSettings/useProjectSettings.cjs');
35
+ var getSessionIdFromMinToken = require('../../../client/extension/functions/getSessionIdFromMinToken/getSessionIdFromMinToken.cjs');
35
36
  require('../../../context/DynamicContext/useDynamicContext/useDynamicContext.cjs');
36
37
  var useInternalDynamicContext = require('../../../context/DynamicContext/useDynamicContext/useInternalDynamicContext/useInternalDynamicContext.cjs');
37
38
  var LoadingContext = require('../../../context/LoadingContext/LoadingContext.cjs');
@@ -292,19 +293,25 @@ const useSyncDynamicWaas = () => {
292
293
  // Initialize waas iframe when user is authenticated
293
294
  // This handles both page reload (user already authenticated) and fresh authentication
294
295
  React.useEffect(() => {
296
+ const tokenSessionId = getSessionIdFromMinToken.getSessionIdFromMinToken();
297
+ const currentSessionId = tokenSessionId !== null && tokenSessionId !== void 0 ? tokenSessionId : user === null || user === void 0 ? void 0 : user.sessionId;
295
298
  // handle logout case where user is logged out but session id is still valid
296
- if (sessionIdRef.current && !(user === null || user === void 0 ? void 0 : user.sessionId)) {
299
+ if (sessionIdRef.current && !currentSessionId) {
297
300
  sessionIdRef.current = undefined;
298
301
  hasWaasInitializedRef.current = false;
299
302
  initializingWaasRef.current = false;
300
303
  clearRecoveredWallets();
301
304
  }
302
- if (shouldInitializeWaas && (user === null || user === void 0 ? void 0 : user.sessionId) && isSdkReadyForWaas()) {
303
- const { sessionId, id: userId } = user;
305
+ if (shouldInitializeWaas &&
306
+ currentSessionId &&
307
+ (user === null || user === void 0 ? void 0 : user.sessionId) &&
308
+ isSdkReadyForWaas()) {
309
+ const { id: userId } = user;
304
310
  const shouldInitialize = !initializingWaasRef.current &&
305
- (!hasWaasInitializedRef.current || sessionIdRef.current !== sessionId);
311
+ (!hasWaasInitializedRef.current ||
312
+ sessionIdRef.current !== currentSessionId);
306
313
  if (shouldInitialize) {
307
- const isSessionIdChanged = sessionIdRef.current !== sessionId;
314
+ const isSessionIdChanged = sessionIdRef.current !== currentSessionId;
308
315
  // A swap from a prior session (e.g. step-up reauth) must rebuild the
309
316
  // WaaS client so the iframe re-auths with the new session instead of
310
317
  // 401-ing on the stale cached one. First init (no prior session) keeps
@@ -318,8 +325,11 @@ const useSyncDynamicWaas = () => {
318
325
  initializeWaas({ forceClientRebuild })
319
326
  .then(() => {
320
327
  logger.logger.debug('[useSyncDynamicWaas] waas initialized');
328
+ // Persist the session id this init actually ran with so a token
329
+ // rotation that happened mid-flight is still detected on the next
330
+ // effect run and triggers a force-rebuild.
321
331
  hasWaasInitializedRef.current = true;
322
- sessionIdRef.current = sessionId;
332
+ sessionIdRef.current = currentSessionId;
323
333
  // Host-observed time to get the WaaS iframe/client ready. Ships to
324
334
  // Datadog (sliced by @version + environmentId) as the host-side
325
335
  // companion to the iframe app's `waas_iframe_*` timing — used to
@@ -334,13 +344,14 @@ const useSyncDynamicWaas = () => {
334
344
  .catch((error) => {
335
345
  logger.logger.warn('[useSyncDynamicWaas] Error initializing waas', {
336
346
  error,
337
- sessionId,
347
+ sessionId: currentSessionId,
338
348
  userId,
339
349
  });
340
350
  logger.logger.instrument('WaaS host init failed', {
341
351
  environmentId,
342
352
  key: 'waas_host_init_failed',
343
353
  reason: error instanceof Error ? error.message : String(error),
354
+ sessionId: currentSessionId,
344
355
  time: Date.now() - initStartedAt,
345
356
  userId,
346
357
  });
@@ -28,6 +28,7 @@ import '../../functions/getWaasAddressTypeLabel/getWaasAddressTypeLabel.js';
28
28
  import '../../../events/dynamicEvents.js';
29
29
  import { useOnboardingCompleteUser } from '../../../client/extension/user/useOnboardingCompleteUser/useOnboardingCompleteUser.js';
30
30
  import { useProjectSettings } from '../../../client/extension/projectSettings/useProjectSettings/useProjectSettings.js';
31
+ import { getSessionIdFromMinToken } from '../../../client/extension/functions/getSessionIdFromMinToken/getSessionIdFromMinToken.js';
31
32
  import '../../../context/DynamicContext/useDynamicContext/useDynamicContext.js';
32
33
  import { useInternalDynamicContext } from '../../../context/DynamicContext/useDynamicContext/useInternalDynamicContext/useInternalDynamicContext.js';
33
34
  import { useLoadingContext } from '../../../context/LoadingContext/LoadingContext.js';
@@ -288,19 +289,25 @@ const useSyncDynamicWaas = () => {
288
289
  // Initialize waas iframe when user is authenticated
289
290
  // This handles both page reload (user already authenticated) and fresh authentication
290
291
  useEffect(() => {
292
+ const tokenSessionId = getSessionIdFromMinToken();
293
+ const currentSessionId = tokenSessionId !== null && tokenSessionId !== void 0 ? tokenSessionId : user === null || user === void 0 ? void 0 : user.sessionId;
291
294
  // handle logout case where user is logged out but session id is still valid
292
- if (sessionIdRef.current && !(user === null || user === void 0 ? void 0 : user.sessionId)) {
295
+ if (sessionIdRef.current && !currentSessionId) {
293
296
  sessionIdRef.current = undefined;
294
297
  hasWaasInitializedRef.current = false;
295
298
  initializingWaasRef.current = false;
296
299
  clearRecoveredWallets();
297
300
  }
298
- if (shouldInitializeWaas && (user === null || user === void 0 ? void 0 : user.sessionId) && isSdkReadyForWaas()) {
299
- const { sessionId, id: userId } = user;
301
+ if (shouldInitializeWaas &&
302
+ currentSessionId &&
303
+ (user === null || user === void 0 ? void 0 : user.sessionId) &&
304
+ isSdkReadyForWaas()) {
305
+ const { id: userId } = user;
300
306
  const shouldInitialize = !initializingWaasRef.current &&
301
- (!hasWaasInitializedRef.current || sessionIdRef.current !== sessionId);
307
+ (!hasWaasInitializedRef.current ||
308
+ sessionIdRef.current !== currentSessionId);
302
309
  if (shouldInitialize) {
303
- const isSessionIdChanged = sessionIdRef.current !== sessionId;
310
+ const isSessionIdChanged = sessionIdRef.current !== currentSessionId;
304
311
  // A swap from a prior session (e.g. step-up reauth) must rebuild the
305
312
  // WaaS client so the iframe re-auths with the new session instead of
306
313
  // 401-ing on the stale cached one. First init (no prior session) keeps
@@ -314,8 +321,11 @@ const useSyncDynamicWaas = () => {
314
321
  initializeWaas({ forceClientRebuild })
315
322
  .then(() => {
316
323
  logger.debug('[useSyncDynamicWaas] waas initialized');
324
+ // Persist the session id this init actually ran with so a token
325
+ // rotation that happened mid-flight is still detected on the next
326
+ // effect run and triggers a force-rebuild.
317
327
  hasWaasInitializedRef.current = true;
318
- sessionIdRef.current = sessionId;
328
+ sessionIdRef.current = currentSessionId;
319
329
  // Host-observed time to get the WaaS iframe/client ready. Ships to
320
330
  // Datadog (sliced by @version + environmentId) as the host-side
321
331
  // companion to the iframe app's `waas_iframe_*` timing — used to
@@ -330,13 +340,14 @@ const useSyncDynamicWaas = () => {
330
340
  .catch((error) => {
331
341
  logger.warn('[useSyncDynamicWaas] Error initializing waas', {
332
342
  error,
333
- sessionId,
343
+ sessionId: currentSessionId,
334
344
  userId,
335
345
  });
336
346
  logger.instrument('WaaS host init failed', {
337
347
  environmentId,
338
348
  key: 'waas_host_init_failed',
339
349
  reason: error instanceof Error ? error.message : String(error),
350
+ sessionId: currentSessionId,
340
351
  time: Date.now() - initStartedAt,
341
352
  userId,
342
353
  });
@@ -73,6 +73,7 @@ const useUserAuth = ({ authMethod, }) => {
73
73
  error instanceof utils.CustomFieldNotUniqueError ||
74
74
  error instanceof utils.UsernameAlreadyExistsError ||
75
75
  error instanceof utils.TooManyEmailVerificationsError ||
76
+ error instanceof utils.PhoneNumberAlreadyLinkedError ||
76
77
  error instanceof utils.InvalidPhoneNumberError)
77
78
  throw error;
78
79
  if (error instanceof utils.NoAccessError) {
@@ -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, ErrorCode, DynamicError, sleep } from '@dynamic-labs/utils';
6
+ import { EmailAlreadyExistsError, CustomFieldNotUniqueError, UsernameAlreadyExistsError, TooManyEmailVerificationsError, PhoneNumberAlreadyLinkedError, InvalidPhoneNumberError, NoAccessError, AccountExistsError, SandboxMaximumThresholdReachedError, UserHasAccountWithEmailError, ErrorCode, DynamicError, sleep } from '@dynamic-labs/utils';
7
7
  import '@dynamic-labs-sdk/client/core';
8
8
  import 'eventemitter3';
9
9
  import '../../../config/ApiEndpoint.js';
@@ -69,6 +69,7 @@ const useUserAuth = ({ authMethod, }) => {
69
69
  error instanceof CustomFieldNotUniqueError ||
70
70
  error instanceof UsernameAlreadyExistsError ||
71
71
  error instanceof TooManyEmailVerificationsError ||
72
+ error instanceof PhoneNumberAlreadyLinkedError ||
72
73
  error instanceof InvalidPhoneNumberError)
73
74
  throw error;
74
75
  if (error instanceof NoAccessError) {
@@ -136,6 +136,9 @@ const useUserDataForm = ({ onSubmit, onError, userProfile, shouldEnforcePolicies
136
136
  else if (e instanceof utils.UsernameAlreadyExistsError) {
137
137
  formikHelper.setErrors({ username: 'Username already exists' });
138
138
  }
139
+ else if (e instanceof utils.PhoneNumberAlreadyLinkedError) {
140
+ formikHelper.setErrors({ phoneNumber: e.message });
141
+ }
139
142
  else if (e instanceof utils.InvalidPhoneNumberError) {
140
143
  formikHelper.setErrors({ phoneNumber: e.message });
141
144
  }
@@ -3,7 +3,7 @@ import { __awaiter } from '../../../../../_virtual/_tslib.js';
3
3
  import { useState, useMemo, useCallback } from 'react';
4
4
  import { object } from 'yup';
5
5
  import { KycFieldType, CustomFieldType } from '@dynamic-labs/sdk-api-core';
6
- import { DynamicError, EmailAlreadyExistsError, CustomFieldNotUniqueError, TooManyEmailVerificationsError, UsernameAlreadyExistsError, InvalidPhoneNumberError } from '@dynamic-labs/utils';
6
+ import { DynamicError, EmailAlreadyExistsError, CustomFieldNotUniqueError, TooManyEmailVerificationsError, UsernameAlreadyExistsError, PhoneNumberAlreadyLinkedError, InvalidPhoneNumberError } from '@dynamic-labs/utils';
7
7
  import { useMockContext } from '../../../context/MockContext/MockContext.js';
8
8
  import '@dynamic-labs/iconic';
9
9
  import '@dynamic-labs/wallet-connector-core';
@@ -132,6 +132,9 @@ const useUserDataForm = ({ onSubmit, onError, userProfile, shouldEnforcePolicies
132
132
  else if (e instanceof UsernameAlreadyExistsError) {
133
133
  formikHelper.setErrors({ username: 'Username already exists' });
134
134
  }
135
+ else if (e instanceof PhoneNumberAlreadyLinkedError) {
136
+ formikHelper.setErrors({ phoneNumber: e.message });
137
+ }
135
138
  else if (e instanceof InvalidPhoneNumberError) {
136
139
  formikHelper.setErrors({ phoneNumber: e.message });
137
140
  }
@@ -35,8 +35,8 @@ require('eventemitter3');
35
35
  require('@dynamic-labs-sdk/client');
36
36
  require('../../config/ApiEndpoint.cjs');
37
37
  require('@dynamic-labs/locale');
38
- var user = require('../../data/api/user/user.cjs');
39
38
  require('../../store/state/dynamicContextProps/dynamicContextProps.cjs');
39
+ var user = require('../../data/api/user/user.cjs');
40
40
  require('../../store/state/primaryWalletId/primaryWalletId.cjs');
41
41
  require('../../store/state/connectedWalletsInfo/connectedWalletsInfo.cjs');
42
42
  require('../../utils/functions/getWaasAddressTypeLabel/getWaasAddressTypeLabel.cjs');
@@ -31,8 +31,8 @@ import 'eventemitter3';
31
31
  import '@dynamic-labs-sdk/client';
32
32
  import '../../config/ApiEndpoint.js';
33
33
  import '@dynamic-labs/locale';
34
- import { mergeUserAccounts } from '../../data/api/user/user.js';
35
34
  import '../../store/state/dynamicContextProps/dynamicContextProps.js';
35
+ import { mergeUserAccounts } from '../../data/api/user/user.js';
36
36
  import '../../store/state/primaryWalletId/primaryWalletId.js';
37
37
  import '../../store/state/connectedWalletsInfo/connectedWalletsInfo.js';
38
38
  import '../../utils/functions/getWaasAddressTypeLabel/getWaasAddressTypeLabel.js';