@dexterai/x402 1.8.2 → 1.9.1
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/README.md +101 -8
- package/dist/adapters/index.cjs +15 -3
- package/dist/adapters/index.cjs.map +1 -1
- package/dist/adapters/index.d.cts +5 -5
- package/dist/adapters/index.d.ts +5 -5
- package/dist/adapters/index.js +5 -3
- package/dist/adapters/index.js.map +1 -1
- package/dist/client/index.cjs +50 -9
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +7 -6
- package/dist/client/index.d.ts +7 -6
- package/dist/client/index.js +37 -9
- package/dist/client/index.js.map +1 -1
- package/dist/react/index.cjs +64 -12
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +13 -4
- package/dist/react/index.d.ts +13 -4
- package/dist/react/index.js +52 -12
- package/dist/react/index.js.map +1 -1
- package/dist/server/index.cjs +43 -18
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +12 -3
- package/dist/server/index.d.ts +12 -3
- package/dist/server/index.js +40 -16
- package/dist/server/index.js.map +1 -1
- package/dist/{solana-BeGAqPta.d.cts → solana-CfHuiW2H.d.cts} +2 -2
- package/dist/{solana-CQD9yMju.d.ts → solana-kZcwbUK9.d.ts} +2 -2
- package/dist/{x402-client-Dk9q2QQF.d.cts → sponsored-access-BCB2CxdG.d.cts} +70 -3
- package/dist/{x402-client-D9b3PHai.d.ts → sponsored-access-H1EX6zpi.d.ts} +70 -3
- package/dist/{types-DYLi7SuF.d.cts → types-BQvaF8lB.d.cts} +7 -5
- package/dist/{types-DYLi7SuF.d.ts → types-BQvaF8lB.d.ts} +7 -5
- package/dist/{types-B477nBpg.d.cts → types-DmqH9yD8.d.cts} +1 -1
- package/dist/{types-BWnUAPvD.d.ts → types-ENcnkof8.d.ts} +1 -1
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +2 -6
package/dist/react/index.d.cts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import { a as X402Client } from '../
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import { a as X402Client } from '../sponsored-access-BCB2CxdG.cjs';
|
|
2
|
+
export { f as fireImpressionBeacon, b as getSponsoredRecommendations } from '../sponsored-access-BCB2CxdG.cjs';
|
|
3
|
+
import { W as WalletSet, B as BalanceInfo } from '../types-DmqH9yD8.cjs';
|
|
4
|
+
import { SponsoredRecommendation } from '@dexterai/x402-ads-types';
|
|
5
|
+
export { SponsoredRecommendation } from '@dexterai/x402-ads-types';
|
|
6
|
+
import { a as AccessPassTier } from '../types-BQvaF8lB.cjs';
|
|
7
|
+
export { A as AccessPassClientConfig, b as AccessPassInfo, X as X402Error } from '../types-BQvaF8lB.cjs';
|
|
5
8
|
|
|
6
9
|
/**
|
|
7
10
|
* React Hook for x402 v2 Payments
|
|
@@ -114,6 +117,12 @@ interface UseX402PaymentReturn {
|
|
|
114
117
|
/** Seconds remaining on the pass */
|
|
115
118
|
remainingSeconds: number | null;
|
|
116
119
|
} | null;
|
|
120
|
+
/**
|
|
121
|
+
* Sponsored recommendations from the most recent payment.
|
|
122
|
+
* Populated when the facilitator returns sponsored-access extensions
|
|
123
|
+
* in the settlement response. Null if no recommendations were delivered.
|
|
124
|
+
*/
|
|
125
|
+
sponsoredRecommendations: SponsoredRecommendation[] | null;
|
|
117
126
|
}
|
|
118
127
|
/**
|
|
119
128
|
* React hook for managing x402 v2 payments across chains
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import { a as X402Client } from '../
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import { a as X402Client } from '../sponsored-access-H1EX6zpi.js';
|
|
2
|
+
export { f as fireImpressionBeacon, b as getSponsoredRecommendations } from '../sponsored-access-H1EX6zpi.js';
|
|
3
|
+
import { W as WalletSet, B as BalanceInfo } from '../types-ENcnkof8.js';
|
|
4
|
+
import { SponsoredRecommendation } from '@dexterai/x402-ads-types';
|
|
5
|
+
export { SponsoredRecommendation } from '@dexterai/x402-ads-types';
|
|
6
|
+
import { a as AccessPassTier } from '../types-BQvaF8lB.js';
|
|
7
|
+
export { A as AccessPassClientConfig, b as AccessPassInfo, X as X402Error } from '../types-BQvaF8lB.js';
|
|
5
8
|
|
|
6
9
|
/**
|
|
7
10
|
* React Hook for x402 v2 Payments
|
|
@@ -114,6 +117,12 @@ interface UseX402PaymentReturn {
|
|
|
114
117
|
/** Seconds remaining on the pass */
|
|
115
118
|
remainingSeconds: number | null;
|
|
116
119
|
} | null;
|
|
120
|
+
/**
|
|
121
|
+
* Sponsored recommendations from the most recent payment.
|
|
122
|
+
* Populated when the facilitator returns sponsored-access extensions
|
|
123
|
+
* in the settlement response. Null if no recommendations were delivered.
|
|
124
|
+
*/
|
|
125
|
+
sponsoredRecommendations: SponsoredRecommendation[] | null;
|
|
117
126
|
}
|
|
118
127
|
/**
|
|
119
128
|
* React hook for managing x402 v2 payments across chains
|
package/dist/react/index.js
CHANGED
|
@@ -124,7 +124,7 @@ var SolanaAdapter = class {
|
|
|
124
124
|
const connection = new Connection(url, "confirmed");
|
|
125
125
|
const userPubkey = new PublicKey(wallet.publicKey.toBase58());
|
|
126
126
|
const { payTo, asset, extra } = accept;
|
|
127
|
-
const amount = accept.amount
|
|
127
|
+
const amount = accept.amount ?? accept.maxAmountRequired;
|
|
128
128
|
if (!amount) {
|
|
129
129
|
throw new Error("Missing amount in payment requirements");
|
|
130
130
|
}
|
|
@@ -362,7 +362,7 @@ var EvmAdapter = class {
|
|
|
362
362
|
throw new Error("Wallet not connected");
|
|
363
363
|
}
|
|
364
364
|
const { payTo, asset, extra } = accept;
|
|
365
|
-
const amount = accept.amount
|
|
365
|
+
const amount = accept.amount ?? accept.maxAmountRequired;
|
|
366
366
|
if (!amount) {
|
|
367
367
|
throw new Error("Missing amount in payment requirements");
|
|
368
368
|
}
|
|
@@ -390,7 +390,9 @@ var EvmAdapter = class {
|
|
|
390
390
|
{ name: "nonce", type: "bytes32" }
|
|
391
391
|
]
|
|
392
392
|
};
|
|
393
|
-
const
|
|
393
|
+
const nonceBytes = new Uint8Array(32);
|
|
394
|
+
(globalThis.crypto ?? (await import("crypto")).webcrypto).getRandomValues(nonceBytes);
|
|
395
|
+
const nonce = "0x" + [...nonceBytes].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
394
396
|
const now = Math.floor(Date.now() / 1e3);
|
|
395
397
|
const authorization = {
|
|
396
398
|
from: wallet.address,
|
|
@@ -447,6 +449,9 @@ function isKnownUSDC(asset) {
|
|
|
447
449
|
|
|
448
450
|
// src/client/x402-client.ts
|
|
449
451
|
var receiptStore = /* @__PURE__ */ new WeakMap();
|
|
452
|
+
function getPaymentReceipt(response) {
|
|
453
|
+
return receiptStore.get(response);
|
|
454
|
+
}
|
|
450
455
|
function createX402Client(config) {
|
|
451
456
|
const {
|
|
452
457
|
adapters = [createSolanaAdapter({ verbose: config.verbose }), createEvmAdapter({ verbose: config.verbose })],
|
|
@@ -482,10 +487,11 @@ function createX402Client(config) {
|
|
|
482
487
|
const parts = jwt.split(".");
|
|
483
488
|
if (parts.length === 3) {
|
|
484
489
|
const payload = JSON.parse(atob(parts[1].replace(/-/g, "+").replace(/_/g, "/")));
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
}
|
|
490
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
491
|
+
const maxExp = now + 86400;
|
|
492
|
+
const expiresAt = Math.min(typeof payload.exp === "number" ? payload.exp : now, maxExp);
|
|
493
|
+
passCache.set(host, { jwt, expiresAt });
|
|
494
|
+
log("Access pass cached for", host, "| expires:", new Date(expiresAt * 1e3).toISOString());
|
|
489
495
|
}
|
|
490
496
|
} catch {
|
|
491
497
|
log("Failed to cache access pass");
|
|
@@ -566,7 +572,7 @@ function createX402Client(config) {
|
|
|
566
572
|
if (adapter.name === "Solana" && !accept.extra?.feePayer) return null;
|
|
567
573
|
const decimals = accept.extra?.decimals ?? (isKnownUSDC(accept.asset) ? 6 : void 0);
|
|
568
574
|
if (typeof decimals !== "number") return null;
|
|
569
|
-
const paymentAmount = accept.amount
|
|
575
|
+
const paymentAmount = accept.amount ?? accept.maxAmountRequired;
|
|
570
576
|
if (!paymentAmount) return null;
|
|
571
577
|
const rpcUrl = getRpcUrl(accept.network, adapter);
|
|
572
578
|
const balance = await adapter.getBalance(accept, wallet, rpcUrl);
|
|
@@ -710,7 +716,7 @@ function createX402Client(config) {
|
|
|
710
716
|
"Payment option missing decimals - provide in extra or use a known stablecoin"
|
|
711
717
|
);
|
|
712
718
|
}
|
|
713
|
-
const paymentAmount = accept.amount
|
|
719
|
+
const paymentAmount = accept.amount ?? accept.maxAmountRequired;
|
|
714
720
|
if (!paymentAmount) {
|
|
715
721
|
throw new X402Error("missing_amount", "Payment option missing amount");
|
|
716
722
|
}
|
|
@@ -875,6 +881,28 @@ function getExplorerUrl(txSignature, network) {
|
|
|
875
881
|
return `https://solscan.io/tx/${txSignature}`;
|
|
876
882
|
}
|
|
877
883
|
|
|
884
|
+
// src/client/sponsored-access.ts
|
|
885
|
+
function getSponsoredAccessInfo(response) {
|
|
886
|
+
const receipt = getPaymentReceipt(response);
|
|
887
|
+
if (!receipt?.extensions?.["sponsored-access"]) return void 0;
|
|
888
|
+
return receipt.extensions["sponsored-access"];
|
|
889
|
+
}
|
|
890
|
+
function getSponsoredRecommendations(response) {
|
|
891
|
+
const info = getSponsoredAccessInfo(response);
|
|
892
|
+
if (!info?.recommendations?.length) return void 0;
|
|
893
|
+
return info.recommendations;
|
|
894
|
+
}
|
|
895
|
+
async function fireImpressionBeacon(response) {
|
|
896
|
+
const info = getSponsoredAccessInfo(response);
|
|
897
|
+
const beaconUrl = info?.tracking?.impressionBeacon;
|
|
898
|
+
if (!beaconUrl) return false;
|
|
899
|
+
try {
|
|
900
|
+
await fetch(beaconUrl, { method: "GET" });
|
|
901
|
+
} catch {
|
|
902
|
+
}
|
|
903
|
+
return true;
|
|
904
|
+
}
|
|
905
|
+
|
|
878
906
|
// src/react/useX402Payment.ts
|
|
879
907
|
function useX402Payment(config) {
|
|
880
908
|
const {
|
|
@@ -890,6 +918,7 @@ function useX402Payment(config) {
|
|
|
890
918
|
const [transactionId, setTransactionId] = useState(null);
|
|
891
919
|
const [transactionNetwork, setTransactionNetwork] = useState(null);
|
|
892
920
|
const [balances, setBalances] = useState([]);
|
|
921
|
+
const [sponsoredRecommendations, setSponsoredRecommendations] = useState(null);
|
|
893
922
|
const log = useCallback((...args) => {
|
|
894
923
|
if (verbose) console.log("[useX402Payment]", ...args);
|
|
895
924
|
}, [verbose]);
|
|
@@ -921,7 +950,7 @@ function useX402Payment(config) {
|
|
|
921
950
|
const accept = {
|
|
922
951
|
scheme: "exact",
|
|
923
952
|
network: SOLANA_MAINNET_NETWORK,
|
|
924
|
-
|
|
953
|
+
amount: "0",
|
|
925
954
|
asset: USDC_MINT,
|
|
926
955
|
payTo: "",
|
|
927
956
|
maxTimeoutSeconds: 60,
|
|
@@ -946,7 +975,7 @@ function useX402Payment(config) {
|
|
|
946
975
|
const accept = {
|
|
947
976
|
scheme: "exact",
|
|
948
977
|
network: BASE_MAINNET_NETWORK,
|
|
949
|
-
|
|
978
|
+
amount: "0",
|
|
950
979
|
asset: USDC_BASE,
|
|
951
980
|
payTo: "",
|
|
952
981
|
maxTimeoutSeconds: 60,
|
|
@@ -977,6 +1006,7 @@ function useX402Payment(config) {
|
|
|
977
1006
|
setError(null);
|
|
978
1007
|
setTransactionId(null);
|
|
979
1008
|
setTransactionNetwork(null);
|
|
1009
|
+
setSponsoredRecommendations(null);
|
|
980
1010
|
}, []);
|
|
981
1011
|
const client = useMemo(() => createX402Client({
|
|
982
1012
|
adapters,
|
|
@@ -1014,6 +1044,13 @@ function useX402Payment(config) {
|
|
|
1014
1044
|
log("Could not parse PAYMENT-RESPONSE header");
|
|
1015
1045
|
}
|
|
1016
1046
|
}
|
|
1047
|
+
const recs = getSponsoredRecommendations(response);
|
|
1048
|
+
setSponsoredRecommendations(recs ?? null);
|
|
1049
|
+
if (recs) {
|
|
1050
|
+
log("Sponsored recommendations received:", recs.length);
|
|
1051
|
+
fireImpressionBeacon(response).catch(() => {
|
|
1052
|
+
});
|
|
1053
|
+
}
|
|
1017
1054
|
setStatus("success");
|
|
1018
1055
|
return response;
|
|
1019
1056
|
} catch (err) {
|
|
@@ -1044,8 +1081,9 @@ function useX402Payment(config) {
|
|
|
1044
1081
|
isAnyWalletConnected,
|
|
1045
1082
|
reset,
|
|
1046
1083
|
refreshBalances,
|
|
1047
|
-
accessPass: null
|
|
1084
|
+
accessPass: null,
|
|
1048
1085
|
// Access pass state managed by useAccessPass hook for granular control
|
|
1086
|
+
sponsoredRecommendations
|
|
1049
1087
|
};
|
|
1050
1088
|
}
|
|
1051
1089
|
|
|
@@ -1243,6 +1281,8 @@ function useAccessPass(config) {
|
|
|
1243
1281
|
}
|
|
1244
1282
|
export {
|
|
1245
1283
|
X402Error,
|
|
1284
|
+
fireImpressionBeacon,
|
|
1285
|
+
getSponsoredRecommendations,
|
|
1246
1286
|
useAccessPass,
|
|
1247
1287
|
useX402Payment
|
|
1248
1288
|
};
|