@volr/react 0.1.129 → 0.1.131
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 +279 -100
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +63 -2
- package/dist/index.d.ts +63 -2
- package/dist/index.js +277 -102
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as nc from 'crypto';
|
|
2
2
|
import { createContext, useRef, useEffect, useMemo, useState, useCallback, useContext } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { signSession, getAuthNonce, signAuthorization, createPasskeyProvider, createMpcProvider, deriveWrapKey, unsealMasterSeed, sealMasterSeed, createMasterKeyProvider, deriveEvmKey, ZERO_HASH, selectSigner, VolrError } from '@volr/sdk-core';
|
|
4
4
|
export { createMasterKeyProvider, createMpcProvider, createPasskeyProvider, deriveEvmKey, deriveWrapKey, sealMasterSeed, uploadBlob } from '@volr/sdk-core';
|
|
5
5
|
import axios from 'axios';
|
|
6
6
|
import { jsx } from 'react/jsx-runtime';
|
|
@@ -9269,12 +9269,13 @@ var APIClient = class {
|
|
|
9269
9269
|
headers: {
|
|
9270
9270
|
"Content-Type": "application/json"
|
|
9271
9271
|
},
|
|
9272
|
+
// Transform BigInt to string before JSON serialization
|
|
9272
9273
|
transformRequest: [
|
|
9273
9274
|
(data) => {
|
|
9274
9275
|
if (data && typeof data === "object") {
|
|
9275
9276
|
return JSON.stringify(
|
|
9276
9277
|
data,
|
|
9277
|
-
(
|
|
9278
|
+
(_key, value) => typeof value === "bigint" ? value.toString() : value
|
|
9278
9279
|
);
|
|
9279
9280
|
}
|
|
9280
9281
|
return data;
|
|
@@ -9298,6 +9299,9 @@ var APIClient = class {
|
|
|
9298
9299
|
this.api.interceptors.response.use(
|
|
9299
9300
|
(response) => response,
|
|
9300
9301
|
async (error) => {
|
|
9302
|
+
if (typeof process !== "undefined" && process.env.NODE_ENV === "test") {
|
|
9303
|
+
sanitizeAxiosErrorForTest(error);
|
|
9304
|
+
}
|
|
9301
9305
|
const originalRequest = error.config;
|
|
9302
9306
|
const requestUrl = originalRequest?.url || "";
|
|
9303
9307
|
const responseData = error.response?.data;
|
|
@@ -9334,7 +9338,14 @@ var APIClient = class {
|
|
|
9334
9338
|
}
|
|
9335
9339
|
return this.api(originalRequest);
|
|
9336
9340
|
} catch (refreshError) {
|
|
9337
|
-
|
|
9341
|
+
const anyErr = refreshError;
|
|
9342
|
+
const status = anyErr?.response?.status;
|
|
9343
|
+
const backendCode = anyErr?.response?.data?.error?.code;
|
|
9344
|
+
const backendMessage = anyErr?.response?.data?.error?.message;
|
|
9345
|
+
const message = backendMessage || anyErr?.message || "Unknown error";
|
|
9346
|
+
console.error(
|
|
9347
|
+
`[APIClient] Token refresh failed${typeof status === "number" ? ` (${status})` : ""}: ${backendCode ? `${backendCode}: ` : ""}${message}`
|
|
9348
|
+
);
|
|
9338
9349
|
return Promise.reject(refreshError);
|
|
9339
9350
|
}
|
|
9340
9351
|
}
|
|
@@ -9415,17 +9426,11 @@ var APIClient = class {
|
|
|
9415
9426
|
if (!this.refreshToken) {
|
|
9416
9427
|
throw new Error("No refresh token available. Please log in again.");
|
|
9417
9428
|
}
|
|
9418
|
-
const
|
|
9419
|
-
(_, reject) => setTimeout(
|
|
9420
|
-
() => reject(new Error("Session refresh timeout. Please check your network connection.")),
|
|
9421
|
-
timeoutMs
|
|
9422
|
-
)
|
|
9423
|
-
);
|
|
9424
|
-
const refreshPromise = this.api.post(
|
|
9429
|
+
const response = await this.api.post(
|
|
9425
9430
|
"/auth/refresh",
|
|
9426
|
-
{ refreshToken: this.refreshToken }
|
|
9431
|
+
{ refreshToken: this.refreshToken },
|
|
9432
|
+
{ timeout: timeoutMs }
|
|
9427
9433
|
);
|
|
9428
|
-
const response = await Promise.race([refreshPromise, timeoutPromise]);
|
|
9429
9434
|
const data = response.data;
|
|
9430
9435
|
if (isErrorResponse(data)) {
|
|
9431
9436
|
this.setAccessToken(null);
|
|
@@ -9453,23 +9458,27 @@ var APIClient = class {
|
|
|
9453
9458
|
}
|
|
9454
9459
|
this.refreshPromise = (async () => {
|
|
9455
9460
|
try {
|
|
9456
|
-
|
|
9457
|
-
"/auth/refresh",
|
|
9458
|
-
|
|
9459
|
-
|
|
9460
|
-
|
|
9461
|
-
|
|
9461
|
+
try {
|
|
9462
|
+
const response = await this.api.post("/auth/refresh", { refreshToken: this.refreshToken });
|
|
9463
|
+
const data = response.data;
|
|
9464
|
+
if (isErrorResponse(data)) {
|
|
9465
|
+
this.setAccessToken(null);
|
|
9466
|
+
this.setRefreshToken(null);
|
|
9467
|
+
safeStorage.removeItem(STORAGE_KEYS.user);
|
|
9468
|
+
throw new Error(data.error.message);
|
|
9469
|
+
}
|
|
9470
|
+
this.setAccessToken(data.data.accessToken);
|
|
9471
|
+
if (data.data.refreshToken) {
|
|
9472
|
+
this.setRefreshToken(data.data.refreshToken);
|
|
9473
|
+
}
|
|
9474
|
+
if (data.data.user) {
|
|
9475
|
+
safeStorage.setItem(STORAGE_KEYS.user, JSON.stringify(data.data.user));
|
|
9476
|
+
}
|
|
9477
|
+
} catch (err) {
|
|
9462
9478
|
this.setAccessToken(null);
|
|
9463
9479
|
this.setRefreshToken(null);
|
|
9464
9480
|
safeStorage.removeItem(STORAGE_KEYS.user);
|
|
9465
|
-
throw
|
|
9466
|
-
}
|
|
9467
|
-
this.setAccessToken(data.data.accessToken);
|
|
9468
|
-
if (data.data.refreshToken) {
|
|
9469
|
-
this.setRefreshToken(data.data.refreshToken);
|
|
9470
|
-
}
|
|
9471
|
-
if (data.data.user) {
|
|
9472
|
-
safeStorage.setItem(STORAGE_KEYS.user, JSON.stringify(data.data.user));
|
|
9481
|
+
throw err;
|
|
9473
9482
|
}
|
|
9474
9483
|
} finally {
|
|
9475
9484
|
this.refreshPromise = null;
|
|
@@ -9517,7 +9526,14 @@ var APIClient = class {
|
|
|
9517
9526
|
const response = await this.api.request(config);
|
|
9518
9527
|
return unwrapResponse(response.data);
|
|
9519
9528
|
} catch (error) {
|
|
9520
|
-
|
|
9529
|
+
const anyErr = error;
|
|
9530
|
+
const status = anyErr?.response?.status;
|
|
9531
|
+
const backendCode = anyErr?.response?.data?.error?.code;
|
|
9532
|
+
const backendMessage = anyErr?.response?.data?.error?.message;
|
|
9533
|
+
const message = backendMessage || anyErr?.message || "Unknown error";
|
|
9534
|
+
console.error(
|
|
9535
|
+
`[APIClient] POST ${normalizedEndpoint} error${typeof status === "number" ? ` (${status})` : ""}: ${backendCode ? `${backendCode}: ` : ""}${message}`
|
|
9536
|
+
);
|
|
9521
9537
|
throw error;
|
|
9522
9538
|
}
|
|
9523
9539
|
}
|
|
@@ -9554,7 +9570,36 @@ var APIClient = class {
|
|
|
9554
9570
|
const response = await this.api.get(normalizedEndpoint);
|
|
9555
9571
|
return unwrapResponse(response.data);
|
|
9556
9572
|
}
|
|
9573
|
+
/**
|
|
9574
|
+
* Internal helper to sanitize Axios errors in test environment so that Vitest
|
|
9575
|
+
* can safely structured-clone them between workers.
|
|
9576
|
+
*
|
|
9577
|
+
* NOTE: This function is exported only for tests. It is a no-op in production
|
|
9578
|
+
* builds where NODE_ENV !== 'test'.
|
|
9579
|
+
*/
|
|
9580
|
+
static sanitizeAxiosErrorForTest(error) {
|
|
9581
|
+
sanitizeAxiosErrorForTest(error);
|
|
9582
|
+
}
|
|
9557
9583
|
};
|
|
9584
|
+
function sanitizeAxiosErrorForTest(error) {
|
|
9585
|
+
if (!error || typeof error !== "object") return;
|
|
9586
|
+
try {
|
|
9587
|
+
const anyErr = error;
|
|
9588
|
+
const cfg = anyErr.config;
|
|
9589
|
+
if (cfg && typeof cfg === "object") {
|
|
9590
|
+
if ("transformRequest" in cfg) cfg.transformRequest = void 0;
|
|
9591
|
+
if ("transformResponse" in cfg) cfg.transformResponse = void 0;
|
|
9592
|
+
if ("adapter" in cfg) cfg.adapter = void 0;
|
|
9593
|
+
}
|
|
9594
|
+
if (anyErr.request) {
|
|
9595
|
+
anyErr.request = void 0;
|
|
9596
|
+
}
|
|
9597
|
+
if (anyErr.response && anyErr.response.request) {
|
|
9598
|
+
anyErr.response.request = void 0;
|
|
9599
|
+
}
|
|
9600
|
+
} catch {
|
|
9601
|
+
}
|
|
9602
|
+
}
|
|
9558
9603
|
|
|
9559
9604
|
// src/config/backend.ts
|
|
9560
9605
|
var DEFAULT_API_BASE_URL = "https://api.volr.io";
|
|
@@ -9627,7 +9672,9 @@ var SessionSync = class {
|
|
|
9627
9672
|
try {
|
|
9628
9673
|
listener(event);
|
|
9629
9674
|
} catch (error) {
|
|
9630
|
-
console.error(
|
|
9675
|
+
console.error(
|
|
9676
|
+
`SessionSync listener error: ${error instanceof Error ? error.message : String(error)}`
|
|
9677
|
+
);
|
|
9631
9678
|
}
|
|
9632
9679
|
}
|
|
9633
9680
|
}
|
|
@@ -9703,10 +9750,41 @@ function useSessionSync({
|
|
|
9703
9750
|
}
|
|
9704
9751
|
|
|
9705
9752
|
// src/config/webauthn.ts
|
|
9753
|
+
function isWindows() {
|
|
9754
|
+
if (typeof navigator === "undefined") return false;
|
|
9755
|
+
const platform = navigator.platform || "";
|
|
9756
|
+
return /Win/.test(platform);
|
|
9757
|
+
}
|
|
9758
|
+
function isLinux() {
|
|
9759
|
+
if (typeof navigator === "undefined") return false;
|
|
9760
|
+
const platform = navigator.platform || "";
|
|
9761
|
+
const ua = navigator.userAgent;
|
|
9762
|
+
return /Linux/.test(platform) && !/CrOS/.test(ua) && !/Android/.test(ua);
|
|
9763
|
+
}
|
|
9764
|
+
function shouldForceCrossDevice() {
|
|
9765
|
+
return isWindows() || isLinux();
|
|
9766
|
+
}
|
|
9706
9767
|
var AUTHENTICATOR_SELECTION = {
|
|
9707
9768
|
userVerification: "required",
|
|
9708
9769
|
residentKey: "required"
|
|
9709
9770
|
};
|
|
9771
|
+
var AUTHENTICATOR_SELECTION_CROSS_DEVICE = {
|
|
9772
|
+
userVerification: "required",
|
|
9773
|
+
residentKey: "required",
|
|
9774
|
+
authenticatorAttachment: "cross-platform"
|
|
9775
|
+
};
|
|
9776
|
+
function getAuthenticatorSelection() {
|
|
9777
|
+
if (shouldForceCrossDevice()) {
|
|
9778
|
+
return AUTHENTICATOR_SELECTION_CROSS_DEVICE;
|
|
9779
|
+
}
|
|
9780
|
+
return AUTHENTICATOR_SELECTION;
|
|
9781
|
+
}
|
|
9782
|
+
function getWebAuthnHints() {
|
|
9783
|
+
if (shouldForceCrossDevice()) {
|
|
9784
|
+
return ["hybrid"];
|
|
9785
|
+
}
|
|
9786
|
+
return void 0;
|
|
9787
|
+
}
|
|
9710
9788
|
var CREDENTIAL_MEDIATION = "required";
|
|
9711
9789
|
var USER_VERIFICATION = "required";
|
|
9712
9790
|
var WEBAUTHN_TIMEOUT = 6e4;
|
|
@@ -9747,6 +9825,17 @@ var PrfNotSupportedError = class _PrfNotSupportedError extends Error {
|
|
|
9747
9825
|
Object.setPrototypeOf(this, _PrfNotSupportedError.prototype);
|
|
9748
9826
|
}
|
|
9749
9827
|
};
|
|
9828
|
+
var WebAuthnBusyError = class _WebAuthnBusyError extends Error {
|
|
9829
|
+
constructor(message) {
|
|
9830
|
+
super(
|
|
9831
|
+
message || "Another passkey authentication is in progress. Please wait a moment and try again."
|
|
9832
|
+
);
|
|
9833
|
+
this.code = "WEBAUTHN_BUSY";
|
|
9834
|
+
this.isRetryable = true;
|
|
9835
|
+
this.name = "WebAuthnBusyError";
|
|
9836
|
+
Object.setPrototypeOf(this, _WebAuthnBusyError.prototype);
|
|
9837
|
+
}
|
|
9838
|
+
};
|
|
9750
9839
|
function isUserCancelledError(error) {
|
|
9751
9840
|
if (error instanceof UserCancelledError) {
|
|
9752
9841
|
return true;
|
|
@@ -9764,8 +9853,40 @@ function isUserCancelledError(error) {
|
|
|
9764
9853
|
}
|
|
9765
9854
|
return false;
|
|
9766
9855
|
}
|
|
9856
|
+
function isWebAuthnBusyError(error) {
|
|
9857
|
+
if (error instanceof WebAuthnBusyError) {
|
|
9858
|
+
return true;
|
|
9859
|
+
}
|
|
9860
|
+
if (error instanceof Error) {
|
|
9861
|
+
const msg = error.message.toLowerCase();
|
|
9862
|
+
if (msg.includes("already in progress") || msg.includes("already pending") || msg.includes("\uC774\uBBF8 \uC694\uCCAD\uC774 \uB300\uAE30 \uC911") || // Korean locale
|
|
9863
|
+
msg.includes("authentication is already in progress") || msg.includes("operation already in progress") || msg.includes("request is already in progress")) {
|
|
9864
|
+
return true;
|
|
9865
|
+
}
|
|
9866
|
+
}
|
|
9867
|
+
return false;
|
|
9868
|
+
}
|
|
9767
9869
|
|
|
9768
9870
|
// src/adapters/passkey.ts
|
|
9871
|
+
var pendingWebAuthnPromise = null;
|
|
9872
|
+
async function withWebAuthnLock(fn) {
|
|
9873
|
+
if (pendingWebAuthnPromise) {
|
|
9874
|
+
try {
|
|
9875
|
+
await pendingWebAuthnPromise;
|
|
9876
|
+
} catch {
|
|
9877
|
+
}
|
|
9878
|
+
}
|
|
9879
|
+
const promise = fn();
|
|
9880
|
+
pendingWebAuthnPromise = promise;
|
|
9881
|
+
try {
|
|
9882
|
+
const result = await promise;
|
|
9883
|
+
return result;
|
|
9884
|
+
} finally {
|
|
9885
|
+
if (pendingWebAuthnPromise === promise) {
|
|
9886
|
+
pendingWebAuthnPromise = null;
|
|
9887
|
+
}
|
|
9888
|
+
}
|
|
9889
|
+
}
|
|
9769
9890
|
function createPasskeyAdapter(options = {}) {
|
|
9770
9891
|
const rpId = options.rpId || (typeof window !== "undefined" ? window.location.hostname : "localhost");
|
|
9771
9892
|
return {
|
|
@@ -9868,72 +9989,88 @@ function createPasskeyAdapter(options = {}) {
|
|
|
9868
9989
|
type: "public-key"
|
|
9869
9990
|
}
|
|
9870
9991
|
];
|
|
9871
|
-
|
|
9872
|
-
|
|
9873
|
-
credential =
|
|
9874
|
-
|
|
9875
|
-
|
|
9876
|
-
|
|
9877
|
-
|
|
9878
|
-
|
|
9879
|
-
|
|
9880
|
-
|
|
9881
|
-
|
|
9882
|
-
|
|
9883
|
-
|
|
9992
|
+
const hints = getWebAuthnHints();
|
|
9993
|
+
return withWebAuthnLock(async () => {
|
|
9994
|
+
let credential = null;
|
|
9995
|
+
try {
|
|
9996
|
+
const requestOptions = {
|
|
9997
|
+
publicKey: {
|
|
9998
|
+
challenge: crypto.getRandomValues(new Uint8Array(32)),
|
|
9999
|
+
rpId,
|
|
10000
|
+
allowCredentials,
|
|
10001
|
+
userVerification: USER_VERIFICATION,
|
|
10002
|
+
// Shared constant
|
|
10003
|
+
extensions: {
|
|
10004
|
+
prf: {
|
|
10005
|
+
eval: {
|
|
10006
|
+
first: prfInput.salt.buffer
|
|
10007
|
+
}
|
|
9884
10008
|
}
|
|
9885
|
-
}
|
|
9886
|
-
|
|
9887
|
-
|
|
9888
|
-
|
|
9889
|
-
|
|
9890
|
-
|
|
9891
|
-
|
|
9892
|
-
|
|
9893
|
-
|
|
9894
|
-
|
|
9895
|
-
|
|
9896
|
-
|
|
9897
|
-
|
|
10009
|
+
},
|
|
10010
|
+
// Chrome 128+ supports hints to prioritize certain authenticator types
|
|
10011
|
+
// On Windows/Linux, this prioritizes QR code over USB security key prompt
|
|
10012
|
+
...hints && { hints }
|
|
10013
|
+
},
|
|
10014
|
+
mediation: CREDENTIAL_MEDIATION
|
|
10015
|
+
// Use shared constant
|
|
10016
|
+
};
|
|
10017
|
+
credential = await navigator.credentials.get(requestOptions);
|
|
10018
|
+
} catch (error) {
|
|
10019
|
+
console.error("[PasskeyAdapter] WebAuthn get() failed:", error);
|
|
10020
|
+
console.error("[PasskeyAdapter] Error name:", error?.name);
|
|
10021
|
+
console.error("[PasskeyAdapter] Error message:", error?.message);
|
|
10022
|
+
const msg = (error?.message || "").toLowerCase();
|
|
10023
|
+
if (msg.includes("already in progress") || msg.includes("already pending") || msg.includes("\uC774\uBBF8 \uC694\uCCAD\uC774 \uB300\uAE30 \uC911") || // Korean
|
|
10024
|
+
msg.includes("operation already in progress") || msg.includes("request is already in progress")) {
|
|
10025
|
+
throw new WebAuthnBusyError(
|
|
10026
|
+
"Another passkey authentication is in progress. Please wait a moment and try again."
|
|
10027
|
+
);
|
|
10028
|
+
}
|
|
10029
|
+
if (error?.name === "NotAllowedError") {
|
|
10030
|
+
throw new UserCancelledError(
|
|
10031
|
+
"User cancelled the passkey prompt or authentication was denied."
|
|
10032
|
+
);
|
|
10033
|
+
}
|
|
10034
|
+
if (error?.name === "NotFoundError" || error?.name === "InvalidStateError") {
|
|
10035
|
+
throw new PasskeyNotFoundError(
|
|
10036
|
+
"No passkey found matching the provided credentialId. This may happen if the passkey was deleted or the credentialId is incorrect."
|
|
10037
|
+
);
|
|
10038
|
+
}
|
|
10039
|
+
if (error?.name === "NotSupportedError") {
|
|
10040
|
+
throw new PrfNotSupportedError(
|
|
10041
|
+
"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+)."
|
|
10042
|
+
);
|
|
10043
|
+
}
|
|
10044
|
+
throw new Error(
|
|
10045
|
+
`[PasskeyAdapter] WebAuthn authentication failed: ${error?.message || "Unknown error"}`
|
|
9898
10046
|
);
|
|
9899
10047
|
}
|
|
9900
|
-
if (
|
|
9901
|
-
|
|
9902
|
-
"
|
|
10048
|
+
if (!credential || !credential.response) {
|
|
10049
|
+
console.error(
|
|
10050
|
+
"[PasskeyAdapter] credential is null or missing response"
|
|
10051
|
+
);
|
|
10052
|
+
throw new Error(
|
|
10053
|
+
"[PasskeyAdapter] Failed to get passkey credential for PRF. The passkey prompt may have been cancelled or no matching credential was found."
|
|
9903
10054
|
);
|
|
9904
10055
|
}
|
|
9905
|
-
|
|
9906
|
-
|
|
9907
|
-
|
|
10056
|
+
const extensionResults = credential.getClientExtensionResults();
|
|
10057
|
+
if (!extensionResults.prf || !extensionResults.prf.results || !extensionResults.prf.results.first) {
|
|
10058
|
+
throw new Error(
|
|
10059
|
+
"[PasskeyAdapter] PRF extension not supported or PRF output missing"
|
|
9908
10060
|
);
|
|
9909
10061
|
}
|
|
9910
|
-
|
|
9911
|
-
|
|
9912
|
-
);
|
|
9913
|
-
|
|
9914
|
-
|
|
9915
|
-
|
|
9916
|
-
|
|
9917
|
-
|
|
9918
|
-
|
|
9919
|
-
|
|
9920
|
-
|
|
9921
|
-
}
|
|
9922
|
-
const extensionResults = credential.getClientExtensionResults();
|
|
9923
|
-
if (!extensionResults.prf || !extensionResults.prf.results || !extensionResults.prf.results.first) {
|
|
9924
|
-
throw new Error(
|
|
9925
|
-
"[PasskeyAdapter] PRF extension not supported or PRF output missing"
|
|
9926
|
-
);
|
|
9927
|
-
}
|
|
9928
|
-
const prfOutputBuffer = extensionResults.prf.results.first;
|
|
9929
|
-
const prfOutput = new Uint8Array(prfOutputBuffer);
|
|
9930
|
-
const credentialIdBytes = new Uint8Array(credential.rawId);
|
|
9931
|
-
const credentialIdBase64 = btoa(String.fromCharCode(...credentialIdBytes)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
9932
|
-
console.log("[PasskeyAdapter] WebAuthn prompt completed successfully");
|
|
9933
|
-
return {
|
|
9934
|
-
prfOutput,
|
|
9935
|
-
credentialId: credentialIdBase64
|
|
9936
|
-
};
|
|
10062
|
+
const prfOutputBuffer = extensionResults.prf.results.first;
|
|
10063
|
+
const prfOutput = new Uint8Array(prfOutputBuffer);
|
|
10064
|
+
const credentialIdBytes = new Uint8Array(credential.rawId);
|
|
10065
|
+
const credentialIdBase64 = btoa(
|
|
10066
|
+
String.fromCharCode(...credentialIdBytes)
|
|
10067
|
+
).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
10068
|
+
console.log("[PasskeyAdapter] WebAuthn prompt completed successfully");
|
|
10069
|
+
return {
|
|
10070
|
+
prfOutput,
|
|
10071
|
+
credentialId: credentialIdBase64
|
|
10072
|
+
};
|
|
10073
|
+
});
|
|
9937
10074
|
}
|
|
9938
10075
|
};
|
|
9939
10076
|
}
|
|
@@ -10299,7 +10436,9 @@ function VolrProvider({ config, children }) {
|
|
|
10299
10436
|
setUser((prev) => ({ ...prev, keyStorageType }));
|
|
10300
10437
|
}
|
|
10301
10438
|
} catch (error2) {
|
|
10302
|
-
console.warn(
|
|
10439
|
+
console.warn(
|
|
10440
|
+
`[Provider] setProvider: Failed to refresh user data: ${error2 instanceof Error ? error2.message : String(error2)}`
|
|
10441
|
+
);
|
|
10303
10442
|
setUser((prev) => ({ ...prev, keyStorageType }));
|
|
10304
10443
|
}
|
|
10305
10444
|
}
|
|
@@ -18650,7 +18789,9 @@ async function pollTransactionStatus(txId, client, maxAttempts = 60) {
|
|
|
18650
18789
|
const intervalMs = getPollingInterval(attempt);
|
|
18651
18790
|
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
18652
18791
|
} catch (error) {
|
|
18653
|
-
console.error(
|
|
18792
|
+
console.error(
|
|
18793
|
+
`[pollTransactionStatus] Error polling transaction ${txId}: ${error instanceof Error ? error.message : String(error)}`
|
|
18794
|
+
);
|
|
18654
18795
|
const intervalMs = getPollingInterval(attempt);
|
|
18655
18796
|
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
18656
18797
|
}
|
|
@@ -18671,6 +18812,11 @@ async function sendCalls(args) {
|
|
|
18671
18812
|
const normalizedFrom = from14;
|
|
18672
18813
|
const normalizedCalls = normalizeCalls(calls);
|
|
18673
18814
|
validateCalls2(normalizedCalls);
|
|
18815
|
+
if (!deps.provider && deps.user?.keyStorageType !== "passkey") {
|
|
18816
|
+
throw new Error(
|
|
18817
|
+
"No wallet provider configured. Please set up a Passkey provider to sign transactions. SIWE is authentication-only."
|
|
18818
|
+
);
|
|
18819
|
+
}
|
|
18674
18820
|
let currentUser = deps.user;
|
|
18675
18821
|
if (deps.user?.keyStorageType === "passkey" && !deps.provider) {
|
|
18676
18822
|
try {
|
|
@@ -18679,7 +18825,9 @@ async function sendCalls(args) {
|
|
|
18679
18825
|
currentUser = refreshedUser;
|
|
18680
18826
|
}
|
|
18681
18827
|
} catch (error) {
|
|
18682
|
-
console.error(
|
|
18828
|
+
console.error(
|
|
18829
|
+
`[sendCalls] Failed to refresh session: ${error instanceof Error ? error.message : String(error)}`
|
|
18830
|
+
);
|
|
18683
18831
|
throw new Error(
|
|
18684
18832
|
`Failed to refresh session before transaction. ${error instanceof Error ? error.message : "Unknown error"}. Please try logging in again.`
|
|
18685
18833
|
);
|
|
@@ -18699,7 +18847,9 @@ async function sendCalls(args) {
|
|
|
18699
18847
|
calls: normalizedCalls
|
|
18700
18848
|
});
|
|
18701
18849
|
} catch (err) {
|
|
18702
|
-
console.error(
|
|
18850
|
+
console.error(
|
|
18851
|
+
`[sendCalls] First precheck failed: ${err instanceof Error ? err.message : String(err)}`
|
|
18852
|
+
);
|
|
18703
18853
|
throw err instanceof Error ? err : new Error(String(err));
|
|
18704
18854
|
}
|
|
18705
18855
|
if (precheckQuote.simulationSuccess === false && precheckQuote.simulationErrors?.length) {
|
|
@@ -19289,7 +19439,9 @@ function useVolrAuthCallback(options = {}) {
|
|
|
19289
19439
|
setIsLoading(false);
|
|
19290
19440
|
options.onSuccess?.(volrUser);
|
|
19291
19441
|
} catch (err) {
|
|
19292
|
-
console.error(
|
|
19442
|
+
console.error(
|
|
19443
|
+
`[useVolrAuthCallback] Token exchange error: ${err instanceof Error ? err.message : String(err)}`
|
|
19444
|
+
);
|
|
19293
19445
|
let errorMsg = "Failed to complete authentication";
|
|
19294
19446
|
if (err instanceof Error) {
|
|
19295
19447
|
if (err.message.includes("AUTH_CODE_EXPIRED")) {
|
|
@@ -19393,7 +19545,9 @@ function useDepositListener(input) {
|
|
|
19393
19545
|
if (cancelled) return;
|
|
19394
19546
|
setStatus({ state: "listening", balance: initial });
|
|
19395
19547
|
} catch (e) {
|
|
19396
|
-
console.error(
|
|
19548
|
+
console.error(
|
|
19549
|
+
`[DepositListener] Error: ${e instanceof Error ? e.message : String(e)}`
|
|
19550
|
+
);
|
|
19397
19551
|
if (cancelled) return;
|
|
19398
19552
|
setStatus({ state: "error", message: e.message || String(e) });
|
|
19399
19553
|
return;
|
|
@@ -19429,7 +19583,9 @@ function useDepositListener(input) {
|
|
|
19429
19583
|
return prev;
|
|
19430
19584
|
});
|
|
19431
19585
|
} catch (err) {
|
|
19432
|
-
console.error(
|
|
19586
|
+
console.error(
|
|
19587
|
+
`[DepositListener] Polling error: ${err instanceof Error ? err.message : String(err)}`
|
|
19588
|
+
);
|
|
19433
19589
|
if (cancelled) return;
|
|
19434
19590
|
setStatus({ state: "error", message: err.message || String(err) });
|
|
19435
19591
|
}
|
|
@@ -19532,6 +19688,8 @@ async function enrollPasskey(params) {
|
|
|
19532
19688
|
};
|
|
19533
19689
|
const prfSalt = deriveWrapKey(tempPrfInput);
|
|
19534
19690
|
const displayName = buildDisplayName(userEmail, userEvmAddress, userId);
|
|
19691
|
+
const authenticatorSelection = getAuthenticatorSelection();
|
|
19692
|
+
const hints = getWebAuthnHints();
|
|
19535
19693
|
const publicKeyCredentialCreationOptions = {
|
|
19536
19694
|
challenge: challenge2,
|
|
19537
19695
|
rp: {
|
|
@@ -19544,7 +19702,7 @@ async function enrollPasskey(params) {
|
|
|
19544
19702
|
displayName
|
|
19545
19703
|
},
|
|
19546
19704
|
pubKeyCredParams: PUBKEY_CRED_PARAMS,
|
|
19547
|
-
authenticatorSelection
|
|
19705
|
+
authenticatorSelection,
|
|
19548
19706
|
timeout: WEBAUTHN_TIMEOUT,
|
|
19549
19707
|
attestation: ATTESTATION,
|
|
19550
19708
|
extensions: {
|
|
@@ -19553,7 +19711,10 @@ async function enrollPasskey(params) {
|
|
|
19553
19711
|
first: prfSalt.buffer
|
|
19554
19712
|
}
|
|
19555
19713
|
}
|
|
19556
|
-
}
|
|
19714
|
+
},
|
|
19715
|
+
// Chrome 128+ supports hints to prioritize certain authenticator types
|
|
19716
|
+
// On Windows/Linux, this prioritizes QR code over USB security key prompt
|
|
19717
|
+
...hints && { hints }
|
|
19557
19718
|
};
|
|
19558
19719
|
const credential = await navigator.credentials.create({
|
|
19559
19720
|
publicKey: publicKeyCredentialCreationOptions
|
|
@@ -20062,7 +20223,9 @@ function useUserBalances() {
|
|
|
20062
20223
|
});
|
|
20063
20224
|
setBalances(initialBalances);
|
|
20064
20225
|
}).catch((err) => {
|
|
20065
|
-
console.error(
|
|
20226
|
+
console.error(
|
|
20227
|
+
`[useUserBalances] Failed to fetch branding: ${err instanceof Error ? err.message : String(err)}`
|
|
20228
|
+
);
|
|
20066
20229
|
setError(err instanceof Error ? err : new Error("Failed to fetch branding"));
|
|
20067
20230
|
}).finally(() => {
|
|
20068
20231
|
setIsLoadingBranding(false);
|
|
@@ -20103,7 +20266,9 @@ function useUserBalances() {
|
|
|
20103
20266
|
error: void 0
|
|
20104
20267
|
};
|
|
20105
20268
|
} catch (err) {
|
|
20106
|
-
console.error(
|
|
20269
|
+
console.error(
|
|
20270
|
+
`[useUserBalances] Failed to fetch balance for ${id}: ${err instanceof Error ? err.message : String(err)}`
|
|
20271
|
+
);
|
|
20107
20272
|
return {
|
|
20108
20273
|
id,
|
|
20109
20274
|
balanceRaw: 0n,
|
|
@@ -20743,7 +20908,12 @@ function getPlatformHint(platform) {
|
|
|
20743
20908
|
case "Windows":
|
|
20744
20909
|
return {
|
|
20745
20910
|
hintKey: "passkey.hint.windows",
|
|
20746
|
-
noteKey: "passkey.hint.
|
|
20911
|
+
noteKey: "passkey.hint.windowsNote"
|
|
20912
|
+
};
|
|
20913
|
+
case "Linux":
|
|
20914
|
+
return {
|
|
20915
|
+
hintKey: "passkey.hint.linux",
|
|
20916
|
+
noteKey: "passkey.hint.windowsNote"
|
|
20747
20917
|
};
|
|
20748
20918
|
default:
|
|
20749
20919
|
return {
|
|
@@ -20937,6 +21107,8 @@ async function completeMigration(params) {
|
|
|
20937
21107
|
credentialId: tempCredentialId
|
|
20938
21108
|
};
|
|
20939
21109
|
const prfSalt = deriveWrapKey(tempPrfInput);
|
|
21110
|
+
const authenticatorSelection = getAuthenticatorSelection();
|
|
21111
|
+
const hints = getWebAuthnHints();
|
|
20940
21112
|
const publicKeyCredentialCreationOptions = {
|
|
20941
21113
|
challenge: challenge2,
|
|
20942
21114
|
rp: {
|
|
@@ -20949,7 +21121,7 @@ async function completeMigration(params) {
|
|
|
20949
21121
|
displayName
|
|
20950
21122
|
},
|
|
20951
21123
|
pubKeyCredParams: PUBKEY_CRED_PARAMS,
|
|
20952
|
-
authenticatorSelection
|
|
21124
|
+
authenticatorSelection,
|
|
20953
21125
|
timeout: WEBAUTHN_TIMEOUT,
|
|
20954
21126
|
attestation: ATTESTATION,
|
|
20955
21127
|
extensions: {
|
|
@@ -20958,7 +21130,10 @@ async function completeMigration(params) {
|
|
|
20958
21130
|
first: prfSalt.buffer
|
|
20959
21131
|
}
|
|
20960
21132
|
}
|
|
20961
|
-
}
|
|
21133
|
+
},
|
|
21134
|
+
// Chrome 128+ supports hints to prioritize certain authenticator types
|
|
21135
|
+
// On Windows/Linux, this prioritizes QR code over USB security key prompt
|
|
21136
|
+
...hints && { hints }
|
|
20962
21137
|
};
|
|
20963
21138
|
const credential = await navigator.credentials.create({
|
|
20964
21139
|
publicKey: publicKeyCredentialCreationOptions
|
|
@@ -21126,6 +21301,6 @@ function detectWalletConnector(provider, providerInfo) {
|
|
|
21126
21301
|
(*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
21127
21302
|
*/
|
|
21128
21303
|
|
|
21129
|
-
export { DEFAULT_EXPIRES_IN_SEC, DEFAULT_MODE, PasskeyNotFoundError, PrfNotSupportedError, UserCancelledError, VolrProvider, analyzeContractForEIP7702, buildCall, buildCalls, checkPrfCompatibility, checkPrfExtensionAvailable, checkPrfSupport, compareERC20Balances, compareWalletStates, completeMigration, createGetNetworkInfo, createPasskeyAdapter, debugTransactionFailure, decryptEntropyForMigration, defaultIdempotencyKey, detectWalletConnector, diagnoseTransactionFailure, getBrowserVersion, getERC20Balance, getIOSVersion, getPasskeyAuthGuidance, getPlatformHint, getUserCredentials, getWalletState, isEIP7702Delegated, isInAppBrowser, isUserCancelledError, listenForSeedRequests, normalizeHex, normalizeHexArray, openMigrationPopup, requestMigration, requestSeedFromOpener, sendSeedToPopup, uploadBlobViaPresign, useDepositListener, useEIP6963, useInternalAuth, useMpcConnection, usePasskeyEnrollment, useUserBalances, useVolr, useVolrAuthCallback, useVolrContext, useVolrLogin, useVolrPaymentApi, useWithdraw };
|
|
21304
|
+
export { DEFAULT_EXPIRES_IN_SEC, DEFAULT_MODE, PasskeyNotFoundError, PrfNotSupportedError, UserCancelledError, VolrProvider, WebAuthnBusyError, analyzeContractForEIP7702, buildCall, buildCalls, checkPrfCompatibility, checkPrfExtensionAvailable, checkPrfSupport, compareERC20Balances, compareWalletStates, completeMigration, createGetNetworkInfo, createPasskeyAdapter, debugTransactionFailure, decryptEntropyForMigration, defaultIdempotencyKey, detectWalletConnector, diagnoseTransactionFailure, getBrowserVersion, getERC20Balance, getIOSVersion, getPasskeyAuthGuidance, getPlatformHint, getUserCredentials, getWalletState, isEIP7702Delegated, isInAppBrowser, isUserCancelledError, isWebAuthnBusyError, listenForSeedRequests, normalizeHex, normalizeHexArray, openMigrationPopup, requestMigration, requestSeedFromOpener, sendSeedToPopup, uploadBlobViaPresign, useDepositListener, useEIP6963, useInternalAuth, useMpcConnection, usePasskeyEnrollment, usePrecheck, useRelay, useUserBalances, useVolr, useVolrAuthCallback, useVolrContext, useVolrLogin, useVolrPaymentApi, useWithdraw };
|
|
21130
21305
|
//# sourceMappingURL=index.js.map
|
|
21131
21306
|
//# sourceMappingURL=index.js.map
|