@turnkey/react-wallet-kit 1.5.0 → 1.6.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 (56) hide show
  1. package/dist/components/auth/Wallet.d.ts +6 -2
  2. package/dist/components/auth/Wallet.d.ts.map +1 -1
  3. package/dist/components/auth/Wallet.js +82 -38
  4. package/dist/components/auth/Wallet.js.map +1 -1
  5. package/dist/components/auth/Wallet.mjs +90 -43
  6. package/dist/components/auth/Wallet.mjs.map +1 -1
  7. package/dist/components/auth/index.d.ts.map +1 -1
  8. package/dist/components/auth/index.js +1 -3
  9. package/dist/components/auth/index.js.map +1 -1
  10. package/dist/components/auth/index.mjs +1 -3
  11. package/dist/components/auth/index.mjs.map +1 -1
  12. package/dist/components/import/Import.d.ts +1 -0
  13. package/dist/components/import/Import.d.ts.map +1 -1
  14. package/dist/components/import/Import.js +3 -1
  15. package/dist/components/import/Import.js.map +1 -1
  16. package/dist/components/import/Import.mjs +3 -1
  17. package/dist/components/import/Import.mjs.map +1 -1
  18. package/dist/components/onramp/OnRamp.js +2 -2
  19. package/dist/components/onramp/OnRamp.js.map +1 -1
  20. package/dist/components/onramp/OnRamp.mjs +2 -2
  21. package/dist/components/onramp/OnRamp.mjs.map +1 -1
  22. package/dist/components/user/ConnectWallet.d.ts +1 -2
  23. package/dist/components/user/ConnectWallet.d.ts.map +1 -1
  24. package/dist/components/user/ConnectWallet.js +0 -2
  25. package/dist/components/user/ConnectWallet.js.map +1 -1
  26. package/dist/components/user/ConnectWallet.mjs +1 -3
  27. package/dist/components/user/ConnectWallet.mjs.map +1 -1
  28. package/dist/providers/client/Provider.d.ts.map +1 -1
  29. package/dist/providers/client/Provider.js +477 -391
  30. package/dist/providers/client/Provider.js.map +1 -1
  31. package/dist/providers/client/Provider.mjs +2303 -2201
  32. package/dist/providers/client/Provider.mjs.map +1 -1
  33. package/dist/providers/client/Types.d.ts +7 -5
  34. package/dist/providers/client/Types.d.ts.map +1 -1
  35. package/dist/providers/client/Types.js.map +1 -1
  36. package/dist/providers/client/Types.mjs.map +1 -1
  37. package/dist/providers/modal/Provider.d.ts +1 -0
  38. package/dist/providers/modal/Provider.d.ts.map +1 -1
  39. package/dist/providers/modal/Provider.js +2 -0
  40. package/dist/providers/modal/Provider.js.map +1 -1
  41. package/dist/providers/modal/Provider.mjs +6 -0
  42. package/dist/providers/modal/Provider.mjs.map +1 -1
  43. package/dist/styles.css +1 -1
  44. package/dist/types/base.d.ts +2 -0
  45. package/dist/types/base.d.ts.map +1 -1
  46. package/dist/types/base.js.map +1 -1
  47. package/dist/types/base.mjs.map +1 -1
  48. package/dist/types/method-types.d.ts +2 -0
  49. package/dist/types/method-types.d.ts.map +1 -1
  50. package/dist/utils/utils.d.ts +3 -2
  51. package/dist/utils/utils.d.ts.map +1 -1
  52. package/dist/utils/utils.js +14 -1
  53. package/dist/utils/utils.js.map +1 -1
  54. package/dist/utils/utils.mjs +23 -5
  55. package/dist/utils/utils.mjs.map +1 -1
  56. package/package.json +4 -4
