@forge-connect/react 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -320,6 +320,7 @@ declare function createApiClient(apiUrl: string): {
320
320
  password?: string;
321
321
  challengeId?: string;
322
322
  signature?: string;
323
+ signedTransaction?: string;
323
324
  walletAddress?: string;
324
325
  }): Promise<{
325
326
  success: true;
@@ -648,7 +649,7 @@ declare function useWallets(): {
648
649
  label?: string;
649
650
  isPrimary?: boolean;
650
651
  }) => Promise<void>;
651
- linkWallet: (walletAddress: string, signMessage: (message: Uint8Array) => Promise<Uint8Array>, chain?: string) => Promise<void>;
652
+ linkWallet: (walletAddress: string, signMessage: ((message: Uint8Array) => Promise<Uint8Array>) | undefined, chain?: string, signTransaction?: (txBase64: string) => Promise<string>) => Promise<void>;
652
653
  };
653
654
 
654
655
  declare function useSessions(): {
package/dist/index.d.ts CHANGED
@@ -320,6 +320,7 @@ declare function createApiClient(apiUrl: string): {
320
320
  password?: string;
321
321
  challengeId?: string;
322
322
  signature?: string;
323
+ signedTransaction?: string;
323
324
  walletAddress?: string;
324
325
  }): Promise<{
325
326
  success: true;
@@ -648,7 +649,7 @@ declare function useWallets(): {
648
649
  label?: string;
649
650
  isPrimary?: boolean;
650
651
  }) => Promise<void>;
651
- linkWallet: (walletAddress: string, signMessage: (message: Uint8Array) => Promise<Uint8Array>, chain?: string) => Promise<void>;
652
+ linkWallet: (walletAddress: string, signMessage: ((message: Uint8Array) => Promise<Uint8Array>) | undefined, chain?: string, signTransaction?: (txBase64: string) => Promise<string>) => Promise<void>;
652
653
  };
653
654
 
