@turnkey/react-wallet-kit 1.0.0-beta.4 → 1.0.0-beta.5

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 (54) hide show
  1. package/dist/components/auth/Wallet.js +3 -3
  2. package/dist/components/auth/Wallet.js.map +1 -1
  3. package/dist/components/auth/Wallet.mjs +6 -6
  4. package/dist/components/auth/Wallet.mjs.map +1 -1
  5. package/dist/index.d.ts +2 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/providers/TurnkeyProvider.d.ts +1 -0
  8. package/dist/providers/TurnkeyProvider.d.ts.map +1 -1
  9. package/dist/providers/TurnkeyProvider.js +1 -0
  10. package/dist/providers/TurnkeyProvider.js.map +1 -1
  11. package/dist/providers/TurnkeyProvider.mjs +1 -0
  12. package/dist/providers/TurnkeyProvider.mjs.map +1 -1
  13. package/dist/providers/client/Hook.d.ts +1 -0
  14. package/dist/providers/client/Hook.d.ts.map +1 -1
  15. package/dist/providers/client/Hook.js +1 -0
  16. package/dist/providers/client/Hook.js.map +1 -1
  17. package/dist/providers/client/Hook.mjs +1 -0
  18. package/dist/providers/client/Hook.mjs.map +1 -1
  19. package/dist/providers/client/Provider.d.ts.map +1 -1
  20. package/dist/providers/client/Provider.js +337 -285
  21. package/dist/providers/client/Provider.js.map +1 -1
  22. package/dist/providers/client/Provider.mjs +1824 -1856
  23. package/dist/providers/client/Provider.mjs.map +1 -1
  24. package/dist/providers/client/Types.d.ts +50 -41
  25. package/dist/providers/client/Types.d.ts.map +1 -1
  26. package/dist/providers/client/Types.js +1 -0
  27. package/dist/providers/client/Types.js.map +1 -1
  28. package/dist/providers/client/Types.mjs +1 -0
  29. package/dist/providers/client/Types.mjs.map +1 -1
  30. package/dist/providers/modal/Hook.d.ts +1 -0
  31. package/dist/providers/modal/Hook.d.ts.map +1 -1
  32. package/dist/providers/modal/Hook.js +1 -0
  33. package/dist/providers/modal/Hook.js.map +1 -1
  34. package/dist/providers/modal/Hook.mjs +1 -0
  35. package/dist/providers/modal/Hook.mjs.map +1 -1
  36. package/dist/providers/modal/Root.d.ts.map +1 -1
  37. package/dist/providers/modal/Root.js +18 -14
  38. package/dist/providers/modal/Root.js.map +1 -1
  39. package/dist/providers/modal/Root.mjs +19 -17
  40. package/dist/providers/modal/Root.mjs.map +1 -1
  41. package/dist/styles.css +1 -1
  42. package/dist/types/base.d.ts +53 -0
  43. package/dist/types/base.d.ts.map +1 -1
  44. package/dist/types/base.js +12 -0
  45. package/dist/types/base.js.map +1 -1
  46. package/dist/types/base.mjs +12 -0
  47. package/dist/types/base.mjs.map +1 -1
  48. package/dist/utils.d.ts +1 -0
  49. package/dist/utils.d.ts.map +1 -1
  50. package/dist/utils.js +31 -2
  51. package/dist/utils.js.map +1 -1
  52. package/dist/utils.mjs +38 -4
  53. package/dist/utils.mjs.map +1 -1
  54. package/package.json +4 -4
