@volr/react 0.1.14 → 0.1.18

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
@@ -9030,9 +9030,10 @@ var safeStorage = {
9030
9030
  }
9031
9031
  };
9032
9032
 
9033
- // ../shared/src/constants/storage.ts
9033
+ // ../shared/dist/constants/storage.js
9034
9034
  var STORAGE_KEYS = {
9035
9035
  accessToken: "volr:accessToken",
9036
+ refreshToken: "volr:refreshToken",
9036
9037
  user: "volr:user",
9037
9038
  provider: "volr:provider",
9038
9039
  credentialId: "volr:credentialId",
@@ -9048,9 +9049,11 @@ var APIClient = class {
9048
9049
  constructor(config) {
9049
9050
  this.refreshPromise = null;
9050
9051
  this.accessToken = null;
9052
+ this.refreshToken = null;
9051
9053
  this.apiKey = null;
9052
9054
  this.apiKey = config.apiKey || null;
9053
9055
  this.accessToken = safeStorage.getItem(STORAGE_KEYS.accessToken);
9056
+ this.refreshToken = safeStorage.getItem(STORAGE_KEYS.refreshToken);
9054
9057
  this.api = axios__default.default.create({
9055
9058
  baseURL: config.baseUrl.replace(/\/+$/, ""),
9056
9059
  withCredentials: true,
@@ -9087,15 +9090,23 @@ var APIClient = class {
9087
9090
  (response) => response,
9088
9091
  async (error) => {
9089
9092
  const originalRequest = error.config;
9093
+ console.log(`[APIClient] Response error:`, error.response?.status, originalRequest?.url);
9094
+ if (originalRequest?.url?.includes("/auth/refresh")) {
9095
+ console.log("[APIClient] Refresh endpoint failed, not retrying");
9096
+ return Promise.reject(error);
9097
+ }
9090
9098
  if (error.response?.status === 401 && !originalRequest._retry) {
9099
+ console.log("[APIClient] 401 received, attempting token refresh...");
9091
9100
  originalRequest._retry = true;
9092
9101
  try {
9093
9102
  await this.refreshAccessToken();
9094
9103
  if (this.accessToken) {
9095
9104
  originalRequest.headers["Authorization"] = `Bearer ${this.accessToken}`;
9096
9105
  }
9106
+ console.log("[APIClient] Token refreshed, retrying original request");
9097
9107
  return this.api(originalRequest);
9098
9108
  } catch (refreshError) {
9109
+ console.error("[APIClient] Token refresh failed:", refreshError);
9099
9110
  return Promise.reject(refreshError);
9100
9111
  }
9101
9112
  }
@@ -9132,6 +9143,76 @@ var APIClient = class {
9132
9143
  getAccessToken() {
9133
9144
  return this.accessToken;
9134
9145
  }
9146
+ /**
9147
+ * Set refresh token
9148
+ */
9149
+ setRefreshToken(token) {
9150
+ this.refreshToken = token;
9151
+ if (token) {
9152
+ safeStorage.setItem(STORAGE_KEYS.refreshToken, token);
9153
+ } else {
9154
+ safeStorage.removeItem(STORAGE_KEYS.refreshToken);
9155
+ }
9156
+ }
9157
+ /**
9158
+ * Get refresh token
9159
+ */
9160
+ getRefreshToken() {
9161
+ return this.refreshToken;
9162
+ }
9163
+ /**
9164
+ * Ensure access token is valid, refresh if missing or expired
9165
+ * Use this before making authenticated requests that need a valid token upfront
9166
+ * Note: Most requests don't need this as the 401 interceptor handles refresh automatically
9167
+ */
9168
+ async ensureAccessToken() {
9169
+ if (this.accessToken) {
9170
+ return;
9171
+ }
9172
+ if (!this.refreshToken) {
9173
+ return;
9174
+ }
9175
+ try {
9176
+ await this.refreshAccessToken();
9177
+ } catch {
9178
+ }
9179
+ }
9180
+ /**
9181
+ * Refresh session and return user data
9182
+ * Use this when you need fresh user data (e.g., before passkey restoration)
9183
+ * @param timeoutMs - Timeout in milliseconds (default: 10000)
9184
+ * @returns User data from refresh response, or null if refresh fails
9185
+ */
9186
+ async refreshSession(timeoutMs = 1e4) {
9187
+ if (!this.refreshToken) {
9188
+ throw new Error("No refresh token available. Please log in again.");
9189
+ }
9190
+ const timeoutPromise = new Promise(
9191
+ (_, reject) => setTimeout(
9192
+ () => reject(new Error("Session refresh timeout. Please check your network connection.")),
9193
+ timeoutMs
9194
+ )
9195
+ );
9196
+ const refreshPromise = this.api.post(
9197
+ "/auth/refresh",
9198
+ { refreshToken: this.refreshToken }
9199
+ );
9200
+ const response = await Promise.race([refreshPromise, timeoutPromise]);
9201
+ const data = response.data;
9202
+ if (isErrorResponse(data)) {
9203
+ this.setAccessToken(null);
9204
+ this.setRefreshToken(null);
9205
+ throw new Error(data.error.message);
9206
+ }
9207
+ this.setAccessToken(data.data.accessToken);
9208
+ if (data.data.refreshToken) {
9209
+ this.setRefreshToken(data.data.refreshToken);
9210
+ }
9211
+ if (data.data.user) {
9212
+ safeStorage.setItem(STORAGE_KEYS.user, JSON.stringify(data.data.user));
9213
+ }
9214
+ return data.data.user ?? null;
9215
+ }
9135
9216
  /**
9136
9217
  * Refresh access token (single-flight)
9137
9218
  */
@@ -9139,19 +9220,26 @@ var APIClient = class {
9139
9220
  if (this.refreshPromise) {
9140
9221
  return this.refreshPromise;
9141
9222
  }
9223
+ if (!this.refreshToken) {
9224
+ throw new Error("No refresh token available. Please log in again.");
9225
+ }
9142
9226
  this.refreshPromise = (async () => {
9143
9227
  try {
9144
9228
  const response = await this.api.post(
9145
9229
  "/auth/refresh",
9146
- {}
9230
+ { refreshToken: this.refreshToken }
9147
9231
  );
9148
9232
  const data = response.data;
9149
9233
  if (isErrorResponse(data)) {
9150
9234
  this.setAccessToken(null);
9235
+ this.setRefreshToken(null);
9151
9236
  safeStorage.removeItem(STORAGE_KEYS.user);
9152
9237
  throw new Error(data.error.message);
9153
9238
  }
9154
9239
  this.setAccessToken(data.data.accessToken);
9240
+ if (data.data.refreshToken) {
9241
+ this.setRefreshToken(data.data.refreshToken);
9242
+ }
9155
9243
  if (data.data.user) {
9156
9244
  safeStorage.setItem(STORAGE_KEYS.user, JSON.stringify(data.data.user));
9157
9245
  }
@@ -9187,6 +9275,7 @@ var APIClient = class {
9187
9275
  */
9188
9276
  async post(endpoint, body, idempotencyKey) {
9189
9277
  const normalizedEndpoint = endpoint.startsWith("/") ? endpoint : `/${endpoint}`;
9278
+ console.log(`[APIClient] POST ${normalizedEndpoint}`);
9190
9279
  const config = {
9191
9280
  method: "POST",
9192
9281
  url: normalizedEndpoint,
@@ -9197,8 +9286,14 @@ var APIClient = class {
9197
9286
  "Idempotency-Key": idempotencyKey
9198
9287
  };
9199
9288
  }
9200
- const response = await this.api.request(config);
9201
- return unwrapResponse(response.data);
9289
+ try {
9290
+ const response = await this.api.request(config);
9291
+ console.log(`[APIClient] POST ${normalizedEndpoint} response:`, response.data);
9292
+ return unwrapResponse(response.data);
9293
+ } catch (error) {
9294
+ console.error(`[APIClient] POST ${normalizedEndpoint} error:`, error);
9295
+ throw error;
9296
+ }
9202
9297
  }
9203
9298
  /**
9204
9299
  * POST request that returns raw binary (ArrayBuffer)
@@ -9532,16 +9627,12 @@ async function restorePasskey(params) {
9532
9627
  );
9533
9628
  console.log("[restorePasskey] prfInput:", prfInput);
9534
9629
  console.log("[restorePasskey] Step 1: Ensuring access token is fresh...");
9535
- const currentToken = client.getAccessToken();
9536
- if (!currentToken) {
9537
- console.log("[restorePasskey] No access token found, calling /auth/refresh...");
9538
- try {
9539
- await client.post("/auth/refresh", {});
9540
- console.log("[restorePasskey] Access token refreshed successfully");
9541
- } catch (error) {
9542
- console.error("[restorePasskey] Failed to refresh access token:", error);
9543
- throw new Error("Failed to refresh access token. Please log in again.");
9544
- }
9630
+ try {
9631
+ await client.ensureAccessToken();
9632
+ console.log("[restorePasskey] Access token ensured");
9633
+ } catch (error) {
9634
+ console.error("[restorePasskey] Failed to ensure access token:", error);
9635
+ throw new Error("Failed to refresh access token. Please log in again.");
9545
9636
  }
9546
9637
  console.log("[restorePasskey] Step 2: Downloading blob via backend proxy for blobUrl:", blobUrl);
9547
9638
  const apiKey = client.getApiKey();
@@ -9653,6 +9744,9 @@ function VolrProvider({ config, children }) {
9653
9744
  const [accessToken, setAccessTokenState] = react.useState(() => {
9654
9745
  return client.getAccessToken();
9655
9746
  });
9747
+ const [refreshToken, setRefreshTokenState] = react.useState(() => {
9748
+ return client.getRefreshToken();
9749
+ });
9656
9750
  const syncRef = react.useRef(null);
9657
9751
  react.useEffect(() => {
9658
9752
  syncRef.current = new SessionSync();
@@ -9668,7 +9762,9 @@ function VolrProvider({ config, children }) {
9668
9762
  client.setApiKey(config.projectApiKey);
9669
9763
  } else if (event.type === "LOGOUT") {
9670
9764
  client.setAccessToken(null);
9765
+ client.setRefreshToken(null);
9671
9766
  setAccessTokenState(null);
9767
+ setRefreshTokenState(null);
9672
9768
  setUser(null);
9673
9769
  setProviderState(null);
9674
9770
  safeStorage.removeItem(STORAGE_KEYS.user);
@@ -9697,49 +9793,16 @@ function VolrProvider({ config, children }) {
9697
9793
  const keyStorageType = newProvider.keyStorageType;
9698
9794
  setProviderState(newProvider);
9699
9795
  try {
9700
- const refreshResponse = await client.post(
9701
- "/auth/refresh",
9702
- {}
9703
- );
9704
- if (refreshResponse.user) {
9705
- console.log(
9706
- "[Provider] setProvider: User data refreshed from backend:",
9707
- refreshResponse.user
9708
- );
9709
- setUser(refreshResponse.user);
9710
- safeStorage.setItem(
9711
- STORAGE_KEYS.user,
9712
- JSON.stringify(refreshResponse.user)
9713
- );
9796
+ const refreshedUser = await client.refreshSession();
9797
+ if (refreshedUser) {
9798
+ console.log("[Provider] setProvider: User data refreshed:", refreshedUser);
9799
+ setUser(refreshedUser);
9714
9800
  } else {
9715
- setUser((prev) => ({
9716
- ...prev,
9717
- keyStorageType
9718
- }));
9719
- safeStorage.setItem(
9720
- STORAGE_KEYS.user,
9721
- JSON.stringify({
9722
- ...user,
9723
- keyStorageType
9724
- })
9725
- );
9801
+ setUser((prev) => ({ ...prev, keyStorageType }));
9726
9802
  }
9727
9803
  } catch (error2) {
9728
- console.warn(
9729
- "[Provider] setProvider: Failed to refresh user data, using partial update:",
9730
- error2
9731
- );
9732
- setUser((prev) => ({
9733
- ...prev,
9734
- keyStorageType
9735
- }));
9736
- safeStorage.setItem(
9737
- STORAGE_KEYS.user,
9738
- JSON.stringify({
9739
- ...user,
9740
- keyStorageType
9741
- })
9742
- );
9804
+ console.warn("[Provider] setProvider: Failed to refresh user data:", error2);
9805
+ setUser((prev) => ({ ...prev, keyStorageType }));
9743
9806
  }
9744
9807
  safeStorage.setItem(STORAGE_KEYS.provider, keyStorageType);
9745
9808
  syncRef.current?.broadcast({
@@ -9764,70 +9827,38 @@ function VolrProvider({ config, children }) {
9764
9827
  const recover = async () => {
9765
9828
  try {
9766
9829
  setIsLoading(true);
9767
- const response = await client.post(
9768
- "/auth/refresh",
9769
- {}
9770
- );
9771
- console.log("[Provider] /auth/refresh response:", response);
9772
- const refreshedToken = client.getAccessToken();
9773
- if (refreshedToken) {
9774
- if (response.user) {
9775
- console.log(
9776
- "[Provider] Setting user from response:",
9777
- response.user
9778
- );
9779
- console.log("[Provider] User fields:", {
9780
- id: response.user.id,
9781
- email: response.user.email,
9782
- accountId: response.user.accountId,
9783
- evmAddress: response.user.evmAddress,
9784
- signerType: response.user.signerType,
9785
- keyStorageType: response.user.keyStorageType,
9786
- walletConnector: response.user.walletConnector,
9787
- blobUrl: response.user.blobUrl,
9788
- prfInput: response.user.prfInput,
9789
- credentialId: response.user.credentialId
9790
- });
9791
- setUser(response.user);
9792
- safeStorage.setItem(
9793
- STORAGE_KEYS.user,
9794
- JSON.stringify(response.user)
9795
- );
9796
- if (!REQUIRE_USER_GESTURE_TO_RESTORE) ; else {
9797
- if (response.user.keyStorageType === "passkey") {
9798
- console.log(
9799
- "[Provider] TTL=0 mode: Provider restoration deferred until transaction (requires user gesture)"
9800
- );
9801
- if (!response.user.blobUrl || !response.user.prfInput) {
9802
- console.warn(
9803
- "[Provider] Passkey user detected but missing blobUrl or prfInput. User needs to re-enroll passkey."
9804
- );
9805
- }
9806
- }
9830
+ if (!client.getRefreshToken()) {
9831
+ console.log("[Provider] No refresh token found, skipping auto-recover");
9832
+ setIsLoading(false);
9833
+ return;
9834
+ }
9835
+ const refreshedUser = await client.refreshSession();
9836
+ console.log("[Provider] Session refreshed, user:", refreshedUser);
9837
+ setAccessTokenState(client.getAccessToken());
9838
+ setRefreshTokenState(client.getRefreshToken());
9839
+ if (refreshedUser) {
9840
+ setUser(refreshedUser);
9841
+ if (!REQUIRE_USER_GESTURE_TO_RESTORE) ; else if (refreshedUser.keyStorageType === "passkey") {
9842
+ console.log("[Provider] TTL=0 mode: Provider restoration deferred");
9843
+ if (!refreshedUser.blobUrl || !refreshedUser.prfInput) {
9844
+ console.warn("[Provider] Passkey user missing blobUrl or prfInput");
9807
9845
  }
9808
- } else {
9809
- console.log(
9810
- "[Provider] No user in response, loading from storage"
9811
- );
9812
- const userStr = safeStorage.getItem(STORAGE_KEYS.user);
9813
- if (userStr) {
9814
- try {
9815
- const storedUser = JSON.parse(userStr);
9816
- console.log(
9817
- "[Provider] Loaded user from storage:",
9818
- storedUser
9819
- );
9820
- setUser(storedUser);
9821
- } catch {
9822
- safeStorage.removeItem(STORAGE_KEYS.user);
9823
- }
9846
+ }
9847
+ } else {
9848
+ const userStr = safeStorage.getItem(STORAGE_KEYS.user);
9849
+ if (userStr) {
9850
+ try {
9851
+ setUser(JSON.parse(userStr));
9852
+ } catch {
9853
+ safeStorage.removeItem(STORAGE_KEYS.user);
9824
9854
  }
9825
9855
  }
9826
- setAccessTokenState(refreshedToken);
9827
9856
  }
9828
9857
  } catch {
9829
9858
  client.setAccessToken(null);
9859
+ client.setRefreshToken(null);
9830
9860
  setAccessTokenState(null);
9861
+ setRefreshTokenState(null);
9831
9862
  setUser(null);
9832
9863
  setProviderState(null);
9833
9864
  safeStorage.removeItem(STORAGE_KEYS.user);
@@ -9845,12 +9876,7 @@ function VolrProvider({ config, children }) {
9845
9876
  async (input) => {
9846
9877
  try {
9847
9878
  setError(null);
9848
- if (!client.getAccessToken()) {
9849
- try {
9850
- await client.post("/auth/refresh", {});
9851
- } catch {
9852
- }
9853
- }
9879
+ await client.ensureAccessToken();
9854
9880
  const response = await client.post(
9855
9881
  "/wallet/precheck",
9856
9882
  input
@@ -9872,12 +9898,7 @@ function VolrProvider({ config, children }) {
9872
9898
  async (input, opts) => {
9873
9899
  try {
9874
9900
  setError(null);
9875
- if (!client.getAccessToken()) {
9876
- try {
9877
- await client.post("/auth/refresh", {});
9878
- } catch {
9879
- }
9880
- }
9901
+ await client.ensureAccessToken();
9881
9902
  const idempotencyKey = opts?.idempotencyKey ?? (typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : `${Date.now()}-${Math.random()}`);
9882
9903
  const serializedInput = serializeBigIntDeep(input);
9883
9904
  const response = await client.post(
@@ -9902,10 +9923,14 @@ function VolrProvider({ config, children }) {
9902
9923
  try {
9903
9924
  setError(null);
9904
9925
  client.setAccessToken(null);
9926
+ client.setRefreshToken(null);
9927
+ setAccessTokenState(null);
9928
+ setRefreshTokenState(null);
9905
9929
  setUser(null);
9906
9930
  setProviderState(null);
9907
9931
  safeStorage.removeItem(STORAGE_KEYS.user);
9908
9932
  safeStorage.removeItem(STORAGE_KEYS.accessToken);
9933
+ safeStorage.removeItem(STORAGE_KEYS.refreshToken);
9909
9934
  safeStorage.removeItem(STORAGE_KEYS.provider);
9910
9935
  syncRef.current?.broadcast({ type: "LOGOUT" });
9911
9936
  } catch (err) {
@@ -9990,22 +10015,25 @@ function VolrProvider({ config, children }) {
9990
10015
  () => ({
9991
10016
  session: {
9992
10017
  accessToken,
9993
- refreshToken: null
9994
- // Cookie-based, opaque
10018
+ refreshToken
9995
10019
  },
9996
10020
  refreshAccessToken: async () => {
9997
- await client.post("/auth/refresh", {});
9998
- const token = client.getAccessToken();
9999
- setAccessTokenState(token);
10021
+ await client.ensureAccessToken();
10022
+ setAccessTokenState(client.getAccessToken());
10023
+ setRefreshTokenState(client.getRefreshToken());
10000
10024
  },
10001
10025
  setAccessToken: (token) => {
10002
10026
  client.setAccessToken(token);
10003
10027
  setAccessTokenState(token);
10004
10028
  },
10029
+ setRefreshToken: (token) => {
10030
+ client.setRefreshToken(token);
10031
+ setRefreshTokenState(token);
10032
+ },
10005
10033
  client
10006
10034
  // Expose APIClient instance
10007
10035
  }),
10008
- [client, accessToken]
10036
+ [client, accessToken, refreshToken]
10009
10037
  );
10010
10038
  return /* @__PURE__ */ jsxRuntime.jsx(VolrContext.Provider, { value: publicValue, children: /* @__PURE__ */ jsxRuntime.jsx(InternalAuthContext.Provider, { value: internalValue, children }) });
10011
10039
  }
@@ -18252,22 +18280,24 @@ async function sendCalls(args) {
18252
18280
  console.log("[sendCalls] Calls normalized");
18253
18281
  let currentUser = deps.user;
18254
18282
  if (deps.user?.keyStorageType === "passkey" && !deps.provider) {
18255
- console.log("[sendCalls] Refreshing user data...");
18283
+ console.log("[sendCalls] Refreshing user data (provider not available)...");
18256
18284
  try {
18257
- const refreshResponse = await deps.client.post(
18258
- "/auth/refresh",
18259
- {}
18260
- );
18261
- if (refreshResponse.user) {
18262
- currentUser = refreshResponse.user;
18263
- console.log("[sendCalls] User data refreshed");
18285
+ const refreshedUser = await deps.client.refreshSession();
18286
+ if (refreshedUser) {
18287
+ currentUser = refreshedUser;
18288
+ console.log("[sendCalls] User data refreshed successfully");
18264
18289
  }
18265
18290
  } catch (error) {
18266
- console.warn(
18267
- "[sendCalls] Failed to refresh user data before transaction:",
18268
- error
18291
+ console.error("[sendCalls] Failed to refresh session:", error);
18292
+ throw new Error(
18293
+ `Failed to refresh session before transaction. ${error instanceof Error ? error.message : "Unknown error"}. Please try logging in again.`
18269
18294
  );
18270
18295
  }
18296
+ } else {
18297
+ console.log("[sendCalls] Skipping user refresh:", {
18298
+ hasProvider: !!deps.provider,
18299
+ keyStorageType: deps.user?.keyStorageType
18300
+ });
18271
18301
  }
18272
18302
  if (opts.preflight !== false) {
18273
18303
  console.log("[sendCalls] Running preflight estimate...");
@@ -18479,41 +18509,9 @@ function useVolrWallet() {
18479
18509
  );
18480
18510
  return { evm };
18481
18511
  }
18482
- function createAxiosInstance(baseUrl, apiKey) {
18483
- const instance = axios__default.default.create({
18484
- baseURL: baseUrl.replace(/\/+$/, ""),
18485
- // Remove trailing slashes
18486
- withCredentials: true,
18487
- // Include cookies
18488
- headers: {
18489
- "Content-Type": "application/json"
18490
- }
18491
- });
18492
- instance.interceptors.request.use((config) => {
18493
- if (apiKey) {
18494
- config.headers["X-API-Key"] = apiKey;
18495
- }
18496
- return config;
18497
- });
18498
- instance.interceptors.response.use(
18499
- (response) => response,
18500
- (error) => {
18501
- if (error.response?.data) {
18502
- const errorData = error.response.data;
18503
- if (errorData.error?.message) {
18504
- error.message = errorData.error.message;
18505
- }
18506
- }
18507
- return Promise.reject(error);
18508
- }
18509
- );
18510
- return instance;
18511
- }
18512
-
18513
- // src/hooks/useVolrLogin.ts
18514
18512
  function useVolrLogin() {
18515
18513
  const { config, setUser } = useVolr();
18516
- const { setAccessToken } = useInternalAuth();
18514
+ const { setAccessToken, setRefreshToken, client } = useInternalAuth();
18517
18515
  const toVolrUser = react.useCallback((u) => {
18518
18516
  return {
18519
18517
  id: u.id,
@@ -18530,27 +18528,18 @@ function useVolrLogin() {
18530
18528
  };
18531
18529
  }, []);
18532
18530
  const apiBaseUrl = resolveApiBaseUrl(config);
18533
- const api = react.useMemo(
18534
- () => createAxiosInstance(apiBaseUrl, config.projectApiKey),
18535
- [apiBaseUrl, config.projectApiKey]
18536
- );
18537
18531
  const requestEmailCode = react.useCallback(
18538
18532
  async (email) => {
18539
18533
  const normalizedEmail = email.trim().toLowerCase();
18540
18534
  if (!normalizedEmail || !normalizedEmail.includes("@")) {
18541
18535
  throw new Error("Invalid email address");
18542
18536
  }
18543
- const response = await api.post("/auth/email/send", {
18537
+ await client.post("/auth/email/send", {
18544
18538
  email: normalizedEmail
18545
18539
  });
18546
- if (!response.data?.ok) {
18547
- throw new Error(
18548
- response.data?.error?.message || "Failed to send verification code"
18549
- );
18550
- }
18551
18540
  safeStorage.setItem(STORAGE_KEYS.lastEmail, normalizedEmail);
18552
18541
  },
18553
- [api]
18542
+ [client]
18554
18543
  );
18555
18544
  const verifyEmailCode = react.useCallback(
18556
18545
  async (email, code) => {
@@ -18562,25 +18551,18 @@ function useVolrLogin() {
18562
18551
  if (!/^\d{6}$/.test(normalizedCode)) {
18563
18552
  throw new Error("Invalid code format");
18564
18553
  }
18565
- const response = await api.post("/auth/email/verify", {
18554
+ const response = await client.post("/auth/email/verify", {
18566
18555
  email: normalizedEmail,
18567
18556
  code: normalizedCode
18568
18557
  });
18569
- if (!response.data?.ok) {
18570
- throw new Error(
18571
- response.data?.error?.message || "Invalid verification code"
18572
- );
18573
- }
18574
- const verifyData = response.data;
18575
- const userFromServer = verifyData?.data?.user;
18576
- const isNewUser = !!verifyData?.data?.isNewUser;
18577
- const accessToken = verifyData?.data?.accessToken || "";
18558
+ const { user: userFromServer, isNewUser, accessToken, refreshToken } = response;
18578
18559
  if (!accessToken) {
18579
- throw new Error(
18580
- "Access token is required but was not provided by the server"
18581
- );
18560
+ throw new Error("Access token is required but was not provided by the server");
18582
18561
  }
18583
18562
  setAccessToken(accessToken);
18563
+ if (refreshToken) {
18564
+ setRefreshToken(refreshToken);
18565
+ }
18584
18566
  if (userFromServer) {
18585
18567
  setUser(toVolrUser(userFromServer));
18586
18568
  } else {
@@ -18594,7 +18576,7 @@ function useVolrLogin() {
18594
18576
  accessToken
18595
18577
  };
18596
18578
  },
18597
- [api, setAccessToken, setUser, toVolrUser]
18579
+ [client, setAccessToken, setRefreshToken, setUser, toVolrUser]
18598
18580
  );
18599
18581
  const handleSocialLogin = react.useCallback(
18600
18582
  async (provider) => {
@@ -18606,42 +18588,26 @@ function useVolrLogin() {
18606
18588
  [apiBaseUrl, config.projectApiKey]
18607
18589
  );
18608
18590
  const requestSiweNonce = react.useCallback(async () => {
18609
- const response = await api.get("/auth/siwe/nonce");
18610
- if (!response.data?.ok) {
18611
- throw new Error(
18612
- response.data?.error?.message || "Failed to generate nonce"
18613
- );
18614
- }
18615
- return response.data.data.nonce;
18616
- }, [api]);
18591
+ const response = await client.get("/auth/siwe/nonce");
18592
+ return response.nonce;
18593
+ }, [client]);
18617
18594
  const verifySiweSignature = react.useCallback(
18618
18595
  async (message, signature, options) => {
18619
18596
  try {
18620
- const response = await api.post("/auth/siwe/verify", {
18597
+ const response = await client.post("/auth/siwe/verify", {
18621
18598
  message,
18622
18599
  signature,
18623
18600
  walletConnector: options?.walletConnector,
18624
18601
  chainId: options?.chainId
18625
18602
  });
18626
- if (!response.data?.ok) {
18627
- console.error(
18628
- "[verifySiweSignature] Backend returned error:",
18629
- response.data
18630
- );
18631
- throw new Error(
18632
- response.data?.error?.message || "Invalid SIWE signature"
18633
- );
18634
- }
18635
- const verifyData = response.data;
18636
- const userFromServer = verifyData?.data?.user;
18637
- const isNewUser = !!verifyData?.data?.isNewUser;
18638
- const accessToken = verifyData?.data?.accessToken || "";
18603
+ const { user: userFromServer, isNewUser, accessToken, refreshToken } = response;
18639
18604
  if (!accessToken) {
18640
- throw new Error(
18641
- "Access token is required but was not provided by the server"
18642
- );
18605
+ throw new Error("Access token is required but was not provided by the server");
18643
18606
  }
18644
18607
  setAccessToken(accessToken);
18608
+ if (refreshToken) {
18609
+ setRefreshToken(refreshToken);
18610
+ }
18645
18611
  if (userFromServer) {
18646
18612
  setUser(toVolrUser(userFromServer));
18647
18613
  }
@@ -18661,7 +18627,7 @@ function useVolrLogin() {
18661
18627
  throw error;
18662
18628
  }
18663
18629
  },
18664
- [api, setAccessToken, setUser, toVolrUser]
18630
+ [client, setAccessToken, setRefreshToken, setUser, toVolrUser]
18665
18631
  );
18666
18632
  const handlePasskeyComplete = react.useCallback(async () => {
18667
18633
  }, []);
@@ -18674,9 +18640,41 @@ function useVolrLogin() {
18674
18640
  handlePasskeyComplete
18675
18641
  };
18676
18642
  }
18643
+ function createAxiosInstance(baseUrl, apiKey) {
18644
+ const instance = axios__default.default.create({
18645
+ baseURL: baseUrl.replace(/\/+$/, ""),
18646
+ // Remove trailing slashes
18647
+ withCredentials: true,
18648
+ // Include cookies
18649
+ headers: {
18650
+ "Content-Type": "application/json"
18651
+ }
18652
+ });
18653
+ instance.interceptors.request.use((config) => {
18654
+ if (apiKey) {
18655
+ config.headers["X-API-Key"] = apiKey;
18656
+ }
18657
+ return config;
18658
+ });
18659
+ instance.interceptors.response.use(
18660
+ (response) => response,
18661
+ (error) => {
18662
+ if (error.response?.data) {
18663
+ const errorData = error.response.data;
18664
+ if (errorData.error?.message) {
18665
+ error.message = errorData.error.message;
18666
+ }
18667
+ }
18668
+ return Promise.reject(error);
18669
+ }
18670
+ );
18671
+ return instance;
18672
+ }
18673
+
18674
+ // src/hooks/useVolrAuthCallback.ts
18677
18675
  function useVolrAuthCallback(options = {}) {
18678
18676
  const { config, setUser } = useVolr();
18679
- const { refreshAccessToken, setAccessToken } = useInternalAuth();
18677
+ const { refreshAccessToken, setAccessToken, setRefreshToken, client } = useInternalAuth();
18680
18678
  const [isLoading, setIsLoading] = react.useState(true);
18681
18679
  const [error, setError] = react.useState(null);
18682
18680
  const [isNewUser, setIsNewUser] = react.useState(false);
@@ -18730,13 +18728,21 @@ function useVolrAuthCallback(options = {}) {
18730
18728
  if (!userRes.data?.ok) {
18731
18729
  throw new Error("Failed to fetch user details");
18732
18730
  }
18733
- const refreshRes = await api.post("/auth/refresh");
18731
+ const currentRefreshToken = client.getRefreshToken();
18732
+ if (!currentRefreshToken) {
18733
+ throw new Error("No refresh token available. Please log in again.");
18734
+ }
18735
+ const refreshRes = await api.post("/auth/refresh", { refreshToken: currentRefreshToken });
18734
18736
  if (!refreshRes.data?.ok) {
18735
18737
  throw new Error("Failed to refresh session");
18736
18738
  }
18737
18739
  const userData = refreshRes.data.data.user;
18738
18740
  const accessToken = refreshRes.data.data.accessToken;
18741
+ const newRefreshToken = refreshRes.data.data.refreshToken;
18739
18742
  setAccessToken(accessToken);
18743
+ if (newRefreshToken) {
18744
+ setRefreshToken(newRefreshToken);
18745
+ }
18740
18746
  const volrUser = toVolrUser(userData);
18741
18747
  setUser(volrUser);
18742
18748
  setLocalUser(volrUser);
@@ -18751,7 +18757,7 @@ function useVolrAuthCallback(options = {}) {
18751
18757
  }
18752
18758
  };
18753
18759
  handleCallback();
18754
- }, [apiBaseUrl, config.projectApiKey, refreshAccessToken, setAccessToken, setUser, toVolrUser]);
18760
+ }, [apiBaseUrl, config.projectApiKey, refreshAccessToken, setAccessToken, setRefreshToken, setUser, toVolrUser, client]);
18755
18761
  return {
18756
18762
  isLoading,
18757
18763
  error,