@@ -71,6 +71,9 @@ const ClientProvider = ({
71
71
  const [user, setUser] = react.useState(undefined);
72
72
  const [clientState, setClientState] = react.useState();
73
73
  const [authState, setAuthState] = react.useState(base.AuthState.Unauthenticated);
74
+ // if there is no authProxyConfigId or if autoFetchWalletKitConfig is specifically
75
+ // set to false, we don't need to fetch the config
76
+ const shouldFetchWalletKitConfig = !!config.authProxyConfigId && (config.autoFetchWalletKitConfig ?? true);
74
77
  // we use this custom hook to only update the state if the value is different
75
78
  // this is so our useEffect that calls `initializeWalletProviderListeners()` only runs when it needs to
76
79
  const [walletProviders, setWalletProviders] = utils.useWalletProviderState();
@@ -378,28 +381,29 @@ const ClientProvider = ({
378
381
  // Set a default ordering for the overall auth methods
379
382
  const methodOrder = config.auth?.methodOrder ?? [oauthOrder.length > 0 ? "socials" : null, resolvedMethods.emailOtpAuthEnabled ? "email" : null, resolvedMethods.smsOtpAuthEnabled ? "sms" : null, resolvedMethods.passkeyAuthEnabled ? "passkey" : null, resolvedMethods.walletAuthEnabled ? "wallet" : null].filter(Boolean);
380
383
  // Warn if they are trying to set auth proxy only settings directly
381
- if (config.auth?.sessionExpirationSeconds) {
382
- console.warn("Turnkey SDK warning. You have set sessionExpirationSeconds directly in the TurnkeyProvider. This setting will be ignored because you are using an auth proxy. Please configure session expiration in the Turnkey dashboard.");
383
- }
384
- if (config.auth?.otpAlphanumeric !== undefined) {
385
- console.warn("Turnkey SDK warning. You have set otpAlphanumeric directly in the TurnkeyProvider. This setting will be ignored because you are using an auth proxy. Please configure OTP settings in the Turnkey dashboard.");
386
- }
387
- if (config.auth?.otpLength) {
388
- console.warn("Turnkey SDK warning. You have set otpLength directly in the TurnkeyProvider. This setting will be ignored because you are using an auth proxy. Please configure OTP settings in the Turnkey dashboard.");
384
+ if (proxyAuthConfig) {
385
+ if (config.auth?.sessionExpirationSeconds) {
386
+ console.warn("Turnkey SDK warning. You have set sessionExpirationSeconds directly in the TurnkeyProvider. This setting will be ignored because you are using an auth proxy. Please configure session expiration in the Turnkey dashboard.");
387
+ }
388
+ if (config.auth?.otpAlphanumeric !== undefined) {
389
+ console.warn("Turnkey SDK warning. You have set otpAlphanumeric directly in the TurnkeyProvider. This setting will be ignored because you are using an auth proxy. Please configure OTP settings in the Turnkey dashboard.");
390
+ }
391
+ if (config.auth?.otpLength) {
392
+ console.warn("Turnkey SDK warning. You have set otpLength directly in the TurnkeyProvider. This setting will be ignored because you are using an auth proxy. Please configure OTP settings in the Turnkey dashboard.");
393
+ }
389
394
  }
390
- // These are settings that can only be set via the auth proxy config
391
- const authProxyOnlySettings = {
392
- sessionExpirationSeconds: proxyAuthConfig?.sessionExpirationSeconds,
393
- otpAlphanumeric: proxyAuthConfig?.otpAlphanumeric ?? true,
394
- // This fallback will never be hit. This is purely for the tests to pass before mono is released
395
- otpLength: proxyAuthConfig?.otpLength ?? "6" // This fallback will never be hit. This is purely for the tests to pass before mono is released
395
+ // These are settings that, if using the auth proxy, must be set in the dashboard. They override any local settings unless they are not using auth proxy or are not fetching the auth proxy config.
396
+ const authProxyPrioSettings = {
397
+ sessionExpirationSeconds: proxyAuthConfig?.sessionExpirationSeconds ?? config.auth?.sessionExpirationSeconds,
398
+ otpAlphanumeric: proxyAuthConfig?.otpAlphanumeric ?? config.auth?.otpAlphanumeric ?? true,
399
+ otpLength: proxyAuthConfig?.otpLength ?? config.auth?.otpLength ?? "6"
396
400
  };
397
401
  return {
398
402
  ...config,
399
403
  // Overrides:
400
404
  auth: {
401
405
  ...config.auth,
402
- ...authProxyOnlySettings,
406
+ ...authProxyPrioSettings,
403
407
  methods: resolvedMethods,
404
408
  oauthConfig: {
405
409
  ...config.auth?.oauthConfig,
@@ -525,8 +529,18 @@ const ClientProvider = ({
525
529
  return;
526
530
  }
527
531
  setSession(allLocalStorageSessions[activeSessionKey]);
528
- await refreshUser();
529
- await refreshWallets();
532
+ // we use `maybeFetchWallets()` instead of `maybeRefreshWallets()` here to avoid a race condition
533
+ // specifically, if WalletConnect finishes initializing before this promise resolves,
534
+ // `maybeRefreshWallets()` could overwrite the WalletConnect wallet state with an outdated
535
+ // list of wallets that doesn’t yet include the WalletConnect wallets
536
+ const [, wallets] = await Promise.all([maybeRefreshUser(), (() => {
537
+ if (!masterConfig?.autoRefreshManagedState) return [];
538
+ return fetchWallets();
539
+ })()]);
540
+ // the prev wallets should only ever be WalletConnect wallets
541
+ if (wallets) {
542
+ setWallets(prev => utils.mergeWalletsWithoutDuplicates(prev, wallets));
543
+ }
530
544
  return;
531
545
  }
532
546
  } catch (error) {
@@ -619,6 +633,32 @@ const ClientProvider = ({
619
633
  // to refresh the uri, there is no need to refresh the wallets state
620
634
  if (evt?.type === "pairingExpired") {
621
635
  debouncedFetchWalletProviders();
636
+ return;
637
+ }
638
+ // if WalletConnect initialization failed, refresh providers
639
+ // (the failed provider will be removed from the list)
640
+ if (evt?.type === "failed") {
641
+ debouncedFetchWalletProviders();
642
+ callbacks?.onError?.(new sdkTypes.TurnkeyError(`WalletConnect initialization failed: ${evt.error || "Unknown error"}`, sdkTypes.TurnkeyErrorCodes.WALLET_CONNECT_INITIALIZATION_ERROR, evt.error));
643
+ return;
644
+ }
645
+ if (evt?.type === "initialized") {
646
+ // this updates our walletProvider state
647
+ const providers = await debouncedFetchWalletProviders();
648
+ // if we have an active session, we need to restore any possibly connected
649
+ // WalletConnect wallets since its now initialized
650
+ const currentSession = await getSession();
651
+ if (currentSession) {
652
+ const wcProviders = providers?.filter(p => p.interfaceType === core.WalletInterfaceType.WalletConnect);
653
+ const wcWallets = await fetchWallets({
654
+ walletProviders: wcProviders,
655
+ connectedOnly: true
656
+ });
657
+ if (wcWallets.length > 0) {
658
+ setWallets(prev => utils.mergeWalletsWithoutDuplicates(prev, wcWallets));
659
+ }
660
+ }
661
+ return;
622
662
  }
623
663
  // any other event (disconnect, chain switch, accounts changed)
624
664
  // we refresh the wallets state
@@ -632,100 +672,6 @@ const ClientProvider = ({
632
672
  cleanups.forEach(remove => remove());
633
673
  };
634
674
  }
635
- /**
636
- * @internal
637
- * Schedules a session expiration and warning timer for the given session key.
638
- *
639
- * - Sets up two timers: one for warning before expiry and one for actual expiry.
640
- * - Uses capped timeouts under the hood so delays > 24.8 days are safe (see utils/timers.ts).
641
- *
642
- * @param params.sessionKey - The key of the session to schedule expiration for.
643
- * @param params.expiry - The expiration time in seconds since epoch.
644
- * @throws {TurnkeyError} If an error occurs while scheduling the session expiration.
645
- */
646
- async function scheduleSessionExpiration(params) {
647
- const {
648
- sessionKey,
649
- expiry
650
- } = params;
651
- try {
652
- const warnKey = `${sessionKey}-warning`;
653
- // Replace any prior timers for this session
654
- timers.clearKey(expiryTimeoutsRef.current, sessionKey);
655
- timers.clearKey(expiryTimeoutsRef.current, warnKey);
656
- const now = Date.now();
657
- const expiryMs = expiry * 1000;
658
- const timeUntilExpiry = expiryMs - now;
659
- const beforeExpiry = async () => {
660
- const activeSession = await getSession();
661
- if (!activeSession && expiryTimeoutsRef.current[warnKey]) {
662
- // Keep nudging until session materializes (short 10s timer is fine)
663
- timers.setTimeoutInMap(expiryTimeoutsRef.current, warnKey, beforeExpiry, 10_000);
664
- return;
665
- }
666
- const session = await getSession({
667
- sessionKey
668
- });
669
- if (!session) return;
670
- callbacks?.beforeSessionExpiry?.({
671
- sessionKey
672
- });
673
- if (masterConfig?.auth?.autoRefreshSession) {
674
- await refreshSession({
675
- expirationSeconds: session.expirationSeconds,
676
- sessionKey
677
- });
678
- }
679
- };
680
- const expireSession = async () => {
681
- const expiredSession = await getSession({
682
- sessionKey
683
- });
684
- if (!expiredSession) return;
685
- callbacks?.onSessionExpired?.({
686
- sessionKey
687
- });
688
- if ((await getActiveSessionKey()) === sessionKey) {
689
- setSession(undefined);
690
- }
691
- setAllSessions(prev => {
692
- if (!prev) return prev;
693
- const next = {
694
- ...prev
695
- };
696
- delete next[sessionKey];
697
- return next;
698
- });
699
- await clearSession({
700
- sessionKey
701
- });
702
- // Remove timers for this session
703
- timers.clearKey(expiryTimeoutsRef.current, sessionKey);
704
- timers.clearKey(expiryTimeoutsRef.current, warnKey);
705
- await logout();
706
- };
707
- // Already expired → expire immediately
708
- if (timeUntilExpiry <= 0) {
709
- await expireSession();
710
- return;
711
- }
712
- // Warning timer (if threshold is in the future)
713
- const warnAt = expiryMs - utils.SESSION_WARNING_THRESHOLD_MS;
714
- if (warnAt <= now) {
715
- void beforeExpiry(); // fire-and-forget is fine
716
- } else {
717
- timers.setCappedTimeoutInMap(expiryTimeoutsRef.current, warnKey, beforeExpiry, warnAt - now);
718
- }
719
- // Actual expiry timer (safe for long delays)
720
- timers.setCappedTimeoutInMap(expiryTimeoutsRef.current, sessionKey, expireSession, timeUntilExpiry);
721
- } catch (error) {
722
- if (error instanceof sdkTypes.TurnkeyError || error instanceof sdkTypes.TurnkeyNetworkError) {
723
- callbacks?.onError?.(error);
724
- } else {
725
- callbacks?.onError?.(new sdkTypes.TurnkeyError(`Failed to schedule session expiration for ${sessionKey}`, sdkTypes.TurnkeyErrorCodes.SCHEDULE_SESSION_EXPIRY_ERROR, error));
726
- }
727
- }
728
- }
729
675
  /**
730
676
  * Clears all scheduled session timers (warning + expiry).
731
677
  *
@@ -782,8 +728,7 @@ const ClientProvider = ({
782
728
  const allSessions = await client.getAllSessions();
783
729
  setSession(session);
784
730
  setAllSessions(allSessions);
785
- await refreshWallets();
786
- await refreshUser();
731
+ await Promise.all([maybeRefreshWallets(), maybeRefreshUser()]);
787
732
  if (masterConfig?.auth?.verifyWalletOnSignup === true && appProofs && appProofs.length > 0 && action === sdkTypes.AuthAction.SIGNUP) {
788
733
  // On signup, if we have appProofs, verify them
789
734
  await handleVerifyAppProofs({
@@ -844,13 +789,9 @@ const ClientProvider = ({
844
789
  }
845
790
  return client.createHttpClient(params);
846
791
  }, [client]);
847
- const createPasskey = react.useCallback(async params => {
848
- if (!client) {
849
- throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
850
- }
851
- return utils.withTurnkeyErrorHandling(() => client.createPasskey({
852
- ...params
853
- }), () => logout(), callbacks, "Failed to create passkey");
792
+ const getActiveSessionKey = react.useCallback(async () => {
793
+ if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
794
+ return utils.withTurnkeyErrorHandling(() => client.getActiveSessionKey(), undefined, callbacks, "Failed to get active session key");
854
795
  }, [client, callbacks]);
855
796
  const logout = react.useCallback(async params => {
856
797
  if (!client) {
@@ -863,9 +804,264 @@ const ClientProvider = ({
863
804
  await client.logout(params);
864
805
  // We only handle post logout if the sessionKey is defined since that means we actually logged out of a session.
865
806
  if (sessionKey) handlePostLogout(sessionKey);
866
- }, () => logout(), callbacks, "Failed to logout");
807
+ }, undefined, callbacks, "Failed to logout");
867
808
  return;
809
+ }, [client, callbacks, getActiveSessionKey]);
810
+ const getSession = react.useCallback(async params => {
811
+ if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
812
+ return utils.withTurnkeyErrorHandling(() => client.getSession(params), undefined, callbacks, "Failed to get session");
813
+ }, [client, callbacks]);
814
+ const getAllSessions = react.useCallback(async () => {
815
+ if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
816
+ return utils.withTurnkeyErrorHandling(() => client.getAllSessions(), undefined, callbacks, "Failed to get all sessions");
817
+ }, [client, callbacks]);
818
+ const createPasskey = react.useCallback(async params => {
819
+ if (!client) {
820
+ throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
821
+ }
822
+ return utils.withTurnkeyErrorHandling(() => client.createPasskey({
823
+ ...params
824
+ }), undefined, callbacks, "Failed to create passkey");
868
825
  }, [client, callbacks]);
826
+ const fetchUser = react.useCallback(async params => {
827
+ if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
828
+ return utils.withTurnkeyErrorHandling(() => client.fetchUser(params), () => logout(), callbacks, "Failed to fetch user");
829
+ }, [client, callbacks, logout]);
830
+ const fetchWalletProviders = react.useCallback(async chain => {
831
+ if (!client) {
832
+ throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
833
+ }
834
+ return utils.withTurnkeyErrorHandling(async () => {
835
+ const newProviders = await client.fetchWalletProviders(chain);
836
+ // we update state with the latest providers
837
+ // we keep this state so that initializeWalletProviderListeners() re-runs
838
+ // whenever the list of connected providers changes
839
+ // this ensures we attach disconnect listeners for each connected provider
840
+ setWalletProviders(newProviders);
841
+ return newProviders;
842
+ }, undefined, callbacks, "Failed to fetch wallet providers");
843
+ }, [client, callbacks]);
844
+ const fetchWallets = react.useCallback(async params => {
845
+ if (!client) {
846
+ throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
847
+ }
848
+ return utils.withTurnkeyErrorHandling(() => client.fetchWallets(params), () => logout(), callbacks, "Failed to fetch wallets");
849
+ }, [client, callbacks, logout]);
850
+ const refreshUser = react.useCallback(async params => {
851
+ const {
852
+ stampWith,
853
+ organizationId,
854
+ userId
855
+ } = params || {};
856
+ if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
857
+ const user = await utils.withTurnkeyErrorHandling(() => fetchUser({
858
+ stampWith,
859
+ ...(organizationId && {
860
+ organizationId
861
+ }),
862
+ ...(userId && {
863
+ userId
864
+ })
865
+ }), () => logout(), callbacks, "Failed to refresh user");
866
+ if (user) {
867
+ setUser(user);
868
+ }
869
+ }, [client, callbacks, fetchUser, logout]);
870
+ /**
871
+ * @internal
872
+ * Auto-refresh user only if enabled in config. This is only used internally.
873
+ *
874
+ * @param params.organizationId - organization ID to specify the sub-organization (defaults to the current session's organizationId).
875
+ * @param params.userId - user ID to fetch specific user details (defaults to the current session's userId).
876
+ * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
877
+ * @returns A promise that resolves when the user is refreshed, or does nothing if auto-refresh is disabled
878
+ */
879
+ const maybeRefreshUser = react.useCallback(async params => {
880
+ if (!masterConfig?.autoRefreshManagedState) return;
881
+ return refreshUser(params);
882
+ }, [masterConfig, refreshUser]);
883
+ const refreshWallets = react.useCallback(async params => {
884
+ const {
885
+ stampWith,
886
+ organizationId,
887
+ userId
888
+ } = params || {};
889
+ if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
890
+ const walletProviders = await utils.withTurnkeyErrorHandling(() => fetchWalletProviders(), undefined, callbacks, "Failed to refresh wallets");
891
+ const wallets = await utils.withTurnkeyErrorHandling(() => fetchWallets({
892
+ stampWith,
893
+ walletProviders,
894
+ ...(organizationId && {
895
+ organizationId
896
+ }),
897
+ ...(userId && {
898
+ userId
899
+ })
900
+ }), () => logout(), callbacks, "Failed to refresh wallets");
901
+ if (wallets) {
902
+ setWallets(wallets);
903
+ }
904
+ return wallets;
905
+ }, [client, callbacks, fetchWalletProviders, fetchWallets, logout]);
906
+ /**
907
+ * @internal
908
+ * Auto-refresh wallets only if enabled in config. This is only used internally.
909
+ *
910
+ * @param params.organizationId - organization ID to specify the sub-organization (defaults to the current session's organizationId).
911
+ * @param params.userId - user ID to fetch specific user details (defaults to the current session's userId).
912
+ * @param params.stampWith - parameter to stamp the request with a specific stamper (StamperType.Passkey, StamperType.ApiKey, or StamperType.Wallet).
913
+ * @returns A promise that resolves to an array of wallets, or an empty array if auto-refresh is disabled
914
+ */
915
+ const maybeRefreshWallets = react.useCallback(async params => {
916
+ if (!masterConfig?.autoRefreshManagedState) return [];
917
+ return refreshWallets(params);
918
+ }, [masterConfig, refreshWallets]);
919
+ const clearSession = react.useCallback(async params => {
920
+ if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
921
+ await utils.withTurnkeyErrorHandling(async () => client.clearSession(params), undefined, callbacks, "Failed to clear session");
922
+ const sessionKey = params?.sessionKey ?? (await getActiveSessionKey());
923
+ if (!sessionKey) return;
924
+ if (!params?.sessionKey) {
925
+ setSession(undefined);
926
+ }
927
+ clearSessionTimeouts([sessionKey]);
928
+ // clear only the cleared session from allSessions
929
+ const newAllSessions = {
930
+ ...allSessions
931
+ };
932
+ if (newAllSessions) {
933
+ delete newAllSessions[sessionKey];
934
+ }
935
+ setAllSessions(newAllSessions);
936
+ return;
937
+ }, [client, callbacks, getActiveSessionKey, allSessions]);
938
+ /**
939
+ * @internal
940
+ * Schedules a session expiration and warning timer for the given session key.
941
+ *
942
+ * - Sets up two timers: one for warning before expiry and one for actual expiry.
943
+ * - Uses capped timeouts under the hood so delays > 24.8 days are safe (see utils/timers.ts).
944
+ *
945
+ * @param params.sessionKey - The key of the session to schedule expiration for.
946
+ * @param params.expiry - The expiration time in seconds since epoch.
947
+ * @throws {TurnkeyError} If an error occurs while scheduling the session expiration.
948
+ */
949
+ const scheduleSessionExpiration = react.useCallback(async params => {
950
+ const {
951
+ sessionKey,
952
+ expiry
953
+ } = params;
954
+ try {
955
+ const warnKey = `${sessionKey}-warning`;
956
+ // Replace any prior timers for this session
957
+ timers.clearKey(expiryTimeoutsRef.current, sessionKey);
958
+ timers.clearKey(expiryTimeoutsRef.current, warnKey);
959
+ const now = Date.now();
960
+ const expiryMs = expiry * 1000;
961
+ const timeUntilExpiry = expiryMs - now;
962
+ const runRefresh = async () => {
963
+ const activeSession = await getSession();
964
+ if (!activeSession && expiryTimeoutsRef.current[warnKey]) {
965
+ // Keep nudging until session materializes (short 10s timer is fine)
966
+ timers.setTimeoutInMap(expiryTimeoutsRef.current, warnKey, runRefresh, 10_000);
967
+ return;
968
+ }
969
+ const session = await getSession({
970
+ sessionKey
971
+ });
972
+ if (!session) return;
973
+ callbacks?.beforeSessionExpiry?.({
974
+ sessionKey
975
+ });
976
+ if (masterConfig?.auth?.autoRefreshSession) {
977
+ await refreshSession({
978
+ expirationSeconds: session.expirationSeconds,
979
+ sessionKey
980
+ });
981
+ }
982
+ };
983
+ const expireSession = async () => {
984
+ const expiredSession = await getSession({
985
+ sessionKey
986
+ });
987
+ if (!expiredSession) return;
988
+ callbacks?.onSessionExpired?.({
989
+ sessionKey
990
+ });
991
+ if ((await getActiveSessionKey()) === sessionKey) {
992
+ setSession(undefined);
993
+ }
994
+ setAllSessions(prev => {
995
+ if (!prev) return prev;
996
+ const next = {
997
+ ...prev
998
+ };
999
+ delete next[sessionKey];
1000
+ return next;
1001
+ });
1002
+ await clearSession({
1003
+ sessionKey
1004
+ });
1005
+ // Remove timers for this session
1006
+ timers.clearKey(expiryTimeoutsRef.current, sessionKey);
1007
+ timers.clearKey(expiryTimeoutsRef.current, warnKey);
1008
+ await logout();
1009
+ };
1010
+ // Already expired → expire immediately
1011
+ if (timeUntilExpiry <= 0) {
1012
+ await expireSession();
1013
+ return;
1014
+ }
1015
+ // Warning timer (if threshold is in the future)
1016
+ const warnAt = expiryMs - utils.SESSION_WARNING_THRESHOLD_MS;
1017
+ if (warnAt <= now) {
1018
+ void runRefresh(); // fire-and-forget is fine
1019
+ } else {
1020
+ timers.setCappedTimeoutInMap(expiryTimeoutsRef.current, warnKey, runRefresh, warnAt - now);
1021
+ }
1022
+ // Actual expiry timer (safe for long delays)
1023
+ timers.setCappedTimeoutInMap(expiryTimeoutsRef.current, sessionKey, expireSession, timeUntilExpiry);
1024
+ } catch (error) {
1025
+ if (error instanceof sdkTypes.TurnkeyError || error instanceof sdkTypes.TurnkeyNetworkError) {
1026
+ callbacks?.onError?.(error);
1027
+ } else {
1028
+ callbacks?.onError?.(new sdkTypes.TurnkeyError(`Failed to schedule session expiration for ${sessionKey}`, sdkTypes.TurnkeyErrorCodes.SCHEDULE_SESSION_EXPIRY_ERROR, error));
1029
+ }
1030
+ }
1031
+ },
1032
+ // Note: `refreshSession()` is intentionally NOT in the dependency array even though
1033
+ // it's called in runRefresh. This is because: `refreshSession()` itself calls `scheduleSessionExpiration()`,
1034
+ // creating a circular dependency that would cause infinite re-renders
1035
+ //
1036
+ // this is fine because `refreshSession()` reference is stable enough for this use case (session
1037
+ // expiration timers are long-lived and don't need to re-subscribe on every `refreshSession()` change)
1038
+ [callbacks, masterConfig, getSession, getActiveSessionKey, clearSession, logout]);
1039
+ const refreshSession = react.useCallback(async params => {
1040
+ if (!client) {
1041
+ throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1042
+ }
1043
+ const activeSessionKey = await client.getActiveSessionKey();
1044
+ if (!activeSessionKey) {
1045
+ throw new sdkTypes.TurnkeyError("No active session found.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
1046
+ }
1047
+ const sessionKey = params?.sessionKey ?? activeSessionKey;
1048
+ const res = await utils.withTurnkeyErrorHandling(() => client.refreshSession({
1049
+ ...params
1050
+ }), () => logout(), callbacks, "Failed to refresh session");
1051
+ const session = await getSession({
1052
+ sessionKey
1053
+ });
1054
+ if (session && sessionKey) {
1055
+ await scheduleSessionExpiration({
1056
+ sessionKey,
1057
+ expiry: session.expiry
1058
+ });
1059
+ }
1060
+ const allSessions = await getAllSessions();
1061
+ setSession(session);
1062
+ setAllSessions(allSessions);
1063
+ return res;
1064
+ }, [client, callbacks, logout, getSession, scheduleSessionExpiration, getAllSessions]);
869
1065
  const loginWithPasskey = react.useCallback(async params => {
870
1066
  if (!client) {
871
1067
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
@@ -884,7 +1080,7 @@ const ClientProvider = ({
884
1080
  });
885
1081
  }
886
1082
  return res;
887
- }, [client, callbacks]);
1083
+ }, [client, callbacks, masterConfig, logout, handlePostAuth]);
888
1084
  const signUpWithPasskey = react.useCallback(async params => {
889
1085
  if (!client) {
890
1086
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
@@ -924,61 +1120,55 @@ const ClientProvider = ({
924
1120
  });
925
1121
  }
926
1122
  return res;
927
- }, [client, callbacks]);
928
- const fetchWalletProviders = react.useCallback(async chain => {
929
- if (!client) {
930
- throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
931
- }
932
- const newProviders = await client.fetchWalletProviders(chain);
933
- // we update state with the latest providers
934
- // we keep this state so that initializeWalletProviderListeners() re-runs
935
- // whenever the list of connected providers changes
936
- // this ensures we attach disconnect listeners for each connected provider
937
- setWalletProviders(newProviders);
938
- return newProviders;
939
- }, [client, callbacks]);
1123
+ }, [client, callbacks, logout, handlePostAuth, masterConfig]);
940
1124
  const connectWalletAccount = react.useCallback(async walletProvider => {
941
1125
  if (!client) {
942
1126
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
943
1127
  }
944
- const address = await client.connectWalletAccount(walletProvider);
945
- let wallets;
946
- const s = await getSession();
947
- if (s) {
948
- // this will update our walletProvider state
949
- wallets = await refreshWallets();
950
- } else {
951
- wallets = await fetchWallets({
952
- connectedOnly: true
953
- });
954
- }
955
- // we narrow to only connected wallets
956
- // because we know the account must come from one of them
957
- const connectedWallets = wallets.filter(w => w.source === core.WalletSource.Connected);
958
- // find the matching account
959
- const matchedAccount = connectedWallets.flatMap(w => w.accounts).find(a => a.address === address);
960
- if (!matchedAccount) {
961
- throw new sdkTypes.TurnkeyError(`No connected wallet account found for address: ${address}`, sdkTypes.TurnkeyErrorCodes.NO_WALLET_FOUND);
962
- }
963
- return matchedAccount;
964
- }, [client, callbacks]);
1128
+ return utils.withTurnkeyErrorHandling(async () => {
1129
+ const address = await client.connectWalletAccount(walletProvider);
1130
+ let wallets;
1131
+ const s = await getSession();
1132
+ if (s) {
1133
+ // this will update our walletProvider state
1134
+ wallets = await maybeRefreshWallets();
1135
+ } else {
1136
+ wallets = await fetchWallets({
1137
+ connectedOnly: true
1138
+ });
1139
+ }
1140
+ // we narrow to only connected wallets
1141
+ // because we know the account must come from one of them
1142
+ const connectedWallets = wallets.filter(w => w.source === core.WalletSource.Connected);
1143
+ // find the matching account
1144
+ const matchedAccount = connectedWallets.flatMap(w => w.accounts).find(a => a.address === address);
1145
+ if (!matchedAccount) {
1146
+ throw new sdkTypes.TurnkeyError(`No connected wallet account found for address: ${address}`, sdkTypes.TurnkeyErrorCodes.NO_WALLET_FOUND);
1147
+ }
1148
+ return matchedAccount;
1149
+ }, () => logout(), callbacks, "Failed to connect wallet account");
1150
+ }, [client, callbacks, getSession, logout, maybeRefreshWallets, fetchWallets]);
965
1151
  const disconnectWalletAccount = react.useCallback(async walletProvider => {
966
1152
  if (!client) {
967
1153
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
968
1154
  }
969
- await client.disconnectWalletAccount(walletProvider);
970
- // no need here to call `refreshWallets()` because the provider emits a disconnect event which
971
- // will trigger a refresh via the listener we set up in `initializeWalletProviderListeners()`
1155
+ await utils.withTurnkeyErrorHandling(async () => {
1156
+ await client.disconnectWalletAccount(walletProvider);
1157
+ // no need here to call `maybeRefreshWallets()` because the provider emits a disconnect event which
1158
+ // will trigger a refresh via the listener we set up in `initializeWalletProviderListeners()`
1159
+ }, undefined, callbacks, "Failed to disconnect wallet account");
972
1160
  }, [client, callbacks]);
973
1161
  const switchWalletAccountChain = react.useCallback(async params => {
974
1162
  if (!client) {
975
1163
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
976
1164
  }
977
- await client.switchWalletAccountChain({
978
- ...params,
979
- walletProviders
980
- });
981
- }, [client, callbacks, walletProviders]);
1165
+ await utils.withTurnkeyErrorHandling(async () => {
1166
+ await client.switchWalletAccountChain({
1167
+ ...params,
1168
+ walletProviders
1169
+ });
1170
+ }, undefined, callbacks, "Failed to switch wallet account chain");
1171
+ }, [client, walletProviders, callbacks]);
982
1172
  const buildWalletLoginRequest = react.useCallback(async params => {
983
1173
  if (!client) {
984
1174
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
@@ -987,8 +1177,8 @@ const ClientProvider = ({
987
1177
  return await utils.withTurnkeyErrorHandling(() => client.buildWalletLoginRequest({
988
1178
  ...params,
989
1179
  expirationSeconds
990
- }), () => logout(), callbacks, "Failed to login with wallet");
991
- }, [client, callbacks]);
1180
+ }), undefined, callbacks, "Failed to login with wallet");
1181
+ }, [client, callbacks, masterConfig]);
992
1182
  const loginWithWallet = react.useCallback(async params => {
993
1183
  if (!client) {
994
1184
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
@@ -997,7 +1187,7 @@ const ClientProvider = ({
997
1187
  const res = await utils.withTurnkeyErrorHandling(() => client.loginWithWallet({
998
1188
  ...params,
999
1189
  expirationSeconds
1000
- }), () => logout(), callbacks, "Failed to login with wallet");
1190
+ }), undefined, callbacks, "Failed to login with wallet");
1001
1191
  if (res) {
1002
1192
  await handlePostAuth({
1003
1193
  method: base.AuthMethod.Wallet,
@@ -1007,7 +1197,7 @@ const ClientProvider = ({
1007
1197
  });
1008
1198
  }
1009
1199
  return res;
1010
- }, [client, callbacks]);
1200
+ }, [client, callbacks, handlePostAuth, masterConfig]);
1011
1201
  const signUpWithWallet = react.useCallback(async params => {
1012
1202
  if (!client) {
1013
1203
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
@@ -1027,7 +1217,7 @@ const ClientProvider = ({
1027
1217
  const res = await utils.withTurnkeyErrorHandling(() => client.signUpWithWallet({
1028
1218
  ...params,
1029
1219
  expirationSeconds
1030
- }), () => logout(), callbacks, "Failed to sign up with wallet");
1220
+ }), undefined, callbacks, "Failed to sign up with wallet");
1031
1221
  if (res) {
1032
1222
  await handlePostAuth({
1033
1223
  method: base.AuthMethod.Wallet,
@@ -1037,7 +1227,7 @@ const ClientProvider = ({
1037
1227
  });
1038
1228
  }
1039
1229
  return res;
1040
- }, [client, callbacks, masterConfig]);
1230
+ }, [client, callbacks, handlePostAuth, masterConfig]);
1041
1231
  const loginOrSignupWithWallet = react.useCallback(async params => {
1042
1232
  if (!client) {
1043
1233
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
@@ -1057,7 +1247,7 @@ const ClientProvider = ({
1057
1247
  const res = await utils.withTurnkeyErrorHandling(() => client.loginOrSignupWithWallet({
1058
1248
  ...params,
1059
1249
  expirationSeconds
1060
- }), () => logout(), callbacks, "Failed to login or sign up with wallet");
1250
+ }), undefined, callbacks, "Failed to login or sign up with wallet");
1061
1251
  if (res) {
1062
1252
  await handlePostAuth({
1063
1253
  method: base.AuthMethod.Wallet,
@@ -1067,24 +1257,24 @@ const ClientProvider = ({
1067
1257
  });
1068
1258
  }
1069
1259
  return res;
1070
- }, [client, callbacks, masterConfig]);
1260
+ }, [client, callbacks, handlePostAuth, masterConfig]);
1071
1261
  const initOtp = react.useCallback(async params => {
1072
1262
  if (!client) {
1073
1263
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1074
1264
  }
1075
- return utils.withTurnkeyErrorHandling(() => client.initOtp(params), () => logout(), callbacks, "Failed to initialize OTP");
1265
+ return utils.withTurnkeyErrorHandling(() => client.initOtp(params), undefined, callbacks, "Failed to initialize OTP");
1076
1266
  }, [client, callbacks]);
1077
1267
  const verifyOtp = react.useCallback(async params => {
1078
1268
  if (!client) {
1079
1269
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1080
1270
  }
1081
- return utils.withTurnkeyErrorHandling(() => client.verifyOtp(params), () => logout(), callbacks, "Failed to verify OTP");
1271
+ return utils.withTurnkeyErrorHandling(() => client.verifyOtp(params), undefined, callbacks, "Failed to verify OTP");
1082
1272
  }, [client, callbacks]);
1083
1273
  const loginWithOtp = react.useCallback(async params => {
1084
1274
  if (!client) {
1085
1275
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1086
1276
  }
1087
- const res = await utils.withTurnkeyErrorHandling(() => client.loginWithOtp(params), () => logout(), callbacks, "Failed to login with OTP");
1277
+ const res = await utils.withTurnkeyErrorHandling(() => client.loginWithOtp(params), undefined, callbacks, "Failed to login with OTP");
1088
1278
  if (res) {
1089
1279
  await handlePostAuth({
1090
1280
  method: base.AuthMethod.Otp,
@@ -1094,7 +1284,7 @@ const ClientProvider = ({
1094
1284
  });
1095
1285
  }
1096
1286
  return res;
1097
- }, [client, callbacks]);
1287
+ }, [client, callbacks, handlePostAuth]);
1098
1288
  const signUpWithOtp = react.useCallback(async params => {
1099
1289
  if (!client) {
1100
1290
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
@@ -1117,7 +1307,7 @@ const ClientProvider = ({
1117
1307
  } : {
1118
1308
  ...params
1119
1309
  };
1120
- const res = await utils.withTurnkeyErrorHandling(() => client.signUpWithOtp(params), () => logout(), callbacks, "Failed to sign up with OTP");
1310
+ const res = await utils.withTurnkeyErrorHandling(() => client.signUpWithOtp(params), undefined, callbacks, "Failed to sign up with OTP");
1121
1311
  if (res) {
1122
1312
  await handlePostAuth({
1123
1313
  method: base.AuthMethod.Otp,
@@ -1127,7 +1317,7 @@ const ClientProvider = ({
1127
1317
  });
1128
1318
  }
1129
1319
  return res;
1130
- }, [client, callbacks, masterConfig]);
1320
+ }, [client, callbacks, masterConfig, handlePostAuth]);
1131
1321
  const completeOtp = react.useCallback(async params => {
1132
1322
  if (!client) {
1133
1323
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
@@ -1150,7 +1340,7 @@ const ClientProvider = ({
1150
1340
  } : {
1151
1341
  ...params
1152
1342
  };
1153
- const res = await utils.withTurnkeyErrorHandling(() => client.completeOtp(params), () => logout(), callbacks, "Failed to complete OTP");
1343
+ const res = await utils.withTurnkeyErrorHandling(() => client.completeOtp(params), undefined, callbacks, "Failed to complete OTP");
1154
1344
  if (res) {
1155
1345
  await handlePostAuth({
1156
1346
  method: base.AuthMethod.Otp,
@@ -1160,12 +1350,12 @@ const ClientProvider = ({
1160
1350
  });
1161
1351
  }
1162
1352
  return res;
1163
- }, [client, callbacks, masterConfig]);
1353
+ }, [client, callbacks, handlePostAuth, masterConfig]);
1164
1354
  const loginWithOauth = react.useCallback(async params => {
1165
1355
  if (!client) {
1166
1356
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1167
1357
  }
1168
- const res = await utils.withTurnkeyErrorHandling(() => client.loginWithOauth(params), () => logout(), callbacks, "Failed to login with OAuth");
1358
+ const res = await utils.withTurnkeyErrorHandling(() => client.loginWithOauth(params), undefined, callbacks, "Failed to login with OAuth");
1169
1359
  if (res) {
1170
1360
  await handlePostAuth({
1171
1361
  method: base.AuthMethod.Oauth,
@@ -1175,7 +1365,7 @@ const ClientProvider = ({
1175
1365
  });
1176
1366
  }
1177
1367
  return res;
1178
- }, [client, callbacks]);
1368
+ }, [client, callbacks, handlePostAuth]);
1179
1369
  const signUpWithOauth = react.useCallback(async params => {
1180
1370
  if (!client) {
1181
1371
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
@@ -1191,7 +1381,7 @@ const ClientProvider = ({
1191
1381
  } : {
1192
1382
  ...params
1193
1383
  };
1194
- const res = await utils.withTurnkeyErrorHandling(() => client.signUpWithOauth(params), () => logout(), callbacks, "Failed to sign up with OAuth");
1384
+ const res = await utils.withTurnkeyErrorHandling(() => client.signUpWithOauth(params), undefined, callbacks, "Failed to sign up with OAuth");
1195
1385
  if (res) {
1196
1386
  await handlePostAuth({
1197
1387
  method: base.AuthMethod.Oauth,
@@ -1201,7 +1391,7 @@ const ClientProvider = ({
1201
1391
  });
1202
1392
  }
1203
1393
  return res;
1204
- }, [client, callbacks, masterConfig]);
1394
+ }, [client, callbacks, handlePostAuth, masterConfig]);
1205
1395
  const completeOauth = react.useCallback(async params => {
1206
1396
  if (!client) {
1207
1397
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
@@ -1217,7 +1407,7 @@ const ClientProvider = ({
1217
1407
  } : {
1218
1408
  ...params
1219
1409
  };
1220
- const res = await utils.withTurnkeyErrorHandling(() => client.completeOauth(params), () => logout(), callbacks, "Failed to complete OAuth");
1410
+ const res = await utils.withTurnkeyErrorHandling(() => client.completeOauth(params), undefined, callbacks, "Failed to complete OAuth");
1221
1411
  if (res) {
1222
1412
  await handlePostAuth({
1223
1413
  method: base.AuthMethod.Oauth,
@@ -1227,29 +1417,23 @@ const ClientProvider = ({
1227
1417
  });
1228
1418
  }
1229
1419
  return res;
1230
- }, [client, callbacks, masterConfig]);
1231
- const fetchWallets = react.useCallback(async params => {
1232
- if (!client) {
1233
- throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1234
- }
1235
- return utils.withTurnkeyErrorHandling(() => client.fetchWallets(params), () => logout(), callbacks, "Failed to fetch wallets");
1236
- }, [client, callbacks]);
1420
+ }, [client, callbacks, masterConfig, handlePostAuth]);
1237
1421
  const fetchWalletAccounts = react.useCallback(async params => {
1238
1422
  if (!client) {
1239
1423
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1240
1424
  }
1241
1425
  return utils.withTurnkeyErrorHandling(() => client.fetchWalletAccounts(params), () => logout(), callbacks, "Failed to fetch wallet accounts");
1242
- }, [client, callbacks]);
1426
+ }, [client, callbacks, logout]);
1243
1427
  const fetchPrivateKeys = react.useCallback(async params => {
1244
1428
  if (!client) {
1245
1429
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1246
1430
  }
1247
1431
  return utils.withTurnkeyErrorHandling(() => client.fetchPrivateKeys(params), () => logout(), callbacks, "Failed to fetch private keys");
1248
- }, [client, callbacks]);
1432
+ }, [client, callbacks, logout]);
1249
1433
  const signMessage = react.useCallback(async params => {
1250
1434
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1251
1435
  return utils.withTurnkeyErrorHandling(() => client.signMessage(params), () => logout(), callbacks, "Failed to sign message");
1252
- }, [client, callbacks]);
1436
+ }, [client, callbacks, logout]);
1253
1437
  const handleSignMessage = react.useCallback(async params => {
1254
1438
  const {
1255
1439
  successPageDuration = 2000
@@ -1286,31 +1470,27 @@ const ClientProvider = ({
1286
1470
  onClose: () => reject(new sdkTypes.TurnkeyError("User canceled the signing process.", sdkTypes.TurnkeyErrorCodes.USER_CANCELED))
1287
1471
  });
1288
1472
  });
1289
- }, [client, callbacks]);
1473
+ }, [client, callbacks, pushPage]);
1290
1474
  const signTransaction = react.useCallback(async params => {
1291
1475
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1292
1476
  return utils.withTurnkeyErrorHandling(() => client.signTransaction(params), () => logout(), callbacks, "Failed to sign transaction");
1293
- }, [client, callbacks]);
1477
+ }, [client, callbacks, logout]);
1294
1478
  const signAndSendTransaction = react.useCallback(async params => {
1295
1479
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1296
1480
  return utils.withTurnkeyErrorHandling(() => client.signAndSendTransaction(params), () => logout(), callbacks, "Failed to sign transaction");
1297
- }, [client, callbacks]);
1298
- const fetchUser = react.useCallback(async params => {
1299
- if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1300
- return utils.withTurnkeyErrorHandling(() => client.fetchUser(params), () => logout(), callbacks, "Failed to fetch user");
1301
- }, [client, callbacks]);
1481
+ }, [client, callbacks, logout]);
1302
1482
  const fetchOrCreateP256ApiKeyUser = react.useCallback(async params => {
1303
1483
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1304
1484
  return utils.withTurnkeyErrorHandling(() => client.fetchOrCreateP256ApiKeyUser(params), () => logout(), callbacks, "Failed to fetch or create delegated access user");
1305
- }, [client, callbacks]);
1485
+ }, [client, callbacks, logout]);
1306
1486
  const fetchOrCreatePolicies = react.useCallback(async params => {
1307
1487
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1308
1488
  return utils.withTurnkeyErrorHandling(() => client.fetchOrCreatePolicies(params), () => logout(), callbacks, "Failed to fetch or create delegated access user");
1309
- }, [client, callbacks]);
1489
+ }, [client, callbacks, logout]);
1310
1490
  const updateUserEmail = react.useCallback(async params => {
1311
1491
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1312
1492
  const res = await utils.withTurnkeyErrorHandling(() => client.updateUserEmail(params), () => logout(), callbacks, "Failed to update user email");
1313
- if (res) await refreshUser({
1493
+ if (res) await maybeRefreshUser({
1314
1494
  stampWith: params?.stampWith,
1315
1495
  ...(params?.organizationId && {
1316
1496
  organizationId: params.organizationId
@@ -1320,11 +1500,11 @@ const ClientProvider = ({
1320
1500
  })
1321
1501
  });
1322
1502
  return res;
1323
- }, [client, callbacks]);
1503
+ }, [client, callbacks, logout, maybeRefreshUser]);
1324
1504
  const removeUserEmail = react.useCallback(async params => {
1325
1505
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1326
1506
  const res = await utils.withTurnkeyErrorHandling(() => client.removeUserEmail(params), () => logout(), callbacks, "Failed to remove user email");
1327
- if (res) await refreshUser({
1507
+ if (res) await maybeRefreshUser({
1328
1508
  stampWith: params?.stampWith,
1329
1509
  ...(params?.organizationId && {
1330
1510
  organizationId: params.organizationId
@@ -1334,11 +1514,11 @@ const ClientProvider = ({
1334
1514
  })
1335
1515
  });
1336
1516
  return res;
1337
- }, [client, callbacks]);
1517
+ }, [client, callbacks, logout, maybeRefreshUser]);
1338
1518
  const updateUserPhoneNumber = react.useCallback(async params => {
1339
1519
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1340
1520
  const res = await utils.withTurnkeyErrorHandling(() => client.updateUserPhoneNumber(params), () => logout(), callbacks, "Failed to update user phone number");
1341
- if (res) await refreshUser({
1521
+ if (res) await maybeRefreshUser({
1342
1522
  stampWith: params?.stampWith,
1343
1523
  ...(params?.organizationId && {
1344
1524
  organizationId: params.organizationId
@@ -1348,11 +1528,11 @@ const ClientProvider = ({
1348
1528
  })
1349
1529
  });
1350
1530
  return res;
1351
- }, [client, callbacks]);
1531
+ }, [client, callbacks, logout, maybeRefreshUser]);
1352
1532
  const removeUserPhoneNumber = react.useCallback(async params => {
1353
1533
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1354
1534
  const res = await utils.withTurnkeyErrorHandling(() => client.removeUserPhoneNumber(params), () => logout(), callbacks, "Failed to remove user phone number");
1355
- if (res) await refreshUser({
1535
+ if (res) await maybeRefreshUser({
1356
1536
  stampWith: params?.stampWith,
1357
1537
  ...(params?.organizationId && {
1358
1538
  organizationId: params.organizationId
@@ -1362,11 +1542,11 @@ const ClientProvider = ({
1362
1542
  })
1363
1543
  });
1364
1544
  return res;
1365
- }, [client, callbacks]);
1545
+ }, [client, callbacks, logout, maybeRefreshUser]);
1366
1546
  const updateUserName = react.useCallback(async params => {
1367
1547
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1368
1548
  const res = await utils.withTurnkeyErrorHandling(() => client.updateUserName(params), () => logout(), callbacks, "Failed to update user name");
1369
- if (res) await refreshUser({
1549
+ if (res) await maybeRefreshUser({
1370
1550
  stampWith: params?.stampWith,
1371
1551
  ...(params?.organizationId && {
1372
1552
  organizationId: params.organizationId
@@ -1376,11 +1556,11 @@ const ClientProvider = ({
1376
1556
  })
1377
1557
  });
1378
1558
  return res;
1379
- }, [client, callbacks]);
1559
+ }, [client, callbacks, logout, maybeRefreshUser]);
1380
1560
  const addOauthProvider = react.useCallback(async params => {
1381
1561
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1382
1562
  const res = await utils.withTurnkeyErrorHandling(() => client.addOauthProvider(params), () => logout(), callbacks, "Failed to add OAuth provider");
1383
- if (res) await refreshUser({
1563
+ if (res) await maybeRefreshUser({
1384
1564
  stampWith: params?.stampWith,
1385
1565
  ...(params?.organizationId && {
1386
1566
  organizationId: params.organizationId
@@ -1390,11 +1570,11 @@ const ClientProvider = ({
1390
1570
  })
1391
1571
  });
1392
1572
  return res;
1393
- }, [client, callbacks]);
1573
+ }, [client, callbacks, logout, maybeRefreshUser]);
1394
1574
  const removeOauthProviders = react.useCallback(async params => {
1395
1575
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1396
1576
  const res = await utils.withTurnkeyErrorHandling(() => client.removeOauthProviders(params), () => logout(), callbacks, "Failed to remove OAuth providers");
1397
- if (res) await refreshUser({
1577
+ if (res) await maybeRefreshUser({
1398
1578
  stampWith: params?.stampWith,
1399
1579
  ...(params?.organizationId && {
1400
1580
  organizationId: params.organizationId
@@ -1404,11 +1584,11 @@ const ClientProvider = ({
1404
1584
  })
1405
1585
  });
1406
1586
  return res;
1407
- }, [client, callbacks]);
1587
+ }, [client, callbacks, logout, maybeRefreshUser]);
1408
1588
  const addPasskey = react.useCallback(async params => {
1409
1589
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1410
1590
  const res = await utils.withTurnkeyErrorHandling(() => client.addPasskey(params), () => logout(), callbacks, "Failed to add passkey");
1411
- if (res) await refreshUser({
1591
+ if (res) await maybeRefreshUser({
1412
1592
  stampWith: params?.stampWith,
1413
1593
  ...(params?.organizationId && {
1414
1594
  organizationId: params.organizationId
@@ -1418,11 +1598,11 @@ const ClientProvider = ({
1418
1598
  })
1419
1599
  });
1420
1600
  return res;
1421
- }, [client, callbacks]);
1601
+ }, [client, callbacks, logout, maybeRefreshUser]);
1422
1602
  const removePasskeys = react.useCallback(async params => {
1423
1603
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1424
1604
  const res = await utils.withTurnkeyErrorHandling(() => client.removePasskeys(params), () => logout(), callbacks, "Failed to remove passkeys");
1425
- if (res) await refreshUser({
1605
+ if (res) await maybeRefreshUser({
1426
1606
  stampWith: params?.stampWith,
1427
1607
  ...(params?.organizationId && {
1428
1608
  organizationId: params.organizationId
@@ -1432,65 +1612,65 @@ const ClientProvider = ({
1432
1612
  })
1433
1613
  });
1434
1614
  return res;
1435
- }, [client, callbacks]);
1615
+ }, [client, callbacks, logout, maybeRefreshUser]);
1436
1616
  const createWallet = react.useCallback(async params => {
1437
1617
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1438
1618
  const res = await utils.withTurnkeyErrorHandling(() => client.createWallet(params), () => logout(), callbacks, "Failed to create wallet");
1439
1619
  const s = await getSession();
1440
- if (res && s) await refreshWallets({
1620
+ if (res && s) await maybeRefreshWallets({
1441
1621
  stampWith: params?.stampWith,
1442
1622
  ...(params?.organizationId && {
1443
1623
  organizationId: params.organizationId
1444
1624
  })
1445
1625
  });
1446
1626
  return res;
1447
- }, [client, session, callbacks]);
1627
+ }, [client, session, callbacks, logout, maybeRefreshWallets, getSession]);
1448
1628
  const createWalletAccounts = react.useCallback(async params => {
1449
1629
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1450
1630
  const res = await utils.withTurnkeyErrorHandling(() => client.createWalletAccounts(params), () => logout(), callbacks, "Failed to create wallet accounts");
1451
1631
  const s = await getSession();
1452
- if (res && s) await refreshWallets({
1632
+ if (res && s) await maybeRefreshWallets({
1453
1633
  stampWith: params?.stampWith,
1454
1634
  ...(params?.organizationId && {
1455
1635
  organizationId: params.organizationId
1456
1636
  })
1457
1637
  });
1458
1638
  return res;
1459
- }, [client, session, callbacks]);
1639
+ }, [client, session, callbacks, logout, getSession, maybeRefreshWallets]);
1460
1640
  const exportWallet = react.useCallback(async params => {
1461
1641
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1462
1642
  const res = await utils.withTurnkeyErrorHandling(() => client.exportWallet(params), () => logout(), callbacks, "Failed to export wallet");
1463
1643
  const s = await getSession();
1464
- if (res && s) await refreshWallets({
1644
+ if (res && s) await maybeRefreshWallets({
1465
1645
  stampWith: params?.stampWith,
1466
1646
  ...(params?.organizationId && {
1467
1647
  organizationId: params.organizationId
1468
1648
  })
1469
1649
  });
1470
1650
  return res;
1471
- }, [client, session, callbacks]);
1651
+ }, [client, session, callbacks, logout, getSession, maybeRefreshWallets]);
1472
1652
  const exportPrivateKey = react.useCallback(async params => {
1473
1653
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1474
1654
  const res = await utils.withTurnkeyErrorHandling(() => client.exportPrivateKey(params), () => logout(), callbacks, "Failed to export private key");
1475
1655
  return res;
1476
- }, [client, callbacks]);
1656
+ }, [client, callbacks, logout]);
1477
1657
  const exportWalletAccount = react.useCallback(async params => {
1478
1658
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1479
1659
  const res = await utils.withTurnkeyErrorHandling(() => client.exportWalletAccount(params), () => logout(), callbacks, "Failed to export wallet accounts");
1480
1660
  const s = await getSession();
1481
- if (res && s) await refreshWallets({
1661
+ if (res && s) await maybeRefreshWallets({
1482
1662
  stampWith: params?.stampWith,
1483
1663
  ...(params?.organizationId && {
1484
1664
  organizationId: params.organizationId
1485
1665
  })
1486
1666
  });
1487
1667
  return res;
1488
- }, [client, callbacks, masterConfig, session, user]);
1668
+ }, [client, callbacks, logout, getSession, maybeRefreshWallets]);
1489
1669
  const importWallet = react.useCallback(async params => {
1490
1670
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1491
1671
  const res = await utils.withTurnkeyErrorHandling(() => client.importWallet(params), () => logout(), callbacks, "Failed to import wallet");
1492
1672
  const s = await getSession();
1493
- if (res && s) await refreshWallets({
1673
+ if (res && s) await maybeRefreshWallets({
1494
1674
  stampWith: params?.stampWith,
1495
1675
  ...(params?.organizationId && {
1496
1676
  organizationId: params.organizationId
@@ -1500,16 +1680,16 @@ const ClientProvider = ({
1500
1680
  })
1501
1681
  });
1502
1682
  return res;
1503
- }, [client, callbacks, masterConfig, session, user]);
1683
+ }, [client, callbacks, logout, getSession, maybeRefreshWallets]);
1504
1684
  const importPrivateKey = react.useCallback(async params => {
1505
1685
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1506
1686
  const res = await utils.withTurnkeyErrorHandling(() => client.importPrivateKey(params), () => logout(), callbacks, "Failed to import private key");
1507
1687
  return res;
1508
- }, [client, callbacks, masterConfig, session, user]);
1688
+ }, [client, callbacks, logout]);
1509
1689
  const deleteSubOrganization = react.useCallback(async params => {
1510
1690
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1511
1691
  return utils.withTurnkeyErrorHandling(() => client.deleteSubOrganization(params), () => logout(), callbacks, "Failed to delete sub-organization");
1512
- }, [client, callbacks, masterConfig, session, user]);
1692
+ }, [client, callbacks, logout]);
1513
1693
  const storeSession = react.useCallback(async params => {
1514
1694
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1515
1695
  await utils.withTurnkeyErrorHandling(() => client.storeSession(params), () => logout(), callbacks, "Failed to store session");
@@ -1526,69 +1706,15 @@ const ClientProvider = ({
1526
1706
  const allSessions = await getAllSessions();
1527
1707
  setSession(session);
1528
1708
  setAllSessions(allSessions);
1529
- await refreshWallets();
1530
- await refreshUser();
1531
- }, [client, callbacks, masterConfig, session, user]);
1532
- const clearSession = react.useCallback(async params => {
1533
- if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1534
- await utils.withTurnkeyErrorHandling(async () => client.clearSession(params), () => logout(), callbacks, "Failed to clear session");
1535
- const sessionKey = params?.sessionKey ?? (await getActiveSessionKey());
1536
- if (!sessionKey) return;
1537
- if (!params?.sessionKey) {
1538
- setSession(undefined);
1539
- }
1540
- clearSessionTimeouts([sessionKey]);
1541
- // clear only the cleared session from allSessions
1542
- const newAllSessions = {
1543
- ...allSessions
1544
- };
1545
- if (newAllSessions) {
1546
- delete newAllSessions[sessionKey];
1547
- }
1548
- setAllSessions(newAllSessions);
1549
- return;
1550
- }, [client, callbacks, session, user, masterConfig]);
1709
+ await Promise.all([maybeRefreshWallets(), maybeRefreshUser()]);
1710
+ }, [client, callbacks, logout, getActiveSessionKey, getSession, scheduleSessionExpiration, getAllSessions, maybeRefreshWallets, maybeRefreshUser]);
1551
1711
  const clearAllSessions = react.useCallback(async () => {
1552
1712
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1553
1713
  setSession(undefined);
1554
1714
  setAllSessions(undefined);
1555
1715
  clearSessionTimeouts();
1556
1716
  return await utils.withTurnkeyErrorHandling(() => client.clearAllSessions(), () => logout(), callbacks, "Failed to clear all sessions");
1557
- }, [client, callbacks, session, user, masterConfig]);
1558
- const refreshSession = react.useCallback(async params => {
1559
- if (!client) {
1560
- throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1561
- }
1562
- const activeSessionKey = await client.getActiveSessionKey();
1563
- if (!activeSessionKey) {
1564
- throw new sdkTypes.TurnkeyError("No active session found.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
1565
- }
1566
- const sessionKey = params?.sessionKey ?? activeSessionKey;
1567
- const res = await utils.withTurnkeyErrorHandling(() => client.refreshSession({
1568
- ...params
1569
- }), () => logout(), callbacks, "Failed to refresh session");
1570
- const session = await getSession({
1571
- sessionKey
1572
- });
1573
- if (session && sessionKey) {
1574
- await scheduleSessionExpiration({
1575
- sessionKey,
1576
- expiry: session.expiry
1577
- });
1578
- }
1579
- const allSessions = await getAllSessions();
1580
- setSession(session);
1581
- setAllSessions(allSessions);
1582
- return res;
1583
- }, [client, callbacks, scheduleSessionExpiration, session, user, masterConfig]);
1584
- const getSession = react.useCallback(async params => {
1585
- if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1586
- return utils.withTurnkeyErrorHandling(() => client.getSession(params), () => logout(), callbacks, "Failed to get session");
1587
- }, [client, callbacks, masterConfig, session, user]);
1588
- const getAllSessions = react.useCallback(async () => {
1589
- if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1590
- return utils.withTurnkeyErrorHandling(() => client.getAllSessions(), () => logout(), callbacks, "Failed to get all sessions");
1591
- }, [client, callbacks, masterConfig, session, user]);
1717
+ }, [client, callbacks, logout, clearSessionTimeouts]);
1592
1718
  const setActiveSession = react.useCallback(async params => {
1593
1719
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1594
1720
  const session = await utils.withTurnkeyErrorHandling(() => client.getSession({
@@ -1601,80 +1727,30 @@ const ClientProvider = ({
1601
1727
  await utils.withTurnkeyErrorHandling(() => client.setActiveSession(params), () => logout(), callbacks, "Failed to set active session");
1602
1728
  setSession(session);
1603
1729
  await utils.withTurnkeyErrorHandling(async () => {
1604
- await refreshWallets();
1605
- await refreshUser();
1730
+ await Promise.all([maybeRefreshWallets(), maybeRefreshUser()]);
1606
1731
  }, () => logout(), callbacks, "Failed to refresh data after setting active session");
1607
1732
  return;
1608
- }, [client, callbacks, session, user, masterConfig]);
1609
- const getActiveSessionKey = react.useCallback(async () => {
1610
- if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1611
- return utils.withTurnkeyErrorHandling(() => client.getActiveSessionKey(), () => logout(), callbacks, "Failed to get active session key");
1612
- }, [client, callbacks, masterConfig, session, user]);
1733
+ }, [client, callbacks, logout, getSession, maybeRefreshWallets, maybeRefreshUser]);
1613
1734
  const clearUnusedKeyPairs = react.useCallback(async () => {
1614
1735
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1615
- return utils.withTurnkeyErrorHandling(() => client.clearUnusedKeyPairs(), () => logout(), callbacks, "Failed to clear unused key pairs");
1616
- }, [client, callbacks, masterConfig, session, user]);
1736
+ return utils.withTurnkeyErrorHandling(() => client.clearUnusedKeyPairs(), undefined, callbacks, "Failed to clear unused key pairs");
1737
+ }, [client, callbacks]);
1617
1738
  const createApiKeyPair = react.useCallback(async params => {
1618
1739
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1619
- return utils.withTurnkeyErrorHandling(() => client.createApiKeyPair(params), () => logout(), callbacks, "Failed to create API key pair");
1620
- }, [client, callbacks, session, user, masterConfig]);
1740
+ return utils.withTurnkeyErrorHandling(() => client.createApiKeyPair(params), undefined, callbacks, "Failed to create API key pair");
1741
+ }, [client, callbacks]);
1621
1742
  const getProxyAuthConfig = react.useCallback(async () => {
1622
1743
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1623
- return utils.withTurnkeyErrorHandling(() => client.getProxyAuthConfig(), () => logout(), callbacks, "Failed to get proxy auth config");
1624
- }, [client, callbacks, masterConfig, session, user]);
1625
- const refreshUser = react.useCallback(async params => {
1626
- if (!masterConfig?.autoRefreshManagedState) return;
1627
- const {
1628
- stampWith,
1629
- organizationId,
1630
- userId
1631
- } = params || {};
1632
- if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1633
- const user = await utils.withTurnkeyErrorHandling(() => fetchUser({
1634
- stampWith,
1635
- ...(organizationId && {
1636
- organizationId
1637
- }),
1638
- ...(userId && {
1639
- userId
1640
- })
1641
- }), () => logout(), callbacks, "Failed to refresh user");
1642
- if (user) {
1643
- setUser(user);
1644
- }
1645
- }, [client, callbacks, fetchUser, masterConfig, session, user]);
1744
+ return utils.withTurnkeyErrorHandling(() => client.getProxyAuthConfig(), undefined, callbacks, "Failed to get proxy auth config");
1745
+ }, [client, callbacks]);
1646
1746
  const fetchBootProofForAppProof = react.useCallback(async params => {
1647
1747
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1648
1748
  return utils.withTurnkeyErrorHandling(() => client.fetchBootProofForAppProof(params), () => logout(), callbacks, "Failed to fetch or create delegated access user");
1649
- }, [client, callbacks]);
1749
+ }, [client, callbacks, logout]);
1650
1750
  const verifyAppProofs = react.useCallback(async params => {
1651
1751
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1652
1752
  return utils.withTurnkeyErrorHandling(() => client.verifyAppProofs(params), () => logout(), callbacks, "Failed to verify app proofs");
1653
- }, [client, callbacks]);
1654
- const refreshWallets = react.useCallback(async params => {
1655
- if (!masterConfig?.autoRefreshManagedState) return [];
1656
- const {
1657
- stampWith,
1658
- organizationId,
1659
- userId
1660
- } = params || {};
1661
- if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1662
- const walletProviders = await utils.withTurnkeyErrorHandling(() => fetchWalletProviders(), () => logout(), callbacks, "Failed to refresh wallets");
1663
- const wallets = await utils.withTurnkeyErrorHandling(() => fetchWallets({
1664
- stampWith,
1665
- walletProviders,
1666
- ...(organizationId && {
1667
- organizationId
1668
- }),
1669
- ...(userId && {
1670
- userId
1671
- })
1672
- }), () => logout(), callbacks, "Failed to refresh wallets");
1673
- if (wallets) {
1674
- setWallets(wallets);
1675
- }
1676
- return wallets;
1677
- }, [client, callbacks, fetchWalletProviders, fetchWallets, masterConfig, session, user]);
1753
+ }, [client, callbacks, logout]);
1678
1754
  const handleDiscordOauth = react.useCallback(async params => {
1679
1755
  const {
1680
1756
  clientId = masterConfig?.auth?.oauthConfig?.discordClientId,
@@ -1814,7 +1890,7 @@ const ClientProvider = ({
1814
1890
  } catch (error) {
1815
1891
  throw error;
1816
1892
  }
1817
- }, [client, callbacks, completeOauth, createApiKeyPair, masterConfig, session, user]);
1893
+ }, [client, callbacks, completeOauth, createApiKeyPair, masterConfig]);
1818
1894
  const handleXOauth = react.useCallback(async params => {
1819
1895
  const {
1820
1896
  clientId = masterConfig?.auth?.oauthConfig?.xClientId,
@@ -1954,7 +2030,7 @@ const ClientProvider = ({
1954
2030
  } catch (error) {
1955
2031
  throw error;
1956
2032
  }
1957
- }, [client, callbacks, masterConfig, session, user]);
2033
+ }, [client, callbacks, completeOauth, createApiKeyPair, masterConfig]);
1958
2034
  const handleGoogleOauth = react.useCallback(async params => {
1959
2035
  const {
1960
2036
  clientId = masterConfig?.auth?.oauthConfig?.googleClientId,
@@ -2083,7 +2159,7 @@ const ClientProvider = ({
2083
2159
  } catch (error) {
2084
2160
  throw error;
2085
2161
  }
2086
- }, [client, callbacks, masterConfig, session, user]);
2162
+ }, [callbacks, completeOauth, createApiKeyPair, masterConfig]);
2087
2163
  const handleAppleOauth = react.useCallback(async params => {
2088
2164
  const {
2089
2165
  clientId = masterConfig?.auth?.oauthConfig?.appleClientId,
@@ -2208,7 +2284,7 @@ const ClientProvider = ({
2208
2284
  } catch (error) {
2209
2285
  throw error;
2210
2286
  }
2211
- }, [client, callbacks, masterConfig, session, user]);
2287
+ }, [callbacks, completeOauth, createApiKeyPair, masterConfig]);
2212
2288
  const handleFacebookOauth = react.useCallback(async params => {
2213
2289
  const {
2214
2290
  clientId = masterConfig?.auth?.oauthConfig?.facebookClientId,
@@ -2351,7 +2427,7 @@ const ClientProvider = ({
2351
2427
  } catch (error) {
2352
2428
  throw error;
2353
2429
  }
2354
- }, [client, callbacks, masterConfig, client, session, user]);
2430
+ }, [callbacks, completeOauth, createApiKeyPair, masterConfig]);
2355
2431
  const handleLogin = react.useCallback(async params => {
2356
2432
  const logo = masterConfig?.ui?.darkMode ? params?.logoDark ?? masterConfig?.ui?.logoDark : params?.logoLight ?? masterConfig?.ui?.logoLight;
2357
2433
  pushPage({
@@ -2364,7 +2440,7 @@ const ClientProvider = ({
2364
2440
  }),
2365
2441
  showTitle: logo ? false : true
2366
2442
  });
2367
- }, [pushPage, masterConfig, client, session, user]);
2443
+ }, [pushPage, masterConfig]);
2368
2444
  const handleExportWallet = react.useCallback(async params => {
2369
2445
  const {
2370
2446
  walletId,
@@ -2391,7 +2467,7 @@ const ClientProvider = ({
2391
2467
  }),
2392
2468
  onClose: () => reject(new sdkTypes.TurnkeyError("User canceled the export wallet process.", sdkTypes.TurnkeyErrorCodes.USER_CANCELED))
2393
2469
  }));
2394
- }, [pushPage, masterConfig, client, session, user]);
2470
+ }, [pushPage]);
2395
2471
  const handleExportPrivateKey = react.useCallback(async params => {
2396
2472
  const {
2397
2473
  privateKeyId,
@@ -2422,7 +2498,7 @@ const ClientProvider = ({
2422
2498
  }),
2423
2499
  onClose: () => reject(new sdkTypes.TurnkeyError("User canceled the export private key process.", sdkTypes.TurnkeyErrorCodes.USER_CANCELED))
2424
2500
  }));