@@ -67,6 +67,9 @@ const ClientProvider = ({
67
67
  const [user, setUser] = react.useState(undefined);
68
68
  const [clientState, setClientState] = react.useState();
69
69
  const [authState, setAuthState] = react.useState(base.AuthState.Unauthenticated);
70
+ // we use this custom hook to only update the state if the value is different
71
+ // this is so our useEffect that calls `initializeWalletProviderListeners()` only runs when it needs to
72
+ const [walletProviders, setWalletProviders] = utils.useWalletProviderState();
70
73
  const expiryTimeoutsRef = react.useRef({});
71
74
  const proxyAuthConfigRef = react.useRef(null);
72
75
  const [allSessions, setAllSessions] = react.useState(undefined);
@@ -74,78 +77,6 @@ const ClientProvider = ({
74
77
  pushPage,
75
78
  closeModal
76
79
  } = Hook.useModal();
77
- react.useEffect(() => {
78
- if (proxyAuthConfigRef.current) return;
79
- // Only fetch the proxy auth config once. Use that to build the master config.
80
- const fetchProxyAuthConfig = async () => {
81
- try {
82
- let proxyAuthConfig;
83
- if (config.authProxyConfigId) {
84
- // Only fetch the proxy auth config if we have an authProxyId. This is a way for devs to explicitly disable the proxy auth.
85
- proxyAuthConfig = await core.getAuthProxyConfig(config.authProxyConfigId, config.authProxyUrl);
86
- proxyAuthConfigRef.current = proxyAuthConfig;
87
- }
88
- setMasterConfig(buildConfig(proxyAuthConfig));
89
- } catch {
90
- setClientState(base.ClientState.Error);
91
- }
92
- };
93
- fetchProxyAuthConfig();
94
- }, []);
95
- react.useEffect(() => {
96
- // Start the client initialization process once we have the master config.
97
- if (!masterConfig) return;
98
- initializeClient();
99
- }, [masterConfig]);
100
- react.useEffect(() => {
101
- // Handle changes to the passed in config prop -- update the master config
102
- // 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
103
- if (!proxyAuthConfigRef.current && config.authProxyConfigId) return;
104
- setMasterConfig(buildConfig(proxyAuthConfigRef.current ?? undefined));
105
- }, [config, proxyAuthConfigRef.current]);
106
- /**
107
- * @internal
108
- * we use debouncedFetchWallets() to prevent multiple rapid wallet events
109
- * like accountsChanged and disconnect from triggering fetchWallets repeatedly
110
- * it must be defined outside the useEffect so all event listeners share the same
111
- * debounced function instance - otherwise, a new one would be created on every render
112
- */
113
- const debouncedFetchWallets = utils.useDebouncedCallback(fetchWallets, 100);
114
- react.useEffect(() => {
115
- if (!client) return;
116
- let cleanup = () => {};
117
- initializeProviders(getWalletProviders, debouncedFetchWallets).then(fn => {
118
- cleanup = fn;
119
- }).catch(err => {
120
- console.error("Failed to init providers:", err);
121
- });
122
- return () => {
123
- cleanup();
124
- };
125
- }, [client, debouncedFetchWallets]);
126
- react.useEffect(() => {
127
- // 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.
128
- // This will ensure that they are always in sync and remove the need to setAuthState manually in other places.
129
- if (session && utils.isValidSession(session)) {
130
- setAuthState(base.AuthState.Authenticated);
131
- } else {
132
- setAuthState(base.AuthState.Unauthenticated);
133
- }
134
- }, [session]);
135
- react.useEffect(() => {
136
- // This will handle any redirect based oAuth. It then initializes the session. This is the last step before client is considered "ready"
137
- if (!client || !masterConfig) return;
138
- completeRedirectOauth().finally(() => {
139
- clearSessionTimeouts();
140
- initializeSessions().finally(() => {
141
- // Set the client state to ready only after all initializations are done.
142
- setClientState(base.ClientState.Ready);
143
- });
144
- });
145
- return () => {
146
- clearSessionTimeouts();
147
- };
148
- }, [client]);
149
80
  const completeRedirectOauth = async () => {
150
81
  // Check for either hash or search parameters that could indicate an OAuth redirect
151
82
  if (window.location.hash || window.location.search) {
@@ -436,6 +367,79 @@ const ClientProvider = ({
436
367
  }
437
368
  }
438
369
  };
370
+ /**
371
+ * @internal
372
+ * Attach listeners for connected wallet providers so we can refresh state on changes.
373
+ *
374
+ * - Ethereum: listens for disconnect and chain switches to trigger a refresh.
375
+ * - Solana: listens for disconnect via Wallet Standard `change` events to trigger a refresh.
376
+ * - WalletConnect: listens for disconnect via our custom wrapper’s `change` event to trigger a refresh.
377
+ *
378
+ * Notes:
379
+ * - Only providers that are connected are bound.
380
+ * - WalletConnect is excluded from the “native” paths and handled via its unified `change` event.
381
+ *
382
+ * @param walletProviders - Discovered providers; only connected ones are bound.
383
+ * @param onWalletsChanged - Invoked when a relevant provider event occurs.
384
+ * @returns Cleanup function that removes all listeners registered by this call.
385
+ */
386
+ async function initializeWalletProviderListeners(walletProviders, onWalletsChanged) {
387
+ if (walletProviders.length === 0) return () => {};
388
+ const cleanups = [];
389
+ // we only want to initialize these listeners for connected walletProviders
390
+ const nativeOnly = provider => provider.interfaceType !== core.WalletInterfaceType.WalletConnect;
391
+ const ethProviders = masterConfig?.walletConfig?.chains.ethereum?.native ? walletProviders.filter(provider => provider.chainInfo.namespace === core.Chain.Ethereum && nativeOnly(provider) && provider.connectedAddresses.length > 0) : [];
392
+ const solProviders = masterConfig?.walletConfig?.chains.solana?.native ? walletProviders.filter(provider => provider.chainInfo.namespace === core.Chain.Solana && nativeOnly(provider) && provider.connectedAddresses.length > 0) : [];
393
+ // we exclude WalletConnect from the native event wiring
394
+ // this is because WC is handled separately with a custom wrapper’s
395
+ // `change` event
396
+ const wcProviders = walletProviders.filter(p => p.interfaceType === core.WalletInterfaceType.WalletConnect && p.connectedAddresses.length > 0);
397
+ function attachEthereumListeners(provider, onWalletsChanged) {
398
+ if (typeof provider.on !== "function") return;
399
+ const handleChainChanged = _chainId => onWalletsChanged();
400
+ const handleAccountsChanged = accounts => {
401
+ if (accounts.length === 0) onWalletsChanged();
402
+ };
403
+ const handleDisconnect = () => onWalletsChanged();
404
+ provider.on("chainChanged", handleChainChanged);
405
+ provider.on("accountsChanged", handleAccountsChanged);
406
+ provider.on("disconnect", handleDisconnect);
407
+ return () => {
408
+ provider.removeListener("chainChanged", handleChainChanged);
409
+ provider.removeListener("accountsChanged", handleAccountsChanged);
410
+ provider.removeListener("disconnect", handleDisconnect);
411
+ };
412
+ }
413
+ function attachSolanaListeners(provider, onWalletsChanged) {
414
+ const cleanups = [];
415
+ const walletEvents = provider?.features?.["standard:events"];
416
+ if (walletEvents?.on) {
417
+ const offChange = walletEvents.on("change", _evt => {
418
+ onWalletsChanged();
419
+ });
420
+ cleanups.push(offChange);
421
+ }
422
+ return () => cleanups.forEach(fn => fn());
423
+ }
424
+ ethProviders.forEach(p => {
425
+ const cleanup = attachEthereumListeners(p.provider, onWalletsChanged);
426
+ if (cleanup) cleanups.push(cleanup);
427
+ });
428
+ solProviders.forEach(p => {
429
+ const cleanup = attachSolanaListeners(p.provider, onWalletsChanged);
430
+ if (cleanup) cleanups.push(cleanup);
431
+ });
432
+ wcProviders.forEach(p => {
433
+ const standardEvents = p.provider?.features?.["standard:events"];
434
+ if (standardEvents?.on) {
435
+ const unsubscribe = standardEvents.on("change", onWalletsChanged);
436
+ cleanups.push(unsubscribe);
437
+ }
438
+ });
439
+ return () => {
440
+ cleanups.forEach(remove => remove());
441
+ };
442
+ }
439
443
  /**
440
444
  * @internal
441
445
  * Schedules a session expiration and warning timeout for the given session key.
@@ -609,23 +613,23 @@ const ClientProvider = ({
609
613
  callbacks?.onError?.(new sdkTypes.TurnkeyError(`Failed to initialize sessions`, sdkTypes.TurnkeyErrorCodes.HANDLE_POST_LOGOUT_ERROR, error));
610
614
  }
611
615
  };
612
- async function createPasskey(params) {
616
+ const createPasskey = react.useCallback(async params => {
613
617
  if (!client) {
614
618
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
615
619
  }
616
620
  return utils.withTurnkeyErrorHandling(() => client.createPasskey({
617
621
  ...params
618
622
  }), callbacks, "Failed to create passkey");
619
- }
620
- async function logout(params) {
623
+ }, [client, callbacks]);
624
+ const logout = react.useCallback(async params => {
621
625
  if (!client) {
622
626
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
623
627
  }
624
- utils.withTurnkeyErrorHandling(() => client.logout(params), callbacks, "Failed to logout");
628
+ await utils.withTurnkeyErrorHandling(() => client.logout(params), callbacks, "Failed to logout");
625
629
  handlePostLogout();
626
630
  return;
627
- }
628
- async function loginWithPasskey(params) {
631
+ }, [client, callbacks]);
632
+ const loginWithPasskey = react.useCallback(async params => {
629
633
  if (!client) {
630
634
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
631
635
  }
@@ -638,8 +642,8 @@ const ClientProvider = ({
638
642
  await handlePostAuth();
639
643
  }
640
644
  return res;
641
- }
642
- async function signUpWithPasskey(params) {
645
+ }, [client, callbacks]);
646
+ const signUpWithPasskey = react.useCallback(async params => {
643
647
  if (!client) {
644
648
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
645
649
  }
@@ -673,92 +677,54 @@ const ClientProvider = ({
673
677
  await handlePostAuth();
674
678
  }
675
679
  return res;
676
- }
677
- async function getWalletProviders(chain) {
680
+ }, [client, callbacks]);
681
+ const getWalletProviders = react.useCallback(async chain => {
678
682
  if (!client) {
679
683
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
680
684
  }
681
- return await client.getWalletProviders(chain);
682
- }
683
- async function connectWalletAccount(walletProvider) {
685
+ const newProviders = await client.getWalletProviders(chain);
686
+ // we update state with the latest providers
687
+ // we keep this state so that initializeWalletProviderListeners() re-runs
688
+ // whenever the list of connected providers changes
689
+ // this ensures we attach disconnect listeners for each connected provider
690
+ setWalletProviders(newProviders);
691
+ return newProviders;
692
+ }, [client, callbacks]);
693
+ const connectWalletAccount = react.useCallback(async walletProvider => {
684
694
  if (!client) {
685
695
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
686
696
  }
687
697
  await client.connectWalletAccount(walletProvider);
698
+ // this will update our walletProvider state
688
699
  await refreshWallets();
689
- }
690
- async function disconnectWalletAccount(walletProvider) {
700
+ }, [client, callbacks]);
701
+ const disconnectWalletAccount = react.useCallback(async walletProvider => {
691
702
  if (!client) {
692
703
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
693
704
  }
694
705
  await client.disconnectWalletAccount(walletProvider);
695
- // we only refresh the wallets if there is an active session
696
- // this is needed because for WalletConnect you can unlink a wallet before
697
- // actually being logged in
698
- if (session) {
706
+ // we only refresh the wallets if:
707
+ // 1. there is an active session. This is needed because for WalletConnect
708
+ // you can unlink a wallet before actually being logged in
709
+ //
710
+ // 2. it was a WalletConnect provider that we just disconnected. Since
711
+ // native providers emit a disconnect event which will already refresh
712
+ // the wallets. This event is triggered in `initializeWalletProviderListeners()`
713
+ if (session && walletProvider.interfaceType === core.WalletInterfaceType.WalletConnect) {
714
+ // this will update our walletProvider state
699
715
  await refreshWallets();
700
716
  }
701
- }
702
- async function switchWalletProviderChain(walletProvider, chainOrId) {
717
+ }, [client, callbacks]);
718
+ const switchWalletAccountChain = react.useCallback(async params => {
703
719
  if (!client) {
704
720
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
705
721
  }
706
- await client.switchWalletProviderChain(walletProvider, chainOrId);
707
- }
708
- // TODO: MOE PLEASE COMMENT THESE
709
- async function initializeProviders(getWalletProviders, onWalletsChanged) {
710
- const cleanups = [];
711
- // we only want to initialize these listeners for native wallet providers
712
- // and not WalletConnect
713
- const nativeOnly = p => p.interfaceType !== core.WalletInterfaceType.WalletConnect;
714
- const ethProviders = masterConfig?.walletConfig?.chains.ethereum?.native ? (await getWalletProviders(core.Chain.Ethereum)).filter(nativeOnly) : [];
715
- const solProviders = masterConfig?.walletConfig?.chains.solana?.native ? (await getWalletProviders(core.Chain.Solana)).filter(nativeOnly) : [];
716
- function attachEthereumListeners(provider, onWalletsChanged) {
717
- if (typeof provider.on !== "function") return;
718
- const handleAccountsChanged = accounts => {
719
- if (accounts.length === 0) onWalletsChanged();
720
- };
721
- const handleDisconnect = () => onWalletsChanged();
722
- provider.on("accountsChanged", handleAccountsChanged);
723
- provider.on("disconnect", handleDisconnect);
724
- return () => {
725
- provider.removeListener("accountsChanged", handleAccountsChanged);
726
- provider.removeListener("disconnect", handleDisconnect);
727
- };
728
- }
729
- function attachSolanaListeners(provider, onWalletsChanged) {
730
- const cleanups = [];
731
- const walletEvents = provider.features?.["standard:events"];
732
- if (walletEvents?.on) {
733
- const handleChange = event => {
734
- if (event.type === "change" || event.type === "accountsChanged") {
735
- onWalletsChanged();
736
- }
737
- };
738
- walletEvents.on("change", handleChange);
739
- walletEvents.on("accountsChanged", handleChange);
740
- cleanups.push(() => {
741
- walletEvents.off?.("change", handleChange);
742
- walletEvents.off?.("accountsChanged", handleChange);
743
- });
744
- }
745
- return cleanups.length > 0 ? () => {
746
- cleanups.forEach(fn => fn());
747
- } : () => {};
748
- }
749
- ethProviders.forEach(p => {
750
- const cleanup = attachEthereumListeners(p.provider, onWalletsChanged);
751
- if (cleanup) cleanups.push(cleanup);
752
- });
753
- solProviders.forEach(p => {
754
- const cleanup = attachSolanaListeners(p.provider, onWalletsChanged);
755
- if (cleanup) cleanups.push(cleanup);
722
+ await client.switchWalletAccountChain({
723
+ ...params,
724
+ walletProviders
756
725
  });
757
- return () => {
758
- cleanups.forEach(remove => remove());
759
- };
760
- }
761
- async function loginWithWallet(params) {
726
+ }, [client, callbacks]);
727
+ const loginWithWallet = react.useCallback(async params => {
762
728
  if (!client) {
763
729
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
764
730
  }
@@ -771,8 +737,8 @@ const ClientProvider = ({
771
737
  await handlePostAuth();
772
738
  }
773
739
  return res;
774
- }
775
- async function signUpWithWallet(params) {
740
+ }, [client, callbacks]);
741
+ const signUpWithWallet = react.useCallback(async params => {
776
742
  if (!client) {
777
743
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
778
744
  }
@@ -796,8 +762,8 @@ const ClientProvider = ({
796
762
  await handlePostAuth();
797
763
  }
798
764
  return res;
799
- }
800
- async function loginOrSignupWithWallet(params) {
765
+ }, [client, callbacks, masterConfig]);
766
+ const loginOrSignupWithWallet = react.useCallback(async params => {
801
767
  if (!client) {
802
768
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
803
769
  }
@@ -821,20 +787,20 @@ const ClientProvider = ({
821
787
  await handlePostAuth();
822
788
  }
823
789
  return res;
824
- }
825
- async function initOtp(params) {
790
+ }, [client, callbacks, masterConfig]);
791
+ const initOtp = react.useCallback(async params => {
826
792
  if (!client) {
827
793
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
828
794
  }
829
795
  return utils.withTurnkeyErrorHandling(() => client.initOtp(params), callbacks, "Failed to initialize OTP");
830
- }
831
- async function verifyOtp(params) {
796
+ }, [client, callbacks]);
797
+ const verifyOtp = react.useCallback(async params => {
832
798
  if (!client) {
833
799
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
834
800
  }
835
801
  return utils.withTurnkeyErrorHandling(() => client.verifyOtp(params), callbacks, "Failed to verify OTP");
836
- }
837
- async function loginWithOtp(params) {
802
+ }, [client, callbacks]);
803
+ const loginWithOtp = react.useCallback(async params => {
838
804
  if (!client) {
839
805
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
840
806
  }
@@ -843,8 +809,8 @@ const ClientProvider = ({
843
809
  await handlePostAuth();
844
810
  }
845
811
  return res;
846
- }
847
- async function signUpWithOtp(params) {
812
+ }, [client, callbacks]);
813
+ const signUpWithOtp = react.useCallback(async params => {
848
814
  if (!client) {
849
815
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
850
816
  }
@@ -871,8 +837,8 @@ const ClientProvider = ({
871
837
  await handlePostAuth();
872
838
  }
873
839
  return res;
874
- }
875
- async function completeOtp(params) {
840
+ }, [client, callbacks, masterConfig]);
841
+ const completeOtp = react.useCallback(async params => {
876
842
  if (!client) {
877
843
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
878
844
  }
@@ -899,8 +865,8 @@ const ClientProvider = ({
899
865
  await handlePostAuth();
900
866
  }
901
867
  return res;
902
- }
903
- async function completeOauth(params) {
868
+ }, [client, callbacks, masterConfig]);
869
+ const completeOauth = react.useCallback(async params => {
904
870
  if (!client) {
905
871
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
906
872
  }
@@ -920,8 +886,8 @@ const ClientProvider = ({
920
886
  await handlePostAuth();
921
887
  }
922
888
  return res;
923
- }
924
- async function loginWithOauth(params) {
889
+ }, [client, callbacks, masterConfig]);
890
+ const loginWithOauth = react.useCallback(async params => {
925
891
  if (!client) {
926
892
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
927
893
  }
@@ -930,8 +896,8 @@ const ClientProvider = ({
930
896
  await handlePostAuth();
931
897
  }
932
898
  return res;
933
- }
934
- async function signUpWithOauth(params) {
899
+ }, [client, callbacks]);
900
+ const signUpWithOauth = react.useCallback(async params => {
935
901
  if (!client) {
936
902
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
937
903
  }
@@ -951,24 +917,24 @@ const ClientProvider = ({
951
917
  await handlePostAuth();
952
918
  }
953
919
  return res;
954
- }
955
- async function fetchWallets(params) {
920
+ }, [client, callbacks, masterConfig]);
921
+ const fetchWallets = react.useCallback(async params => {
956
922
  if (!client) {
957
923
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
958
924
  }
959
925
  return utils.withTurnkeyErrorHandling(() => client.fetchWallets(params), callbacks, "Failed to fetch wallets");
960
- }
961
- async function fetchWalletAccounts(params) {
926
+ }, [client, callbacks]);
927
+ const fetchWalletAccounts = react.useCallback(async params => {
962
928
  if (!client) {
963
929
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
964
930
  }
965
931
  return utils.withTurnkeyErrorHandling(() => client.fetchWalletAccounts(params), callbacks, "Failed to fetch wallet accounts");
966
- }
967
- async function signMessage(params) {
932
+ }, [client, callbacks]);
933
+ const signMessage = react.useCallback(async params => {
968
934
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
969
935
  return utils.withTurnkeyErrorHandling(() => client.signMessage(params), callbacks, "Failed to sign message");
970
- }
971
- async function handleSignMessage(params) {
936
+ }, [client, callbacks]);
937
+ const handleSignMessage = react.useCallback(async params => {
972
938
  const {
973
939
  successPageDuration = 2000
974
940
  } = params;
@@ -1000,146 +966,146 @@ const ClientProvider = ({
1000
966
  })
1001
967
  });
1002
968
  });
1003
- }
1004
- async function signTransaction(params) {
969
+ }, [client, callbacks]);
970
+ const signTransaction = react.useCallback(async params => {
1005
971
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1006
972
  return utils.withTurnkeyErrorHandling(() => client.signTransaction(params), callbacks, "Failed to sign transaction");
1007
- }
1008
- async function signAndSendTransaction(params) {
973
+ }, [client, callbacks]);
974
+ const signAndSendTransaction = react.useCallback(async params => {
1009
975
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1010
976
  return utils.withTurnkeyErrorHandling(() => client.signAndSendTransaction(params), callbacks, "Failed to sign transaction");
1011
- }
1012
- async function fetchUser(params) {
977
+ }, [client, callbacks]);
978
+ const fetchUser = react.useCallback(async params => {
1013
979
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1014
980
  return utils.withTurnkeyErrorHandling(() => client.fetchUser(params), callbacks, "Failed to fetch user");
1015
- }
1016
- async function updateUserEmail(params) {
981
+ }, [client, callbacks]);
982
+ const updateUserEmail = react.useCallback(async params => {
1017
983
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1018
984
  const res = await utils.withTurnkeyErrorHandling(() => client.updateUserEmail(params), callbacks, "Failed to update user email");
1019
985
  if (res) await refreshUser({
1020
986
  stampWith: params?.stampWith
1021
987
  });
1022
988
  return res;
1023
- }
1024
- async function removeUserEmail(params) {
989
+ }, [client, callbacks]);
990
+ const removeUserEmail = react.useCallback(async params => {
1025
991
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1026
992
  const res = await utils.withTurnkeyErrorHandling(() => client.removeUserEmail(params), callbacks, "Failed to remove user email");
1027
993
  if (res) await refreshUser({
1028
994
  stampWith: params?.stampWith
1029
995
  });
1030
996
  return res;
1031
- }
1032
- async function updateUserPhoneNumber(params) {
997
+ }, [client, callbacks]);
998
+ const updateUserPhoneNumber = react.useCallback(async params => {
1033
999
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1034
1000
  const res = await utils.withTurnkeyErrorHandling(() => client.updateUserPhoneNumber(params), callbacks, "Failed to update user phone number");
1035
1001
  if (res) await refreshUser({
1036
1002
  stampWith: params?.stampWith
1037
1003
  });
1038
1004
  return res;
1039
- }
1040
- async function removeUserPhoneNumber(params) {
1005
+ }, [client, callbacks]);
1006
+ const removeUserPhoneNumber = react.useCallback(async params => {
1041
1007
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1042
1008
  const res = await utils.withTurnkeyErrorHandling(() => client.removeUserPhoneNumber(params), callbacks, "Failed to remove user phone number");
1043
1009
  if (res) await refreshUser({
1044
1010
  stampWith: params?.stampWith
1045
1011
  });
1046
1012
  return res;
1047
- }
1048
- async function updateUserName(params) {
1013
+ }, [client, callbacks]);
1014
+ const updateUserName = react.useCallback(async params => {
1049
1015
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1050
1016
  const res = await utils.withTurnkeyErrorHandling(() => client.updateUserName(params), callbacks, "Failed to update user name");
1051
1017
  if (res) await refreshUser({
1052
1018
  stampWith: params?.stampWith
1053
1019
  });
1054
1020
  return res;
1055
- }
1056
- async function addOauthProvider(params) {
1021
+ }, [client, callbacks]);
1022
+ const addOauthProvider = react.useCallback(async params => {
1057
1023
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1058
1024
  const res = await utils.withTurnkeyErrorHandling(() => client.addOauthProvider(params), callbacks, "Failed to add OAuth provider");
1059
1025
  if (res) await refreshUser({
1060
1026
  stampWith: params?.stampWith
1061
1027
  });
1062
1028
  return res;
1063
- }
1064
- async function removeOauthProviders(params) {
1029
+ }, [client, callbacks]);
1030
+ const removeOauthProviders = react.useCallback(async params => {
1065
1031
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1066
1032
  const res = await utils.withTurnkeyErrorHandling(() => client.removeOauthProviders(params), callbacks, "Failed to remove OAuth providers");
1067
1033
  if (res) await refreshUser({
1068
1034
  stampWith: params?.stampWith
1069
1035
  });
1070
1036
  return res;
1071
- }
1072
- async function addPasskey(params) {
1037
+ }, [client, callbacks]);
1038
+ const addPasskey = react.useCallback(async params => {
1073
1039
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1074
1040
  const res = await utils.withTurnkeyErrorHandling(() => client.addPasskey(params), callbacks, "Failed to add passkey");
1075
1041
  if (res) await refreshUser({
1076
1042
  stampWith: params?.stampWith
1077
1043
  });
1078
1044
  return res;
1079
- }
1080
- async function removePasskeys(params) {
1045
+ }, [client, callbacks]);
1046
+ const removePasskeys = react.useCallback(async params => {
1081
1047
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1082
1048
  const res = await utils.withTurnkeyErrorHandling(() => client.removePasskeys(params), callbacks, "Failed to remove passkeys");
1083
1049
  if (res) await refreshUser({
1084
1050
  stampWith: params?.stampWith
1085
1051
  });
1086
1052
  return res;
1087
- }
1088
- async function createWallet(params) {
1053
+ }, [client, callbacks]);
1054
+ const createWallet = react.useCallback(async params => {
1089
1055
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1090
1056
  const res = await utils.withTurnkeyErrorHandling(() => client.createWallet(params), callbacks, "Failed to create wallet");
1091
1057
  if (res) await refreshWallets({
1092
1058
  stampWith: params?.stampWith
1093
1059
  });
1094
1060
  return res;
1095
- }
1096
- async function createWalletAccounts(params) {
1061
+ }, [client, callbacks]);
1062
+ const createWalletAccounts = react.useCallback(async params => {
1097
1063
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1098
1064
  const res = await utils.withTurnkeyErrorHandling(() => client.createWalletAccounts(params), callbacks, "Failed to create wallet accounts");
1099
1065
  if (res) await refreshWallets({
1100
1066
  stampWith: params?.stampWith
1101
1067
  });
1102
1068
  return res;
1103
- }
1104
- async function exportWallet(params) {
1069
+ }, [client, callbacks]);
1070
+ const exportWallet = react.useCallback(async params => {
1105
1071
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1106
1072
  const res = await utils.withTurnkeyErrorHandling(() => client.exportWallet(params), callbacks, "Failed to export wallet");
1107
1073
  if (res) await refreshWallets({
1108
1074
  stampWith: params?.stampWith
1109
1075
  });
1110
1076
  return res;
1111
- }
1112
- async function exportPrivateKey(params) {
1077
+ }, [client, callbacks]);
1078
+ const exportPrivateKey = react.useCallback(async params => {
1113
1079
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1114
1080
  const res = await utils.withTurnkeyErrorHandling(() => client.exportPrivateKey(params), callbacks, "Failed to export private key");
1115
1081
  return res;
1116
- }
1117
- async function exportWalletAccount(params) {
1082
+ }, [client, callbacks]);
1083
+ const exportWalletAccount = react.useCallback(async params => {
1118
1084
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1119
1085
  const res = await utils.withTurnkeyErrorHandling(() => client.exportWalletAccount(params), callbacks, "Failed to export wallet accounts");
1120
1086
  if (res) await refreshWallets({
1121
1087
  stampWith: params?.stampWith
1122
1088
  });
1123
1089
  return res;
1124
- }
1125
- async function importWallet(params) {
1090
+ }, [client, callbacks]);
1091
+ const importWallet = react.useCallback(async params => {
1126
1092
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1127
1093
  const res = await utils.withTurnkeyErrorHandling(() => client.importWallet(params), callbacks, "Failed to import wallet");
1128
1094
  if (res) await refreshWallets({
1129
1095
  stampWith: params?.stampWith
1130
1096
  });
1131
1097
  return res;
1132
- }
1133
- async function importPrivateKey(params) {
1098
+ }, [client, callbacks]);
1099
+ const importPrivateKey = react.useCallback(async params => {
1134
1100
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1135
1101
  const res = await utils.withTurnkeyErrorHandling(() => client.importPrivateKey(params), callbacks, "Failed to import private key");
1136
1102
  return res;
1137
- }
1138
- async function deleteSubOrganization(params) {
1103
+ }, [client, callbacks]);
1104
+ const deleteSubOrganization = react.useCallback(async params => {
1139
1105
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1140
1106
  return utils.withTurnkeyErrorHandling(() => client.deleteSubOrganization(params), callbacks, "Failed to delete sub-organization");
1141
- }
1142
- async function storeSession(params) {
1107
+ }, [client, callbacks]);
1108
+ const storeSession = react.useCallback(async params => {
1143
1109
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1144
1110
  await utils.withTurnkeyErrorHandling(() => client.storeSession(params), callbacks, "Failed to store session");
1145
1111
  const sessionKey = await getActiveSessionKey();
@@ -1156,8 +1122,8 @@ const ClientProvider = ({
1156
1122
  setSession(session);
1157
1123
  setAllSessions(allSessions);
1158
1124
  return;
1159
- }
1160
- async function clearSession(params) {
1125
+ }, [client, callbacks]);
1126
+ const clearSession = react.useCallback(async params => {
1161
1127
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1162
1128
  await utils.withTurnkeyErrorHandling(() => client.clearSession(params), callbacks, "Failed to clear session");
1163
1129
  const session = await getSession();
@@ -1165,14 +1131,14 @@ const ClientProvider = ({
1165
1131
  setSession(session);
1166
1132
  setAllSessions(allSessions);
1167
1133
  return;
1168
- }
1169
- async function clearAllSessions() {
1134
+ }, [client, callbacks]);
1135
+ const clearAllSessions = react.useCallback(async () => {
1170
1136
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1171
1137
  setSession(undefined);
1172
1138
  setAllSessions(undefined);
1173
1139
  return await utils.withTurnkeyErrorHandling(() => client.clearAllSessions(), callbacks, "Failed to clear all sessions");
1174
- }
1175
- async function refreshSession(params) {
1140
+ }, [client, callbacks]);
1141
+ const refreshSession = react.useCallback(async params => {
1176
1142
  if (!client) {
1177
1143
  throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1178
1144
  }
@@ -1200,16 +1166,16 @@ const ClientProvider = ({
1200
1166
  setSession(session);
1201
1167
  setAllSessions(allSessions);
1202
1168
  return res;
1203
- }
1204
- async function getSession(params) {
1169
+ }, [client, callbacks]);
1170
+ const getSession = react.useCallback(async params => {
1205
1171
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1206
1172
  return utils.withTurnkeyErrorHandling(() => client.getSession(params), callbacks, "Failed to get session");
1207
- }
1208
- async function getAllSessions() {
1173
+ }, [client, callbacks]);
1174
+ const getAllSessions = react.useCallback(async () => {
1209
1175
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1210
1176
  return utils.withTurnkeyErrorHandling(() => client.getAllSessions(), callbacks, "Failed to get all sessions");
1211
- }
1212
- async function setActiveSession(params) {
1177
+ }, [client, callbacks]);
1178
+ const setActiveSession = react.useCallback(async params => {
1213
1179
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1214
1180
  const session = await utils.withTurnkeyErrorHandling(() => client.getSession({
1215
1181
  sessionKey: params.sessionKey
@@ -1220,24 +1186,24 @@ const ClientProvider = ({
1220
1186
  await utils.withTurnkeyErrorHandling(() => client.setActiveSession(params), callbacks, "Failed to set active session");
1221
1187
  setSession(session);
1222
1188
  return;
1223
- }
1224
- async function getActiveSessionKey() {
1189
+ }, [client, callbacks]);
1190
+ const getActiveSessionKey = react.useCallback(async () => {
1225
1191
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1226
1192
  return utils.withTurnkeyErrorHandling(() => client.getActiveSessionKey(), callbacks, "Failed to get active session key");
1227
- }
1228
- async function clearUnusedKeyPairs() {
1193
+ }, [client, callbacks]);
1194
+ const clearUnusedKeyPairs = react.useCallback(async () => {
1229
1195
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1230
1196
  return utils.withTurnkeyErrorHandling(() => client.clearUnusedKeyPairs(), callbacks, "Failed to clear unused key pairs");
1231
- }
1232
- async function createApiKeyPair(params) {
1197
+ }, [client, callbacks]);
1198
+ const createApiKeyPair = react.useCallback(async params => {
1233
1199
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1234
1200
  return utils.withTurnkeyErrorHandling(() => client.createApiKeyPair(params), callbacks, "Failed to create API key pair");
1235
- }
1236
- async function getProxyAuthConfig() {
1201
+ }, [client, callbacks]);
1202
+ const getProxyAuthConfig = react.useCallback(async () => {
1237
1203
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1238
1204
  return utils.withTurnkeyErrorHandling(() => client.getProxyAuthConfig(), callbacks, "Failed to get proxy auth config");
1239
- }
1240
- async function refreshUser(params) {
1205
+ }, [client, callbacks]);
1206
+ const refreshUser = react.useCallback(async params => {
1241
1207
  const {
1242
1208
  stampWith
1243
1209
  } = params || {};
@@ -1248,20 +1214,22 @@ const ClientProvider = ({
1248
1214
  if (user) {
1249
1215
  setUser(user);
1250
1216
  }
1251
- }
1252
- async function refreshWallets(params) {
1217
+ }, [client, callbacks]);
1218
+ const refreshWallets = react.useCallback(async params => {
1253
1219
  const {
1254
1220
  stampWith
1255
1221
  } = params || {};
1256
1222
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
1223
+ const walletProviders = await utils.withTurnkeyErrorHandling(() => getWalletProviders(), callbacks, "Failed to refresh wallets");
1257
1224
  const wallets = await utils.withTurnkeyErrorHandling(() => fetchWallets({
1258
- stampWith
1225
+ stampWith,
1226
+ walletProviders
1259
1227
  }), callbacks, "Failed to refresh wallets");
1260
1228
  if (wallets) {
1261
1229
  setWallets(wallets);
1262
1230
  }
1263
- }
1264
- async function handleGoogleOauth(params) {
1231
+ }, [client, callbacks, getWalletProviders, fetchWallets]);
1232
+ const handleGoogleOauth = react.useCallback(async params => {
1265
1233
  const {
1266
1234
  clientId = masterConfig?.auth?.oauthConfig?.googleClientId,
1267
1235
  openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
@@ -1377,8 +1345,8 @@ const ClientProvider = ({
1377
1345
  } catch (error) {
1378
1346
  throw error;
1379
1347
  }
1380
- }
1381
- async function handleAppleOauth(params) {
1348
+ }, [client, callbacks]);
1349
+ const handleAppleOauth = react.useCallback(async params => {
1382
1350
  const {
1383
1351
  clientId = masterConfig?.auth?.oauthConfig?.appleClientId,
1384
1352
  openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
@@ -1490,8 +1458,8 @@ const ClientProvider = ({
1490
1458
  } catch (error) {
1491
1459
  throw error;
1492
1460
  }
1493
- }
1494
- async function handleFacebookOauth(params) {
1461
+ }, [client, callbacks]);
1462
+ const handleFacebookOauth = react.useCallback(async params => {
1495
1463
  const {
1496
1464
  clientId = masterConfig?.auth?.oauthConfig?.facebookClientId,
1497
1465
  openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
@@ -1622,14 +1590,14 @@ const ClientProvider = ({
1622
1590
  } catch (error) {
1623
1591
  throw error;
1624
1592
  }
1625
- }
1626
- const handleLogin = async () => {
1593
+ }, [client, callbacks]);
1594
+ const handleLogin = react.useCallback(async () => {
1627
1595
  pushPage({
1628
1596
  key: "Log in or sign up",
1629
1597
  content: jsxRuntime.jsx(index.AuthComponent, {})
1630
1598
  });
1631
- };
1632
- const handleExportWallet = async params => {
1599
+ }, [pushPage]);
1600
+ const handleExportWallet = react.useCallback(async params => {
1633
1601
  const {
1634
1602
  walletId,
1635
1603
  targetPublicKey,
@@ -1648,8 +1616,8 @@ const ClientProvider = ({
1648
1616
  } : {})
1649
1617
  })
1650
1618
  });
1651
- };
1652
- const handleExportPrivateKey = async params => {
1619
+ }, [pushPage]);
1620
+ const handleExportPrivateKey = react.useCallback(async params => {
1653
1621
  const {
1654
1622
  privateKeyId,
1655
1623
  targetPublicKey,
@@ -1668,8 +1636,8 @@ const ClientProvider = ({
1668
1636
  } : {})
1669
1637
  })
1670
1638
  });
1671
- };
1672
- const handleExportWalletAccount = async params => {
1639
+ }, [pushPage]);
1640
+ const handleExportWalletAccount = react.useCallback(async params => {
1673
1641
  const {
1674
1642
  address,
1675
1643
  targetPublicKey,
@@ -1688,8 +1656,8 @@ const ClientProvider = ({
1688
1656
  } : {})
1689
1657
  })
1690
1658
  });
1691
- };
1692
- const handleImportWallet = async params => {
1659
+ }, [pushPage]);
1660
+ const handleImportWallet = react.useCallback(async params => {
1693
1661
  const {
1694
1662
  defaultWalletAccounts,
1695
1663
  successPageDuration = 2000,
@@ -1720,8 +1688,8 @@ const ClientProvider = ({
1720
1688
  }
1721
1689
  throw new sdkTypes.TurnkeyError("Failed to import wallet.", sdkTypes.TurnkeyErrorCodes.IMPORT_WALLET_ERROR, error);
1722
1690
  }
1723
- };
1724
- const handleUpdateUserName = async params => {
1691
+ }, [pushPage]);
1692
+ const handleUpdateUserName = react.useCallback(async params => {
1725
1693
  const {
1726
1694
  successPageDuration = 2000,
1727
1695
  subTitle,
@@ -1786,8 +1754,8 @@ const ClientProvider = ({
1786
1754
  }
1787
1755
  throw new sdkTypes.TurnkeyError("Failed to update user name.", sdkTypes.TurnkeyErrorCodes.UPDATE_USER_NAME_ERROR, error);
1788
1756
  }
1789
- };
1790
- const handleUpdateUserPhoneNumber = async params => {
1757
+ }, [pushPage]);
1758
+ const handleUpdateUserPhoneNumber = react.useCallback(async params => {
1791
1759
  const {
1792
1760
  successPageDuration = 2000,
1793
1761
  subTitle,
@@ -1890,8 +1858,8 @@ const ClientProvider = ({
1890
1858
  }
1891
1859
  throw new sdkTypes.TurnkeyError("Failed to initialize OTP for sms verification.", sdkTypes.TurnkeyErrorCodes.INIT_OTP_ERROR, error);
1892
1860
  }
1893
- };
1894
- const handleUpdateUserEmail = async params => {
1861
+ }, [pushPage]);
1862
+ const handleUpdateUserEmail = react.useCallback(async params => {
1895
1863
  const {
1896
1864
  successPageDuration = 2000,
1897
1865
  subTitle,
@@ -1987,8 +1955,8 @@ const ClientProvider = ({
1987
1955
  }
1988
1956
  throw new sdkTypes.TurnkeyError("Failed to initialize OTP for email verification.", sdkTypes.TurnkeyErrorCodes.INIT_OTP_ERROR, error);
1989
1957
  }
1990
- };
1991
- const handleAddEmail = async params => {
1958
+ }, [pushPage]);
1959
+ const handleAddEmail = react.useCallback(async params => {
1992
1960
  const {
1993
1961
  successPageDuration = 2000,
1994
1962
  subTitle,
@@ -2084,8 +2052,8 @@ const ClientProvider = ({
2084
2052
  }
2085
2053
  throw new sdkTypes.TurnkeyError("Failed to initialize OTP for email verification.", sdkTypes.TurnkeyErrorCodes.INIT_OTP_ERROR, error);
2086
2054
  }
2087
- };
2088
- const handleAddPhoneNumber = async params => {
2055
+ }, [pushPage]);
2056
+ const handleAddPhoneNumber = react.useCallback(async params => {
2089
2057
  const {
2090
2058
  successPageDuration = 2000,
2091
2059
  subTitle,
@@ -2192,8 +2160,8 @@ const ClientProvider = ({
2192
2160
  }
2193
2161
  throw new sdkTypes.TurnkeyError("Failed to initialize OTP for sms verification.", sdkTypes.TurnkeyErrorCodes.INIT_OTP_ERROR, error);
2194
2162
  }
2195
- };
2196
- const handleRemovePasskey = async params => {
2163
+ }, [pushPage]);
2164
+ const handleRemovePasskey = react.useCallback(async params => {
2197
2165
  const {
2198
2166
  authenticatorId,
2199
2167
  successPageDuration = 2000,
@@ -2233,8 +2201,8 @@ const ClientProvider = ({
2233
2201
  preventBack: true
2234
2202
  });
2235
2203
  }), callbacks, "Failed to remove passkey");
2236
- };
2237
- const handleAddPasskey = async params => {
2204
+ }, [pushPage]);
2205
+ const handleAddPasskey = react.useCallback(async params => {
2238
2206
  const {
2239
2207
  name,
2240
2208
  displayName,
@@ -2278,8 +2246,8 @@ const ClientProvider = ({
2278
2246
  }
2279
2247
  throw new sdkTypes.TurnkeyError("Failed to add passkey in handler.", sdkTypes.TurnkeyErrorCodes.ADD_PASSKEY_ERROR, error);
2280
2248
  }
2281
- };
2282
- const handleRemoveOauthProvider = async params => {
2249
+ }, [pushPage]);
2250
+ const handleRemoveOauthProvider = react.useCallback(async params => {
2283
2251
  const {
2284
2252
  providerId,
2285
2253
  successPageDuration = 2000,
@@ -2322,8 +2290,8 @@ const ClientProvider = ({
2322
2290
  }
2323
2291
  throw new sdkTypes.TurnkeyError("Failed to remove OAuth provider in handler.", sdkTypes.TurnkeyErrorCodes.REMOVE_OAUTH_PROVIDER_ERROR, error);
2324
2292
  }
2325
- };
2326
- const handleAddOauthProvider = async params => {
2293
+ }, [pushPage]);
2294
+ const handleAddOauthProvider = react.useCallback(async params => {
2327
2295
  if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
2328
2296
  if (!session) {
2329
2297
  throw new sdkTypes.TurnkeyError("No active session found.", sdkTypes.TurnkeyErrorCodes.NO_SESSION_FOUND);
@@ -2381,8 +2349,8 @@ const ClientProvider = ({
2381
2349
  throw new sdkTypes.TurnkeyError(`Unsupported OAuth provider: ${providerName}`, sdkTypes.TurnkeyErrorCodes.NOT_FOUND);
2382
2350
  }
2383
2351
  }
2384
- };
2385
- const handleLinkExternalWallet = async params => {
2352
+ }, [pushPage]);
2353
+ const handleLinkExternalWallet = react.useCallback(async params => {
2386
2354
  const {
2387
2355
  successPageDuration = 2000
2388
2356
  } = params || {};
@@ -2401,8 +2369,8 @@ const ClientProvider = ({
2401
2369
  successPageDuration: successPageDuration
2402
2370
  })
2403
2371
  });
2404
- };
2405
- const handleRemoveUserEmail = async params => {
2372
+ }, [pushPage]);
2373
+ const handleRemoveUserEmail = react.useCallback(async params => {
2406
2374
  const {
2407
2375
  successPageDuration = 2000,
2408
2376
  stampWith,
@@ -2440,8 +2408,8 @@ const ClientProvider = ({
2440
2408
  }
2441
2409
  throw new sdkTypes.TurnkeyError("Failed to remove user email.", sdkTypes.TurnkeyErrorCodes.UPDATE_USER_EMAIL_ERROR, error);
2442
2410
  }
2443
- };
2444
- const handleRemoveUserPhoneNumber = async params => {
2411
+ }, [pushPage]);
2412
+ const handleRemoveUserPhoneNumber = react.useCallback(async params => {
2445
2413
  const {
2446
2414
  successPageDuration = 2000,
2447
2415
  stampWith,
@@ -2479,7 +2447,91 @@ const ClientProvider = ({
2479
2447
  }
2480
2448
  throw new sdkTypes.TurnkeyError("Failed to remove user phone number.", sdkTypes.TurnkeyErrorCodes.UPDATE_USER_PHONE_NUMBER_ERROR, error);
2481
2449
  }
2482
- };
2450
+ }, [pushPage]);
2451
+ react.useEffect(() => {
2452
+ if (proxyAuthConfigRef.current) return;
2453
+ // Only fetch the proxy auth config once. Use that to build the master config.
2454
+ const fetchProxyAuthConfig = async () => {
2455
+ try {
2456
+ let proxyAuthConfig;
2457
+ if (config.authProxyConfigId) {
2458
+ // Only fetch the proxy auth config if we have an authProxyId. This is a way for devs to explicitly disable the proxy auth.
2459
+ proxyAuthConfig = await core.getAuthProxyConfig(config.authProxyConfigId, config.authProxyUrl);
2460
+ proxyAuthConfigRef.current = proxyAuthConfig;
2461
+ }
2462
+ setMasterConfig(buildConfig(proxyAuthConfig));
2463
+ } catch {
2464
+ setClientState(base.ClientState.Error);
2465
+ }
2466
+ };
2467
+ fetchProxyAuthConfig();
2468
+ }, []);
2469
+ react.useEffect(() => {
2470
+ // Start the client initialization process once we have the master config.
2471
+ if (!masterConfig) return;
2472
+ initializeClient();
2473
+ }, [masterConfig]);
2474
+ react.useEffect(() => {
2475
+ // Handle changes to the passed in config prop -- update the master config
2476
+ // 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
2477
+ if (!proxyAuthConfigRef.current && config.authProxyConfigId) return;
2478
+ setMasterConfig(buildConfig(proxyAuthConfigRef.current ?? undefined));
2479
+ }, [config, proxyAuthConfigRef.current]);
2480
+ /**
2481
+ * @internal
2482
+ * We create `debouncedRefreshWallets()` so that multiple rapid wallet events
2483
+ * (for example, on Solana a single disconnect can emit several events we listen for)
2484
+ * only trigger `refreshWallets()` once.
2485
+ *
2486
+ * Defining the debounced function outside of the `useEffect` ensures all event
2487
+ * listeners in `initializeProviders` share the same instance, instead of creating
2488
+ * a new one on every render.
2489
+ */
2490
+ const debouncedRefreshWallets = utils.useDebouncedCallback(refreshWallets, 100);
2491
+ react.useEffect(() => {
2492
+ if (!client) return;
2493
+ const handleRefreshWallets = async () => {
2494
+ // we only refresh the wallets if there is an active session
2495
+ // this is needed because a disconnect event can occur
2496
+ // while the user is unauthenticated
2497
+ if (session) {
2498
+ // this will update our walletProvider state
2499
+ await debouncedRefreshWallets();
2500
+ }
2501
+ };
2502
+ let cleanup = () => {};
2503
+ initializeWalletProviderListeners(walletProviders, handleRefreshWallets).then(fn => {
2504
+ cleanup = fn;
2505
+ }).catch(err => {
2506
+ console.error("Failed to init providers:", err);
2507
+ });
2508
+ return () => {
2509
+ cleanup();
2510
+ };
2511
+ }, [client, walletProviders]);
2512
+ react.useEffect(() => {
2513
+ // 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.
2514
+ // This will ensure that they are always in sync and remove the need to setAuthState manually in other places.
2515
+ if (session && utils.isValidSession(session)) {
2516
+ setAuthState(base.AuthState.Authenticated);
2517
+ } else {
2518
+ setAuthState(base.AuthState.Unauthenticated);
2519
+ }
2520
+ }, [session]);
2521
+ react.useEffect(() => {
2522
+ // This will handle any redirect based oAuth. It then initializes the session. This is the last step before client is considered "ready"
2523
+ if (!client || !masterConfig) return;
2524
+ completeRedirectOauth().finally(() => {
2525
+ clearSessionTimeouts();
2526
+ initializeSessions().finally(() => {
2527
+ // Set the client state to ready only after all initializations are done.
2528
+ setClientState(base.ClientState.Ready);
2529
+ });
2530
+ });
2531
+ return () => {
2532
+ clearSessionTimeouts();
2533
+ };
2534
+ }, [client]);
2483
2535
  return jsxRuntime.jsx(Types.ClientContext.Provider, {
2484
2536
  value: {
2485
2537
  session,
@@ -2497,7 +2549,7 @@ const ClientProvider = ({
2497
2549
  getWalletProviders,
2498
2550
  connectWalletAccount,
2499
2551
  disconnectWalletAccount,
2500
- switchWalletProviderChain,
2552
+ switchWalletAccountChain,
2501
2553
  loginWithWallet,
2502
2554
  signUpWithWallet,
2503
2555
  loginOrSignupWithWallet,