654
655
  declare function useSessions(): {
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/provider.tsx
2
- import { useState as useState16, useCallback as useCallback8, useEffect as useEffect12, useRef as useRef8, useMemo as useMemo3 } from "react";
2
+ import { useState as useState16, useCallback as useCallback9, useEffect as useEffect12, useRef as useRef9, useMemo as useMemo3 } from "react";
3
3
 
4
4
  // src/context.ts
5
5
  import { createContext } from "react";
@@ -402,26 +402,6 @@ function createApiClient(apiUrl) {
402
402
  }
403
403
 
404
404
  // src/utils.ts
405
- var TOKEN_KEY = "fc_access_token";
406
- function getStoredToken() {
407
- try {
408
- return localStorage.getItem(TOKEN_KEY);
409
- } catch {
410
- return null;
411
- }
412
- }
413
- function setStoredToken(token) {
414
- try {
415
- localStorage.setItem(TOKEN_KEY, token);
416
- } catch {
417
- }
418
- }
419
- function removeStoredToken() {
420
- try {
421
- localStorage.removeItem(TOKEN_KEY);
422
- } catch {
423
- }
424
- }
425
405
  function decodeJWT(token) {
426
406
  try {
427
407
  const parts = token.split(".");
@@ -1253,7 +1233,7 @@ async function startAuthentication(options) {
1253
1233
  }
1254
1234
 
1255
1235
  // src/runtime-imports.ts
1256
- var importSolanaWeb3 = () => new Function('return import("@solana/web3.js")')();
1236
+ var importSolanaWeb3 = () => import("@solana/web3.js");
1257
1237
 
1258
1238
  // src/components/tabs/wallet-connect.tsx
1259
1239
  import { Fragment, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
@@ -2164,19 +2144,33 @@ function useWallets() {
2164
2144
  [api, getAccessToken, fetchWallets]
2165
2145
  );
2166
2146
  const linkWallet = useCallback4(
2167
- async (walletAddress, signMessage, chain = "solana") => {
2147
+ async (walletAddress, signMessage, chain = "solana", signTransaction) => {
2168
2148
  const token = getAccessToken();
2169
2149
  if (!token) throw new Error("Please sign in to continue.");
2170
- const { challengeId, message: challengeMessage } = await api.walletChallenge(walletAddress, chain);
2171
- const encoded = new TextEncoder().encode(challengeMessage);
2172
- const signatureBytes = await signMessage(encoded);
2173
- const signature = chain === "solana" ? uint8ArrayToBase58(signatureBytes) : Array.from(signatureBytes).map((b) => b.toString(16).padStart(2, "0")).join("");
2174
- await api.linkAuthMethod(token, {
2175
- provider: `${chain}_wallet`,
2176
- challengeId,
2177
- signature,
2178
- walletAddress
2179
- });
2150
+ if (signMessage) {
2151
+ const { challengeId, message: challengeMessage } = await api.walletChallenge(walletAddress, chain);
2152
+ const encoded = new TextEncoder().encode(challengeMessage);
2153
+ const signatureBytes = await signMessage(encoded);
2154
+ const signature = chain === "solana" ? uint8ArrayToBase58(signatureBytes) : Array.from(signatureBytes).map((b) => b.toString(16).padStart(2, "0")).join("");
2155
+ await api.linkAuthMethod(token, {
2156
+ provider: `${chain}_wallet`,
2157
+ challengeId,
2158
+ signature,
2159
+ walletAddress
2160
+ });
2161
+ } else {
2162
+ if (!signTransaction) {
2163
+ throw new Error("Wallet does not support message signing or transaction signing.");
2164
+ }
2165
+ const { challengeId, transaction: txBase64 } = await api.walletChallengeTx(walletAddress, chain);
2166
+ const signedTxBase64 = await signTransaction(txBase64);
2167
+ await api.linkAuthMethod(token, {
2168
+ provider: `${chain}_wallet_tx`,
2169
+ challengeId,
2170
+ signedTransaction: signedTxBase64,
2171
+ walletAddress
2172
+ });
2173
+ }
2180
2174
  await fetchWallets();
2181
2175
  },
2182
2176
  [api, getAccessToken, fetchWallets]
@@ -3284,7 +3278,7 @@ function SecurityTab() {
3284
3278
  }
3285
3279
 
3286
3280
  // src/components/link-auth-modal.tsx
3287
- import { useState as useState15, useEffect as useEffect11, useMemo as useMemo2 } from "react";
3281
+ import { useState as useState15, useEffect as useEffect11, useMemo as useMemo2, useRef as useRef8, useCallback as useCallback8 } from "react";
3288
3282
  import { Fragment as Fragment6, jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
3289
3283
  function LinkAuthModal() {
3290
3284
  const { linkModal, closeLinkModal, config } = useForgeConnect();
@@ -3568,10 +3562,23 @@ function WalletLinkStep({ onBack, onSuccess, onFatalError }) {
3568
3562
  const [loading, setLoading] = useState15(false);
3569
3563
  const [error, setError] = useState15("");
3570
3564
  const [showOther, setShowOther] = useState15(false);
3565
+ const [coldWallet, setColdWallet] = useState15(false);
3571
3566
  const mobile = useMemo2(() => isMobile(), []);
3572
3567
  const walletConfig = config.walletConfig;
3573
3568
  const preferred = walletConfig?.preferredWallets ?? [];
3574
3569
  const onlyPreferred = walletConfig?.onlyPreferred ?? false;
3570
+ const coldWalletRef = useRef8(coldWallet);
3571
+ coldWalletRef.current = coldWallet;
3572
+ const buildSignTxFnForAdapter = useCallback8((adapter) => {
3573
+ if (!adapter.signTransaction) return void 0;
3574
+ return async (txBase64) => {
3575
+ const { Transaction } = await importSolanaWeb3();
3576
+ const bytes = Uint8Array.from(atob(txBase64), (c) => c.charCodeAt(0));
3577
+ const tx = Transaction.from(bytes);
3578
+ const signedTx = await adapter.signTransaction(tx);
3579
+ return btoa(String.fromCharCode(...new Uint8Array(signedTx.serialize())));
3580
+ };
3581
+ }, []);
3575
3582
  const handleConnect = async (w) => {
3576
3583
  if (w.readyState !== "Installed") {
3577
3584
  if (mobile) {
@@ -3591,9 +3598,14 @@ function WalletLinkStep({ onBack, onSuccess, onFatalError }) {
3591
3598
  if (!w.adapter.connected) await w.adapter.connect();
3592
3599
  const pk = w.adapter.publicKey;
3593
3600
  if (!pk) throw new Error("Wallet did not provide a public key.");
3601
+ const useCold = coldWalletRef.current;
3594
3602
  const adapterSignMessage = w.adapter.signMessage ? (msg) => w.adapter.signMessage(msg) : void 0;
3595
- if (!adapterSignMessage) throw new Error("This wallet does not support message signing.");
3596
- await linkWallet(pk.toBase58(), adapterSignMessage, "solana");
3603
+ await linkWallet(
3604
+ pk.toBase58(),
3605
+ useCold ? void 0 : adapterSignMessage,
3606
+ "solana",
3607
+ useCold ? buildSignTxFnForAdapter(w.adapter) : void 0
3608
+ );
3597
3609
  onSuccess();
3598
3610
  } catch (err) {
3599
3611
  onFatalError(err instanceof Error ? err.message : "Could not link this wallet. Please try again.");
@@ -3650,7 +3662,7 @@ function WalletLinkStep({ onBack, onSuccess, onFatalError }) {
3650
3662
  return /* @__PURE__ */ jsxs15("div", { className: "fc-tab", children: [
3651
3663
  loading ? /* @__PURE__ */ jsxs15("div", { style: { textAlign: "center", padding: "24px 0" }, children: [
3652
3664
  /* @__PURE__ */ jsx16("p", { className: "fc-tab-title", children: "Connecting..." }),
3653
- /* @__PURE__ */ jsx16("p", { className: "fc-text", children: "Approve the connection, then sign the verification request in your wallet" }),
3665
+ /* @__PURE__ */ jsx16("p", { className: "fc-text", children: coldWallet ? "Confirm the transaction on your device" : "Approve the connection, then sign the verification request in your wallet" }),
3654
3666
  error && /* @__PURE__ */ jsxs15(Fragment6, { children: [
3655
3667
  /* @__PURE__ */ jsx16("p", { className: "fc-error", children: error }),
3656
3668
  /* @__PURE__ */ jsx16(
@@ -3708,6 +3720,21 @@ function WalletLinkStep({ onBack, onSuccess, onFatalError }) {
3708
3720
  ] }, w.adapter.name))
3709
3721
  ] }),
3710
3722
  preferredWallets.length === 0 && otherWallets.length === 0 && mobileExtraWallets.length === 0 && /* @__PURE__ */ jsx16("p", { className: "fc-text", children: "No wallet found. Please install a Solana wallet (like Phantom) to continue." }),
3723
+ /* @__PURE__ */ jsxs15("label", { className: "fc-cold-wallet-toggle", children: [
3724
+ /* @__PURE__ */ jsx16(
3725
+ "input",
3726
+ {
3727
+ type: "checkbox",
3728
+ checked: coldWallet,
3729
+ onChange: (e) => setColdWallet(e.target.checked)
3730
+ }
3731
+ ),
3732
+ /* @__PURE__ */ jsx16("span", { className: "fc-toggle-track" }),
3733
+ /* @__PURE__ */ jsxs15("span", { className: "fc-cold-wallet-label", children: [
3734
+ /* @__PURE__ */ jsx16("span", { children: "Hardware wallet" }),
3735
+ /* @__PURE__ */ jsx16("span", { children: "Ledger, Trezor, Keystone..." })
3736
+ ] })
3737
+ ] }),
3711
3738
  error && /* @__PURE__ */ jsx16("p", { className: "fc-error", children: error })
3712
3739
  ] }),
3713
3740
  !loading && onBack && /* @__PURE__ */ jsx16("div", { className: "fc-switch", children: /* @__PURE__ */ jsx16("button", { type: "button", className: "fc-link", onClick: onBack, children: "Back" }) })
@@ -3738,52 +3765,32 @@ function ForgeConnectProvider({ config, children, onLogin, onLogout, walletAdapt
3738
3765
  const [accountModal, setAccountModal] = useState16({ isOpen: false });
3739
3766
  const [linkModal, setLinkModal] = useState16({ isOpen: false });
3740
3767
  const [challengeToken, setChallengeToken] = useState16(null);
3741
- const apiRef = useRef8(createApiClient(config.apiUrl));
3742
- const refreshTimerRef = useRef8(null);
3768
+ const apiRef = useRef9(createApiClient(config.apiUrl));
3769
+ const refreshTimerRef = useRef9(null);
3743
3770
  const api = apiRef.current;
3744
- const scheduleRefresh = useCallback8((token) => {
3771
+ const scheduleRefresh = useCallback9((token) => {
3745
3772
  if (refreshTimerRef.current) clearTimeout(refreshTimerRef.current);
3746
3773
  const delay = getRefreshDelay(token);
3747
3774
  if (delay === null) return;
3748
3775
  refreshTimerRef.current = setTimeout(async () => {
3749
3776
  try {
3750
3777
  const { accessToken } = await api.refresh();
3751
- setStoredToken(accessToken);
3752
3778
  setAuth((prev) => ({ ...prev, accessToken }));
3753
3779
  scheduleRefresh(accessToken);
3754
3780
  } catch {
3755
- removeStoredToken();
3756
3781
  setAuth({ status: "unauthenticated", user: null, accessToken: null });
3757
3782
  }
3758
3783
  }, delay);
3759
3784
  }, [api]);
3760
3785
  useEffect12(() => {
3761
3786
  const init = async () => {
3762
- const token = getStoredToken();
3763
- if (!token) {
3764
- setAuth({ status: "unauthenticated", user: null, accessToken: null });
3765
- return;
3766
- }
3767
3787
  try {
3768
- const user = await api.getMe(token);
3769
- setAuth({ status: "authenticated", user, accessToken: token });
3770
- scheduleRefresh(token);
3771
- } catch (err) {
3772
- if (err instanceof ForgeConnectApiError && err.status === 401) {
3773
- try {
3774
- const { accessToken } = await api.refresh();
3775
- const user = await api.getMe(accessToken);
3776
- setStoredToken(accessToken);
3777
- setAuth({ status: "authenticated", user, accessToken });
3778
- scheduleRefresh(accessToken);
3779
- } catch {
3780
- removeStoredToken();
3781
- setAuth({ status: "unauthenticated", user: null, accessToken: null });
3782
- }
3783
- } else {
3784
- removeStoredToken();
3785
- setAuth({ status: "unauthenticated", user: null, accessToken: null });
3786
- }
3788
+ const { accessToken } = await api.refresh();
3789
+ const user = await api.getMe(accessToken);
3790
+ setAuth({ status: "authenticated", user, accessToken });
3791
+ scheduleRefresh(accessToken);
3792
+ } catch {
3793
+ setAuth({ status: "unauthenticated", user: null, accessToken: null });
3787
3794
  }
3788
3795
  };
3789
3796
  init();
@@ -3826,7 +3833,6 @@ function ForgeConnectProvider({ config, children, onLogin, onLogout, walletAdapt
3826
3833
  }
3827
3834
  const token = result.accessToken;
3828
3835
  if (!token) return;
3829
- setStoredToken(token);
3830
3836
  setModal({ isOpen: true, step: "success" });
3831
3837
  const user = await api.getMe(token);
3832
3838
  setAuth({ status: "authenticated", user, accessToken: token });
@@ -3836,7 +3842,6 @@ function ForgeConnectProvider({ config, children, onLogin, onLogout, walletAdapt
3836
3842
  setModal({ isOpen: false, step: "method-select" });
3837
3843
  }, 1500);
3838
3844
  } catch {
3839
- removeStoredToken();
3840
3845
  }
3841
3846
  };
3842
3847
  window.addEventListener("message", handleMessage);
@@ -3852,9 +3857,8 @@ function ForgeConnectProvider({ config, children, onLogin, onLogout, walletAdapt
3852
3857
  }
3853
3858
  }
3854
3859
  }, []);
3855
- const handleAuthSuccess = useCallback8(
3860
+ const handleAuthSuccess = useCallback9(
3856
3861
  async (token) => {
3857
- setStoredToken(token);
3858
3862
  const user = await api.getMe(token);
3859
3863
  setAuth({ status: "authenticated", user, accessToken: token });
3860
3864
  scheduleRefresh(token);
@@ -3866,7 +3870,7 @@ function ForgeConnectProvider({ config, children, onLogin, onLogout, walletAdapt
3866
3870
  },
3867
3871
  [api, scheduleRefresh, onLogin]
3868
3872
  );
3869
- const loginWithEmail = useCallback8(
3873
+ const loginWithEmail = useCallback9(
3870
3874
  async (email, password) => {
3871
3875
  const res = await api.login(email, password);
3872
3876
  if (res.requires2FA) {
@@ -3878,19 +3882,19 @@ function ForgeConnectProvider({ config, children, onLogin, onLogout, walletAdapt
3878
3882
  },
3879
3883
  [api, handleAuthSuccess]
3880
3884
  );
3881
- const register = useCallback8(
3885
+ const register = useCallback9(
3882
3886
  async (email, password, displayName) => {
3883
3887
  await api.register(email, password, displayName);
3884
3888
  },
3885
3889
  [api]
3886
3890
  );
3887
- const sendOtp = useCallback8(
3891
+ const sendOtp = useCallback9(
3888
3892
  async (email) => {
3889
3893
  await api.sendOtp(email);
3890
3894
  },
3891
3895
  [api]
3892
3896
  );
3893
- const verifyOtp = useCallback8(
3897
+ const verifyOtp = useCallback9(
3894
3898
  async (email, code) => {
3895
3899
  const res = await api.verifyOtp(email, code);
3896
3900
  if (res.requires2FA) {
@@ -3902,7 +3906,7 @@ function ForgeConnectProvider({ config, children, onLogin, onLogout, walletAdapt
3902
3906
  },
3903
3907
  [api, handleAuthSuccess]
3904
3908
  );
3905
- const loginWithWallet = useCallback8(
3909
+ const loginWithWallet = useCallback9(
3906
3910
  async (walletAddress, signMessage, chain = "solana", signTransaction) => {
3907
3911
  if (signMessage) {
3908
3912
  const { challengeId: challengeId2, message: challengeMessage } = await api.walletChallenge(walletAddress, chain);
@@ -3933,7 +3937,7 @@ function ForgeConnectProvider({ config, children, onLogin, onLogout, walletAdapt
3933
3937
  },
3934
3938
  [api, handleAuthSuccess]
3935
3939
  );
3936
- const loginWithOAuth = useCallback8(
3940
+ const loginWithOAuth = useCallback9(
3937
3941
  (provider) => {
3938
3942
  const callbackUrl = `${config.apiUrl}/auth/oauth/${provider}`;
3939
3943
  const redirectUri = encodeURIComponent(window.location.origin + "/fc-oauth-callback");
@@ -3955,9 +3959,8 @@ function ForgeConnectProvider({ config, children, onLogin, onLogout, walletAdapt
3955
3959
  },
3956
3960
  [config.apiUrl]
3957
3961
  );
3958
- const logout = useCallback8(async () => {
3962
+ const logout = useCallback9(async () => {
3959
3963
  const token = auth.accessToken;
3960
- removeStoredToken();
3961
3964
  if (refreshTimerRef.current) clearTimeout(refreshTimerRef.current);
3962
3965
  setAuth({ status: "unauthenticated", user: null, accessToken: null });
3963
3966
  onLogout?.();
@@ -3968,19 +3971,19 @@ function ForgeConnectProvider({ config, children, onLogin, onLogout, walletAdapt
3968
3971
  }
3969
3972
  }
3970
3973
  }, [auth.accessToken, api, onLogout]);
3971
- const forgotPassword = useCallback8(
3974
+ const forgotPassword = useCallback9(
3972
3975
  async (email) => {
3973
3976
  await api.forgotPassword(email);
3974
3977
  },
3975
3978
  [api]
3976
3979
  );
3977
- const resetPassword = useCallback8(
3980
+ const resetPassword = useCallback9(
3978
3981
  async (token, password) => {
3979
3982
  await api.resetPassword(token, password);
3980
3983
  },
3981
3984
  [api]
3982
3985
  );
3983
- const verifyEmailToken = useCallback8(
3986
+ const verifyEmailToken = useCallback9(
3984
3987
  async (token) => {
3985
3988
  const res = await api.verifyEmailToken(token);
3986
3989
  if (res.requires2FA) {
@@ -3992,27 +3995,26 @@ function ForgeConnectProvider({ config, children, onLogin, onLogout, walletAdapt
3992
3995
  },
3993
3996
  [api, handleAuthSuccess]
3994
3997
  );
3995
- const loginWithPasskey = useCallback8(async () => {
3998
+ const loginWithPasskey = useCallback9(async () => {
3996
3999
  const { options, challengeKey } = await api.getPasskeyLoginOptions(config.webauthnRpId);
3997
4000
  const authResponse = await startAuthentication({ optionsJSON: options });
3998
4001
  const { accessToken } = await api.verifyPasskeyLogin(challengeKey, authResponse, config.webauthnRpId, config.webauthnOrigin);
3999
4002
  await handleAuthSuccess(accessToken);
4000
4003
  }, [api, handleAuthSuccess, config.webauthnRpId, config.webauthnOrigin]);
4001
- const verify2FA = useCallback8(async (code) => {
4004
+ const verify2FA = useCallback9(async (code) => {
4002
4005
  if (!challengeToken) throw new Error("No 2FA challenge active");
4003
4006
  const { accessToken } = await api.verify2FA(challengeToken, code);
4004
4007
  setChallengeToken(null);
4005
4008
  await handleAuthSuccess(accessToken);
4006
4009
  }, [api, challengeToken, handleAuthSuccess]);
4007
- const verifyRecoveryCode = useCallback8(async (code) => {
4010
+ const verifyRecoveryCode = useCallback9(async (code) => {
4008
4011
  if (!challengeToken) throw new Error("No 2FA challenge active");
4009
4012
  const { accessToken } = await api.verifyRecoveryCode(challengeToken, code);
4010
4013
  setChallengeToken(null);
4011
4014
  await handleAuthSuccess(accessToken);
4012
4015
  }, [api, challengeToken, handleAuthSuccess]);
4013
- const logoutAll = useCallback8(async () => {
4016
+ const logoutAll = useCallback9(async () => {
4014
4017
  const token = auth.accessToken;
4015
- removeStoredToken();
4016
4018
  if (refreshTimerRef.current) clearTimeout(refreshTimerRef.current);
4017
4019
  setAuth({ status: "unauthenticated", user: null, accessToken: null });
4018
4020
  onLogout?.();
@@ -4023,7 +4025,7 @@ function ForgeConnectProvider({ config, children, onLogin, onLogout, walletAdapt
4023
4025
  }
4024
4026
  }
4025
4027
  }, [auth.accessToken, api, onLogout]);
4026
- const openModal = useCallback8(() => {
4028
+ const openModal = useCallback9(() => {
4027
4029
  const methods = resolveLoginMethods(config);
4028
4030
  if (methods.length === 1 && isOAuthMethod(methods[0])) {
4029
4031
  loginWithOAuth(methods[0]);
@@ -4036,25 +4038,25 @@ function ForgeConnectProvider({ config, children, onLogin, onLogout, walletAdapt
4036
4038
  const step = resolveInitialStep(config, methods);
4037
4039
  setModal({ isOpen: true, step });
4038
4040
  }, [config, loginWithOAuth]);
4039
- const closeModal = useCallback8(() => {
4041
+ const closeModal = useCallback9(() => {
4040
4042
  setModal({ isOpen: false, step: "method-select" });
4041
4043
  }, []);
4042
- const setModalStep = useCallback8((step) => {
4044
+ const setModalStep = useCallback9((step) => {
4043
4045
  setModal((prev) => ({ ...prev, step }));
4044
4046
  }, []);
4045
- const openAccountModal = useCallback8(() => {
4047
+ const openAccountModal = useCallback9(() => {
4046
4048
  setAccountModal({ isOpen: true });
4047
4049
  }, []);
4048
- const closeAccountModal = useCallback8(() => {
4050
+ const closeAccountModal = useCallback9(() => {
4049
4051
  setAccountModal({ isOpen: false });
4050
4052
  }, []);
4051
- const openLinkModal = useCallback8((mode) => {
4053
+ const openLinkModal = useCallback9((mode) => {
4052
4054
  setLinkModal({ isOpen: true, mode: mode ?? "auth" });
4053
4055
  }, []);
4054
- const closeLinkModal = useCallback8(() => {
4056
+ const closeLinkModal = useCallback9(() => {
4055
4057
  setLinkModal({ isOpen: false });
4056
4058
  }, []);
4057
- const getAccessToken = useCallback8(() => auth.accessToken, [auth.accessToken]);
4059
+ const getAccessToken = useCallback9(() => auth.accessToken, [auth.accessToken]);
4058
4060
  const value = useMemo3(() => ({
4059
4061
  auth,
4060
4062
  modal,
@@ -4158,14 +4160,14 @@ function AccountButton({ className, loginLabel, compact }) {
4158
4160
  }
4159
4161
 
4160
4162
  // src/hooks/use-admin.ts
4161
- import { useState as useState17, useCallback as useCallback9 } from "react";
4163
+ import { useState as useState17, useCallback as useCallback10 } from "react";
4162
4164
  function useAdmin() {
4163
4165
  const { api, getAccessToken } = useForgeConnect();
4164
4166
  const [users, setUsers] = useState17(null);
4165
4167
  const [selectedUser, setSelectedUser] = useState17(null);
4166
4168
  const [userSessions, setUserSessions] = useState17(null);
4167
4169
  const [loading, setLoading] = useState17(false);
4168
- const listUsers = useCallback9(
4170
+ const listUsers = useCallback10(
4169
4171
  async (params) => {
4170
4172
  const token = getAccessToken();
4171
4173
  if (!token) throw new Error("Please sign in to continue.");
@@ -4180,7 +4182,7 @@ function useAdmin() {
4180
4182
  },
4181
4183
  [api, getAccessToken]
4182
4184
  );
4183
- const getUser = useCallback9(
4185
+ const getUser = useCallback10(
4184
4186
  async (id) => {
4185
4187
  const token = getAccessToken();
4186
4188
  if (!token) throw new Error("Please sign in to continue.");
@@ -4195,7 +4197,7 @@ function useAdmin() {
4195
4197
  },
4196
4198
  [api, getAccessToken]
4197
4199
  );
4198
- const updateUserStatus = useCallback9(
4200
+ const updateUserStatus = useCallback10(
4199
4201
  async (id, status) => {
4200
4202
  const token = getAccessToken();
4201
4203
  if (!token) throw new Error("Please sign in to continue.");
@@ -4206,7 +4208,7 @@ function useAdmin() {
4206
4208
  },
4207
4209
  [api, getAccessToken, selectedUser?.id, getUser]
4208
4210
  );
4209
- const getUserSessions = useCallback9(
4211
+ const getUserSessions = useCallback10(
4210
4212
  async (id) => {
4211
4213
  const token = getAccessToken();
4212
4214
  if (!token) throw new Error("Please sign in to continue.");
@@ -4221,7 +4223,7 @@ function useAdmin() {
4221
4223
  },
4222
4224
  [api, getAccessToken]
4223
4225
  );
4224
- const revokeUserSessions = useCallback9(
4226
+ const revokeUserSessions = useCallback10(
4225
4227
  async (id) => {
4226
4228
  const token = getAccessToken();
4227
4229
  if (!token) throw new Error("Please sign in to continue.");
@@ -4244,7 +4246,7 @@ function useAdmin() {
4244
4246
  }
4245
4247
 
4246
4248
  // src/hooks/use-roles.ts
4247
- import { useState as useState18, useCallback as useCallback10 } from "react";
4249
+ import { useState as useState18, useCallback as useCallback11 } from "react";
4248
4250
  function useRoles() {
4249
4251
  const { api, getAccessToken } = useForgeConnect();
4250
4252
  const [roles, setRoles] = useState18(null);
@@ -4253,7 +4255,7 @@ function useRoles() {
4253
4255
  const [roleUsers, setRoleUsers] = useState18(null);
4254
4256
  const [permissionDomains, setPermissionDomains] = useState18(null);
4255
4257
  const [loading, setLoading] = useState18(false);
4256
- const listRoles = useCallback10(
4258
+ const listRoles = useCallback11(
4257
4259
  async (tenantId) => {
4258
4260
  const token = getAccessToken();
4259
4261
  if (!token) throw new Error("Please sign in to continue.");
@@ -4268,7 +4270,7 @@ function useRoles() {
4268
4270
  },
4269
4271
  [api, getAccessToken]
4270
4272
  );
4271
- const getRoleUsers = useCallback10(
4273
+ const getRoleUsers = useCallback11(
4272
4274
  async (id) => {
4273
4275
  const token = getAccessToken();
4274
4276
  if (!token) throw new Error("Please sign in to continue.");
@@ -4278,7 +4280,7 @@ function useRoles() {
4278
4280
  },
4279
4281
  [api, getAccessToken]
4280
4282
  );
4281
- const getRole = useCallback10(
4283
+ const getRole = useCallback11(
4282
4284
  async (id) => {
4283
4285
  const token = getAccessToken();
4284
4286
  if (!token) throw new Error("Please sign in to continue.");
@@ -4295,7 +4297,7 @@ function useRoles() {
4295
4297
  },
4296
4298
  [api, getAccessToken, getRoleUsers]
4297
4299
  );
4298
- const createRole = useCallback10(
4300
+ const createRole = useCallback11(
4299
4301
  async (data) => {
4300
4302
  const token = getAccessToken();
4301
4303
  if (!token) throw new Error("Please sign in to continue.");
@@ -4305,7 +4307,7 @@ function useRoles() {
4305
4307
  },
4306
4308
  [api, getAccessToken, listRoles]
4307
4309
  );
4308
- const updateRole = useCallback10(
4310
+ const updateRole = useCallback11(
4309
4311
  async (id, data) => {
4310
4312
  const token = getAccessToken();
4311
4313
  if (!token) throw new Error("Please sign in to continue.");
@@ -4315,7 +4317,7 @@ function useRoles() {
4315
4317
  },
4316
4318
  [api, getAccessToken]
4317
4319
  );
4318
- const deleteRole = useCallback10(
4320
+ const deleteRole = useCallback11(
4319
4321
  async (id) => {
4320
4322
  const token = getAccessToken();
4321
4323
  if (!token) throw new Error("Please sign in to continue.");
@@ -4324,7 +4326,7 @@ function useRoles() {
4324
4326
  },
4325
4327
  [api, getAccessToken, selectedRole?.id]
4326
4328
  );
4327
- const getPermissions = useCallback10(
4329
+ const getPermissions = useCallback11(
4328
4330
  async () => {
4329
4331
  const token = getAccessToken();
4330
4332
  if (!token) throw new Error("Please sign in to continue.");
@@ -4334,7 +4336,7 @@ function useRoles() {
4334
4336
  },
4335
4337
  [api, getAccessToken]
4336
4338
  );
4337
- const getUserRoles = useCallback10(
4339
+ const getUserRoles = useCallback11(
4338
4340
  async (userId, tenantId) => {
4339
4341
  const token = getAccessToken();
4340
4342
  if (!token) throw new Error("Please sign in to continue.");
@@ -4349,7 +4351,7 @@ function useRoles() {
4349
4351
  },
4350
4352
  [api, getAccessToken]
4351
4353
  );
4352
- const assignRole = useCallback10(
4354
+ const assignRole = useCallback11(
4353
4355
  async (userId, roleId, tenantId) => {
4354
4356
  const token = getAccessToken();
4355
4357
  if (!token) throw new Error("Please sign in to continue.");
@@ -4357,7 +4359,7 @@ function useRoles() {
4357
4359
  },
4358
4360
  [api, getAccessToken]
4359
4361
  );
4360
- const revokeRole = useCallback10(
4362
+ const revokeRole = useCallback11(
4361
4363
  async (userId, roleId, tenantId) => {
4362
4364
  const token = getAccessToken();
4363
4365
  if (!token) throw new Error("Please sign in to continue.");