2425
- }, [pushPage, masterConfig, client, session, user]);
2501
+ }, [pushPage]);
2426
2502
  const handleExportWalletAccount = react.useCallback(async params => {
2427
2503
  const {
2428
2504
  address,
@@ -2453,13 +2529,14 @@ const ClientProvider = ({
2453
2529
  }),
2454
2530
  onClose: () => reject(new sdkTypes.TurnkeyError("User canceled the export wallet account process.", sdkTypes.TurnkeyErrorCodes.USER_CANCELED))
2455
2531
  }));
2456
- }, [pushPage, masterConfig, client, session, user]);
2532
+ }, [pushPage]);
2457
2533
  const handleImportWallet = react.useCallback(async params => {
2458
2534
  const {
2459
2535
  defaultWalletAccounts,
2460
2536
  successPageDuration = 2000,
2461
2537
  stampWith,
2462
2538
  walletName,
2539
+ clearClipboardOnPaste,
2463
2540
  organizationId,
2464
2541
  userId
2465
2542
  } = params || {};
@@ -2478,6 +2555,9 @@ const ClientProvider = ({
2478
2555
  ...(successPageDuration !== undefined && {
2479
2556
  successPageDuration
2480
2557
  }),
2558
+ ...(clearClipboardOnPaste !== undefined && {
2559
+ clearClipboardOnPaste // Note: This is defaulted to true in the IframeStamper
2560
+ }),
2481
2561
  ...(stampWith !== undefined && {
2482
2562
  stampWith
2483
2563
  }),
@@ -2498,7 +2578,7 @@ const ClientProvider = ({
2498
2578
  }
2499
2579
  throw new sdkTypes.TurnkeyError("Failed to import wallet.", sdkTypes.TurnkeyErrorCodes.IMPORT_WALLET_ERROR, error);
2500
2580
  }
2501
- }, [pushPage, masterConfig, client, session, user]);
2581
+ }, [pushPage, logout]);
2502
2582
  const handleImportPrivateKey = react.useCallback(async params => {
2503
2583
  const {
2504
2584
  curve,
@@ -2506,6 +2586,7 @@ const ClientProvider = ({
2506
2586
  successPageDuration = 2000,
2507
2587
  stampWith,
2508
2588
  keyName,
2589
+ clearClipboardOnPaste,
2509
2590
  organizationId
2510
2591
  } = params || {};
2511
2592
  try {
@@ -2522,6 +2603,9 @@ const ClientProvider = ({
2522
2603
  ...(successPageDuration !== undefined && {
2523
2604
  successPageDuration
2524
2605
  }),
2606
+ ...(clearClipboardOnPaste !== undefined && {
2607
+ clearClipboardOnPaste // Note: This is defaulted to true in the IframeStamper
2608
+ }),
2525
2609
  ...(stampWith !== undefined && {
2526
2610
  stampWith
2527
2611
  }),
@@ -2539,7 +2623,7 @@ const ClientProvider = ({
2539
2623
  }
2540
2624
  throw new sdkTypes.TurnkeyError("Failed to import private key.", sdkTypes.TurnkeyErrorCodes.IMPORT_WALLET_ERROR, error);
2541
2625
  }
2542
- }, [pushPage, masterConfig, client, session, user]);
2626
+ }, [pushPage, logout]);
2543
2627
  const handleUpdateUserName = react.useCallback(async params => {
2544
2628
  const {
2545
2629
  successPageDuration = 2000,
@@ -2616,7 +2700,7 @@ const ClientProvider = ({
2616
2700
  }
2617
2701
  throw new sdkTypes.TurnkeyError("Failed to update user name.", sdkTypes.TurnkeyErrorCodes.UPDATE_USER_NAME_ERROR, error);
2618
2702
  }
2619
- }, [pushPage, masterConfig, client, session, user]);
2703
+ }, [client, getSession, user, pushPage, closeModal, updateUserName, logout]);
2620
2704
  const handleUpdateUserPhoneNumber = react.useCallback(async params => {
2621
2705
  const {
2622
2706
  successPageDuration = 2000,
@@ -2738,7 +2822,7 @@ const ClientProvider = ({
2738
2822
  }
2739
2823
  throw new sdkTypes.TurnkeyError("Failed to initialize OTP for sms verification.", sdkTypes.TurnkeyErrorCodes.INIT_OTP_ERROR, error);
2740
2824
  }
2741
- }, [pushPage, masterConfig, client, session, user]);
2825
+ }, [client, masterConfig, getSession, pushPage, closeModal, logout, initOtp, verifyOtp, updateUserPhoneNumber, user, callbacks]);
2742
2826
  const handleUpdateUserEmail = react.useCallback(async params => {
2743
2827
  const {
2744
2828
  successPageDuration = 2000,
@@ -2853,7 +2937,7 @@ const ClientProvider = ({
2853
2937
  }
2854
2938
  throw new sdkTypes.TurnkeyError("Failed to initialize OTP for email verification.", sdkTypes.TurnkeyErrorCodes.INIT_OTP_ERROR, error);
2855
2939
  }
2856
- }, [pushPage, masterConfig, client, session, user]);
2940
+ }, [client, getSession, pushPage, closeModal, logout, initOtp, masterConfig, verifyOtp, updateUserEmail, user, callbacks]);
2857
2941
  const handleAddEmail = react.useCallback(async params => {
2858
2942
  const {
2859
2943
  successPageDuration = 2000,
@@ -2966,7 +3050,7 @@ const ClientProvider = ({
2966
3050
  }
2967
3051
  throw new sdkTypes.TurnkeyError("Failed to initialize OTP for email verification.", sdkTypes.TurnkeyErrorCodes.INIT_OTP_ERROR, error);
2968
3052
  }
2969
- }, [pushPage, client, session, user]);
3053
+ }, [client, getSession, pushPage, closeModal, user, logout, initOtp, masterConfig, verifyOtp, updateUserEmail, callbacks]);
2970
3054
  const handleAddPhoneNumber = react.useCallback(async params => {
2971
3055
  const {
2972
3056
  successPageDuration = 2000,
@@ -3088,7 +3172,7 @@ const ClientProvider = ({
3088
3172
  }
3089
3173
  throw new sdkTypes.TurnkeyError("Failed to initialize OTP for sms verification.", sdkTypes.TurnkeyErrorCodes.INIT_OTP_ERROR, error);
3090
3174
  }
3091
- }, [pushPage, masterConfig, client, session, user]);
3175
+ }, [client, masterConfig, getSession, pushPage, closeModal, user, logout, callbacks, initOtp, verifyOtp, updateUserPhoneNumber]);
3092
3176
  const handleRemovePasskey = react.useCallback(async params => {
3093
3177
  const {
3094
3178
  authenticatorId,
@@ -3134,7 +3218,7 @@ const ClientProvider = ({
3134
3218
  preventBack: true
3135
3219
  });
3136
3220
  }), () => logout(), callbacks, "Failed to remove passkey");
