@dexterai/x402 1.6.5 → 1.7.0
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.d.cts +4 -4
- package/dist/adapters/index.d.ts +4 -4
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +6 -6
- package/dist/client/index.d.ts +6 -6
- package/dist/client/index.js.map +1 -1
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +4 -4
- package/dist/react/index.d.ts +4 -4
- package/dist/react/index.js.map +1 -1
- package/dist/server/index.cjs +124 -15
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +89 -7
- package/dist/server/index.d.ts +89 -7
- package/dist/server/index.js +123 -15
- package/dist/server/index.js.map +1 -1
- package/dist/{solana-Bve65qm4.d.ts → solana-CJdhHls8.d.ts} +2 -2
- package/dist/{solana-BYh8ehOi.d.cts → solana-CnW6P4lJ.d.cts} +2 -2
- package/dist/{types--r7urkVI.d.cts → types-BB-2vowq.d.cts} +1 -1
- package/dist/{types-CcVAaoro.d.cts → types-C6ty4U6C.d.cts} +39 -1
- package/dist/{types-CcVAaoro.d.ts → types-C6ty4U6C.d.ts} +39 -1
- package/dist/{types-BtpD4ULe.d.ts → types-ClEZ34n4.d.ts} +1 -1
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/{x402-client-BxQWcK2Z.d.ts → x402-client-B9ECWy7k.d.ts} +2 -2
- package/dist/{x402-client-Dcm2FQ9f.d.cts → x402-client-BhLOoqwa.d.cts} +2 -2
- package/package.json +10 -2
package/dist/server/index.cjs
CHANGED
|
@@ -58,6 +58,7 @@ __export(server_exports, {
|
|
|
58
58
|
getTextModels: () => getTextModels,
|
|
59
59
|
isValidModel: () => isValidModel,
|
|
60
60
|
isValidModelId: () => isValidModelId,
|
|
61
|
+
stripePayTo: () => stripePayTo,
|
|
61
62
|
x402AccessPass: () => x402AccessPass,
|
|
62
63
|
x402BrowserSupport: () => x402BrowserSupport,
|
|
63
64
|
x402Middleware: () => x402Middleware
|
|
@@ -260,6 +261,10 @@ function createX402Server(config) {
|
|
|
260
261
|
} = config;
|
|
261
262
|
const facilitator = new FacilitatorClient(facilitatorUrl);
|
|
262
263
|
let cachedExtra = null;
|
|
264
|
+
async function resolvePayTo(context) {
|
|
265
|
+
if (typeof payTo === "string") return payTo;
|
|
266
|
+
return payTo(context || {});
|
|
267
|
+
}
|
|
263
268
|
async function getNetworkExtra() {
|
|
264
269
|
if (!cachedExtra) {
|
|
265
270
|
cachedExtra = await facilitator.getNetworkExtra(network);
|
|
@@ -275,7 +280,7 @@ function createX402Server(config) {
|
|
|
275
280
|
version: cachedExtra.version
|
|
276
281
|
};
|
|
277
282
|
}
|
|
278
|
-
async function
|
|
283
|
+
async function buildPaymentAccept(resolvedPayTo, options) {
|
|
279
284
|
const {
|
|
280
285
|
amountAtomic,
|
|
281
286
|
timeoutSeconds = defaultTimeoutSeconds
|
|
@@ -287,11 +292,18 @@ function createX402Server(config) {
|
|
|
287
292
|
amount: amountAtomic,
|
|
288
293
|
maxAmountRequired: amountAtomic,
|
|
289
294
|
asset: asset.address,
|
|
290
|
-
payTo,
|
|
295
|
+
payTo: resolvedPayTo,
|
|
291
296
|
maxTimeoutSeconds: timeoutSeconds,
|
|
292
297
|
extra
|
|
293
298
|
};
|
|
294
299
|
}
|
|
300
|
+
async function getPaymentAccept(options) {
|
|
301
|
+
const address = await resolvePayTo({
|
|
302
|
+
amountAtomic: options.amountAtomic,
|
|
303
|
+
resourceUrl: options.resourceUrl
|
|
304
|
+
});
|
|
305
|
+
return buildPaymentAccept(address, options);
|
|
306
|
+
}
|
|
295
307
|
async function buildRequirements(options) {
|
|
296
308
|
const {
|
|
297
309
|
resourceUrl,
|
|
@@ -324,18 +336,18 @@ function createX402Server(config) {
|
|
|
324
336
|
};
|
|
325
337
|
}
|
|
326
338
|
async function verifyPayment(paymentSignatureHeader, requirements) {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
resourceUrl: ""
|
|
330
|
-
}
|
|
331
|
-
return facilitator.verifyPayment(paymentSignatureHeader,
|
|
339
|
+
if (!requirements) {
|
|
340
|
+
const address = await resolvePayTo({ paymentHeader: paymentSignatureHeader });
|
|
341
|
+
requirements = await buildPaymentAccept(address, { amountAtomic: "0", resourceUrl: "" });
|
|
342
|
+
}
|
|
343
|
+
return facilitator.verifyPayment(paymentSignatureHeader, requirements);
|
|
332
344
|
}
|
|
333
345
|
async function settlePayment(paymentSignatureHeader, requirements) {
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
resourceUrl: ""
|
|
337
|
-
}
|
|
338
|
-
return facilitator.settlePayment(paymentSignatureHeader,
|
|
346
|
+
if (!requirements) {
|
|
347
|
+
const address = await resolvePayTo({ paymentHeader: paymentSignatureHeader });
|
|
348
|
+
requirements = await buildPaymentAccept(address, { amountAtomic: "0", resourceUrl: "" });
|
|
349
|
+
}
|
|
350
|
+
return facilitator.settlePayment(paymentSignatureHeader, requirements);
|
|
339
351
|
}
|
|
340
352
|
return {
|
|
341
353
|
buildRequirements,
|
|
@@ -356,9 +368,7 @@ function x402Middleware(config) {
|
|
|
356
368
|
const {
|
|
357
369
|
payTo,
|
|
358
370
|
amount,
|
|
359
|
-
network = DEFAULT_NETWORK,
|
|
360
371
|
asset,
|
|
361
|
-
facilitatorUrl,
|
|
362
372
|
description,
|
|
363
373
|
resourceUrl: staticResourceUrl,
|
|
364
374
|
mimeType,
|
|
@@ -368,6 +378,9 @@ function x402Middleware(config) {
|
|
|
368
378
|
getAmount,
|
|
369
379
|
getDescription
|
|
370
380
|
} = config;
|
|
381
|
+
const providerDefaults = typeof payTo !== "string" ? payTo._x402Defaults : void 0;
|
|
382
|
+
const network = config.network ?? providerDefaults?.network ?? DEFAULT_NETWORK;
|
|
383
|
+
const facilitatorUrl = config.facilitatorUrl ?? providerDefaults?.facilitatorUrl;
|
|
371
384
|
const log = verbose ? console.log.bind(console, "[x402:middleware]") : () => {
|
|
372
385
|
};
|
|
373
386
|
const server = createX402Server({
|
|
@@ -643,11 +656,12 @@ if (btn) {
|
|
|
643
656
|
payload = btoa(payload);
|
|
644
657
|
|
|
645
658
|
// 6. Build payment-signature header (x402 v2 format)
|
|
659
|
+
// Solana: payload must be { transaction: base64Tx } per SDK spec
|
|
646
660
|
const paymentSignature = {
|
|
647
661
|
x402Version: accept.x402Version ?? 2,
|
|
648
662
|
resource: requirements.resource,
|
|
649
663
|
accepted: accept,
|
|
650
|
-
payload,
|
|
664
|
+
payload: { transaction: payload },
|
|
651
665
|
};
|
|
652
666
|
const paymentHeader = btoa(JSON.stringify(paymentSignature));
|
|
653
667
|
|
|
@@ -1806,6 +1820,100 @@ function formatTokenPricing(model = DEFAULT_MODEL) {
|
|
|
1806
1820
|
const actualModel = MODEL_PRICING[model] ? model : DEFAULT_MODEL;
|
|
1807
1821
|
return `$${pricing.input.toFixed(2)} per 1M tokens (${actualModel})`;
|
|
1808
1822
|
}
|
|
1823
|
+
|
|
1824
|
+
// src/server/stripe-payto.ts
|
|
1825
|
+
var STRIPE_NETWORK_KEYS = {
|
|
1826
|
+
"base": "base",
|
|
1827
|
+
"base-sepolia": "base_sepolia"
|
|
1828
|
+
};
|
|
1829
|
+
var CAIP2_NETWORKS = {
|
|
1830
|
+
"base": "eip155:8453",
|
|
1831
|
+
"base-sepolia": "eip155:84532"
|
|
1832
|
+
};
|
|
1833
|
+
var USDC_DECIMALS3 = 6;
|
|
1834
|
+
function stripePayTo(secretKeyOrConfig) {
|
|
1835
|
+
const config = typeof secretKeyOrConfig === "string" ? { secretKey: secretKeyOrConfig } : secretKeyOrConfig;
|
|
1836
|
+
const networkName = config.network ?? "base";
|
|
1837
|
+
const stripeNetworkKey = STRIPE_NETWORK_KEYS[networkName] ?? "base";
|
|
1838
|
+
const caip2Network = CAIP2_NETWORKS[networkName] ?? "eip155:8453";
|
|
1839
|
+
const apiVersion = config.apiVersion ?? "2026-01-28.clover";
|
|
1840
|
+
let stripeClient = null;
|
|
1841
|
+
async function getStripe() {
|
|
1842
|
+
if (stripeClient) return stripeClient;
|
|
1843
|
+
try {
|
|
1844
|
+
const { default: Stripe } = await import("stripe");
|
|
1845
|
+
stripeClient = new Stripe(config.secretKey, {
|
|
1846
|
+
apiVersion,
|
|
1847
|
+
appInfo: {
|
|
1848
|
+
name: "@dexterai/x402",
|
|
1849
|
+
url: "https://dexter.cash/sdk"
|
|
1850
|
+
}
|
|
1851
|
+
});
|
|
1852
|
+
return stripeClient;
|
|
1853
|
+
} catch {
|
|
1854
|
+
throw new Error(
|
|
1855
|
+
'The "stripe" package is required for stripePayTo(). Install it with: npm install stripe'
|
|
1856
|
+
);
|
|
1857
|
+
}
|
|
1858
|
+
}
|
|
1859
|
+
const provider = async (context) => {
|
|
1860
|
+
if (context.paymentHeader) {
|
|
1861
|
+
try {
|
|
1862
|
+
const decoded = JSON.parse(
|
|
1863
|
+
Buffer.from(context.paymentHeader, "base64").toString()
|
|
1864
|
+
);
|
|
1865
|
+
const toAddress = decoded.payload?.authorization?.to;
|
|
1866
|
+
if (toAddress && typeof toAddress === "string") {
|
|
1867
|
+
return toAddress;
|
|
1868
|
+
}
|
|
1869
|
+
const acceptedPayTo = decoded.accepted?.payTo;
|
|
1870
|
+
if (acceptedPayTo && typeof acceptedPayTo === "string") {
|
|
1871
|
+
return acceptedPayTo;
|
|
1872
|
+
}
|
|
1873
|
+
} catch {
|
|
1874
|
+
}
|
|
1875
|
+
throw new Error(
|
|
1876
|
+
"Could not extract deposit address from payment header. Ensure the client is sending a valid x402 PAYMENT-SIGNATURE."
|
|
1877
|
+
);
|
|
1878
|
+
}
|
|
1879
|
+
const stripe = await getStripe();
|
|
1880
|
+
const amountAtomic = context.amountAtomic ? parseInt(context.amountAtomic, 10) : 1e4;
|
|
1881
|
+
const amountInCents = Math.max(1, Math.round(amountAtomic / Math.pow(10, USDC_DECIMALS3 - 2)));
|
|
1882
|
+
const paymentIntent = await stripe.paymentIntents.create({
|
|
1883
|
+
amount: amountInCents,
|
|
1884
|
+
currency: "usd",
|
|
1885
|
+
payment_method_types: ["crypto"],
|
|
1886
|
+
payment_method_data: {
|
|
1887
|
+
type: "crypto"
|
|
1888
|
+
},
|
|
1889
|
+
payment_method_options: {
|
|
1890
|
+
crypto: {
|
|
1891
|
+
mode: "custom"
|
|
1892
|
+
}
|
|
1893
|
+
},
|
|
1894
|
+
confirm: true
|
|
1895
|
+
});
|
|
1896
|
+
const nextAction = paymentIntent.next_action;
|
|
1897
|
+
if (!nextAction?.crypto_collect_deposit_details) {
|
|
1898
|
+
throw new Error(
|
|
1899
|
+
"Stripe PaymentIntent did not return crypto deposit details. Ensure your Stripe account has crypto payins enabled: https://support.stripe.com/questions/get-started-with-pay-with-crypto"
|
|
1900
|
+
);
|
|
1901
|
+
}
|
|
1902
|
+
const depositDetails = nextAction.crypto_collect_deposit_details;
|
|
1903
|
+
const payToAddress = depositDetails.deposit_addresses?.[stripeNetworkKey]?.address;
|
|
1904
|
+
if (!payToAddress) {
|
|
1905
|
+
throw new Error(
|
|
1906
|
+
`No deposit address found for network "${stripeNetworkKey}". Available networks: ${Object.keys(depositDetails.deposit_addresses || {}).join(", ")}`
|
|
1907
|
+
);
|
|
1908
|
+
}
|
|
1909
|
+
return payToAddress;
|
|
1910
|
+
};
|
|
1911
|
+
provider._x402Defaults = {
|
|
1912
|
+
network: caip2Network,
|
|
1913
|
+
facilitatorUrl: "https://x402.dexter.cash"
|
|
1914
|
+
};
|
|
1915
|
+
return provider;
|
|
1916
|
+
}
|
|
1809
1917
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1810
1918
|
0 && (module.exports = {
|
|
1811
1919
|
BASE_MAINNET_NETWORK,
|
|
@@ -1836,6 +1944,7 @@ function formatTokenPricing(model = DEFAULT_MODEL) {
|
|
|
1836
1944
|
getTextModels,
|
|
1837
1945
|
isValidModel,
|
|
1838
1946
|
isValidModelId,
|
|
1947
|
+
stripePayTo,
|
|
1839
1948
|
x402AccessPass,
|
|
1840
1949
|
x402BrowserSupport,
|
|
1841
1950
|
x402Middleware
|