@volr/react 0.1.20 → 0.1.21
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 +278 -195
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +278 -195
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -9330,6 +9330,21 @@ var APIClient = class {
|
|
|
9330
9330
|
}
|
|
9331
9331
|
};
|
|
9332
9332
|
|
|
9333
|
+
// src/config/backend.ts
|
|
9334
|
+
var DEFAULT_API_BASE_URL = "https://api.volr.io";
|
|
9335
|
+
function resolveApiBaseUrl(config) {
|
|
9336
|
+
const anyConfig = config;
|
|
9337
|
+
const devOverride = anyConfig.__devApiBaseUrl;
|
|
9338
|
+
if (devOverride && typeof devOverride === "string") {
|
|
9339
|
+
return devOverride.replace(/\/+$/, "");
|
|
9340
|
+
}
|
|
9341
|
+
const override = anyConfig.apiBaseUrl;
|
|
9342
|
+
if (override && typeof override === "string") {
|
|
9343
|
+
return override.replace(/\/+$/, "");
|
|
9344
|
+
}
|
|
9345
|
+
return DEFAULT_API_BASE_URL;
|
|
9346
|
+
}
|
|
9347
|
+
|
|
9333
9348
|
// src/headless/auth-sync.ts
|
|
9334
9349
|
var SessionSync = class {
|
|
9335
9350
|
constructor() {
|
|
@@ -9343,11 +9358,12 @@ var SessionSync = class {
|
|
|
9343
9358
|
}
|
|
9344
9359
|
if (typeof window !== "undefined") {
|
|
9345
9360
|
window.addEventListener("storage", (e) => {
|
|
9346
|
-
if (e.key === STORAGE_KEYS.accessToken || e.key === STORAGE_KEYS.user) {
|
|
9361
|
+
if (e.key === STORAGE_KEYS.accessToken || e.key === STORAGE_KEYS.refreshToken || e.key === STORAGE_KEYS.user) {
|
|
9347
9362
|
this.notifyListeners({
|
|
9348
9363
|
type: "REFRESH",
|
|
9349
9364
|
payload: {
|
|
9350
|
-
accessToken: safeStorage.getItem(STORAGE_KEYS.accessToken) || ""
|
|
9365
|
+
accessToken: safeStorage.getItem(STORAGE_KEYS.accessToken) || "",
|
|
9366
|
+
refreshToken: safeStorage.getItem(STORAGE_KEYS.refreshToken)
|
|
9351
9367
|
}
|
|
9352
9368
|
});
|
|
9353
9369
|
}
|
|
@@ -9401,19 +9417,63 @@ var SessionSync = class {
|
|
|
9401
9417
|
}
|
|
9402
9418
|
};
|
|
9403
9419
|
|
|
9404
|
-
// src/
|
|
9405
|
-
|
|
9406
|
-
|
|
9407
|
-
|
|
9408
|
-
|
|
9409
|
-
|
|
9410
|
-
|
|
9411
|
-
|
|
9412
|
-
|
|
9413
|
-
|
|
9414
|
-
|
|
9415
|
-
|
|
9416
|
-
|
|
9420
|
+
// src/react/hooks/useSessionSync.ts
|
|
9421
|
+
function useSessionSync({
|
|
9422
|
+
client,
|
|
9423
|
+
config,
|
|
9424
|
+
setAccessTokenState,
|
|
9425
|
+
setRefreshTokenState,
|
|
9426
|
+
setUser,
|
|
9427
|
+
setProviderState
|
|
9428
|
+
}) {
|
|
9429
|
+
const syncRef = react.useRef(null);
|
|
9430
|
+
react.useEffect(() => {
|
|
9431
|
+
syncRef.current = new SessionSync();
|
|
9432
|
+
const unsubscribe = syncRef.current.subscribe((event) => {
|
|
9433
|
+
if (event.type === "LOGIN") {
|
|
9434
|
+
client.setAccessToken(event.payload.accessToken);
|
|
9435
|
+
setAccessTokenState(event.payload.accessToken);
|
|
9436
|
+
client.setRefreshToken(event.payload.refreshToken);
|
|
9437
|
+
setRefreshTokenState(event.payload.refreshToken);
|
|
9438
|
+
setUser(event.payload.user);
|
|
9439
|
+
safeStorage.setItem(
|
|
9440
|
+
STORAGE_KEYS.user,
|
|
9441
|
+
JSON.stringify(event.payload.user)
|
|
9442
|
+
);
|
|
9443
|
+
client.setApiKey(config.projectApiKey);
|
|
9444
|
+
} else if (event.type === "LOGOUT") {
|
|
9445
|
+
client.setAccessToken(null);
|
|
9446
|
+
client.setRefreshToken(null);
|
|
9447
|
+
setAccessTokenState(null);
|
|
9448
|
+
setRefreshTokenState(null);
|
|
9449
|
+
setUser(null);
|
|
9450
|
+
setProviderState(null);
|
|
9451
|
+
safeStorage.removeItem(STORAGE_KEYS.user);
|
|
9452
|
+
safeStorage.removeItem(STORAGE_KEYS.provider);
|
|
9453
|
+
} else if (event.type === "REFRESH") {
|
|
9454
|
+
client.setAccessToken(event.payload.accessToken);
|
|
9455
|
+
setAccessTokenState(event.payload.accessToken);
|
|
9456
|
+
if (event.payload.refreshToken) {
|
|
9457
|
+
client.setRefreshToken(event.payload.refreshToken);
|
|
9458
|
+
setRefreshTokenState(event.payload.refreshToken);
|
|
9459
|
+
}
|
|
9460
|
+
} else if (event.type === "PROVIDER_SET") {
|
|
9461
|
+
setUser(
|
|
9462
|
+
(prev) => prev ? {
|
|
9463
|
+
...prev,
|
|
9464
|
+
keyStorageType: event.payload.keyStorageType,
|
|
9465
|
+
address: event.payload.address
|
|
9466
|
+
} : null
|
|
9467
|
+
);
|
|
9468
|
+
safeStorage.setItem(STORAGE_KEYS.provider, event.payload.keyStorageType);
|
|
9469
|
+
}
|
|
9470
|
+
});
|
|
9471
|
+
return () => {
|
|
9472
|
+
unsubscribe();
|
|
9473
|
+
syncRef.current?.destroy();
|
|
9474
|
+
};
|
|
9475
|
+
}, [client, config.projectApiKey, setAccessTokenState, setRefreshTokenState, setUser, setProviderState]);
|
|
9476
|
+
return syncRef;
|
|
9417
9477
|
}
|
|
9418
9478
|
|
|
9419
9479
|
// src/config/webauthn.ts
|
|
@@ -9676,6 +9736,120 @@ async function restorePasskey(params) {
|
|
|
9676
9736
|
provider
|
|
9677
9737
|
};
|
|
9678
9738
|
}
|
|
9739
|
+
|
|
9740
|
+
// src/react/hooks/useAutoRecover.ts
|
|
9741
|
+
function useAutoRecover({
|
|
9742
|
+
client,
|
|
9743
|
+
config,
|
|
9744
|
+
setAccessTokenState,
|
|
9745
|
+
setRefreshTokenState,
|
|
9746
|
+
setUser,
|
|
9747
|
+
setProviderState,
|
|
9748
|
+
setProvider,
|
|
9749
|
+
setIsLoading
|
|
9750
|
+
}) {
|
|
9751
|
+
const REQUIRE_USER_GESTURE_TO_RESTORE = true;
|
|
9752
|
+
const hasRecoveredRef = react.useRef(false);
|
|
9753
|
+
const restorationAttemptedRef = react.useRef(false);
|
|
9754
|
+
react.useEffect(() => {
|
|
9755
|
+
if (config.autoRecoverOnLogin !== false && !hasRecoveredRef.current) {
|
|
9756
|
+
hasRecoveredRef.current = true;
|
|
9757
|
+
const recover = async () => {
|
|
9758
|
+
try {
|
|
9759
|
+
setIsLoading(true);
|
|
9760
|
+
if (!client.getRefreshToken()) {
|
|
9761
|
+
console.log("[Provider] No refresh token found, skipping auto-recover");
|
|
9762
|
+
setIsLoading(false);
|
|
9763
|
+
return;
|
|
9764
|
+
}
|
|
9765
|
+
const refreshedUser = await client.refreshSession();
|
|
9766
|
+
console.log("[Provider] Session refreshed, user:", refreshedUser);
|
|
9767
|
+
setAccessTokenState(client.getAccessToken());
|
|
9768
|
+
setRefreshTokenState(client.getRefreshToken());
|
|
9769
|
+
if (refreshedUser) {
|
|
9770
|
+
setUser(refreshedUser);
|
|
9771
|
+
if (!REQUIRE_USER_GESTURE_TO_RESTORE) ; else if (refreshedUser.keyStorageType === "passkey") {
|
|
9772
|
+
console.log("[Provider] TTL=0 mode: Provider restoration deferred");
|
|
9773
|
+
if (!refreshedUser.blobUrl || !refreshedUser.prfInput) {
|
|
9774
|
+
console.warn("[Provider] Passkey user missing blobUrl or prfInput");
|
|
9775
|
+
}
|
|
9776
|
+
}
|
|
9777
|
+
} else {
|
|
9778
|
+
const userStr = safeStorage.getItem(STORAGE_KEYS.user);
|
|
9779
|
+
if (userStr) {
|
|
9780
|
+
try {
|
|
9781
|
+
setUser(JSON.parse(userStr));
|
|
9782
|
+
} catch {
|
|
9783
|
+
safeStorage.removeItem(STORAGE_KEYS.user);
|
|
9784
|
+
}
|
|
9785
|
+
}
|
|
9786
|
+
}
|
|
9787
|
+
} catch {
|
|
9788
|
+
client.setAccessToken(null);
|
|
9789
|
+
client.setRefreshToken(null);
|
|
9790
|
+
setAccessTokenState(null);
|
|
9791
|
+
setRefreshTokenState(null);
|
|
9792
|
+
setUser(null);
|
|
9793
|
+
setProviderState(null);
|
|
9794
|
+
safeStorage.removeItem(STORAGE_KEYS.user);
|
|
9795
|
+
safeStorage.removeItem(STORAGE_KEYS.provider);
|
|
9796
|
+
} finally {
|
|
9797
|
+
setIsLoading(false);
|
|
9798
|
+
}
|
|
9799
|
+
};
|
|
9800
|
+
recover();
|
|
9801
|
+
} else {
|
|
9802
|
+
setIsLoading(false);
|
|
9803
|
+
}
|
|
9804
|
+
}, [client, config.autoRecoverOnLogin, setAccessTokenState, setRefreshTokenState, setUser, setProviderState, setProvider, setIsLoading]);
|
|
9805
|
+
}
|
|
9806
|
+
function useWalletEvents({
|
|
9807
|
+
user,
|
|
9808
|
+
logout,
|
|
9809
|
+
setUser,
|
|
9810
|
+
setProviderState
|
|
9811
|
+
}) {
|
|
9812
|
+
react.useEffect(() => {
|
|
9813
|
+
if (!user) return;
|
|
9814
|
+
if (typeof window === "undefined" || !window.ethereum) {
|
|
9815
|
+
return;
|
|
9816
|
+
}
|
|
9817
|
+
const ethereum = window.ethereum;
|
|
9818
|
+
const handleAccountsChanged = (accounts) => {
|
|
9819
|
+
console.log("[Provider] accountsChanged event:", accounts);
|
|
9820
|
+
if (accounts.length === 0) {
|
|
9821
|
+
console.warn("[Provider] Wallet disconnected, logging out...");
|
|
9822
|
+
setTimeout(() => logout(), 3e3);
|
|
9823
|
+
} else if (user.evmAddress && accounts[0].toLowerCase() !== user.evmAddress.toLowerCase()) {
|
|
9824
|
+
console.warn("[Provider] Account changed, logging out in 3 seconds...");
|
|
9825
|
+
setTimeout(() => logout(), 3e3);
|
|
9826
|
+
}
|
|
9827
|
+
};
|
|
9828
|
+
const handleChainChanged = (chainIdHex) => {
|
|
9829
|
+
const newChainId = parseInt(chainIdHex, 16);
|
|
9830
|
+
console.log("[Provider] chainChanged event:", newChainId);
|
|
9831
|
+
setUser(
|
|
9832
|
+
(prev) => prev ? { ...prev, lastWalletChainId: newChainId } : null
|
|
9833
|
+
);
|
|
9834
|
+
window.location.reload();
|
|
9835
|
+
};
|
|
9836
|
+
const handleDisconnect = () => {
|
|
9837
|
+
console.log("[Provider] disconnect event");
|
|
9838
|
+
setProviderState(null);
|
|
9839
|
+
safeStorage.removeItem(STORAGE_KEYS.provider);
|
|
9840
|
+
};
|
|
9841
|
+
ethereum.on("accountsChanged", handleAccountsChanged);
|
|
9842
|
+
ethereum.on("chainChanged", handleChainChanged);
|
|
9843
|
+
ethereum.on("disconnect", handleDisconnect);
|
|
9844
|
+
return () => {
|
|
9845
|
+
ethereum.removeListener("accountsChanged", handleAccountsChanged);
|
|
9846
|
+
ethereum.removeListener("chainChanged", handleChainChanged);
|
|
9847
|
+
ethereum.removeListener("disconnect", handleDisconnect);
|
|
9848
|
+
};
|
|
9849
|
+
}, [user, logout, setUser, setProviderState]);
|
|
9850
|
+
}
|
|
9851
|
+
|
|
9852
|
+
// src/utils/json.ts
|
|
9679
9853
|
function serializeBigIntDeep(obj) {
|
|
9680
9854
|
if (obj === null || obj === void 0) {
|
|
9681
9855
|
return obj;
|
|
@@ -9697,8 +9871,62 @@ function serializeBigIntDeep(obj) {
|
|
|
9697
9871
|
}
|
|
9698
9872
|
return obj;
|
|
9699
9873
|
}
|
|
9874
|
+
|
|
9875
|
+
// src/react/hooks/useVolrActions.ts
|
|
9876
|
+
function useVolrActions({
|
|
9877
|
+
client,
|
|
9878
|
+
setError
|
|
9879
|
+
}) {
|
|
9880
|
+
const precheck = react.useCallback(
|
|
9881
|
+
async (input) => {
|
|
9882
|
+
try {
|
|
9883
|
+
setError(null);
|
|
9884
|
+
await client.ensureAccessToken();
|
|
9885
|
+
const response = await client.post(
|
|
9886
|
+
"/wallet/precheck",
|
|
9887
|
+
input
|
|
9888
|
+
);
|
|
9889
|
+
return response.quote;
|
|
9890
|
+
} catch (err) {
|
|
9891
|
+
const error = err instanceof Error ? err : new Error("Precheck failed");
|
|
9892
|
+
const diag = err?.response?.data?.error?.developerDiagnostics;
|
|
9893
|
+
if (diag) {
|
|
9894
|
+
console.error("[volr][precheck] developerDiagnostics:", diag);
|
|
9895
|
+
}
|
|
9896
|
+
setError(error);
|
|
9897
|
+
throw error;
|
|
9898
|
+
}
|
|
9899
|
+
},
|
|
9900
|
+
[client, setError]
|
|
9901
|
+
);
|
|
9902
|
+
const relay = react.useCallback(
|
|
9903
|
+
async (input, opts) => {
|
|
9904
|
+
try {
|
|
9905
|
+
setError(null);
|
|
9906
|
+
await client.ensureAccessToken();
|
|
9907
|
+
const idempotencyKey = opts?.idempotencyKey ?? (typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : `${Date.now()}-${Math.random()}`);
|
|
9908
|
+
const serializedInput = serializeBigIntDeep(input);
|
|
9909
|
+
const response = await client.post(
|
|
9910
|
+
"/wallet/relay",
|
|
9911
|
+
serializedInput,
|
|
9912
|
+
idempotencyKey
|
|
9913
|
+
);
|
|
9914
|
+
return response;
|
|
9915
|
+
} catch (err) {
|
|
9916
|
+
const error = err instanceof Error ? err : new Error("Relay failed");
|
|
9917
|
+
const diag = err?.response?.data?.error?.developerDiagnostics;
|
|
9918
|
+
if (diag) {
|
|
9919
|
+
console.error("[volr][relay] developerDiagnostics:", diag);
|
|
9920
|
+
}
|
|
9921
|
+
setError(error);
|
|
9922
|
+
throw error;
|
|
9923
|
+
}
|
|
9924
|
+
},
|
|
9925
|
+
[client, setError]
|
|
9926
|
+
);
|
|
9927
|
+
return { precheck, relay };
|
|
9928
|
+
}
|
|
9700
9929
|
function VolrProvider({ config, children }) {
|
|
9701
|
-
const REQUIRE_USER_GESTURE_TO_RESTORE = true;
|
|
9702
9930
|
const providerCountRef = react.useRef(0);
|
|
9703
9931
|
react.useEffect(() => {
|
|
9704
9932
|
providerCountRef.current++;
|
|
@@ -9747,45 +9975,14 @@ function VolrProvider({ config, children }) {
|
|
|
9747
9975
|
const [refreshToken, setRefreshTokenState] = react.useState(() => {
|
|
9748
9976
|
return client.getRefreshToken();
|
|
9749
9977
|
});
|
|
9750
|
-
const syncRef =
|
|
9751
|
-
|
|
9752
|
-
|
|
9753
|
-
|
|
9754
|
-
|
|
9755
|
-
|
|
9756
|
-
|
|
9757
|
-
|
|
9758
|
-
safeStorage.setItem(
|
|
9759
|
-
STORAGE_KEYS.user,
|
|
9760
|
-
JSON.stringify(event.payload.user)
|
|
9761
|
-
);
|
|
9762
|
-
client.setApiKey(config.projectApiKey);
|
|
9763
|
-
} else if (event.type === "LOGOUT") {
|
|
9764
|
-
client.setAccessToken(null);
|
|
9765
|
-
client.setRefreshToken(null);
|
|
9766
|
-
setAccessTokenState(null);
|
|
9767
|
-
setRefreshTokenState(null);
|
|
9768
|
-
setUser(null);
|
|
9769
|
-
setProviderState(null);
|
|
9770
|
-
safeStorage.removeItem(STORAGE_KEYS.user);
|
|
9771
|
-
safeStorage.removeItem(STORAGE_KEYS.provider);
|
|
9772
|
-
} else if (event.type === "REFRESH") {
|
|
9773
|
-
client.setAccessToken(event.payload.accessToken);
|
|
9774
|
-
setAccessTokenState(event.payload.accessToken);
|
|
9775
|
-
} else if (event.type === "PROVIDER_SET") {
|
|
9776
|
-
setUser((prev) => ({
|
|
9777
|
-
...prev,
|
|
9778
|
-
keyStorageType: event.payload.keyStorageType,
|
|
9779
|
-
address: event.payload.address
|
|
9780
|
-
}));
|
|
9781
|
-
safeStorage.setItem(STORAGE_KEYS.provider, event.payload.keyStorageType);
|
|
9782
|
-
}
|
|
9783
|
-
});
|
|
9784
|
-
return () => {
|
|
9785
|
-
unsubscribe();
|
|
9786
|
-
syncRef.current?.destroy();
|
|
9787
|
-
};
|
|
9788
|
-
}, [client, config.projectApiKey]);
|
|
9978
|
+
const syncRef = useSessionSync({
|
|
9979
|
+
client,
|
|
9980
|
+
config,
|
|
9981
|
+
setAccessTokenState,
|
|
9982
|
+
setRefreshTokenState,
|
|
9983
|
+
setUser,
|
|
9984
|
+
setProviderState
|
|
9985
|
+
});
|
|
9789
9986
|
const setProvider = react.useCallback(
|
|
9790
9987
|
async (newProvider) => {
|
|
9791
9988
|
try {
|
|
@@ -9817,108 +10014,22 @@ function VolrProvider({ config, children }) {
|
|
|
9817
10014
|
throw error2;
|
|
9818
10015
|
}
|
|
9819
10016
|
},
|
|
9820
|
-
[client, user]
|
|
9821
|
-
);
|
|
9822
|
-
const hasRecoveredRef = react.useRef(false);
|
|
9823
|
-
const restorationAttemptedRef = react.useRef(false);
|
|
9824
|
-
react.useEffect(() => {
|
|
9825
|
-
if (config.autoRecoverOnLogin !== false && !hasRecoveredRef.current) {
|
|
9826
|
-
hasRecoveredRef.current = true;
|
|
9827
|
-
const recover = async () => {
|
|
9828
|
-
try {
|
|
9829
|
-
setIsLoading(true);
|
|
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");
|
|
9845
|
-
}
|
|
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);
|
|
9854
|
-
}
|
|
9855
|
-
}
|
|
9856
|
-
}
|
|
9857
|
-
} catch {
|
|
9858
|
-
client.setAccessToken(null);
|
|
9859
|
-
client.setRefreshToken(null);
|
|
9860
|
-
setAccessTokenState(null);
|
|
9861
|
-
setRefreshTokenState(null);
|
|
9862
|
-
setUser(null);
|
|
9863
|
-
setProviderState(null);
|
|
9864
|
-
safeStorage.removeItem(STORAGE_KEYS.user);
|
|
9865
|
-
safeStorage.removeItem(STORAGE_KEYS.provider);
|
|
9866
|
-
} finally {
|
|
9867
|
-
setIsLoading(false);
|
|
9868
|
-
}
|
|
9869
|
-
};
|
|
9870
|
-
recover();
|
|
9871
|
-
} else {
|
|
9872
|
-
setIsLoading(false);
|
|
9873
|
-
}
|
|
9874
|
-
}, [client, config.autoRecoverOnLogin]);
|
|
9875
|
-
const precheck = react.useCallback(
|
|
9876
|
-
async (input) => {
|
|
9877
|
-
try {
|
|
9878
|
-
setError(null);
|
|
9879
|
-
await client.ensureAccessToken();
|
|
9880
|
-
const response = await client.post(
|
|
9881
|
-
"/wallet/precheck",
|
|
9882
|
-
input
|
|
9883
|
-
);
|
|
9884
|
-
return response.quote;
|
|
9885
|
-
} catch (err) {
|
|
9886
|
-
const error2 = err instanceof Error ? err : new Error("Precheck failed");
|
|
9887
|
-
const diag = err?.response?.data?.error?.developerDiagnostics;
|
|
9888
|
-
if (diag) {
|
|
9889
|
-
console.error("[volr][precheck] developerDiagnostics:", diag);
|
|
9890
|
-
}
|
|
9891
|
-
setError(error2);
|
|
9892
|
-
throw error2;
|
|
9893
|
-
}
|
|
9894
|
-
},
|
|
9895
|
-
[client]
|
|
9896
|
-
);
|
|
9897
|
-
const relay = react.useCallback(
|
|
9898
|
-
async (input, opts) => {
|
|
9899
|
-
try {
|
|
9900
|
-
setError(null);
|
|
9901
|
-
await client.ensureAccessToken();
|
|
9902
|
-
const idempotencyKey = opts?.idempotencyKey ?? (typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : `${Date.now()}-${Math.random()}`);
|
|
9903
|
-
const serializedInput = serializeBigIntDeep(input);
|
|
9904
|
-
const response = await client.post(
|
|
9905
|
-
"/wallet/relay",
|
|
9906
|
-
serializedInput,
|
|
9907
|
-
idempotencyKey
|
|
9908
|
-
);
|
|
9909
|
-
return response;
|
|
9910
|
-
} catch (err) {
|
|
9911
|
-
const error2 = err instanceof Error ? err : new Error("Relay failed");
|
|
9912
|
-
const diag = err?.response?.data?.error?.developerDiagnostics;
|
|
9913
|
-
if (diag) {
|
|
9914
|
-
console.error("[volr][relay] developerDiagnostics:", diag);
|
|
9915
|
-
}
|
|
9916
|
-
setError(error2);
|
|
9917
|
-
throw error2;
|
|
9918
|
-
}
|
|
9919
|
-
},
|
|
9920
|
-
[client]
|
|
10017
|
+
[client, user, syncRef]
|
|
9921
10018
|
);
|
|
10019
|
+
useAutoRecover({
|
|
10020
|
+
client,
|
|
10021
|
+
config,
|
|
10022
|
+
setAccessTokenState,
|
|
10023
|
+
setRefreshTokenState,
|
|
10024
|
+
setUser,
|
|
10025
|
+
setProviderState,
|
|
10026
|
+
setProvider,
|
|
10027
|
+
setIsLoading
|
|
10028
|
+
});
|
|
10029
|
+
const { precheck, relay } = useVolrActions({
|
|
10030
|
+
client,
|
|
10031
|
+
setError
|
|
10032
|
+
});
|
|
9922
10033
|
const logout = react.useCallback(async () => {
|
|
9923
10034
|
try {
|
|
9924
10035
|
setError(null);
|
|
@@ -9938,45 +10049,13 @@ function VolrProvider({ config, children }) {
|
|
|
9938
10049
|
setError(error2);
|
|
9939
10050
|
throw error2;
|
|
9940
10051
|
}
|
|
9941
|
-
}, [client]);
|
|
9942
|
-
|
|
9943
|
-
|
|
9944
|
-
|
|
9945
|
-
|
|
9946
|
-
|
|
9947
|
-
|
|
9948
|
-
const handleAccountsChanged = (accounts) => {
|
|
9949
|
-
console.log("[Provider] accountsChanged event:", accounts);
|
|
9950
|
-
if (accounts.length === 0) {
|
|
9951
|
-
console.warn("[Provider] Wallet disconnected, logging out...");
|
|
9952
|
-
setTimeout(() => logout(), 3e3);
|
|
9953
|
-
} else if (user.evmAddress && accounts[0].toLowerCase() !== user.evmAddress.toLowerCase()) {
|
|
9954
|
-
console.warn("[Provider] Account changed, logging out in 3 seconds...");
|
|
9955
|
-
setTimeout(() => logout(), 3e3);
|
|
9956
|
-
}
|
|
9957
|
-
};
|
|
9958
|
-
const handleChainChanged = (chainIdHex) => {
|
|
9959
|
-
const newChainId = parseInt(chainIdHex, 16);
|
|
9960
|
-
console.log("[Provider] chainChanged event:", newChainId);
|
|
9961
|
-
setUser(
|
|
9962
|
-
(prev) => prev ? { ...prev, lastWalletChainId: newChainId } : null
|
|
9963
|
-
);
|
|
9964
|
-
window.location.reload();
|
|
9965
|
-
};
|
|
9966
|
-
const handleDisconnect = () => {
|
|
9967
|
-
console.log("[Provider] disconnect event");
|
|
9968
|
-
setProviderState(null);
|
|
9969
|
-
safeStorage.removeItem(STORAGE_KEYS.provider);
|
|
9970
|
-
};
|
|
9971
|
-
ethereum.on("accountsChanged", handleAccountsChanged);
|
|
9972
|
-
ethereum.on("chainChanged", handleChainChanged);
|
|
9973
|
-
ethereum.on("disconnect", handleDisconnect);
|
|
9974
|
-
return () => {
|
|
9975
|
-
ethereum.removeListener("accountsChanged", handleAccountsChanged);
|
|
9976
|
-
ethereum.removeListener("chainChanged", handleChainChanged);
|
|
9977
|
-
ethereum.removeListener("disconnect", handleDisconnect);
|
|
9978
|
-
};
|
|
9979
|
-
}, [user, logout, setUser]);
|
|
10052
|
+
}, [client, syncRef]);
|
|
10053
|
+
useWalletEvents({
|
|
10054
|
+
user,
|
|
10055
|
+
logout,
|
|
10056
|
+
setUser,
|
|
10057
|
+
setProviderState
|
|
10058
|
+
});
|
|
9980
10059
|
const publicValue = react.useMemo(
|
|
9981
10060
|
() => ({
|
|
9982
10061
|
config,
|
|
@@ -18562,6 +18641,10 @@ function useVolrLogin() {
|
|
|
18562
18641
|
setAccessToken(accessToken);
|
|
18563
18642
|
if (refreshToken) {
|
|
18564
18643
|
setRefreshToken(refreshToken);
|
|
18644
|
+
} else {
|
|
18645
|
+
console.warn(
|
|
18646
|
+
"[useVolrLogin] Access token received but refresh token is missing. Check if backend is updated to return refresh token in body."
|
|
18647
|
+
);
|
|
18565
18648
|
}
|
|
18566
18649
|
if (userFromServer) {
|
|
18567
18650
|
setUser(toVolrUser(userFromServer));
|