@dexterai/x402 1.5.1 → 1.5.3
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/client/index.cjs +4 -12
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.js +4 -12
- package/dist/client/index.js.map +1 -1
- package/dist/react/index.cjs +78 -34
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +79 -35
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
package/dist/react/index.js
CHANGED
|
@@ -613,19 +613,11 @@ function createX402Client(config) {
|
|
|
613
613
|
return null;
|
|
614
614
|
}
|
|
615
615
|
const accessPassJwt = passResponse.headers.get("ACCESS-PASS");
|
|
616
|
-
if (
|
|
617
|
-
|
|
616
|
+
if (accessPassJwt) {
|
|
617
|
+
cachePass(url, accessPassJwt);
|
|
618
|
+
log("Access pass purchased and cached");
|
|
618
619
|
}
|
|
619
|
-
|
|
620
|
-
log("Access pass purchased and cached");
|
|
621
|
-
const retryResponse = await customFetch(input, {
|
|
622
|
-
...init,
|
|
623
|
-
headers: {
|
|
624
|
-
...init?.headers || {},
|
|
625
|
-
"Authorization": `Bearer ${accessPassJwt}`
|
|
626
|
-
}
|
|
627
|
-
});
|
|
628
|
-
return retryResponse;
|
|
620
|
+
return passResponse;
|
|
629
621
|
}
|
|
630
622
|
async function x402Fetch(input, init) {
|
|
631
623
|
const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
@@ -1050,7 +1042,7 @@ function useX402Payment(config) {
|
|
|
1050
1042
|
}
|
|
1051
1043
|
|
|
1052
1044
|
// src/react/useAccessPass.ts
|
|
1053
|
-
import { useState as useState2, useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo2 } from "react";
|
|
1045
|
+
import { useState as useState2, useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo2, useRef } from "react";
|
|
1054
1046
|
function useAccessPass(config) {
|
|
1055
1047
|
const {
|
|
1056
1048
|
wallets: walletSet,
|
|
@@ -1061,13 +1053,43 @@ function useAccessPass(config) {
|
|
|
1061
1053
|
autoConnect = true,
|
|
1062
1054
|
verbose = false
|
|
1063
1055
|
} = config;
|
|
1056
|
+
const storageKey = `x402-access-pass:${resourceUrl}`;
|
|
1057
|
+
function loadPersistedPass() {
|
|
1058
|
+
if (typeof sessionStorage === "undefined") return null;
|
|
1059
|
+
try {
|
|
1060
|
+
const stored = sessionStorage.getItem(storageKey);
|
|
1061
|
+
if (!stored) return null;
|
|
1062
|
+
const parsed = JSON.parse(stored);
|
|
1063
|
+
if (new Date(parsed.expiresAt).getTime() <= Date.now()) {
|
|
1064
|
+
sessionStorage.removeItem(storageKey);
|
|
1065
|
+
return null;
|
|
1066
|
+
}
|
|
1067
|
+
return parsed;
|
|
1068
|
+
} catch {
|
|
1069
|
+
return null;
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
function persistPass(jwt, tier, expiresAt) {
|
|
1073
|
+
if (typeof sessionStorage === "undefined") return;
|
|
1074
|
+
try {
|
|
1075
|
+
sessionStorage.setItem(storageKey, JSON.stringify({ jwt, tier, expiresAt }));
|
|
1076
|
+
} catch {
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
const persisted = loadPersistedPass();
|
|
1064
1080
|
const [tiers, setTiers] = useState2(null);
|
|
1065
1081
|
const [customRatePerHour, setCustomRatePerHour] = useState2(null);
|
|
1066
1082
|
const [isLoadingTiers, setIsLoadingTiers] = useState2(false);
|
|
1067
|
-
const [passJwt, setPassJwt] = useState2(null);
|
|
1068
|
-
const [passInfo, setPassInfo] = useState2(
|
|
1083
|
+
const [passJwt, setPassJwt] = useState2(persisted?.jwt || null);
|
|
1084
|
+
const [passInfo, setPassInfo] = useState2(
|
|
1085
|
+
persisted ? { tier: persisted.tier, expiresAt: persisted.expiresAt } : null
|
|
1086
|
+
);
|
|
1069
1087
|
const [isPurchasing, setIsPurchasing] = useState2(false);
|
|
1070
1088
|
const [purchaseError, setPurchaseError] = useState2(null);
|
|
1089
|
+
const passJwtRef = useRef(passJwt);
|
|
1090
|
+
useEffect2(() => {
|
|
1091
|
+
passJwtRef.current = passJwt;
|
|
1092
|
+
}, [passJwt]);
|
|
1071
1093
|
const log = useCallback2((...args) => {
|
|
1072
1094
|
if (verbose) console.log("[useAccessPass]", ...args);
|
|
1073
1095
|
}, [verbose]);
|
|
@@ -1134,25 +1156,31 @@ function useAccessPass(config) {
|
|
|
1134
1156
|
else if (durationSeconds) url += (url.includes("?") ? "&" : "?") + `duration=${durationSeconds}`;
|
|
1135
1157
|
const res = await client.fetch(url, { method: "POST" });
|
|
1136
1158
|
const jwt = res.headers.get("ACCESS-PASS");
|
|
1159
|
+
log("ACCESS-PASS header:", jwt ? "found" : "NOT FOUND");
|
|
1137
1160
|
if (jwt) {
|
|
1138
1161
|
setPassJwt(jwt);
|
|
1162
|
+
let passTier = tier || "unknown";
|
|
1163
|
+
let passExpiresAt = "";
|
|
1139
1164
|
try {
|
|
1140
1165
|
const body = await res.json();
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
expiresAt: body.accessPass?.expiresAt || ""
|
|
1144
|
-
});
|
|
1166
|
+
passTier = body.accessPass?.tier || passTier;
|
|
1167
|
+
passExpiresAt = body.accessPass?.expiresAt || "";
|
|
1145
1168
|
} catch {
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1169
|
+
}
|
|
1170
|
+
if (!passExpiresAt) {
|
|
1171
|
+
try {
|
|
1172
|
+
const parts = jwt.split(".");
|
|
1173
|
+
if (parts.length === 3) {
|
|
1174
|
+
const payload = JSON.parse(atob(parts[1].replace(/-/g, "+").replace(/_/g, "/")));
|
|
1175
|
+
passTier = payload.tier || passTier;
|
|
1176
|
+
passExpiresAt = new Date(payload.exp * 1e3).toISOString();
|
|
1177
|
+
}
|
|
1178
|
+
} catch {
|
|
1153
1179
|
}
|
|
1154
1180
|
}
|
|
1155
|
-
|
|
1181
|
+
setPassInfo({ tier: passTier, expiresAt: passExpiresAt });
|
|
1182
|
+
persistPass(jwt, passTier, passExpiresAt);
|
|
1183
|
+
log("Pass purchased and persisted:", passTier, passExpiresAt);
|
|
1156
1184
|
}
|
|
1157
1185
|
} catch (err) {
|
|
1158
1186
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
@@ -1164,17 +1192,33 @@ function useAccessPass(config) {
|
|
|
1164
1192
|
}, [resourceUrl, client, log]);
|
|
1165
1193
|
const fetchWithPass = useCallback2(async (path, init) => {
|
|
1166
1194
|
const url = path.startsWith("http") ? path : `${resourceUrl.replace(/\/$/, "")}${path.startsWith("/") ? "" : "/"}${path}`;
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
"
|
|
1195
|
+
const currentJwt = passJwtRef.current;
|
|
1196
|
+
if (currentJwt) {
|
|
1197
|
+
try {
|
|
1198
|
+
const parts = currentJwt.split(".");
|
|
1199
|
+
if (parts.length === 3) {
|
|
1200
|
+
const payload = JSON.parse(atob(parts[1].replace(/-/g, "+").replace(/_/g, "/")));
|
|
1201
|
+
if (payload.exp && payload.exp > Date.now() / 1e3) {
|
|
1202
|
+
return fetch(url, {
|
|
1203
|
+
...init,
|
|
1204
|
+
headers: {
|
|
1205
|
+
...init?.headers || {},
|
|
1206
|
+
"Authorization": `Bearer ${currentJwt}`
|
|
1207
|
+
}
|
|
1208
|
+
});
|
|
1209
|
+
}
|
|
1173
1210
|
}
|
|
1174
|
-
}
|
|
1211
|
+
} catch {
|
|
1212
|
+
}
|
|
1213
|
+
setPassJwt(null);
|
|
1214
|
+
setPassInfo(null);
|
|
1215
|
+
try {
|
|
1216
|
+
sessionStorage.removeItem(storageKey);
|
|
1217
|
+
} catch {
|
|
1218
|
+
}
|
|
1175
1219
|
}
|
|
1176
1220
|
return client.fetch(url, init);
|
|
1177
|
-
}, [resourceUrl,
|
|
1221
|
+
}, [resourceUrl, client, storageKey]);
|
|
1178
1222
|
return {
|
|
1179
1223
|
tiers,
|
|
1180
1224
|
customRatePerHour,
|