@dynamic-labs/sdk-react-core 4.96.0 → 4.96.1

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 CHANGED
@@ -1,4 +1,12 @@
1
1
 
2
+ ### [4.96.1](https://github.com/dynamic-labs/dynamic-auth/compare/v4.96.0...v4.96.1) (2026-08-10)
3
+
4
+
5
+ ### Bug Fixes
6
+
7
+ * security updates ([#12151](https://github.com/dynamic-labs/dynamic-auth/issues/12151)) ([faf22dd](https://github.com/dynamic-labs/dynamic-auth/commit/faf22dda11f5cfd888e860bd05731604ee19b51d))
8
+ * **sdk-react-core:** avoid spurious WaaS client rebuild on transient user sessionId churn ([#12183](https://github.com/dynamic-labs/dynamic-auth/issues/12183)) ([6248f74](https://github.com/dynamic-labs/dynamic-auth/commit/6248f7498fbd279031a4e9176fa707bca360f0f1))
9
+
2
10
  ## [4.96.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.95.2...v4.96.0) (2026-08-03)
3
11
 
4
12
 
package/package.cjs CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
- var version = "4.96.0";
6
+ var version = "4.96.1";
7
7
  var dependencies = {
8
8
  "@dynamic-labs/sdk-api-core": "0.0.1093",
9
9
  "@dynamic-labs-sdk/client": "1.20.0",
package/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  'use client'
2
- var version = "4.96.0";
2
+ var version = "4.96.1";
3
3
  var dependencies = {
4
4
  "@dynamic-labs/sdk-api-core": "0.0.1093",
5
5
  "@dynamic-labs-sdk/client": "1.20.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynamic-labs/sdk-react-core",
3
- "version": "4.96.0",
3
+ "version": "4.96.1",
4
4
  "dependencies": {
5
5
  "@dynamic-labs/sdk-api-core": "0.0.1093",
6
6
  "@dynamic-labs-sdk/client": "1.20.0",
@@ -18,17 +18,17 @@
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": "4.96.0",
22
- "@dynamic-labs/iconic": "4.96.0",
23
- "@dynamic-labs/locale": "4.96.0",
24
- "@dynamic-labs/logger": "4.96.0",
25
- "@dynamic-labs/multi-wallet": "4.96.0",
26
- "@dynamic-labs/rpc-providers": "4.96.0",
27
- "@dynamic-labs/store": "4.96.0",
28
- "@dynamic-labs/types": "4.96.0",
29
- "@dynamic-labs/utils": "4.96.0",
30
- "@dynamic-labs/wallet-book": "4.96.0",
31
- "@dynamic-labs/wallet-connector-core": "4.96.0",
21
+ "@dynamic-labs/assert-package-version": "4.96.1",
22
+ "@dynamic-labs/iconic": "4.96.1",
23
+ "@dynamic-labs/locale": "4.96.1",
24
+ "@dynamic-labs/logger": "4.96.1",
25
+ "@dynamic-labs/multi-wallet": "4.96.1",
26
+ "@dynamic-labs/rpc-providers": "4.96.1",
27
+ "@dynamic-labs/store": "4.96.1",
28
+ "@dynamic-labs/types": "4.96.1",
29
+ "@dynamic-labs/utils": "4.96.1",
30
+ "@dynamic-labs/wallet-book": "4.96.1",
31
+ "@dynamic-labs/wallet-connector-core": "4.96.1",
32
32
  "eventemitter3": "5.0.1"
33
33
  },
34
34
  "devDependencies": {
@@ -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';
@@ -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');
@@ -219,19 +220,22 @@ const useSyncDynamicWaas = () => {
219
220
  // Initialize waas iframe when user is authenticated
220
221
  // This handles both page reload (user already authenticated) and fresh authentication
221
222
  React.useEffect(() => {
223
+ const tokenSessionId = getSessionIdFromMinToken.getSessionIdFromMinToken();
224
+ const currentSessionId = tokenSessionId !== null && tokenSessionId !== void 0 ? tokenSessionId : user === null || user === void 0 ? void 0 : user.sessionId;
222
225
  // handle logout case where user is logged out but session id is still valid
223
- if (sessionIdRef.current && !(user === null || user === void 0 ? void 0 : user.sessionId)) {
226
+ if (sessionIdRef.current && !currentSessionId) {
224
227
  sessionIdRef.current = undefined;
225
228
  hasWaasInitializedRef.current = false;
226
229
  initializingWaasRef.current = false;
227
230
  clearRecoveredWallets();
228
231
  }
229
- if (shouldInitializeWaas && (user === null || user === void 0 ? void 0 : user.sessionId)) {
230
- const { sessionId, id: userId } = user;
232
+ if (shouldInitializeWaas && currentSessionId && (user === null || user === void 0 ? void 0 : user.sessionId)) {
233
+ const { id: userId } = user;
231
234
  const shouldInitialize = !initializingWaasRef.current &&
232
- (!hasWaasInitializedRef.current || sessionIdRef.current !== sessionId);
235
+ (!hasWaasInitializedRef.current ||
236
+ sessionIdRef.current !== currentSessionId);
233
237
  if (shouldInitialize) {
234
- const isSessionIdChanged = sessionIdRef.current !== sessionId;
238
+ const isSessionIdChanged = sessionIdRef.current !== currentSessionId;
235
239
  // A swap from a prior session (e.g. step-up reauth) must rebuild the
236
240
  // WaaS client so the iframe re-auths with the new session instead of
237
241
  // 401-ing on the stale cached one. First init (no prior session) keeps
@@ -245,8 +249,11 @@ const useSyncDynamicWaas = () => {
245
249
  initializeWaas({ forceClientRebuild })
246
250
  .then(() => {
247
251
  logger.logger.debug('[useSyncDynamicWaas] waas initialized');
252
+ // Persist the session id this init actually ran with so a token
253
+ // rotation that happened mid-flight is still detected on the next
254
+ // effect run and triggers a force-rebuild.
248
255
  hasWaasInitializedRef.current = true;
249
- sessionIdRef.current = sessionId;
256
+ sessionIdRef.current = currentSessionId;
250
257
  // Host-observed time to get the WaaS iframe/client ready. Ships to
251
258
  // Datadog (sliced by @version + environmentId) as the host-side
252
259
  // companion to the iframe app's `waas_iframe_*` timing — used to
@@ -261,13 +268,14 @@ const useSyncDynamicWaas = () => {
261
268
  .catch((error) => {
262
269
  logger.logger.warn('[useSyncDynamicWaas] Error initializing waas', {
263
270
  error,
264
- sessionId,
271
+ sessionId: currentSessionId,
265
272
  userId,
266
273
  });
267
274
  logger.logger.instrument('WaaS host init failed', {
268
275
  environmentId,
269
276
  key: 'waas_host_init_failed',
270
277
  reason: error instanceof Error ? error.message : String(error),
278
+ sessionId: currentSessionId,
271
279
  time: Date.now() - initStartedAt,
272
280
  userId,
273
281
  });
@@ -277,7 +285,13 @@ const useSyncDynamicWaas = () => {
277
285
  });
278
286
  }
279
287
  }
280
- }, [initializeWaas, shouldInitializeWaas, user]);
288
+ }, [
289
+ initializeWaas,
290
+ shouldInitializeWaas,
291
+ user,
292
+ environmentId,
293
+ clearRecoveredWallets,
294
+ ]);
281
295
  React.useEffect(() => {
282
296
  if (shouldCreateWallets()) {
283
297
  handleWalletCreation();
@@ -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';
@@ -215,19 +216,22 @@ const useSyncDynamicWaas = () => {
215
216
  // Initialize waas iframe when user is authenticated
216
217
  // This handles both page reload (user already authenticated) and fresh authentication
217
218
  useEffect(() => {
219
+ const tokenSessionId = getSessionIdFromMinToken();
220
+ const currentSessionId = tokenSessionId !== null && tokenSessionId !== void 0 ? tokenSessionId : user === null || user === void 0 ? void 0 : user.sessionId;
218
221
  // handle logout case where user is logged out but session id is still valid
219
- if (sessionIdRef.current && !(user === null || user === void 0 ? void 0 : user.sessionId)) {
222
+ if (sessionIdRef.current && !currentSessionId) {
220
223
  sessionIdRef.current = undefined;
221
224
  hasWaasInitializedRef.current = false;
222
225
  initializingWaasRef.current = false;
223
226
  clearRecoveredWallets();
224
227
  }
225
- if (shouldInitializeWaas && (user === null || user === void 0 ? void 0 : user.sessionId)) {
226
- const { sessionId, id: userId } = user;
228
+ if (shouldInitializeWaas && currentSessionId && (user === null || user === void 0 ? void 0 : user.sessionId)) {
229
+ const { id: userId } = user;
227
230
  const shouldInitialize = !initializingWaasRef.current &&
228
- (!hasWaasInitializedRef.current || sessionIdRef.current !== sessionId);
231
+ (!hasWaasInitializedRef.current ||
232
+ sessionIdRef.current !== currentSessionId);
229
233
  if (shouldInitialize) {
230
- const isSessionIdChanged = sessionIdRef.current !== sessionId;
234
+ const isSessionIdChanged = sessionIdRef.current !== currentSessionId;
231
235
  // A swap from a prior session (e.g. step-up reauth) must rebuild the
232
236
  // WaaS client so the iframe re-auths with the new session instead of
233
237
  // 401-ing on the stale cached one. First init (no prior session) keeps
@@ -241,8 +245,11 @@ const useSyncDynamicWaas = () => {
241
245
  initializeWaas({ forceClientRebuild })
242
246
  .then(() => {
243
247
  logger.debug('[useSyncDynamicWaas] waas initialized');
248
+ // Persist the session id this init actually ran with so a token
249
+ // rotation that happened mid-flight is still detected on the next
250
+ // effect run and triggers a force-rebuild.
244
251
  hasWaasInitializedRef.current = true;
245
- sessionIdRef.current = sessionId;
252
+ sessionIdRef.current = currentSessionId;
246
253
  // Host-observed time to get the WaaS iframe/client ready. Ships to
247
254
  // Datadog (sliced by @version + environmentId) as the host-side
248
255
  // companion to the iframe app's `waas_iframe_*` timing — used to
@@ -257,13 +264,14 @@ const useSyncDynamicWaas = () => {
257
264
  .catch((error) => {
258
265
  logger.warn('[useSyncDynamicWaas] Error initializing waas', {
259
266
  error,
260
- sessionId,
267
+ sessionId: currentSessionId,
261
268
  userId,
262
269
  });
263
270
  logger.instrument('WaaS host init failed', {
264
271
  environmentId,
265
272
  key: 'waas_host_init_failed',
266
273
  reason: error instanceof Error ? error.message : String(error),
274
+ sessionId: currentSessionId,
267
275
  time: Date.now() - initStartedAt,
268
276
  userId,
269
277
  });
@@ -273,7 +281,13 @@ const useSyncDynamicWaas = () => {
273
281
  });
274
282
  }
275
283
  }
276
- }, [initializeWaas, shouldInitializeWaas, user]);
284
+ }, [
285
+ initializeWaas,
286
+ shouldInitializeWaas,
287
+ user,
288
+ environmentId,
289
+ clearRecoveredWallets,
290
+ ]);
277
291
  useEffect(() => {
278
292
  if (shouldCreateWallets()) {
279
293
  handleWalletCreation();