@volr/react 0.1.69 → 0.1.71

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.cjs CHANGED
@@ -18691,45 +18691,15 @@ function useVolrLogin() {
18691
18691
  handlePasskeyComplete
18692
18692
  };
18693
18693
  }
18694
- function createAxiosInstance(baseUrl, apiKey) {
18695
- const instance = axios__default.default.create({
18696
- baseURL: baseUrl.replace(/\/+$/, ""),
18697
- // Remove trailing slashes
18698
- withCredentials: true,
18699
- // Include cookies
18700
- headers: {
18701
- "Content-Type": "application/json"
18702
- }
18703
- });
18704
- instance.interceptors.request.use((config) => {
18705
- if (apiKey) {
18706
- config.headers["X-API-Key"] = apiKey;
18707
- }
18708
- return config;
18709
- });
18710
- instance.interceptors.response.use(
18711
- (response) => response,
18712
- (error) => {
18713
- if (error.response?.data) {
18714
- const errorData = error.response.data;
18715
- if (errorData.error?.message) {
18716
- error.message = errorData.error.message;
18717
- }
18718
- }
18719
- return Promise.reject(error);
18720
- }
18721
- );
18722
- return instance;
18723
- }
18724
-
18725
- // src/hooks/useVolrAuthCallback.ts
18726
18694
  function useVolrAuthCallback(options = {}) {
18727
- const { config, setUser } = useVolrContext();
18728
- const { refreshAccessToken, setAccessToken, setRefreshToken, client } = useInternalAuth();
18695
+ const { clearUrlParams = true } = options;
18696
+ const { setUser } = useVolrContext();
18697
+ const { setAccessToken, setRefreshToken, client } = useInternalAuth();
18729
18698
  const [isLoading, setIsLoading] = react.useState(true);
18730
18699
  const [error, setError] = react.useState(null);
18731
18700
  const [isNewUser, setIsNewUser] = react.useState(false);
18732
18701
  const [user, setLocalUser] = react.useState(null);
18702
+ const hasProcessed = react.useRef(false);
18733
18703
  const toVolrUser = react.useCallback((u) => {
18734
18704
  return {
18735
18705
  id: u.id,
@@ -18745,24 +18715,31 @@ function useVolrAuthCallback(options = {}) {
18745
18715
  credentialId: u.credentialId ?? void 0
18746
18716
  };
18747
18717
  }, []);
18748
- const apiBaseUrl = resolveApiBaseUrl(config);
18749
18718
  react.useEffect(() => {
18750
18719
  const handleCallback = async () => {
18751
18720
  if (typeof window === "undefined") return;
18721
+ if (hasProcessed.current) return;
18722
+ hasProcessed.current = true;
18752
18723
  const searchParams = new URLSearchParams(window.location.search);
18753
- const success = searchParams.get("success");
18724
+ const authCode = searchParams.get("code");
18754
18725
  const errorParam = searchParams.get("error");
18755
- const userId = searchParams.get("userId");
18756
18726
  const isNew = searchParams.get("isNewUser") === "true";
18757
18727
  if (errorParam) {
18758
- const errorMsg = `Authentication failed: ${errorParam}`;
18728
+ const errorMsg = `Authentication failed: ${errorParam.replace(/_/g, " ")}`;
18729
+ setError(errorMsg);
18730
+ setIsLoading(false);
18731
+ options.onError?.(errorMsg);
18732
+ return;
18733
+ }
18734
+ if (!authCode) {
18735
+ const errorMsg = "No authorization code found. Please try logging in again.";
18759
18736
  setError(errorMsg);
18760
18737
  setIsLoading(false);
18761
18738
  options.onError?.(errorMsg);
18762
18739
  return;
18763
18740
  }
18764
- if (success !== "true" || !userId) {
18765
- const errorMsg = "Invalid callback parameters";
18741
+ if (!authCode.startsWith("volr_auth_")) {
18742
+ const errorMsg = "Invalid authorization code format";
18766
18743
  setError(errorMsg);
18767
18744
  setIsLoading(false);
18768
18745
  options.onError?.(errorMsg);
@@ -18770,45 +18747,44 @@ function useVolrAuthCallback(options = {}) {
18770
18747
  }
18771
18748
  try {
18772
18749
  setIsNewUser(isNew);
18773
- await refreshAccessToken();
18774
- const api = createAxiosInstance(
18775
- apiBaseUrl,
18776
- config.projectApiKey
18777
- );
18778
- const userRes = await api.get(`/auth/onboarding/${userId}`);
18779
- if (!userRes.data?.ok) {
18780
- throw new Error("Failed to fetch user details");
18781
- }
18782
- const currentRefreshToken = client.getRefreshToken();
18783
- if (!currentRefreshToken) {
18784
- throw new Error("No refresh token available. Please log in again.");
18785
- }
18786
- const refreshRes = await api.post("/auth/refresh", { refreshToken: currentRefreshToken });
18787
- if (!refreshRes.data?.ok) {
18788
- throw new Error("Failed to refresh session");
18750
+ const response = await client.post("/auth/token/exchange", { code: authCode });
18751
+ const { user: userData, accessToken, refreshToken } = response;
18752
+ if (!accessToken) {
18753
+ throw new Error("No access token received from server");
18789
18754
  }
18790
- const userData = refreshRes.data.data.user;
18791
- const accessToken = refreshRes.data.data.accessToken;
18792
- const newRefreshToken = refreshRes.data.data.refreshToken;
18793
18755
  setAccessToken(accessToken);
18794
- if (newRefreshToken) {
18795
- setRefreshToken(newRefreshToken);
18756
+ if (refreshToken) {
18757
+ setRefreshToken(refreshToken);
18796
18758
  }
18797
18759
  const volrUser = toVolrUser(userData);
18798
18760
  setUser(volrUser);
18799
18761
  setLocalUser(volrUser);
18762
+ if (clearUrlParams && typeof window !== "undefined") {
18763
+ const url = new URL(window.location.href);
18764
+ url.search = "";
18765
+ window.history.replaceState({}, "", url.toString());
18766
+ }
18800
18767
  setIsLoading(false);
18801
18768
  options.onSuccess?.(volrUser);
18802
18769
  } catch (err) {
18803
- console.error("Callback error:", err);
18804
- const errorMsg = err.message || "Failed to complete authentication";
18770
+ console.error("[useVolrAuthCallback] Token exchange error:", err);
18771
+ let errorMsg = "Failed to complete authentication";
18772
+ if (err instanceof Error) {
18773
+ if (err.message.includes("AUTH_CODE_EXPIRED")) {
18774
+ errorMsg = "Login link has expired. Please try again.";
18775
+ } else if (err.message.includes("AUTH_INVALID_CODE")) {
18776
+ errorMsg = "Invalid login link. Please try again.";
18777
+ } else {
18778
+ errorMsg = err.message;
18779
+ }
18780
+ }
18805
18781
  setError(errorMsg);
18806
18782
  setIsLoading(false);
18807
18783
  options.onError?.(errorMsg);
18808
18784
  }
18809
18785
  };
18810
18786
  handleCallback();
18811
- }, [apiBaseUrl, config.projectApiKey, refreshAccessToken, setAccessToken, setRefreshToken, setUser, toVolrUser, client]);
18787
+ }, []);
18812
18788
  return {
18813
18789
  isLoading,
18814
18790
  error,
@@ -18890,10 +18866,8 @@ function useDepositListener(input) {
18890
18866
  try {
18891
18867
  if (!rpcUrlRef.current) {
18892
18868
  rpcUrlRef.current = await getRpcUrl(input.chainId);
18893
- console.log("[DepositListener] RPC URL:", rpcUrlRef.current);
18894
18869
  }
18895
18870
  const initial = await fetchBalance();
18896
- console.log("[DepositListener] Initial balance:", initial.toString());
18897
18871
  if (cancelled) return;
18898
18872
  setStatus({ state: "listening", balance: initial });
18899
18873
  } catch (e) {
@@ -18903,16 +18877,13 @@ function useDepositListener(input) {
18903
18877
  return;
18904
18878
  }
18905
18879
  const intervalMs = input.pollIntervalMs ?? config.deposit?.pollIntervalMs ?? 6e3;
18906
- console.log("[DepositListener] Polling interval:", intervalMs, "ms");
18907
18880
  intervalRef.current = window.setInterval(async () => {
18908
18881
  try {
18909
18882
  const current = await fetchBalance();
18910
- console.log("[DepositListener] Current balance:", current.toString());
18911
18883
  if (cancelled) return;
18912
18884
  setStatus((prev) => {
18913
18885
  if (prev.state === "listening") {
18914
18886
  if (current > prev.balance) {
18915
- console.log("[DepositListener] \u2705 DEPOSIT DETECTED! Previous:", prev.balance.toString(), "New:", current.toString());
18916
18887
  return {
18917
18888
  state: "detected",
18918
18889
  previousBalance: prev.balance,
@@ -18921,7 +18892,6 @@ function useDepositListener(input) {
18921
18892
  };
18922
18893
  }
18923
18894
  if (current !== prev.balance) {
18924
- console.log("[DepositListener] \u26A0\uFE0F Balance changed (decreased or other). Previous:", prev.balance.toString(), "New:", current.toString());
18925
18895
  return {
18926
18896
  state: "detected",
18927
18897
  previousBalance: prev.balance,
@@ -18932,7 +18902,6 @@ function useDepositListener(input) {
18932
18902
  return prev;
18933
18903
  }
18934
18904
  if (prev.state === "detected") {
18935
- console.log("[DepositListener] Resuming listening from new balance:", current.toString());
18936
18905
  return { state: "listening", balance: current };
18937
18906
  }
18938
18907
  return prev;
@@ -19365,6 +19334,36 @@ function useMpcConnection() {
19365
19334
  error
19366
19335
  };
19367
19336
  }
19337
+ function createAxiosInstance(baseUrl, apiKey) {
19338
+ const instance = axios__default.default.create({
19339
+ baseURL: baseUrl.replace(/\/+$/, ""),
19340
+ // Remove trailing slashes
19341
+ withCredentials: true,
19342
+ // Include cookies
19343
+ headers: {
19344
+ "Content-Type": "application/json"
19345
+ }
19346
+ });
19347
+ instance.interceptors.request.use((config) => {
19348
+ if (apiKey) {
19349
+ config.headers["X-API-Key"] = apiKey;
19350
+ }
19351
+ return config;
19352
+ });
19353
+ instance.interceptors.response.use(
19354
+ (response) => response,
19355
+ (error) => {
19356
+ if (error.response?.data) {
19357
+ const errorData = error.response.data;
19358
+ if (errorData.error?.message) {
19359
+ error.message = errorData.error.message;
19360
+ }
19361
+ }
19362
+ return Promise.reject(error);
19363
+ }
19364
+ );
19365
+ return instance;
19366
+ }
19368
19367
 
19369
19368
  // src/headless/blobs.ts
19370
19369
  async function uploadBlobViaPresign(params) {