@dexterai/x402 1.9.2 → 1.9.4
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/adapters/index.cjs +14 -5
- 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 +14 -5
- package/dist/adapters/index.js.map +1 -1
- package/dist/client/index.cjs +60 -24
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +22 -8
- package/dist/client/index.d.ts +22 -8
- package/dist/client/index.js +59 -24
- package/dist/client/index.js.map +1 -1
- package/dist/react/index.cjs +63 -30
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +10 -5
- package/dist/react/index.d.ts +10 -5
- package/dist/react/index.js +63 -30
- package/dist/react/index.js.map +1 -1
- package/dist/server/index.cjs +36 -10
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +48 -14
- package/dist/server/index.d.ts +48 -14
- package/dist/server/index.js +35 -10
- package/dist/server/index.js.map +1 -1
- package/dist/{solana-CfHuiW2H.d.cts → solana-BcOfK6Eq.d.cts} +2 -2
- package/dist/{solana-kZcwbUK9.d.ts → solana-Cxr5byPa.d.ts} +2 -2
- package/dist/{sponsored-access-H1EX6zpi.d.ts → sponsored-access-Br6YPA-m.d.cts} +20 -2
- package/dist/{sponsored-access-BCB2CxdG.d.cts → sponsored-access-D1_mINs4.d.ts} +20 -2
- package/dist/{types-ENcnkof8.d.ts → types-BIHhO2-I.d.ts} +1 -1
- package/dist/{types-DmqH9yD8.d.cts → types-CfKflCZO.d.cts} +1 -1
- package/dist/{types-BQvaF8lB.d.cts → types-CjLMR7qs.d.cts} +1 -1
- package/dist/{types-BQvaF8lB.d.ts → types-CjLMR7qs.d.ts} +1 -1
- package/dist/utils/index.cjs +8 -6
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.js +8 -6
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
package/dist/react/index.d.cts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { a as X402Client } from '../sponsored-access-
|
|
2
|
-
export { f as fireImpressionBeacon, b as getSponsoredRecommendations } from '../sponsored-access-
|
|
3
|
-
import { W as WalletSet, B as BalanceInfo } from '../types-
|
|
1
|
+
import { a as X402Client } from '../sponsored-access-Br6YPA-m.cjs';
|
|
2
|
+
export { f as fireImpressionBeacon, b as getSponsoredRecommendations } from '../sponsored-access-Br6YPA-m.cjs';
|
|
3
|
+
import { W as WalletSet, B as BalanceInfo } from '../types-CfKflCZO.cjs';
|
|
4
4
|
import { SponsoredRecommendation } from '@dexterai/x402-ads-types';
|
|
5
5
|
export { SponsoredRecommendation } from '@dexterai/x402-ads-types';
|
|
6
|
-
import { a as AccessPassTier } from '../types-
|
|
7
|
-
export { A as AccessPassClientConfig, b as AccessPassInfo, X as X402Error } from '../types-
|
|
6
|
+
import { a as AccessPassTier } from '../types-CjLMR7qs.cjs';
|
|
7
|
+
export { A as AccessPassClientConfig, b as AccessPassInfo, X as X402Error } from '../types-CjLMR7qs.cjs';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* React Hook for x402 v2 Payments
|
|
@@ -135,6 +135,11 @@ declare function useX402Payment(config: UseX402PaymentConfig): UseX402PaymentRet
|
|
|
135
135
|
* Dedicated hook for managing the access pass lifecycle:
|
|
136
136
|
* tier discovery, pass purchase, token caching, and auto-fetch with pass.
|
|
137
137
|
*
|
|
138
|
+
* **Storage:** Access pass JWTs are stored in `sessionStorage` (cleared on browser close).
|
|
139
|
+
* This means passes don't persist across tabs or sessions. The JWT is accessible to
|
|
140
|
+
* any JavaScript on the page — ensure your site is free of XSS vulnerabilities.
|
|
141
|
+
* The server re-verifies the JWT signature on every request regardless.
|
|
142
|
+
*
|
|
138
143
|
* @example
|
|
139
144
|
* ```tsx
|
|
140
145
|
* import { useAccessPass } from '@dexterai/x402/react';
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { a as X402Client } from '../sponsored-access-
|
|
2
|
-
export { f as fireImpressionBeacon, b as getSponsoredRecommendations } from '../sponsored-access-
|
|
3
|
-
import { W as WalletSet, B as BalanceInfo } from '../types-
|
|
1
|
+
import { a as X402Client } from '../sponsored-access-D1_mINs4.js';
|
|
2
|
+
export { f as fireImpressionBeacon, b as getSponsoredRecommendations } from '../sponsored-access-D1_mINs4.js';
|
|
3
|
+
import { W as WalletSet, B as BalanceInfo } from '../types-BIHhO2-I.js';
|
|
4
4
|
import { SponsoredRecommendation } from '@dexterai/x402-ads-types';
|
|
5
5
|
export { SponsoredRecommendation } from '@dexterai/x402-ads-types';
|
|
6
|
-
import { a as AccessPassTier } from '../types-
|
|
7
|
-
export { A as AccessPassClientConfig, b as AccessPassInfo, X as X402Error } from '../types-
|
|
6
|
+
import { a as AccessPassTier } from '../types-CjLMR7qs.js';
|
|
7
|
+
export { A as AccessPassClientConfig, b as AccessPassInfo, X as X402Error } from '../types-CjLMR7qs.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* React Hook for x402 v2 Payments
|
|
@@ -135,6 +135,11 @@ declare function useX402Payment(config: UseX402PaymentConfig): UseX402PaymentRet
|
|
|
135
135
|
* Dedicated hook for managing the access pass lifecycle:
|
|
136
136
|
* tier discovery, pass purchase, token caching, and auto-fetch with pass.
|
|
137
137
|
*
|
|
138
|
+
* **Storage:** Access pass JWTs are stored in `sessionStorage` (cleared on browser close).
|
|
139
|
+
* This means passes don't persist across tabs or sessions. The JWT is accessible to
|
|
140
|
+
* any JavaScript on the page — ensure your site is free of XSS vulnerabilities.
|
|
141
|
+
* The server re-verifies the JWT signature on every request regardless.
|
|
142
|
+
*
|
|
138
143
|
* @example
|
|
139
144
|
* ```tsx
|
|
140
145
|
* import { useAccessPass } from '@dexterai/x402/react';
|
package/dist/react/index.js
CHANGED
|
@@ -109,8 +109,11 @@ var SolanaAdapter = class {
|
|
|
109
109
|
const account = await getAccount(connection, ata, void 0, programId);
|
|
110
110
|
const decimals = accept.extra?.decimals ?? 6;
|
|
111
111
|
return Number(account.amount) / Math.pow(10, decimals);
|
|
112
|
-
} catch {
|
|
113
|
-
|
|
112
|
+
} catch (err) {
|
|
113
|
+
if (err && typeof err === "object" && "name" in err && (err.name === "TokenAccountNotFoundError" || err.name === "TokenInvalidAccountOwnerError")) {
|
|
114
|
+
return 0;
|
|
115
|
+
}
|
|
116
|
+
throw err;
|
|
114
117
|
}
|
|
115
118
|
}
|
|
116
119
|
async buildTransaction(accept, wallet, rpcUrl) {
|
|
@@ -338,15 +341,21 @@ var EvmAdapter = class {
|
|
|
338
341
|
]
|
|
339
342
|
})
|
|
340
343
|
});
|
|
344
|
+
if (!response.ok) {
|
|
345
|
+
throw new Error(`RPC request failed: ${response.status}`);
|
|
346
|
+
}
|
|
341
347
|
const result = await response.json();
|
|
342
|
-
if (result.error
|
|
348
|
+
if (result.error) {
|
|
349
|
+
throw new Error(`RPC error: ${JSON.stringify(result.error)}`);
|
|
350
|
+
}
|
|
351
|
+
if (!result.result || result.result === "0x") {
|
|
343
352
|
return 0;
|
|
344
353
|
}
|
|
345
354
|
const balance = BigInt(result.result);
|
|
346
355
|
const decimals = accept.extra?.decimals ?? 6;
|
|
347
356
|
return Number(balance) / Math.pow(10, decimals);
|
|
348
|
-
} catch {
|
|
349
|
-
|
|
357
|
+
} catch (err) {
|
|
358
|
+
throw err;
|
|
350
359
|
}
|
|
351
360
|
}
|
|
352
361
|
encodeBalanceOf(address) {
|
|
@@ -462,7 +471,8 @@ function createX402Client(config) {
|
|
|
462
471
|
maxAmountAtomic,
|
|
463
472
|
fetch: customFetch = globalThis.fetch,
|
|
464
473
|
verbose = false,
|
|
465
|
-
accessPass: accessPassConfig
|
|
474
|
+
accessPass: accessPassConfig,
|
|
475
|
+
onPaymentRequired
|
|
466
476
|
} = config;
|
|
467
477
|
const log = verbose ? console.log.bind(console, "[x402]") : () => {
|
|
468
478
|
};
|
|
@@ -575,13 +585,17 @@ function createX402Client(config) {
|
|
|
575
585
|
const paymentAmount = accept.amount ?? accept.maxAmountRequired;
|
|
576
586
|
if (!paymentAmount) return null;
|
|
577
587
|
const rpcUrl = getRpcUrl(accept.network, adapter);
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
588
|
+
try {
|
|
589
|
+
const balance = await adapter.getBalance(accept, wallet, rpcUrl);
|
|
590
|
+
const requiredAmount = Number(paymentAmount) / Math.pow(10, decimals);
|
|
591
|
+
if (balance < requiredAmount) {
|
|
592
|
+
throw new X402Error(
|
|
593
|
+
"insufficient_balance",
|
|
594
|
+
`Insufficient balance for access pass. Have $${balance.toFixed(4)}, need $${requiredAmount.toFixed(4)}`
|
|
595
|
+
);
|
|
596
|
+
}
|
|
597
|
+
} catch (err) {
|
|
598
|
+
if (err instanceof X402Error) throw err;
|
|
585
599
|
}
|
|
586
600
|
const signedTx = await adapter.buildTransaction(accept, wallet, rpcUrl);
|
|
587
601
|
let payload;
|
|
@@ -594,13 +608,19 @@ function createX402Client(config) {
|
|
|
594
608
|
let resolvedResource = requirements.resource;
|
|
595
609
|
if (typeof requirements.resource === "string") {
|
|
596
610
|
try {
|
|
597
|
-
|
|
611
|
+
const resolved = new URL(requirements.resource, originalUrl);
|
|
612
|
+
if (["http:", "https:"].includes(resolved.protocol)) {
|
|
613
|
+
resolvedResource = resolved.toString();
|
|
614
|
+
}
|
|
598
615
|
} catch {
|
|
599
616
|
}
|
|
600
617
|
} else if (requirements.resource && typeof requirements.resource === "object" && "url" in requirements.resource) {
|
|
601
618
|
const rObj = requirements.resource;
|
|
602
619
|
try {
|
|
603
|
-
|
|
620
|
+
const resolved = new URL(rObj.url, originalUrl);
|
|
621
|
+
if (["http:", "https:"].includes(resolved.protocol)) {
|
|
622
|
+
resolvedResource = { ...rObj, url: resolved.toString() };
|
|
623
|
+
}
|
|
604
624
|
} catch {
|
|
605
625
|
}
|
|
606
626
|
}
|
|
@@ -728,16 +748,27 @@ function createX402Client(config) {
|
|
|
728
748
|
}
|
|
729
749
|
const rpcUrl = getRpcUrl(accept.network, adapter);
|
|
730
750
|
log("Checking balance...");
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
751
|
+
try {
|
|
752
|
+
const balance = await adapter.getBalance(accept, wallet, rpcUrl);
|
|
753
|
+
const requiredAmount = Number(paymentAmount) / Math.pow(10, decimals);
|
|
754
|
+
if (balance < requiredAmount) {
|
|
755
|
+
const network = adapter.name === "EVM" ? "Base" : "Solana";
|
|
756
|
+
throw new X402Error(
|
|
757
|
+
"insufficient_balance",
|
|
758
|
+
`Insufficient USDC balance on ${network}. Have $${balance.toFixed(4)}, need $${requiredAmount.toFixed(4)}`
|
|
759
|
+
);
|
|
760
|
+
}
|
|
761
|
+
log(`Balance OK: $${balance.toFixed(4)} >= $${requiredAmount.toFixed(4)}`);
|
|
762
|
+
} catch (err) {
|
|
763
|
+
if (err instanceof X402Error) throw err;
|
|
764
|
+
log("Balance check failed (RPC error), proceeding with transaction attempt");
|
|
765
|
+
}
|
|
766
|
+
if (onPaymentRequired) {
|
|
767
|
+
const approved = await onPaymentRequired(accept);
|
|
768
|
+
if (!approved) {
|
|
769
|
+
throw new X402Error("payment_rejected", "Payment rejected by onPaymentRequired callback");
|
|
770
|
+
}
|
|
739
771
|
}
|
|
740
|
-
log(`Balance OK: $${balance.toFixed(4)} >= $${requiredAmount.toFixed(4)}`);
|
|
741
772
|
log("Building transaction...");
|
|
742
773
|
const signedTx = await adapter.buildTransaction(accept, wallet, rpcUrl);
|
|
743
774
|
log("Transaction signed");
|
|
@@ -822,13 +853,15 @@ function createX402Client(config) {
|
|
|
822
853
|
}
|
|
823
854
|
|
|
824
855
|
// src/utils.ts
|
|
856
|
+
function isSolanaNetwork(network) {
|
|
857
|
+
return network.startsWith("solana:") || network === "solana";
|
|
858
|
+
}
|
|
859
|
+
function isEvmNetwork(network) {
|
|
860
|
+
return network.startsWith("eip155:") || ["base", "ethereum", "arbitrum"].includes(network);
|
|
861
|
+
}
|
|
825
862
|
function getChainFamily(network) {
|
|
826
|
-
if (network
|
|
827
|
-
|
|
828
|
-
}
|
|
829
|
-
if (network.startsWith("eip155:") || ["base", "ethereum", "arbitrum"].includes(network)) {
|
|
830
|
-
return "evm";
|
|
831
|
-
}
|
|
863
|
+
if (isSolanaNetwork(network)) return "solana";
|
|
864
|
+
if (isEvmNetwork(network)) return "evm";
|
|
832
865
|
return "unknown";
|
|
833
866
|
}
|
|
834
867
|
function getChainName(network) {
|