@x402/extensions 2.3.1 → 2.5.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/cjs/index.js CHANGED
@@ -31,6 +31,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
33
  BAZAAR: () => BAZAAR,
34
+ EIP2612_GAS_SPONSORING: () => EIP2612_GAS_SPONSORING,
35
+ ERC20_APPROVAL_GAS_SPONSORING: () => ERC20_APPROVAL_GAS_SPONSORING,
36
+ ERC20_APPROVAL_GAS_SPONSORING_VERSION: () => ERC20_APPROVAL_GAS_SPONSORING_VERSION,
34
37
  InMemorySIWxStorage: () => InMemorySIWxStorage,
35
38
  PAYMENT_IDENTIFIER: () => PAYMENT_IDENTIFIER,
36
39
  PAYMENT_ID_MAX_LENGTH: () => PAYMENT_ID_MAX_LENGTH,
@@ -44,22 +47,28 @@ __export(src_exports, {
44
47
  appendPaymentIdentifierToExtensions: () => appendPaymentIdentifierToExtensions,
45
48
  bazaarResourceServerExtension: () => bazaarResourceServerExtension,
46
49
  buildSIWxSchema: () => buildSIWxSchema,
50
+ createErc20ApprovalGasSponsoringExtension: () => createErc20ApprovalGasSponsoringExtension,
47
51
  createSIWxClientHook: () => createSIWxClientHook,
48
52
  createSIWxMessage: () => createSIWxMessage,
49
53
  createSIWxPayload: () => createSIWxPayload,
50
54
  createSIWxRequestHook: () => createSIWxRequestHook,
51
55
  createSIWxSettleHook: () => createSIWxSettleHook,
52
56
  declareDiscoveryExtension: () => declareDiscoveryExtension,
57
+ declareEip2612GasSponsoringExtension: () => declareEip2612GasSponsoringExtension,
58
+ declareErc20ApprovalGasSponsoringExtension: () => declareErc20ApprovalGasSponsoringExtension,
53
59
  declarePaymentIdentifierExtension: () => declarePaymentIdentifierExtension,
54
60
  declareSIWxExtension: () => declareSIWxExtension,
55
61
  decodeBase58: () => decodeBase58,
56
62
  encodeBase58: () => encodeBase58,
57
63
  encodeSIWxHeader: () => encodeSIWxHeader,
64
+ erc20ApprovalGasSponsoringSchema: () => erc20ApprovalGasSponsoringSchema,
58
65
  extractAndValidatePaymentIdentifier: () => extractAndValidatePaymentIdentifier,
59
66
  extractDiscoveryInfo: () => extractDiscoveryInfo,
60
67
  extractDiscoveryInfoFromExtension: () => extractDiscoveryInfoFromExtension,
61
68
  extractDiscoveryInfoV1: () => extractDiscoveryInfoV1,
62
69
  extractEVMChainId: () => extractEVMChainId,
70
+ extractEip2612GasSponsoringInfo: () => extractEip2612GasSponsoringInfo,
71
+ extractErc20ApprovalGasSponsoringInfo: () => extractErc20ApprovalGasSponsoringInfo,
63
72
  extractPaymentIdentifier: () => extractPaymentIdentifier,
64
73
  extractResourceMetadataV1: () => extractResourceMetadataV1,
65
74
  extractSolanaChainReference: () => extractSolanaChainReference,
@@ -69,10 +78,13 @@ __export(src_exports, {
69
78
  getEVMAddress: () => getEVMAddress,
70
79
  getSolanaAddress: () => getSolanaAddress,
71
80
  hasPaymentIdentifier: () => hasPaymentIdentifier,
81
+ isBodyExtensionConfig: () => isBodyExtensionConfig,
72
82
  isDiscoverableV1: () => isDiscoverableV1,
73
83
  isEVMSigner: () => isEVMSigner,
84
+ isMcpExtensionConfig: () => isMcpExtensionConfig,
74
85
  isPaymentIdentifierExtension: () => isPaymentIdentifierExtension,
75
86
  isPaymentIdentifierRequired: () => isPaymentIdentifierRequired,
87
+ isQueryExtensionConfig: () => isQueryExtensionConfig,
76
88
  isSolanaSigner: () => isSolanaSigner,
77
89
  isValidPaymentId: () => isValidPaymentId,
78
90
  parseSIWxHeader: () => parseSIWxHeader,
@@ -83,6 +95,8 @@ __export(src_exports, {
83
95
  siwxResourceServerExtension: () => siwxResourceServerExtension,
84
96
  validateAndExtract: () => validateAndExtract,
85
97
  validateDiscoveryExtension: () => validateDiscoveryExtension,
98
+ validateEip2612GasSponsoringInfo: () => validateEip2612GasSponsoringInfo,
99
+ validateErc20ApprovalGasSponsoringInfo: () => validateErc20ApprovalGasSponsoringInfo,
86
100
  validatePaymentIdentifier: () => validatePaymentIdentifier,
87
101
  validatePaymentIdentifierRequirement: () => validatePaymentIdentifierRequirement,
88
102
  validateSIWxMessage: () => validateSIWxMessage,
@@ -94,10 +108,23 @@ __export(src_exports, {
94
108
  });
95
109
  module.exports = __toCommonJS(src_exports);
96
110
 
111
+ // src/bazaar/http/types.ts
112
+ var isQueryExtensionConfig = (config) => {
113
+ return !("bodyType" in config) && !("toolName" in config);
114
+ };
115
+ var isBodyExtensionConfig = (config) => {
116
+ return "bodyType" in config;
117
+ };
118
+
119
+ // src/bazaar/mcp/types.ts
120
+ var isMcpExtensionConfig = (config) => {
121
+ return "toolName" in config;
122
+ };
123
+
97
124
  // src/bazaar/types.ts
98
- var BAZAAR = "bazaar";
125
+ var BAZAAR = { key: "bazaar" };
99
126
 
100
- // src/bazaar/resourceService.ts
127
+ // src/bazaar/http/resourceService.ts
101
128
  function createQueryDiscoveryExtension({
102
129
  method,
103
130
  input = {},
@@ -229,7 +256,97 @@ function createBodyDiscoveryExtension({
229
256
  }
230
257
  };
231
258
  }
259
+
260
+ // src/bazaar/mcp/resourceService.ts
261
+ function createMcpDiscoveryExtension({
262
+ toolName,
263
+ description,
264
+ transport,
265
+ inputSchema,
266
+ example,
267
+ output
268
+ }) {
269
+ return {
270
+ info: {
271
+ input: {
272
+ type: "mcp",
273
+ toolName,
274
+ ...description !== void 0 ? { description } : {},
275
+ ...transport !== void 0 ? { transport } : {},
276
+ inputSchema,
277
+ ...example !== void 0 ? { example } : {}
278
+ },
279
+ ...output?.example ? {
280
+ output: {
281
+ type: "json",
282
+ example: output.example
283
+ }
284
+ } : {}
285
+ },
286
+ schema: {
287
+ $schema: "https://json-schema.org/draft/2020-12/schema",
288
+ type: "object",
289
+ properties: {
290
+ input: {
291
+ type: "object",
292
+ properties: {
293
+ type: {
294
+ type: "string",
295
+ const: "mcp"
296
+ },
297
+ toolName: {
298
+ type: "string"
299
+ },
300
+ ...description !== void 0 ? {
301
+ description: {
302
+ type: "string"
303
+ }
304
+ } : {},
305
+ ...transport !== void 0 ? {
306
+ transport: {
307
+ type: "string",
308
+ enum: ["streamable-http", "sse"]
309
+ }
310
+ } : {},
311
+ inputSchema: {
312
+ type: "object"
313
+ },
314
+ ...example !== void 0 ? {
315
+ example: {
316
+ type: "object"
317
+ }
318
+ } : {}
319
+ },
320
+ required: ["type", "toolName", "inputSchema"],
321
+ additionalProperties: false
322
+ },
323
+ ...output?.example ? {
324
+ output: {
325
+ type: "object",
326
+ properties: {
327
+ type: {
328
+ type: "string"
329
+ },
330
+ example: {
331
+ type: "object",
332
+ ...output.schema && typeof output.schema === "object" ? output.schema : {}
333
+ }
334
+ },
335
+ required: ["type"]
336
+ }
337
+ } : {}
338
+ },
339
+ required: ["input"]
340
+ }
341
+ };
342
+ }
343
+
344
+ // src/bazaar/resourceService.ts
232
345
  function declareDiscoveryExtension(config) {
346
+ if ("toolName" in config) {
347
+ const extension2 = createMcpDiscoveryExtension(config);
348
+ return { bazaar: extension2 };
349
+ }
233
350
  const bodyType = config.bodyType;
234
351
  const isBodyMethod2 = bodyType !== void 0;
235
352
  const extension = isBodyMethod2 ? createBodyDiscoveryExtension(config) : createQueryDiscoveryExtension(config);
@@ -241,12 +358,15 @@ function isHTTPRequestContext(ctx) {
241
358
  return ctx !== null && typeof ctx === "object" && "method" in ctx && "adapter" in ctx;
242
359
  }
243
360
  var bazaarResourceServerExtension = {
244
- key: BAZAAR,
361
+ key: BAZAAR.key,
245
362
  enrichDeclaration: (declaration, transportContext) => {
246
363
  if (!isHTTPRequestContext(transportContext)) {
247
364
  return declaration;
248
365
  }
249
366
  const extension = declaration;
367
+ if (extension.info?.input?.type === "mcp") {
368
+ return declaration;
369
+ }
250
370
  const method = transportContext.method;
251
371
  const existingInputProps = extension.schema?.properties?.input?.properties || {};
252
372
  const updatedInputProps = {
@@ -429,7 +549,7 @@ function extractDiscoveryInfo(paymentPayload, paymentRequirements, validate = tr
429
549
  if (paymentPayload.x402Version === 2) {
430
550
  resourceUrl = paymentPayload.resource?.url ?? "";
431
551
  if (paymentPayload.extensions) {
432
- const bazaarExtension = paymentPayload.extensions[BAZAAR];
552
+ const bazaarExtension = paymentPayload.extensions[BAZAAR.key];
433
553
  if (bazaarExtension && typeof bazaarExtension === "object") {
434
554
  try {
435
555
  const extension = bazaarExtension;
@@ -472,14 +592,17 @@ function extractDiscoveryInfo(paymentPayload, paymentRequirements, validate = tr
472
592
  description = requirementsV1.description;
473
593
  mimeType = requirementsV1.mimeType;
474
594
  }
475
- return {
595
+ const base = {
476
596
  resourceUrl: normalizedResourceUrl,
477
597
  description,
478
598
  mimeType,
479
- method: discoveryInfo.input.method,
480
599
  x402Version: paymentPayload.x402Version,
481
600
  discoveryInfo
482
601
  };
602
+ if (discoveryInfo.input.type === "mcp") {
603
+ return { ...base, toolName: discoveryInfo.input.toolName };
604
+ }
605
+ return { ...base, method: discoveryInfo.input.method };
483
606
  }
484
607
  function extractDiscoveryInfoFromExtension(extension, validate = true) {
485
608
  if (validate) {
@@ -1202,7 +1325,9 @@ function createSIWxSettleHook(options) {
1202
1325
  if (!ctx.result.success) return;
1203
1326
  const address = ctx.result.payer;
1204
1327
  if (!address) return;
1205
- const resource = new URL(ctx.paymentPayload.resource.url).pathname;
1328
+ const resourceUrl = ctx.paymentPayload.resource?.url;
1329
+ if (!resourceUrl) return;
1330
+ const resource = new URL(resourceUrl).pathname;
1206
1331
  await storage.recordPayment(resource, address);
1207
1332
  onEvent?.({ type: "payment_recorded", resource, address });
1208
1333
  };
@@ -1499,9 +1624,187 @@ var paymentIdentifierResourceServerExtension = {
1499
1624
  // No enrichment needed - the declaration is static
1500
1625
  // Future hooks for idempotency could be added here if needed
1501
1626
  };
1627
+
1628
+ // src/eip2612-gas-sponsoring/types.ts
1629
+ var EIP2612_GAS_SPONSORING = { key: "eip2612GasSponsoring" };
1630
+
1631
+ // src/eip2612-gas-sponsoring/resourceService.ts
1632
+ var eip2612GasSponsoringSchema = {
1633
+ $schema: "https://json-schema.org/draft/2020-12/schema",
1634
+ type: "object",
1635
+ properties: {
1636
+ from: {
1637
+ type: "string",
1638
+ pattern: "^0x[a-fA-F0-9]{40}$",
1639
+ description: "The address of the sender."
1640
+ },
1641
+ asset: {
1642
+ type: "string",
1643
+ pattern: "^0x[a-fA-F0-9]{40}$",
1644
+ description: "The address of the ERC-20 token contract."
1645
+ },
1646
+ spender: {
1647
+ type: "string",
1648
+ pattern: "^0x[a-fA-F0-9]{40}$",
1649
+ description: "The address of the spender (Canonical Permit2)."
1650
+ },
1651
+ amount: {
1652
+ type: "string",
1653
+ pattern: "^[0-9]+$",
1654
+ description: "The amount to approve (uint256). Typically MaxUint."
1655
+ },
1656
+ nonce: {
1657
+ type: "string",
1658
+ pattern: "^[0-9]+$",
1659
+ description: "The current nonce of the sender."
1660
+ },
1661
+ deadline: {
1662
+ type: "string",
1663
+ pattern: "^[0-9]+$",
1664
+ description: "The timestamp at which the signature expires."
1665
+ },
1666
+ signature: {
1667
+ type: "string",
1668
+ pattern: "^0x[a-fA-F0-9]+$",
1669
+ description: "The 65-byte concatenated signature (r, s, v) as a hex string."
1670
+ },
1671
+ version: {
1672
+ type: "string",
1673
+ pattern: "^[0-9]+(\\.[0-9]+)*$",
1674
+ description: "Schema version identifier."
1675
+ }
1676
+ },
1677
+ required: ["from", "asset", "spender", "amount", "nonce", "deadline", "signature", "version"]
1678
+ };
1679
+ function declareEip2612GasSponsoringExtension() {
1680
+ const key = EIP2612_GAS_SPONSORING.key;
1681
+ return {
1682
+ [key]: {
1683
+ info: {
1684
+ description: "The facilitator accepts EIP-2612 gasless Permit to `Permit2` canonical contract.",
1685
+ version: "1"
1686
+ },
1687
+ schema: eip2612GasSponsoringSchema
1688
+ }
1689
+ };
1690
+ }
1691
+
1692
+ // src/eip2612-gas-sponsoring/facilitator.ts
1693
+ function extractEip2612GasSponsoringInfo(paymentPayload) {
1694
+ if (!paymentPayload.extensions) {
1695
+ return null;
1696
+ }
1697
+ const extension = paymentPayload.extensions[EIP2612_GAS_SPONSORING.key];
1698
+ if (!extension?.info) {
1699
+ return null;
1700
+ }
1701
+ const info = extension.info;
1702
+ if (!info.from || !info.asset || !info.spender || !info.amount || !info.nonce || !info.deadline || !info.signature || !info.version) {
1703
+ return null;
1704
+ }
1705
+ return info;
1706
+ }
1707
+ function validateEip2612GasSponsoringInfo(info) {
1708
+ const addressPattern = /^0x[a-fA-F0-9]{40}$/;
1709
+ const numericPattern = /^[0-9]+$/;
1710
+ const hexPattern = /^0x[a-fA-F0-9]+$/;
1711
+ const versionPattern = /^[0-9]+(\.[0-9]+)*$/;
1712
+ return addressPattern.test(info.from) && addressPattern.test(info.asset) && addressPattern.test(info.spender) && numericPattern.test(info.amount) && numericPattern.test(info.nonce) && numericPattern.test(info.deadline) && hexPattern.test(info.signature) && versionPattern.test(info.version);
1713
+ }
1714
+
1715
+ // src/erc20-approval-gas-sponsoring/types.ts
1716
+ var ERC20_APPROVAL_GAS_SPONSORING = {
1717
+ key: "erc20ApprovalGasSponsoring"
1718
+ };
1719
+ var ERC20_APPROVAL_GAS_SPONSORING_VERSION = "1";
1720
+ function createErc20ApprovalGasSponsoringExtension(signer, client) {
1721
+ return {
1722
+ ...ERC20_APPROVAL_GAS_SPONSORING,
1723
+ signer: {
1724
+ ...signer,
1725
+ sendRawTransaction: client.sendRawTransaction.bind(client)
1726
+ }
1727
+ };
1728
+ }
1729
+
1730
+ // src/erc20-approval-gas-sponsoring/resourceService.ts
1731
+ var erc20ApprovalGasSponsoringSchema = {
1732
+ $schema: "https://json-schema.org/draft/2020-12/schema",
1733
+ type: "object",
1734
+ properties: {
1735
+ from: {
1736
+ type: "string",
1737
+ pattern: "^0x[a-fA-F0-9]{40}$",
1738
+ description: "The address of the sender (token owner)."
1739
+ },
1740
+ asset: {
1741
+ type: "string",
1742
+ pattern: "^0x[a-fA-F0-9]{40}$",
1743
+ description: "The address of the ERC-20 token contract."
1744
+ },
1745
+ spender: {
1746
+ type: "string",
1747
+ pattern: "^0x[a-fA-F0-9]{40}$",
1748
+ description: "The address of the spender (Canonical Permit2)."
1749
+ },
1750
+ amount: {
1751
+ type: "string",
1752
+ pattern: "^[0-9]+$",
1753
+ description: "The amount approved (uint256). Always MaxUint256."
1754
+ },
1755
+ signedTransaction: {
1756
+ type: "string",
1757
+ pattern: "^0x[a-fA-F0-9]+$",
1758
+ description: "The RLP-encoded signed EIP-1559 transaction as a hex string."
1759
+ },
1760
+ version: {
1761
+ type: "string",
1762
+ pattern: "^[0-9]+(\\.[0-9]+)*$",
1763
+ description: "Schema version identifier."
1764
+ }
1765
+ },
1766
+ required: ["from", "asset", "spender", "amount", "signedTransaction", "version"]
1767
+ };
1768
+ function declareErc20ApprovalGasSponsoringExtension() {
1769
+ const key = ERC20_APPROVAL_GAS_SPONSORING.key;
1770
+ return {
1771
+ [key]: {
1772
+ info: {
1773
+ description: "The facilitator broadcasts a pre-signed ERC-20 approve() transaction to grant Permit2 allowance.",
1774
+ version: ERC20_APPROVAL_GAS_SPONSORING_VERSION
1775
+ },
1776
+ schema: erc20ApprovalGasSponsoringSchema
1777
+ }
1778
+ };
1779
+ }
1780
+
1781
+ // src/erc20-approval-gas-sponsoring/facilitator.ts
1782
+ var import__3 = __toESM(require("ajv/dist/2020.js"));
1783
+ function extractErc20ApprovalGasSponsoringInfo(paymentPayload) {
1784
+ if (!paymentPayload.extensions) {
1785
+ return null;
1786
+ }
1787
+ const extension = paymentPayload.extensions[ERC20_APPROVAL_GAS_SPONSORING.key];
1788
+ if (!extension?.info) {
1789
+ return null;
1790
+ }
1791
+ const info = extension.info;
1792
+ if (!info.from || !info.asset || !info.spender || !info.amount || !info.signedTransaction || !info.version) {
1793
+ return null;
1794
+ }
1795
+ return info;
1796
+ }
1797
+ function validateErc20ApprovalGasSponsoringInfo(info) {
1798
+ const ajv = new import__3.default({ strict: false, allErrors: true });
1799
+ const validate = ajv.compile(erc20ApprovalGasSponsoringSchema);
1800
+ return validate(info);
1801
+ }
1502
1802
  // Annotate the CommonJS export names for ESM import in node:
1503
1803
  0 && (module.exports = {
1504
1804
  BAZAAR,
1805
+ EIP2612_GAS_SPONSORING,
1806
+ ERC20_APPROVAL_GAS_SPONSORING,
1807
+ ERC20_APPROVAL_GAS_SPONSORING_VERSION,
1505
1808
  InMemorySIWxStorage,
1506
1809
  PAYMENT_IDENTIFIER,
1507
1810
  PAYMENT_ID_MAX_LENGTH,
@@ -1515,22 +1818,28 @@ var paymentIdentifierResourceServerExtension = {
1515
1818
  appendPaymentIdentifierToExtensions,
1516
1819
  bazaarResourceServerExtension,
1517
1820
  buildSIWxSchema,
1821
+ createErc20ApprovalGasSponsoringExtension,
1518
1822
  createSIWxClientHook,
1519
1823
  createSIWxMessage,
1520
1824
  createSIWxPayload,
1521
1825
  createSIWxRequestHook,
1522
1826
  createSIWxSettleHook,
1523
1827
  declareDiscoveryExtension,
1828
+ declareEip2612GasSponsoringExtension,
1829
+ declareErc20ApprovalGasSponsoringExtension,
1524
1830
  declarePaymentIdentifierExtension,
1525
1831
  declareSIWxExtension,
1526
1832
  decodeBase58,
1527
1833
  encodeBase58,
1528
1834
  encodeSIWxHeader,
1835
+ erc20ApprovalGasSponsoringSchema,
1529
1836
  extractAndValidatePaymentIdentifier,
1530
1837
  extractDiscoveryInfo,
1531
1838
  extractDiscoveryInfoFromExtension,
1532
1839
  extractDiscoveryInfoV1,
1533
1840
  extractEVMChainId,
1841
+ extractEip2612GasSponsoringInfo,
1842
+ extractErc20ApprovalGasSponsoringInfo,
1534
1843
  extractPaymentIdentifier,
1535
1844
  extractResourceMetadataV1,
1536
1845
  extractSolanaChainReference,
@@ -1540,10 +1849,13 @@ var paymentIdentifierResourceServerExtension = {
1540
1849
  getEVMAddress,
1541
1850
  getSolanaAddress,
1542
1851
  hasPaymentIdentifier,
1852
+ isBodyExtensionConfig,
1543
1853
  isDiscoverableV1,
1544
1854
  isEVMSigner,
1855
+ isMcpExtensionConfig,
1545
1856
  isPaymentIdentifierExtension,
1546
1857
  isPaymentIdentifierRequired,
1858
+ isQueryExtensionConfig,
1547
1859
  isSolanaSigner,
1548
1860
  isValidPaymentId,
1549
1861
  parseSIWxHeader,
@@ -1554,6 +1866,8 @@ var paymentIdentifierResourceServerExtension = {
1554
1866
  siwxResourceServerExtension,
1555
1867
  validateAndExtract,
1556
1868
  validateDiscoveryExtension,
1869
+ validateEip2612GasSponsoringInfo,
1870
+ validateErc20ApprovalGasSponsoringInfo,
1557
1871
  validatePaymentIdentifier,
1558
1872
  validatePaymentIdentifierRequirement,
1559
1873
  validateSIWxMessage,