@volr/react 0.1.129 → 0.1.130

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
@@ -9293,12 +9293,13 @@ var APIClient = class {
9293
9293
  headers: {
9294
9294
  "Content-Type": "application/json"
9295
9295
  },
9296
+ // Transform BigInt to string before JSON serialization
9296
9297
  transformRequest: [
9297
9298
  (data) => {
9298
9299
  if (data && typeof data === "object") {
9299
9300
  return JSON.stringify(
9300
9301
  data,
9301
- (_, value) => typeof value === "bigint" ? value.toString() : value
9302
+ (_key, value) => typeof value === "bigint" ? value.toString() : value
9302
9303
  );
9303
9304
  }
9304
9305
  return data;
@@ -9322,6 +9323,9 @@ var APIClient = class {
9322
9323
  this.api.interceptors.response.use(
9323
9324
  (response) => response,
9324
9325
  async (error) => {
9326
+ if (typeof process !== "undefined" && process.env.NODE_ENV === "test") {
9327
+ sanitizeAxiosErrorForTest(error);
9328
+ }
9325
9329
  const originalRequest = error.config;
9326
9330
  const requestUrl = originalRequest?.url || "";
9327
9331
  const responseData = error.response?.data;
@@ -9358,7 +9362,14 @@ var APIClient = class {
9358
9362
  }
9359
9363
  return this.api(originalRequest);
9360
9364
  } catch (refreshError) {
9361
- console.error("[APIClient] Token refresh failed:", refreshError);
9365
+ const anyErr = refreshError;
9366
+ const status = anyErr?.response?.status;
9367
+ const backendCode = anyErr?.response?.data?.error?.code;
9368
+ const backendMessage = anyErr?.response?.data?.error?.message;
9369
+ const message = backendMessage || anyErr?.message || "Unknown error";
9370
+ console.error(
9371
+ `[APIClient] Token refresh failed${typeof status === "number" ? ` (${status})` : ""}: ${backendCode ? `${backendCode}: ` : ""}${message}`
9372
+ );
9362
9373
  return Promise.reject(refreshError);
9363
9374
  }
9364
9375
  }
@@ -9439,17 +9450,11 @@ var APIClient = class {
9439
9450
  if (!this.refreshToken) {
9440
9451
  throw new Error("No refresh token available. Please log in again.");
9441
9452
  }
9442
- const timeoutPromise = new Promise(
9443
- (_, reject) => setTimeout(
9444
- () => reject(new Error("Session refresh timeout. Please check your network connection.")),
9445
- timeoutMs
9446
- )
9447
- );
9448
- const refreshPromise = this.api.post(
9453
+ const response = await this.api.post(
9449
9454
  "/auth/refresh",
9450
- { refreshToken: this.refreshToken }
9455
+ { refreshToken: this.refreshToken },
9456
+ { timeout: timeoutMs }
9451
9457
  );
9452
- const response = await Promise.race([refreshPromise, timeoutPromise]);
9453
9458
  const data = response.data;
9454
9459
  if (isErrorResponse(data)) {
9455
9460
  this.setAccessToken(null);
@@ -9477,23 +9482,27 @@ var APIClient = class {
9477
9482
  }
9478
9483
  this.refreshPromise = (async () => {
9479
9484
  try {
9480
- const response = await this.api.post(
9481
- "/auth/refresh",
9482
- { refreshToken: this.refreshToken }
9483
- );
9484
- const data = response.data;
9485
- if (isErrorResponse(data)) {
9485
+ try {
9486
+ const response = await this.api.post("/auth/refresh", { refreshToken: this.refreshToken });
9487
+ const data = response.data;
9488
+ if (isErrorResponse(data)) {
9489
+ this.setAccessToken(null);
9490
+ this.setRefreshToken(null);
9491
+ safeStorage.removeItem(STORAGE_KEYS.user);
9492
+ throw new Error(data.error.message);
9493
+ }
9494
+ this.setAccessToken(data.data.accessToken);
9495
+ if (data.data.refreshToken) {
9496
+ this.setRefreshToken(data.data.refreshToken);
9497
+ }
9498
+ if (data.data.user) {
9499
+ safeStorage.setItem(STORAGE_KEYS.user, JSON.stringify(data.data.user));
9500
+ }
9501
+ } catch (err) {
9486
9502
  this.setAccessToken(null);
9487
9503
  this.setRefreshToken(null);
9488
9504
  safeStorage.removeItem(STORAGE_KEYS.user);
9489
- throw new Error(data.error.message);
9490
- }
9491
- this.setAccessToken(data.data.accessToken);
9492
- if (data.data.refreshToken) {
9493
- this.setRefreshToken(data.data.refreshToken);
9494
- }
9495
- if (data.data.user) {
9496
- safeStorage.setItem(STORAGE_KEYS.user, JSON.stringify(data.data.user));
9505
+ throw err;
9497
9506
  }
9498
9507
  } finally {
9499
9508
  this.refreshPromise = null;
@@ -9541,7 +9550,14 @@ var APIClient = class {
9541
9550
  const response = await this.api.request(config);
9542
9551
  return unwrapResponse(response.data);
9543
9552
  } catch (error) {
9544
- console.error(`[APIClient] POST ${normalizedEndpoint} error:`, error);
9553
+ const anyErr = error;
9554
+ const status = anyErr?.response?.status;
9555
+ const backendCode = anyErr?.response?.data?.error?.code;
9556
+ const backendMessage = anyErr?.response?.data?.error?.message;
9557
+ const message = backendMessage || anyErr?.message || "Unknown error";
9558
+ console.error(
9559
+ `[APIClient] POST ${normalizedEndpoint} error${typeof status === "number" ? ` (${status})` : ""}: ${backendCode ? `${backendCode}: ` : ""}${message}`
9560
+ );
9545
9561
  throw error;
9546
9562
  }
9547
9563
  }
@@ -9578,7 +9594,36 @@ var APIClient = class {
9578
9594
  const response = await this.api.get(normalizedEndpoint);
9579
9595
  return unwrapResponse(response.data);
9580
9596
  }
9597
+ /**
9598
+ * Internal helper to sanitize Axios errors in test environment so that Vitest
9599
+ * can safely structured-clone them between workers.
9600
+ *
9601
+ * NOTE: This function is exported only for tests. It is a no-op in production
9602
+ * builds where NODE_ENV !== 'test'.
9603
+ */
9604
+ static sanitizeAxiosErrorForTest(error) {
9605
+ sanitizeAxiosErrorForTest(error);
9606
+ }
9581
9607
  };
9608
+ function sanitizeAxiosErrorForTest(error) {
9609
+ if (!error || typeof error !== "object") return;
9610
+ try {
9611
+ const anyErr = error;
9612
+ const cfg = anyErr.config;
9613
+ if (cfg && typeof cfg === "object") {
9614
+ if ("transformRequest" in cfg) cfg.transformRequest = void 0;
9615
+ if ("transformResponse" in cfg) cfg.transformResponse = void 0;
9616
+ if ("adapter" in cfg) cfg.adapter = void 0;
9617
+ }
9618
+ if (anyErr.request) {
9619
+ anyErr.request = void 0;
9620
+ }
9621
+ if (anyErr.response && anyErr.response.request) {
9622
+ anyErr.response.request = void 0;
9623
+ }
9624
+ } catch {
9625
+ }
9626
+ }
9582
9627
 
9583
9628
  // src/config/backend.ts
9584
9629
  var DEFAULT_API_BASE_URL = "https://api.volr.io";
@@ -9651,7 +9696,9 @@ var SessionSync = class {
9651
9696
  try {
9652
9697
  listener(event);
9653
9698
  } catch (error) {
9654
- console.error("SessionSync listener error:", error);
9699
+ console.error(
9700
+ `SessionSync listener error: ${error instanceof Error ? error.message : String(error)}`
9701
+ );
9655
9702
  }
9656
9703
  }
9657
9704
  }
@@ -9771,6 +9818,17 @@ var PrfNotSupportedError = class _PrfNotSupportedError extends Error {
9771
9818
  Object.setPrototypeOf(this, _PrfNotSupportedError.prototype);
9772
9819
  }
9773
9820
  };
9821
+ var WebAuthnBusyError = class _WebAuthnBusyError extends Error {
9822
+ constructor(message) {
9823
+ super(
9824
+ message || "Another passkey authentication is in progress. Please wait a moment and try again."
9825
+ );
9826
+ this.code = "WEBAUTHN_BUSY";
9827
+ this.isRetryable = true;
9828
+ this.name = "WebAuthnBusyError";
9829
+ Object.setPrototypeOf(this, _WebAuthnBusyError.prototype);
9830
+ }
9831
+ };
9774
9832
  function isUserCancelledError(error) {
9775
9833
  if (error instanceof UserCancelledError) {
9776
9834
  return true;
@@ -9788,8 +9846,40 @@ function isUserCancelledError(error) {
9788
9846
  }
9789
9847
  return false;
9790
9848
  }
9849
+ function isWebAuthnBusyError(error) {
9850
+ if (error instanceof WebAuthnBusyError) {
9851
+ return true;
9852
+ }
9853
+ if (error instanceof Error) {
9854
+ const msg = error.message.toLowerCase();
9855
+ if (msg.includes("already in progress") || msg.includes("already pending") || msg.includes("\uC774\uBBF8 \uC694\uCCAD\uC774 \uB300\uAE30 \uC911") || // Korean locale
9856
+ msg.includes("authentication is already in progress") || msg.includes("operation already in progress") || msg.includes("request is already in progress")) {
9857
+ return true;
9858
+ }
9859
+ }
9860
+ return false;
9861
+ }
9791
9862
 
9792
9863
  // src/adapters/passkey.ts
9864
+ var pendingWebAuthnPromise = null;
9865
+ async function withWebAuthnLock(fn) {
9866
+ if (pendingWebAuthnPromise) {
9867
+ try {
9868
+ await pendingWebAuthnPromise;
9869
+ } catch {
9870
+ }
9871
+ }
9872
+ const promise = fn();
9873
+ pendingWebAuthnPromise = promise;
9874
+ try {
9875
+ const result = await promise;
9876
+ return result;
9877
+ } finally {
9878
+ if (pendingWebAuthnPromise === promise) {
9879
+ pendingWebAuthnPromise = null;
9880
+ }
9881
+ }
9882
+ }
9793
9883
  function createPasskeyAdapter(options = {}) {
9794
9884
  const rpId = options.rpId || (typeof window !== "undefined" ? window.location.hostname : "localhost");
9795
9885
  return {
@@ -9892,72 +9982,83 @@ function createPasskeyAdapter(options = {}) {
9892
9982
  type: "public-key"
9893
9983
  }
9894
9984
  ];
9895
- let credential = null;
9896
- try {
9897
- credential = await navigator.credentials.get({
9898
- publicKey: {
9899
- challenge: crypto.getRandomValues(new Uint8Array(32)),
9900
- rpId,
9901
- allowCredentials,
9902
- userVerification: USER_VERIFICATION,
9903
- // Shared constant
9904
- extensions: {
9905
- prf: {
9906
- eval: {
9907
- first: prfInput.salt.buffer
9985
+ return withWebAuthnLock(async () => {
9986
+ let credential = null;
9987
+ try {
9988
+ credential = await navigator.credentials.get({
9989
+ publicKey: {
9990
+ challenge: crypto.getRandomValues(new Uint8Array(32)),
9991
+ rpId,
9992
+ allowCredentials,
9993
+ userVerification: USER_VERIFICATION,
9994
+ // Shared constant
9995
+ extensions: {
9996
+ prf: {
9997
+ eval: {
9998
+ first: prfInput.salt.buffer
9999
+ }
9908
10000
  }
9909
10001
  }
9910
- }
9911
- },
9912
- mediation: CREDENTIAL_MEDIATION
9913
- // Use shared constant
9914
- });
9915
- } catch (error) {
9916
- console.error("[PasskeyAdapter] WebAuthn get() failed:", error);
9917
- console.error("[PasskeyAdapter] Error name:", error?.name);
9918
- console.error("[PasskeyAdapter] Error message:", error?.message);
9919
- if (error?.name === "NotAllowedError") {
9920
- throw new UserCancelledError(
9921
- "User cancelled the passkey prompt or authentication was denied."
10002
+ },
10003
+ mediation: CREDENTIAL_MEDIATION
10004
+ // Use shared constant
10005
+ });
10006
+ } catch (error) {
10007
+ console.error("[PasskeyAdapter] WebAuthn get() failed:", error);
10008
+ console.error("[PasskeyAdapter] Error name:", error?.name);
10009
+ console.error("[PasskeyAdapter] Error message:", error?.message);
10010
+ const msg = (error?.message || "").toLowerCase();
10011
+ if (msg.includes("already in progress") || msg.includes("already pending") || msg.includes("\uC774\uBBF8 \uC694\uCCAD\uC774 \uB300\uAE30 \uC911") || // Korean
10012
+ msg.includes("operation already in progress") || msg.includes("request is already in progress")) {
10013
+ throw new WebAuthnBusyError(
10014
+ "Another passkey authentication is in progress. Please wait a moment and try again."
10015
+ );
10016
+ }
10017
+ if (error?.name === "NotAllowedError") {
10018
+ throw new UserCancelledError(
10019
+ "User cancelled the passkey prompt or authentication was denied."
10020
+ );
10021
+ }
10022
+ if (error?.name === "NotFoundError" || error?.name === "InvalidStateError") {
10023
+ throw new PasskeyNotFoundError(
10024
+ "No passkey found matching the provided credentialId. This may happen if the passkey was deleted or the credentialId is incorrect."
10025
+ );
10026
+ }
10027
+ if (error?.name === "NotSupportedError") {
10028
+ throw new PrfNotSupportedError(
10029
+ "WebAuthn PRF extension is not supported by this browser or device. Please use a browser that supports WebAuthn PRF extension (Chrome 108+, Edge 108+, Safari 16.4+)."
10030
+ );
10031
+ }
10032
+ throw new Error(
10033
+ `[PasskeyAdapter] WebAuthn authentication failed: ${error?.message || "Unknown error"}`
9922
10034
  );
9923
10035
  }
9924
- if (error?.name === "NotFoundError" || error?.name === "InvalidStateError") {
9925
- throw new PasskeyNotFoundError(
9926
- "No passkey found matching the provided credentialId. This may happen if the passkey was deleted or the credentialId is incorrect."
10036
+ if (!credential || !credential.response) {
10037
+ console.error(
10038
+ "[PasskeyAdapter] credential is null or missing response"
10039
+ );
10040
+ throw new Error(
10041
+ "[PasskeyAdapter] Failed to get passkey credential for PRF. The passkey prompt may have been cancelled or no matching credential was found."
9927
10042
  );
9928
10043
  }
9929
- if (error?.name === "NotSupportedError") {
9930
- throw new PrfNotSupportedError(
9931
- "WebAuthn PRF extension is not supported by this browser or device. Please use a browser that supports WebAuthn PRF extension (Chrome 108+, Edge 108+, Safari 16.4+)."
10044
+ const extensionResults = credential.getClientExtensionResults();
10045
+ if (!extensionResults.prf || !extensionResults.prf.results || !extensionResults.prf.results.first) {
10046
+ throw new Error(
10047
+ "[PasskeyAdapter] PRF extension not supported or PRF output missing"
9932
10048
  );
9933
10049
  }
9934
- throw new Error(
9935
- `[PasskeyAdapter] WebAuthn authentication failed: ${error?.message || "Unknown error"}`
9936
- );
9937
- }
9938
- if (!credential || !credential.response) {
9939
- console.error(
9940
- "[PasskeyAdapter] credential is null or missing response"
9941
- );
9942
- throw new Error(
9943
- "[PasskeyAdapter] Failed to get passkey credential for PRF. The passkey prompt may have been cancelled or no matching credential was found."
9944
- );
9945
- }
9946
- const extensionResults = credential.getClientExtensionResults();
9947
- if (!extensionResults.prf || !extensionResults.prf.results || !extensionResults.prf.results.first) {
9948
- throw new Error(
9949
- "[PasskeyAdapter] PRF extension not supported or PRF output missing"
9950
- );
9951
- }
9952
- const prfOutputBuffer = extensionResults.prf.results.first;
9953
- const prfOutput = new Uint8Array(prfOutputBuffer);
9954
- const credentialIdBytes = new Uint8Array(credential.rawId);
9955
- const credentialIdBase64 = btoa(String.fromCharCode(...credentialIdBytes)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
9956
- console.log("[PasskeyAdapter] WebAuthn prompt completed successfully");
9957
- return {
9958
- prfOutput,
9959
- credentialId: credentialIdBase64
9960
- };
10050
+ const prfOutputBuffer = extensionResults.prf.results.first;
10051
+ const prfOutput = new Uint8Array(prfOutputBuffer);
10052
+ const credentialIdBytes = new Uint8Array(credential.rawId);
10053
+ const credentialIdBase64 = btoa(
10054
+ String.fromCharCode(...credentialIdBytes)
10055
+ ).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
10056
+ console.log("[PasskeyAdapter] WebAuthn prompt completed successfully");
10057
+ return {
10058
+ prfOutput,
10059
+ credentialId: credentialIdBase64
10060
+ };
10061
+ });
9961
10062
  }
9962
10063
  };
9963
10064
  }
@@ -10323,7 +10424,9 @@ function VolrProvider({ config, children }) {
10323
10424
  setUser((prev) => ({ ...prev, keyStorageType }));
10324
10425
  }
10325
10426
  } catch (error2) {
10326
- console.warn("[Provider] setProvider: Failed to refresh user data:", error2);
10427
+ console.warn(
10428
+ `[Provider] setProvider: Failed to refresh user data: ${error2 instanceof Error ? error2.message : String(error2)}`
10429
+ );
10327
10430
  setUser((prev) => ({ ...prev, keyStorageType }));
10328
10431
  }
10329
10432
  }
@@ -18674,7 +18777,9 @@ async function pollTransactionStatus(txId, client, maxAttempts = 60) {
18674
18777
  const intervalMs = getPollingInterval(attempt);
18675
18778
  await new Promise((resolve) => setTimeout(resolve, intervalMs));
18676
18779
  } catch (error) {
18677
- console.error(`[pollTransactionStatus] Error polling transaction ${txId}:`, error);
18780
+ console.error(
18781
+ `[pollTransactionStatus] Error polling transaction ${txId}: ${error instanceof Error ? error.message : String(error)}`
18782
+ );
18678
18783
  const intervalMs = getPollingInterval(attempt);
18679
18784
  await new Promise((resolve) => setTimeout(resolve, intervalMs));
18680
18785
  }
@@ -18695,6 +18800,11 @@ async function sendCalls(args) {
18695
18800
  const normalizedFrom = from14;
18696
18801
  const normalizedCalls = normalizeCalls(calls);
18697
18802
  validateCalls2(normalizedCalls);
18803
+ if (!deps.provider && deps.user?.keyStorageType !== "passkey") {
18804
+ throw new Error(
18805
+ "No wallet provider configured. Please set up a Passkey provider to sign transactions. SIWE is authentication-only."
18806
+ );
18807
+ }
18698
18808
  let currentUser = deps.user;
18699
18809
  if (deps.user?.keyStorageType === "passkey" && !deps.provider) {
18700
18810
  try {
@@ -18703,7 +18813,9 @@ async function sendCalls(args) {
18703
18813
  currentUser = refreshedUser;
18704
18814
  }
18705
18815
  } catch (error) {
18706
- console.error("[sendCalls] Failed to refresh session:", error);
18816
+ console.error(
18817
+ `[sendCalls] Failed to refresh session: ${error instanceof Error ? error.message : String(error)}`
18818
+ );
18707
18819
  throw new Error(
18708
18820
  `Failed to refresh session before transaction. ${error instanceof Error ? error.message : "Unknown error"}. Please try logging in again.`
18709
18821
  );
@@ -18723,7 +18835,9 @@ async function sendCalls(args) {
18723
18835
  calls: normalizedCalls
18724
18836
  });
18725
18837
  } catch (err) {
18726
- console.error("[sendCalls] First precheck failed:", err);
18838
+ console.error(
18839
+ `[sendCalls] First precheck failed: ${err instanceof Error ? err.message : String(err)}`
18840
+ );
18727
18841
  throw err instanceof Error ? err : new Error(String(err));
18728
18842
  }
18729
18843
  if (precheckQuote.simulationSuccess === false && precheckQuote.simulationErrors?.length) {
@@ -19313,7 +19427,9 @@ function useVolrAuthCallback(options = {}) {
19313
19427
  setIsLoading(false);
19314
19428
  options.onSuccess?.(volrUser);
19315
19429
  } catch (err) {
19316
- console.error("[useVolrAuthCallback] Token exchange error:", err);
19430
+ console.error(
19431
+ `[useVolrAuthCallback] Token exchange error: ${err instanceof Error ? err.message : String(err)}`
19432
+ );
19317
19433
  let errorMsg = "Failed to complete authentication";
19318
19434
  if (err instanceof Error) {
19319
19435
  if (err.message.includes("AUTH_CODE_EXPIRED")) {
@@ -19417,7 +19533,9 @@ function useDepositListener(input) {
19417
19533
  if (cancelled) return;
19418
19534
  setStatus({ state: "listening", balance: initial });
19419
19535
  } catch (e) {
19420
- console.error("[DepositListener] Error:", e);
19536
+ console.error(
19537
+ `[DepositListener] Error: ${e instanceof Error ? e.message : String(e)}`
19538
+ );
19421
19539
  if (cancelled) return;
19422
19540
  setStatus({ state: "error", message: e.message || String(e) });
19423
19541
  return;
@@ -19453,7 +19571,9 @@ function useDepositListener(input) {
19453
19571
  return prev;
19454
19572
  });
19455
19573
  } catch (err) {
19456
- console.error("[DepositListener] Polling error:", err);
19574
+ console.error(
19575
+ `[DepositListener] Polling error: ${err instanceof Error ? err.message : String(err)}`
19576
+ );
19457
19577
  if (cancelled) return;
19458
19578
  setStatus({ state: "error", message: err.message || String(err) });
19459
19579
  }
@@ -20086,7 +20206,9 @@ function useUserBalances() {
20086
20206
  });
20087
20207
  setBalances(initialBalances);
20088
20208
  }).catch((err) => {
20089
- console.error("[useUserBalances] Failed to fetch branding:", err);
20209
+ console.error(
20210
+ `[useUserBalances] Failed to fetch branding: ${err instanceof Error ? err.message : String(err)}`
20211
+ );
20090
20212
  setError(err instanceof Error ? err : new Error("Failed to fetch branding"));
20091
20213
  }).finally(() => {
20092
20214
  setIsLoadingBranding(false);
@@ -20127,7 +20249,9 @@ function useUserBalances() {
20127
20249
  error: void 0
20128
20250
  };
20129
20251
  } catch (err) {
20130
- console.error(`[useUserBalances] Failed to fetch balance for ${id}:`, err);
20252
+ console.error(
20253
+ `[useUserBalances] Failed to fetch balance for ${id}: ${err instanceof Error ? err.message : String(err)}`
20254
+ );
20131
20255
  return {
20132
20256
  id,
20133
20257
  balanceRaw: 0n,
@@ -21184,6 +21308,7 @@ exports.PasskeyNotFoundError = PasskeyNotFoundError;
21184
21308
  exports.PrfNotSupportedError = PrfNotSupportedError;
21185
21309
  exports.UserCancelledError = UserCancelledError;
21186
21310
  exports.VolrProvider = VolrProvider;
21311
+ exports.WebAuthnBusyError = WebAuthnBusyError;
21187
21312
  exports.analyzeContractForEIP7702 = analyzeContractForEIP7702;
21188
21313
  exports.buildCall = buildCall;
21189
21314
  exports.buildCalls = buildCalls;
@@ -21210,6 +21335,7 @@ exports.getWalletState = getWalletState;
21210
21335
  exports.isEIP7702Delegated = isEIP7702Delegated;
21211
21336
  exports.isInAppBrowser = isInAppBrowser;
21212
21337
  exports.isUserCancelledError = isUserCancelledError;
21338
+ exports.isWebAuthnBusyError = isWebAuthnBusyError;
21213
21339
  exports.listenForSeedRequests = listenForSeedRequests;
21214
21340
  exports.normalizeHex = normalizeHex;
21215
21341
  exports.normalizeHexArray = normalizeHexArray;
@@ -21223,6 +21349,8 @@ exports.useEIP6963 = useEIP6963;
21223
21349
  exports.useInternalAuth = useInternalAuth;
21224
21350
  exports.useMpcConnection = useMpcConnection;
21225
21351
  exports.usePasskeyEnrollment = usePasskeyEnrollment;
21352
+ exports.usePrecheck = usePrecheck;
21353
+ exports.useRelay = useRelay;
21226
21354
  exports.useUserBalances = useUserBalances;
21227
21355
  exports.useVolr = useVolr;
21228
21356
  exports.useVolrAuthCallback = useVolrAuthCallback;