3137
- }, [pushPage, masterConfig, client, session, user]);
3221
+ }, [client, getSession, pushPage, logout, callbacks]);
3138
3222
  const handleAddPasskey = react.useCallback(async params => {
3139
3223
  const {
3140
3224
  name,
@@ -3187,7 +3271,7 @@ const ClientProvider = ({
3187
3271
  }
3188
3272
  throw new sdkTypes.TurnkeyError("Failed to add passkey in handler.", sdkTypes.TurnkeyErrorCodes.ADD_PASSKEY_ERROR, error);
3189
3273
  }
3190
- }, [pushPage, masterConfig, client, session, user]);
3274
+ }, [client, getSession, addPasskey, pushPage, closeModal]);
3191
3275
  const handleRemoveOauthProvider = react.useCallback(async params => {
3192
3276
  const {
3193
3277
  providerId,
@@ -3237,7 +3321,7 @@ const ClientProvider = ({
3237
3321
  }
3238
3322
  throw new sdkTypes.TurnkeyError("Failed to remove OAuth provider in handler.", sdkTypes.TurnkeyErrorCodes.REMOVE_OAUTH_PROVIDER_ERROR, error);
3239
3323
  }
3240
- }, [pushPage, masterConfig, client, session, user]);
3324
+ }, [client, getSession, pushPage]);
3241
3325
  const handleAddOauthProvider = react.useCallback(async params => {
3242
3326
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
3243
3327
  const {
@@ -3323,7 +3407,7 @@ const ClientProvider = ({
3323
3407
  reject(error);
3324
3408
  }
3325
3409
  });
3326
- }, [pushPage, masterConfig, client, session, user]);
3410
+ }, [client, getSession, addOauthProvider, pushPage, closeModal, handleDiscordOauth, handleXOauth, handleGoogleOauth, handleAppleOauth, handleFacebookOauth]);
3327
3411
  const handleConnectExternalWallet = react.useCallback(async params => {
3328
3412
  const {
3329
3413
  successPageDuration = 2000
@@ -3332,12 +3416,10 @@ const ClientProvider = ({
3332
3416
  if (!masterConfig?.walletConfig?.features?.connecting) {
3333
3417
  throw new sdkTypes.TurnkeyError("Wallet connecting is not enabled.", sdkTypes.TurnkeyErrorCodes.FEATURE_NOT_ENABLED);
3334
3418
  }
3335
- const providers = await fetchWalletProviders();
3336
3419
  return new Promise((resolve, reject) => {
3337
3420
  pushPage({
3338
3421
  key: "Connect wallet",
3339
3422
  content: jsxRuntime.jsx(ConnectWallet.ConnectWalletModal, {
3340
- providers: providers,
3341
3423
  successPageDuration: successPageDuration,
3342
3424
  onSuccess: (type, account) => {
3343
3425
  resolve({
@@ -3349,7 +3431,7 @@ const ClientProvider = ({
3349
3431
  onClose: () => reject(new sdkTypes.TurnkeyError("User canceled the connect wallet process.", sdkTypes.TurnkeyErrorCodes.USER_CANCELED))
3350
3432
  });
3351
3433
  });
3352
- }, [pushPage, masterConfig, client, session, user]);
3434
+ }, [client, masterConfig, fetchWalletProviders, pushPage]);
3353
3435
  const handleRemoveUserEmail = react.useCallback(async params => {
3354
3436
  const {
3355
3437
  successPageDuration = 2000,
@@ -3394,7 +3476,7 @@ const ClientProvider = ({
3394
3476
  }
3395
3477
  throw new sdkTypes.TurnkeyError("Failed to remove user email.", sdkTypes.TurnkeyErrorCodes.UPDATE_USER_EMAIL_ERROR, error);
3396
3478
  }
3397
- }, [pushPage, masterConfig, client, session, user]);
3479
+ }, [getSession, pushPage]);
3398
3480
  const handleRemoveUserPhoneNumber = react.useCallback(async params => {
3399
3481
  const {
3400
3482
  successPageDuration = 2000,
@@ -3439,7 +3521,7 @@ const ClientProvider = ({
3439
3521
  }
3440
3522
  throw new sdkTypes.TurnkeyError("Failed to remove user phone number.", sdkTypes.TurnkeyErrorCodes.UPDATE_USER_PHONE_NUMBER_ERROR, error);
3441
3523
  }
3442
- }, [pushPage, masterConfig, client, session, user]);
3524
+ }, [getSession, pushPage]);
3443
3525
  const handleOnRamp = react.useCallback(async params => {
3444
3526
  const {
3445
3527
  walletAccount,
@@ -3604,14 +3686,14 @@ const ClientProvider = ({
3604
3686
  });
3605
3687
  };
3606
3688
  pushPage({
3607
- key: "Fiat On-Ramp",
3689
+ key: "Fiat OnRamp",
3608
3690
  content: jsxRuntime.jsx(OnRampContainer, {}),
3609
3691
  showTitle: false,
3610
3692
  preventBack: true,
3611
- onClose: () => reject(new sdkTypes.TurnkeyError("User canceled the on-ramp process.", sdkTypes.TurnkeyErrorCodes.USER_CANCELED))
3693
+ onClose: () => reject(new sdkTypes.TurnkeyError("User canceled the onramp process.", sdkTypes.TurnkeyErrorCodes.USER_CANCELED))
3612
3694
  });
3613
3695
  });
3614
- }, [pushPage, client]);
3696
+ }, [getSession, client, pushPage]);
3615
3697
  const handleVerifyAppProofs = react.useCallback(async params => {
3616
3698
  const {
3617
3699
  appProofs,
@@ -3655,16 +3737,18 @@ const ClientProvider = ({
3655
3737
  }
3656
3738
  throw new sdkTypes.TurnkeyError("Failed to verify app proofs.", sdkTypes.TurnkeyErrorCodes.VERIFY_APP_PROOFS_ERROR, error);
3657
3739
  }
3658
- }, [pushPage, client]);
3740
+ }, [getSession, pushPage]);
3659
3741
  react.useEffect(() => {
3660
3742
  if (proxyAuthConfigRef.current) return;
3661
3743
  // Only fetch the proxy auth config once. Use that to build the master config.
3662
3744
  const fetchProxyAuthConfig = async () => {
3663
3745
  try {
3664
3746
  let proxyAuthConfig;
3665
- if (config.authProxyConfigId) {
3666
- // Only fetch the proxy auth config if we have an authProxyId. This is a way for devs to explicitly disable the proxy auth.
3667
- proxyAuthConfig = await core.getAuthProxyConfig(config.authProxyConfigId, config.authProxyUrl);
3747
+ if (shouldFetchWalletKitConfig) {
3748
+ // Only fetch the proxy auth config if we have an authProxyId and the autoFetchWalletKitConfig param is enabled or not passed in.
3749
+ proxyAuthConfig = await core.getAuthProxyConfig(config.authProxyConfigId,
3750
+ // Can assert safely. See shouldFetchWalletKitConfig definition.
3751
+ config.authProxyUrl);
3668
3752
  proxyAuthConfigRef.current = proxyAuthConfig;
3669
3753
  }
3670
3754
  setMasterConfig(buildConfig(proxyAuthConfig));
@@ -3681,31 +3765,33 @@ const ClientProvider = ({
3681
3765
  }, [masterConfig]);
3682
3766
  react.useEffect(() => {
3683
3767
  // Handle changes to the passed in config prop -- update the master config
3684
- // If the proxyAuthConfigRef is already set, we don't need to fetch it again. Rebuild the master config with the updated config and stored proxyAuthConfig
3685
- if (!proxyAuthConfigRef.current && config.authProxyConfigId) return;
3768
+ // Rebuild the master config with the updated config and stored proxyAuthConfig
3769
+ // If we don't have a stored proxyAuthConfig and we need to fetch it, we wait until that fetch is done in the other useEffect.
3770
+ // If shouldFetchWalletKitConfig is false, we'll never have a proxyAuthConfig to build the master config with, so this useEffect should always run.
3771
+ if (!proxyAuthConfigRef.current && shouldFetchWalletKitConfig) return;
3686
3772
  setMasterConfig(buildConfig(proxyAuthConfigRef.current ?? undefined));
3687
3773
  }, [config, proxyAuthConfigRef.current]);
3688
3774
  /**
3689
3775
  * @internal
3690
3776
  * We create `debouncedRefreshWallets()` so that multiple rapid wallet events
3691
3777
  * (for example, on Solana a single disconnect can emit several events we listen for)
3692
- * only trigger `refreshWallets()` once.
3778
+ * only trigger `maybeRefreshWallets()` once.
3693
3779
  *
3694
3780
  * Defining the debounced function outside of the `useEffect` ensures all event
3695
3781
  * listeners in `initializeWalletProviderListeners` share the same instance, instead of creating
3696
3782
  * a new one on every render.
3697
3783
  */
3698
- const debouncedRefreshWallets = utils.useDebouncedCallback(refreshWallets, 100);
3784
+ const debouncedRefreshWallets = utils.useDebouncedCallback(maybeRefreshWallets, 100);
3699
3785
  const debouncedFetchWalletProviders = utils.useDebouncedCallback(fetchWalletProviders, 100);
3700
3786
  react.useEffect(() => {
3701
- if (!client) return;
3702
3787
  const handleUpdateState = async () => {
3703
3788
  // we only refresh the wallets if there is an active session
3704
3789
  // this is needed because a disconnect event can occur
3705
3790
  // while the user is unauthenticated
3706
3791
  //
3707
3792
  // WalletProviders state is updated regardless of session state
3708
- if (session) {
3793
+ const currentSession = await getSession();
3794
+ if (currentSession) {
3709
3795
  // this updates both the wallets and walletProviders state
3710
3796
  await debouncedRefreshWallets();
3711
3797
  } else {
@@ -3722,7 +3808,7 @@ const ClientProvider = ({
3722
3808
  return () => {
3723
3809
  cleanup();
3724
3810
  };
3725
- }, [client, walletProviders, session]);
3811
+ }, [walletProviders, getSession, debouncedRefreshWallets, debouncedFetchWalletProviders]);
3726
3812
  react.useEffect(() => {
3727
3813
  // authState must be consistent with session state. We found during testing that there are cases where the session and authState can be out of sync in very rare edge cases.
3728
3814
  // This will ensure that they are always in sync and remove the need to setAuthState manually in other places.