@devlab.group/agent-commerce 2.2.1 → 2.4.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.
Files changed (61) hide show
  1. package/README.md +20 -16
  2. package/dist/ap2.d.ts +6 -5
  3. package/dist/ap2.js +3 -3
  4. package/dist/{authorization-CMkIuAkO.d.ts → authorization-DjAecwuW.d.ts} +1 -1
  5. package/dist/{chunk-REBY2IEP.js → chunk-4OEXK3YG.js} +4 -4
  6. package/dist/{chunk-REBY2IEP.js.map → chunk-4OEXK3YG.js.map} +1 -1
  7. package/dist/{chunk-2DAJAJI7.js → chunk-6WACRJVT.js} +3 -3
  8. package/dist/{chunk-2DAJAJI7.js.map → chunk-6WACRJVT.js.map} +1 -1
  9. package/dist/{chunk-XYHDQ22D.js → chunk-AITMDXKW.js} +3 -3
  10. package/dist/{chunk-XYHDQ22D.js.map → chunk-AITMDXKW.js.map} +1 -1
  11. package/dist/{chunk-BNUD4RBN.js → chunk-WUIAUAA7.js} +200 -8
  12. package/dist/chunk-WUIAUAA7.js.map +1 -0
  13. package/dist/cli/{ap2-HLBIUSTK.js → ap2-QDHPRSTF.js} +3 -3
  14. package/dist/cli/{ap2-HLBIUSTK.js.map → ap2-QDHPRSTF.js.map} +1 -1
  15. package/dist/cli/{chunk-QZ6TOMX6.js → chunk-AZDWFVDW.js} +200 -8
  16. package/dist/cli/chunk-AZDWFVDW.js.map +1 -0
  17. package/dist/cli/{chunk-SNM3OVCY.js → chunk-DCMW67JM.js} +19 -5
  18. package/dist/cli/chunk-DCMW67JM.js.map +1 -0
  19. package/dist/cli/{chunk-ILUYEQSV.js → chunk-G2JEY7MB.js} +26 -9
  20. package/dist/cli/chunk-G2JEY7MB.js.map +1 -0
  21. package/dist/cli/{chunk-2LN5PO5I.js → chunk-PIMFPCNZ.js} +3 -2
  22. package/dist/cli/chunk-PIMFPCNZ.js.map +1 -0
  23. package/dist/cli/chunk-UXB65XCS.js +8 -0
  24. package/dist/cli/{chunk-QY3K6PEQ.js.map → chunk-UXB65XCS.js.map} +1 -1
  25. package/dist/cli/{chunk-KTV52MCU.js → chunk-WYOGIANL.js} +3 -3
  26. package/dist/cli/{chunk-KTV52MCU.js.map → chunk-WYOGIANL.js.map} +1 -1
  27. package/dist/cli/{config-VYAJGZXE.js → config-UI4EDG4L.js} +5 -5
  28. package/dist/cli/{config-VYAJGZXE.js.map → config-UI4EDG4L.js.map} +1 -1
  29. package/dist/cli/index.js +98 -12
  30. package/dist/cli/index.js.map +1 -1
  31. package/dist/cli/{mcp-HFD7ZNCQ.js → mcp-26LJMN4N.js} +3 -3
  32. package/dist/cli/{mcp-HFD7ZNCQ.js.map → mcp-26LJMN4N.js.map} +1 -1
  33. package/dist/cli/{provider-JV5HCQGR.js → provider-Z4OJNAYI.js} +5 -5
  34. package/dist/cli/{provider-JV5HCQGR.js.map → provider-Z4OJNAYI.js.map} +1 -1
  35. package/dist/cli/{run-WV44B62Y.js → run-TEPYJUHG.js} +33 -12
  36. package/dist/cli/run-TEPYJUHG.js.map +1 -0
  37. package/dist/cli/{x402-NADFV5CD.js → x402-BMVONZKA.js} +6 -6
  38. package/dist/cli/{x402-NADFV5CD.js.map → x402-BMVONZKA.js.map} +1 -1
  39. package/dist/{constants-nackLItD.d.ts → constants-BG22tE8S.d.ts} +2 -1
  40. package/dist/index.d.ts +35 -12
  41. package/dist/index.js +61 -11
  42. package/dist/index.js.map +1 -1
  43. package/dist/mcp.d.ts +5 -4
  44. package/dist/mcp.js +1 -1
  45. package/dist/mpp.d.ts +5 -4
  46. package/dist/mpp.js +3 -3
  47. package/dist/{networks-DTWRlj-K.d.ts → networks-DDHYJLcg.d.ts} +2 -1
  48. package/dist/{protocol-adapter-CfxU8Z2T.d.ts → protocol-adapter-C9odYl6l.d.ts} +4 -3
  49. package/dist/{runtime-7vLNYvmU.d.ts → runtime-Cl_BLVZV.d.ts} +8 -1
  50. package/dist/{types-CVw6Sf46.d.ts → types-j7MnUXYN.d.ts} +2 -1
  51. package/dist/x402.d.ts +27 -18
  52. package/dist/x402.js +4 -4
  53. package/package.json +6 -6
  54. package/dist/chunk-BNUD4RBN.js.map +0 -1
  55. package/dist/cli/chunk-2LN5PO5I.js.map +0 -1
  56. package/dist/cli/chunk-ILUYEQSV.js.map +0 -1
  57. package/dist/cli/chunk-QY3K6PEQ.js +0 -8
  58. package/dist/cli/chunk-QZ6TOMX6.js.map +0 -1
  59. package/dist/cli/chunk-SNM3OVCY.js.map +0 -1
  60. package/dist/cli/index.d.ts +0 -1
  61. package/dist/cli/run-WV44B62Y.js.map +0 -1
@@ -1,9 +1,9 @@
1
- import { chainIdFromCaip2 } from './chunk-QZ6TOMX6.js';
2
- export { createX402PaymentProvider } from './chunk-QZ6TOMX6.js';
3
- import './chunk-KTV52MCU.js';
1
+ import { chainIdFromCaip2 } from './chunk-AZDWFVDW.js';
2
+ export { createX402PaymentProvider } from './chunk-AZDWFVDW.js';
3
+ import './chunk-WYOGIANL.js';
4
4
  export { SUPPORTED_NETWORK_IDS } from './chunk-OZ4LAWBK.js';
5
5
  import './chunk-OSTCU6ZK.js';
6
- import './chunk-QY3K6PEQ.js';
6
+ import './chunk-UXB65XCS.js';
7
7
  import { CommerceError } from './chunk-QQ3WY5L3.js';
8
8
  import './chunk-3M6U7ILB.js';
9
9
  import { PaymentRequirementsV2Schema } from '@x402/core/schemas';
@@ -92,5 +92,5 @@ function randomNonce() {
92
92
  }
93
93
 
94
94
  export { createPaymentProof };
95
- //# sourceMappingURL=x402-NADFV5CD.js.map
96
- //# sourceMappingURL=x402-NADFV5CD.js.map
95
+ //# sourceMappingURL=x402-BMVONZKA.js.map
96
+ //# sourceMappingURL=x402-BMVONZKA.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/payments/x402/client.ts"],"names":[],"mappings":"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","file":"x402-NADFV5CD.js","sourcesContent":["/**\n * Client-side payment helper: builds and EIP-712-signs an x402 v2 `exact`/EVM\n * authorization on the buyer's side. The demo buyer agent and the test suites\n * use it, and the `/x402` entry exports it. The gateway never calls it and\n * never holds a buyer key.\n *\n * It signs directly rather than through the SDK's `x402Client` because of\n * `overrides`: negative tests need deliberately wrong authorizations that a\n * conforming client will not produce. The x402 settlement E2E suite also\n * settles a payment built by `x402Client` itself to cover interoperability.\n */\n\nimport { PaymentRequirementsV2Schema } from '@x402/core/schemas';\nimport type { PaymentPayload, PaymentRequirements } from '@x402/core/types';\nimport { getAddress, toHex } from 'viem';\nimport { privateKeyToAccount } from 'viem/accounts';\nimport { CommerceError } from '../../core';\nimport { chainIdFromCaip2 } from './chain';\n\nexport interface CreatePaymentProofOptions {\n /** The buyer's private key. It signs locally and is never sent anywhere */\n readonly buyerPrivateKey: `0x${string}`;\n /** One entry from PaymentRequiredEnvelope.payment.accepts, verbatim */\n readonly accepts: Readonly<Record<string, unknown>>;\n /** For negative tests only: a wrong amount, recipient, nonce or validity window */\n readonly overrides?: {\n readonly value?: string;\n readonly payTo?: string;\n readonly nonce?: `0x${string}`;\n readonly validBefore?: number;\n readonly validAfter?: number;\n };\n}\n\nconst X402_VERSION = 2;\n\nconst TRANSFER_WITH_AUTHORIZATION_TYPES = {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n} as const;\n\n/** Returns the base64 `PAYMENT-SIGNATURE` value to send back to the gateway */\nexport async function createPaymentProof(options: CreatePaymentProofOptions): Promise<string> {\n const requirements = PaymentRequirementsV2Schema.parse(options.accepts);\n const method = requirements.extra?.['assetTransferMethod'];\n if (method !== undefined && method !== 'eip3009') {\n throw new CommerceError(\n 'INPUT_INVALID',\n `createPaymentProof: signs EIP-3009 only, and this offer uses \"${String(method)}\"; sign it with the SDK's x402Client`,\n );\n }\n if (\n !requirements.extra ||\n typeof requirements.extra['name'] !== 'string' ||\n typeof requirements.extra['version'] !== 'string'\n ) {\n throw new CommerceError(\n 'INPUT_INVALID',\n 'createPaymentProof: payment requirement is missing extra.name/extra.version, so the EIP-712 domain cannot be built',\n );\n }\n\n const chainId = chainIdFromCaip2(requirements.network);\n if (chainId === undefined) {\n throw new CommerceError(\n 'INPUT_INVALID',\n `createPaymentProof: network \"${requirements.network}\" is not a CAIP-2 eip155 identifier, so there is no chain id to sign against`,\n );\n }\n\n const account = privateKeyToAccount(options.buyerPrivateKey);\n\n const nonce = options.overrides?.nonce ?? randomNonce();\n const nowSeconds = Math.floor(Date.now() / 1000);\n // 0, as in the SDK's own v2 client: nothing here wants the authorization\n // delayed\n const validAfter = options.overrides?.validAfter ?? 0;\n const validBefore = options.overrides?.validBefore ?? nowSeconds + requirements.maxTimeoutSeconds;\n const to = getAddress((options.overrides?.payTo ?? requirements.payTo) as `0x${string}`);\n const value = BigInt(options.overrides?.value ?? requirements.amount);\n\n const signature = await account.signTypedData({\n domain: {\n name: requirements.extra['name'],\n version: requirements.extra['version'],\n chainId,\n verifyingContract: getAddress(requirements.asset as `0x${string}`),\n },\n types: TRANSFER_WITH_AUTHORIZATION_TYPES,\n primaryType: 'TransferWithAuthorization',\n message: {\n from: account.address,\n to,\n value,\n validAfter: BigInt(validAfter),\n validBefore: BigInt(validBefore),\n nonce,\n },\n });\n\n // v2 echoes the chosen requirement back as `accepted` so a stateless\n // facilitator knows which offer was taken. The gateway verifies against its\n // own copy.\n const payload: PaymentPayload = {\n x402Version: X402_VERSION,\n accepted: requirements as PaymentRequirements,\n payload: {\n signature,\n authorization: {\n from: account.address,\n to,\n value: value.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n },\n },\n };\n\n return Buffer.from(JSON.stringify(payload), 'utf8').toString('base64');\n}\n\nfunction randomNonce(): `0x${string}` {\n const bytes = new Uint8Array(32);\n crypto.getRandomValues(bytes);\n return toHex(bytes);\n}\n"]}
1
+ {"version":3,"sources":["../../src/payments/x402/client.ts"],"names":[],"mappings":"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","file":"x402-BMVONZKA.js","sourcesContent":["/**\n * Client-side payment helper: builds and EIP-712-signs an x402 v2 `exact`/EVM\n * authorization on the buyer's side. The demo buyer agent and the test suites\n * use it, and the `/x402` entry exports it. The gateway never calls it and\n * never holds a buyer key.\n *\n * It signs directly rather than through the SDK's `x402Client` because of\n * `overrides`: negative tests need deliberately wrong authorizations that a\n * conforming client will not produce. The x402 settlement E2E suite also\n * settles a payment built by `x402Client` itself to cover interoperability.\n */\n\nimport { PaymentRequirementsV2Schema } from '@x402/core/schemas';\nimport type { PaymentPayload, PaymentRequirements } from '@x402/core/types';\nimport { getAddress, toHex } from 'viem';\nimport { privateKeyToAccount } from 'viem/accounts';\nimport { CommerceError } from '../../core';\nimport { chainIdFromCaip2 } from './chain';\n\nexport interface CreatePaymentProofOptions {\n /** The buyer's private key. It signs locally and is never sent anywhere */\n readonly buyerPrivateKey: `0x${string}`;\n /** One entry from PaymentRequiredEnvelope.payment.accepts, verbatim */\n readonly accepts: Readonly<Record<string, unknown>>;\n /** For negative tests only: a wrong amount, recipient, nonce or validity window */\n readonly overrides?: {\n readonly value?: string;\n readonly payTo?: string;\n readonly nonce?: `0x${string}`;\n readonly validBefore?: number;\n readonly validAfter?: number;\n };\n}\n\nconst X402_VERSION = 2;\n\nconst TRANSFER_WITH_AUTHORIZATION_TYPES = {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n} as const;\n\n/** Returns the base64 `PAYMENT-SIGNATURE` value to send back to the gateway */\nexport async function createPaymentProof(options: CreatePaymentProofOptions): Promise<string> {\n const requirements = PaymentRequirementsV2Schema.parse(options.accepts);\n const method = requirements.extra?.['assetTransferMethod'];\n if (method !== undefined && method !== 'eip3009') {\n throw new CommerceError(\n 'INPUT_INVALID',\n `createPaymentProof: signs EIP-3009 only, and this offer uses \"${String(method)}\"; sign it with the SDK's x402Client`,\n );\n }\n if (\n !requirements.extra ||\n typeof requirements.extra['name'] !== 'string' ||\n typeof requirements.extra['version'] !== 'string'\n ) {\n throw new CommerceError(\n 'INPUT_INVALID',\n 'createPaymentProof: payment requirement is missing extra.name/extra.version, so the EIP-712 domain cannot be built',\n );\n }\n\n const chainId = chainIdFromCaip2(requirements.network);\n if (chainId === undefined) {\n throw new CommerceError(\n 'INPUT_INVALID',\n `createPaymentProof: network \"${requirements.network}\" is not a CAIP-2 eip155 identifier, so there is no chain id to sign against`,\n );\n }\n\n const account = privateKeyToAccount(options.buyerPrivateKey);\n\n const nonce = options.overrides?.nonce ?? randomNonce();\n const nowSeconds = Math.floor(Date.now() / 1000);\n // 0, as in the SDK's own v2 client: nothing here wants the authorization\n // delayed\n const validAfter = options.overrides?.validAfter ?? 0;\n const validBefore = options.overrides?.validBefore ?? nowSeconds + requirements.maxTimeoutSeconds;\n const to = getAddress((options.overrides?.payTo ?? requirements.payTo) as `0x${string}`);\n const value = BigInt(options.overrides?.value ?? requirements.amount);\n\n const signature = await account.signTypedData({\n domain: {\n name: requirements.extra['name'],\n version: requirements.extra['version'],\n chainId,\n verifyingContract: getAddress(requirements.asset as `0x${string}`),\n },\n types: TRANSFER_WITH_AUTHORIZATION_TYPES,\n primaryType: 'TransferWithAuthorization',\n message: {\n from: account.address,\n to,\n value,\n validAfter: BigInt(validAfter),\n validBefore: BigInt(validBefore),\n nonce,\n },\n });\n\n // v2 echoes the chosen requirement back as `accepted` so a stateless\n // facilitator knows which offer was taken. The gateway verifies against its\n // own copy.\n const payload: PaymentPayload = {\n x402Version: X402_VERSION,\n accepted: requirements as PaymentRequirements,\n payload: {\n signature,\n authorization: {\n from: account.address,\n to,\n value: value.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n },\n },\n };\n\n return Buffer.from(JSON.stringify(payload), 'utf8').toString('base64');\n}\n\nfunction randomNonce(): `0x${string}` {\n const bytes = new Uint8Array(32);\n crypto.getRandomValues(bytes);\n return toHex(bytes);\n}\n"]}
@@ -46,4 +46,5 @@ type MppNetwork = (typeof MPP_NETWORKS)[number];
46
46
  /** Compact descriptor value naming the core draft, intent and method */
47
47
  declare const MPP_SUPPORTED_SPEC: string;
48
48
 
49
- export { type MppNetwork as M, MPPX_VERSION as a, MPP_PROFILE as b, MPP_SPEC_COMMIT as c, MPP_SPEC_DRAFTS as d, MPP_SPEC_REPOSITORY as e, MPP_SUPPORTED_SPEC as f };
49
+ export { MPPX_VERSION as a, MPP_PROFILE as b, MPP_SPEC_COMMIT as c, MPP_SPEC_DRAFTS as d, MPP_SPEC_REPOSITORY as e, MPP_SUPPORTED_SPEC as f };
50
+ export type { MppNetwork as M };
package/dist/index.d.ts CHANGED
@@ -1,13 +1,13 @@
1
- import { f as Ap2AuthorizationConfig } from './types-CVw6Sf46.js';
2
- import { I as IsoTimestamp, D as DecimalAmount, P as PaymentMethodName, a as CommerceResource, b as PaymentSubmission, B as BackendHandler, A as AdapterDescriptor, c as AdapterHealth, R as ResourceRegistry, d as PaymentProvider, L as Logger, C as Clock, e as IdGenerator } from './runtime-7vLNYvmU.js';
3
- export { f as AdapterHealthComponent, g as AuthorizationMethodName, h as BackendMethod, i as DEFAULT_BACKEND_TIMEOUT_MS, J as JsonSchema, N as NOOP_LOGGER, j as PAYMENT_METHOD_NAMES, k as PROTOCOL_NAMES, l as PaymentChallenge, m as PaymentContext, n as PaymentRequirement, o as PaymentResult, p as PaymentSettlementContext, q as PaymentVerificationContext, r as Pricing, s as ProtocolName, t as systemClock } from './runtime-7vLNYvmU.js';
4
- import { M as MppNetwork } from './constants-nackLItD.js';
5
- import { X as X402PaymentFlow, a as X402FacilitatorConfig } from './guardrails-CX_jYXvZ.js';
6
- import { C as CustomNetworks } from './networks-DTWRlj-K.js';
7
- import { a as AuthorizationRequirement, b as AuthorizationSubmission, A as AuthorizationProvider } from './authorization-CMkIuAkO.js';
8
- export { c as AuthorizationFinalizeContext, d as AuthorizationRecord, e as AuthorizationVerification, f as AuthorizationVerificationContext } from './authorization-CMkIuAkO.js';
9
- import { D as DeliveredOutcome, P as PaymentRequiredOutcome, C as CommerceEvent, a as PaymentAttempt, b as CommerceReceipt, E as ExecutionPipeline, c as ProtocolAdapter, H as HttpProtocolAdapter, A as AdapterHttpRoute, d as ProtocolAdapterContext } from './protocol-adapter-CfxU8Z2T.js';
10
- export { e as COMMERCE_EVENT_TYPES, f as CanonicalRequest, g as CommerceEventType, h as EventSink, i as ExecutionOutcome, j as isHttpProtocolAdapter } from './protocol-adapter-CfxU8Z2T.js';
1
+ import { Ap2AuthorizationConfig } from './ap2.js';
2
+ import { I as IsoTimestamp, D as DecimalAmount, P as PaymentMethodName, a as CommerceResource, b as PaymentSubmission, B as BackendHandler, A as AdapterDescriptor, c as AdapterHealth, R as ResourceRegistry, d as PaymentProvider, L as Logger, C as Clock, e as IdGenerator } from './runtime-Cl_BLVZV.js';
3
+ export { f as AdapterHealthComponent, g as AuthorizationMethodName, h as BackendMethod, i as DEFAULT_BACKEND_TIMEOUT_MS, J as JsonSchema, N as NOOP_LOGGER, j as PAYMENT_METHOD_NAMES, k as PROTOCOL_NAMES, l as PaymentChallenge, m as PaymentContext, n as PaymentRequirement, o as PaymentResult, p as PaymentSettlementContext, q as PaymentVerificationContext, r as Pricing, s as ProtocolName, t as systemClock } from './runtime-Cl_BLVZV.js';
4
+ import { M as MppNetwork } from './constants-BG22tE8S.js';
5
+ import { X402PaymentFlow, X402FacilitatorConfig } from './x402.js';
6
+ import { C as CustomNetworks } from './networks-DDHYJLcg.js';
7
+ import { a as AuthorizationRequirement, b as AuthorizationSubmission, A as AuthorizationProvider } from './authorization-DjAecwuW.js';
8
+ export { c as AuthorizationFinalizeContext, d as AuthorizationRecord, e as AuthorizationVerification, f as AuthorizationVerificationContext } from './authorization-DjAecwuW.js';
9
+ import { D as DeliveredOutcome, P as PaymentRequiredOutcome, C as CommerceEvent, a as PaymentAttempt, b as CommerceReceipt, E as ExecutionPipeline, c as ProtocolAdapter, H as HttpProtocolAdapter, A as AdapterHttpRoute, d as ProtocolAdapterContext } from './protocol-adapter-C9odYl6l.js';
10
+ export { e as COMMERCE_EVENT_TYPES, f as CanonicalRequest, g as CommerceEventType, h as EventSink, i as ExecutionOutcome, j as isHttpProtocolAdapter } from './protocol-adapter-C9odYl6l.js';
11
11
  import { FastifyInstance } from 'fastify';
12
12
  import { IncomingMessage, ServerResponse } from 'node:http';
13
13
 
@@ -336,6 +336,13 @@ interface ReceiptListOptions extends ListOptions {
336
336
  */
337
337
  readonly undelivered?: boolean;
338
338
  }
339
+ interface PaymentAttemptListOptions extends ListOptions {
340
+ /**
341
+ * When true, return only attempts counted by {@link ReceiptStore.countUncertainPaymentAttempts}.
342
+ * Stores that ignore this flag do not filter by settlement status.
343
+ */
344
+ readonly uncertain?: boolean;
345
+ }
339
346
  interface ReceiptStore {
340
347
  init(): Promise<void>;
341
348
  /** Append a canonical event. Must not throw into the caller's flow */
@@ -371,8 +378,16 @@ interface ReceiptStore {
371
378
  * notice, because settlement is final and the gateway issues no refunds.
372
379
  */
373
380
  countUndeliveredReceipts(): Promise<number>;
381
+ /**
382
+ * Counts `settlement-uncertain` and legacy `failed` payment attempts.
383
+ * Funds may have moved, but the pipeline withholds delivery and writes no
384
+ * receipt for an uncertain settlement. {@link countUndeliveredReceipts}
385
+ * therefore misses these attempts. Reconcile them on chain using
386
+ * `externalReference` when it holds a transaction hash.
387
+ */
388
+ countUncertainPaymentAttempts(): Promise<number>;
374
389
  listEvents(options?: ListOptions): Promise<readonly CommerceEvent[]>;
375
- listPaymentAttempts(options?: ListOptions): Promise<readonly PaymentAttempt[]>;
390
+ listPaymentAttempts(options?: PaymentAttemptListOptions): Promise<readonly PaymentAttempt[]>;
376
391
  readonly descriptor: AdapterDescriptor;
377
392
  health(): Promise<AdapterHealth>;
378
393
  close(): Promise<void>;
@@ -520,6 +535,13 @@ interface GatewayConfig {
520
535
  * Absent when no resource overrides its offers.
521
536
  */
522
537
  readonly resourceOptions?: Readonly<Record<string, readonly X402OptionConfig[]>>;
538
+ /**
539
+ * Experimental ERC-8409 quotes. Config loading includes this field only
540
+ * when `quote.enabled` is true. The signing key must not hold funds.
541
+ */
542
+ readonly quote?: {
543
+ readonly signerPrivateKey: string;
544
+ };
523
545
  };
524
546
  readonly mpp?: {
525
547
  readonly enabled: boolean;
@@ -725,4 +747,5 @@ interface SqliteReceiptStoreOptions {
725
747
  }
726
748
  declare function createSqliteReceiptStore(options: SqliteReceiptStoreOptions): ReceiptStore;
727
749
 
728
- export { A2A_AGENT_CARD_PATH, A2A_PROTOCOL_VERSION, A2A_SPEC_VERSION, type A2aAdapterOptions, ACP_API_VERSION, ACP_SPEC_VERSION, ACP_WELL_KNOWN_PATH, AUTHORIZATION_HEADER, AUTHORIZATION_INPUT_FIELD, type AcpAdapterOptions, AdapterDescriptor, AdapterHealth, AdapterHttpRoute, AuthorizationProvider, AuthorizationRequirement, AuthorizationSubmission, type BackendExecutor, BackendHandler, type BackendRequest, type BackendResponse, COMMERCE_ERROR_CODES, COMMERCE_ERROR_HTTP_STATUS, Clock, CommerceError, type CommerceErrorCode, type CommerceErrorInfo, type CommerceErrorOptions, CommerceEvent, CommerceReceipt, CommerceResource, DELIVERY_SUMMARY_META_KEY, DecimalAmount, DeliveredOutcome, type DeliverySummary, type ErrorEnvelope, ExecutionPipeline, type GatewayConfig, type GatewayInstance, type GatewayOptions, HttpProtocolAdapter, IdGenerator, IsoTimestamp, type ListOptions, Logger, MAX_AUTHORIZATION_HEADER_BYTES, PAYMENT_HEADER, PAYMENT_INPUT_FIELD, PAYMENT_REQUIRED_HEADER, PAYMENT_RESPONSE_HEADER, PaymentAttempt, type PaymentAttemptReservation, type PaymentAttemptUpdate, PaymentMethodName, PaymentProvider, type PaymentRequiredEnvelope, PaymentRequiredOutcome, PaymentSubmission, ProtocolAdapter, ProtocolAdapterContext, RESERVED_INPUT_FIELDS, RETRYABLE_ERROR_CODES, type ReceiptListOptions, type ReceiptStore, ResourceRegistry, createA2aAdapter, createAcpAdapter, createGateway, createSqliteReceiptStore, extractReservedInputFields, isCommerceError, isPaymentRequiredEnvelope, loadConfig, parseAuthorizationHeader, parseAuthorizationSubmission, parseConfig, createSqliteReceiptStore as receipts, toCommerceError, toDeliverySummary, toErrorEnvelope, toPaymentRequiredEnvelope };
750
+ export { A2A_AGENT_CARD_PATH, A2A_PROTOCOL_VERSION, A2A_SPEC_VERSION, ACP_API_VERSION, ACP_SPEC_VERSION, ACP_WELL_KNOWN_PATH, AUTHORIZATION_HEADER, AUTHORIZATION_INPUT_FIELD, AdapterDescriptor, AdapterHealth, AdapterHttpRoute, AuthorizationProvider, AuthorizationRequirement, AuthorizationSubmission, BackendHandler, COMMERCE_ERROR_CODES, COMMERCE_ERROR_HTTP_STATUS, Clock, CommerceError, CommerceEvent, CommerceReceipt, CommerceResource, DELIVERY_SUMMARY_META_KEY, DecimalAmount, DeliveredOutcome, ExecutionPipeline, HttpProtocolAdapter, IdGenerator, IsoTimestamp, Logger, MAX_AUTHORIZATION_HEADER_BYTES, PAYMENT_HEADER, PAYMENT_INPUT_FIELD, PAYMENT_REQUIRED_HEADER, PAYMENT_RESPONSE_HEADER, PaymentAttempt, PaymentMethodName, PaymentProvider, PaymentRequiredOutcome, PaymentSubmission, ProtocolAdapter, ProtocolAdapterContext, RESERVED_INPUT_FIELDS, RETRYABLE_ERROR_CODES, ResourceRegistry, createA2aAdapter, createAcpAdapter, createGateway, createSqliteReceiptStore, extractReservedInputFields, isCommerceError, isPaymentRequiredEnvelope, loadConfig, parseAuthorizationHeader, parseAuthorizationSubmission, parseConfig, createSqliteReceiptStore as receipts, toCommerceError, toDeliverySummary, toErrorEnvelope, toPaymentRequiredEnvelope };
751
+ export type { A2aAdapterOptions, AcpAdapterOptions, BackendExecutor, BackendRequest, BackendResponse, CommerceErrorCode, CommerceErrorInfo, CommerceErrorOptions, DeliverySummary, ErrorEnvelope, GatewayConfig, GatewayInstance, GatewayOptions, ListOptions, PaymentAttemptListOptions, PaymentAttemptReservation, PaymentAttemptUpdate, PaymentRequiredEnvelope, ReceiptListOptions, ReceiptStore };
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
- import { openSqliteDatabase, AP2_SPEC_VERSION, AP2_MODES, AP2_DEFAULT_CLOCK_SKEW_SECONDS, AP2_JWK_MEMBERS, AP2_KEY_TYPE, AP2_SIGNING_ALGORITHM, AP2_JWK_CURVE, AP2_JWK_COORDINATE_BYTES, AP2_MAX_CLOCK_SKEW_SECONDS } from './chunk-2DAJAJI7.js';
1
+ import { openSqliteDatabase, AP2_SPEC_VERSION, AP2_MODES, AP2_DEFAULT_CLOCK_SKEW_SECONDS, AP2_JWK_MEMBERS, AP2_KEY_TYPE, AP2_SIGNING_ALGORITHM, AP2_JWK_CURVE, AP2_JWK_COORDINATE_BYTES, AP2_MAX_CLOCK_SKEW_SECONDS } from './chunk-6WACRJVT.js';
2
2
  import { readCappedBody, createBearerCheck, MCP_TOOL_NAME_PATTERN, settlementResponse, joinUrl, settlementResponseFromDetails, settlementFailure, x402ErrorCode, x402RefusalStatus } from './chunk-ES3V6ECS.js';
3
3
  import { MPP_DEFAULT_NETWORK, isMppNetwork, MPP_NETWORKS, MPP_DEFAULT_PAYMENT_FLOW, MPP_MIN_CHALLENGE_SECRET_LENGTH, MPP_PROFILE } from './chunk-6Z2H53CG.js';
4
4
  import { contentDigest, CONTENT_DIGEST_METADATA_KEY, mppProblem, mppProblemDetail } from './chunk-5ZYXBCDX.js';
5
- import { X402_PAYMENT_FLOWS, validateCustomNetworks, findX402Network, X402_DEFAULT_PAYMENT_FLOW, resolveX402Deployment, SETTLE_AFTER_BACKEND_METADATA_KEY, resolveDeploymentMode, requireX402Network, resolveX402Option, isEvmAddress, isEvmZeroAddress, x402OfferName, REUSE_REJECTED_AUTHORIZATION_METADATA_KEY } from './chunk-REBY2IEP.js';
6
- import { RESERVED_INPUT_FIELDS, PROTOCOL_NAMES, PAYMENT_METHOD_NAMES, PAYMENT_HEADER, AUTHORIZATION_HEADER, CommerceError, systemClock, NOOP_LOGGER, PACKAGE_VERSION, toCommerceError, DEFAULT_BACKEND_TIMEOUT_MS, isCommerceError, describeError, isHttpProtocolAdapter, toLogInfo, extractReservedInputFields, parseAuthorizationHeader, toPaymentRequiredEnvelope, PAYMENT_REQUIRED_HEADER, PAYMENT_RESPONSE_HEADER, toErrorEnvelope, DELIVERY_SUMMARY_META_KEY, toDeliverySummary, PAYMENT_INPUT_FIELD, AUTHORIZATION_INPUT_FIELD, parseAuthorizationSubmission } from './chunk-XYHDQ22D.js';
7
- export { AUTHORIZATION_HEADER, AUTHORIZATION_INPUT_FIELD, COMMERCE_ERROR_CODES, COMMERCE_ERROR_HTTP_STATUS, COMMERCE_EVENT_TYPES, CommerceError, DEFAULT_BACKEND_TIMEOUT_MS, DELIVERY_SUMMARY_META_KEY, MAX_AUTHORIZATION_HEADER_BYTES, NOOP_LOGGER, PAYMENT_HEADER, PAYMENT_INPUT_FIELD, PAYMENT_METHOD_NAMES, PAYMENT_REQUIRED_HEADER, PAYMENT_RESPONSE_HEADER, PROTOCOL_NAMES, RESERVED_INPUT_FIELDS, RETRYABLE_ERROR_CODES, extractReservedInputFields, isCommerceError, isHttpProtocolAdapter, isPaymentRequiredEnvelope, parseAuthorizationHeader, parseAuthorizationSubmission, systemClock, toCommerceError, toDeliverySummary, toErrorEnvelope, toPaymentRequiredEnvelope } from './chunk-XYHDQ22D.js';
5
+ import { X402_PAYMENT_FLOWS, validateCustomNetworks, findX402Network, X402_DEFAULT_PAYMENT_FLOW, resolveX402Deployment, SETTLE_AFTER_BACKEND_METADATA_KEY, resolveDeploymentMode, requireX402Network, resolveX402Option, isEvmAddress, isEvmZeroAddress, x402OfferName, REUSE_REJECTED_AUTHORIZATION_METADATA_KEY } from './chunk-4OEXK3YG.js';
6
+ import { RESERVED_INPUT_FIELDS, PROTOCOL_NAMES, PAYMENT_METHOD_NAMES, PAYMENT_HEADER, AUTHORIZATION_HEADER, CommerceError, systemClock, NOOP_LOGGER, PACKAGE_VERSION, toCommerceError, DEFAULT_BACKEND_TIMEOUT_MS, isCommerceError, describeError, isHttpProtocolAdapter, toLogInfo, extractReservedInputFields, parseAuthorizationHeader, toPaymentRequiredEnvelope, PAYMENT_REQUIRED_HEADER, PAYMENT_RESPONSE_HEADER, toErrorEnvelope, DELIVERY_SUMMARY_META_KEY, toDeliverySummary, PAYMENT_INPUT_FIELD, AUTHORIZATION_INPUT_FIELD, parseAuthorizationSubmission } from './chunk-AITMDXKW.js';
7
+ export { AUTHORIZATION_HEADER, AUTHORIZATION_INPUT_FIELD, COMMERCE_ERROR_CODES, COMMERCE_ERROR_HTTP_STATUS, COMMERCE_EVENT_TYPES, CommerceError, DEFAULT_BACKEND_TIMEOUT_MS, DELIVERY_SUMMARY_META_KEY, MAX_AUTHORIZATION_HEADER_BYTES, NOOP_LOGGER, PAYMENT_HEADER, PAYMENT_INPUT_FIELD, PAYMENT_METHOD_NAMES, PAYMENT_REQUIRED_HEADER, PAYMENT_RESPONSE_HEADER, PROTOCOL_NAMES, RESERVED_INPUT_FIELDS, RETRYABLE_ERROR_CODES, extractReservedInputFields, isCommerceError, isHttpProtocolAdapter, isPaymentRequiredEnvelope, parseAuthorizationHeader, parseAuthorizationSubmission, systemClock, toCommerceError, toDeliverySummary, toErrorEnvelope, toPaymentRequiredEnvelope } from './chunk-AITMDXKW.js';
8
8
  import { isRecord } from './chunk-2CJNA7MS.js';
9
9
  import { promises, accessSync, constants } from 'fs';
10
10
  import * as path from 'path';
@@ -725,6 +725,16 @@ function normalizeX402(raw, resources) {
725
725
  const resourceOptions = Object.fromEntries(
726
726
  Object.entries(resourceTerms).map(([id, terms]) => [id, terms.options])
727
727
  );
728
+ let quote;
729
+ if (raw.quote !== void 0 && toBoolean(raw.quote.enabled, `${at}.quote.enabled`)) {
730
+ if (raw.quote.signerPrivateKey === void 0) {
731
+ throw x402Invalid(
732
+ `${at}.quote.signerPrivateKey is required when quotes are enabled`,
733
+ `${at}.quote.signerPrivateKey`
734
+ );
735
+ }
736
+ quote = { signerPrivateKey: raw.quote.signerPrivateKey };
737
+ }
728
738
  const config = {
729
739
  enabled: toBoolean(raw.enabled, `${at}.enabled`),
730
740
  ...first,
@@ -735,7 +745,8 @@ function normalizeX402(raw, resources) {
735
745
  ...allowUnauthenticatedFacilitator !== void 0 ? { allowUnauthenticatedFacilitator } : {},
736
746
  ...networks !== void 0 ? { networks } : {},
737
747
  options,
738
- ...Object.keys(resourceOptions).length > 0 ? { resourceOptions } : {}
748
+ ...Object.keys(resourceOptions).length > 0 ? { resourceOptions } : {},
749
+ ...quote !== void 0 ? { quote } : {}
739
750
  };
740
751
  return { config, ...rail, resources: resourceTerms };
741
752
  }
@@ -832,8 +843,8 @@ var MerchantSchema = z.object({
832
843
  var ServerSchema = z.object({
833
844
  port: NumberOrString,
834
845
  host: z.string().min(1),
835
- // Shared secret gating /api/receipts and /api/events. Without it both
836
- // routes 404.
846
+ // Required for /api/receipts, /api/events and /api/payment-attempts;
847
+ // these routes return 404 when the token is unset
837
848
  adminToken: z.string().min(1).optional(),
838
849
  // Browser origins allowed to call the gateway; none by default. A request
839
850
  // with any other `Origin` gets 403 on every route. Entries match the
@@ -865,7 +876,8 @@ var RESERVED_GATEWAY_PATHS = [
865
876
  "/api/resources",
866
877
  "/api/resources/:id/invoke",
867
878
  "/api/receipts",
868
- "/api/events"
879
+ "/api/events",
880
+ "/api/payment-attempts"
869
881
  ];
870
882
  var MountPathSchema = z.string().min(1).refine((value) => value.startsWith("/"), {
871
883
  message: 'must start with "/" - it is an absolute gateway path, e.g. "/mcp".'
@@ -1022,7 +1034,12 @@ var X402Schema = z.object({
1022
1034
  // Real funds. Never defaulted; see src/payments/x402/guardrails.ts
1023
1035
  allowMainnet: BooleanOrString.optional(),
1024
1036
  // Accepts credential-free facilitator access on mainnet. Never defaulted
1025
- allowUnauthenticatedFacilitator: BooleanOrString.optional()
1037
+ allowUnauthenticatedFacilitator: BooleanOrString.optional(),
1038
+ // Experimental ERC-8409 quotes; signing a quote transfers no funds
1039
+ quote: z.object({
1040
+ enabled: BooleanOrString,
1041
+ signerPrivateKey: z.string().min(1).optional()
1042
+ }).strict().optional()
1026
1043
  }).strict();
1027
1044
  var MppSchema = z.object({
1028
1045
  enabled: BooleanOrString,
@@ -1719,6 +1736,7 @@ function createPaymentAdmission(ctx, authorizeAndReserve) {
1719
1736
  amount: pricing.amount,
1720
1737
  currency: pricing.currency,
1721
1738
  requestedAt: options.clock.nowIso(),
1739
+ input: validInput,
1722
1740
  // Transport facts a rail may bind into its challenge, such as a body digest
1723
1741
  ...request.metadata !== void 0 ? { metadata: request.metadata } : {}
1724
1742
  });
@@ -3622,6 +3640,12 @@ function publicOffer(option, statuses) {
3622
3640
  function flowOverrides(flows) {
3623
3641
  return flows !== void 0 && Object.keys(flows).length > 0 ? { resourcePaymentFlows: flows } : {};
3624
3642
  }
3643
+ function publicQuote(providers) {
3644
+ const x402 = providers.find((provider) => provider.name === "x402");
3645
+ if (x402?.quote === void 0) return void 0;
3646
+ const { issuer, requestScheme, extension } = x402.quote;
3647
+ return { issuer, requestScheme, extension, status: "experimental" };
3648
+ }
3625
3649
  function buildWellKnownDocument(options) {
3626
3650
  const adapters = options.adapters.map(({ descriptor, health }) => ({
3627
3651
  ...descriptor,
@@ -3632,6 +3656,7 @@ function buildWellKnownDocument(options) {
3632
3656
  const offerStatuses = new Map(
3633
3657
  (x402Health?.components ?? []).map((component) => [component.name, component.status])
3634
3658
  );
3659
+ const quote = publicQuote(options.paymentProviders);
3635
3660
  return {
3636
3661
  gateway: {
3637
3662
  implementationVersion: PACKAGE_VERSION,
@@ -3671,7 +3696,8 @@ function buildWellKnownDocument(options) {
3671
3696
  list.map((option) => publicOffer(option, offerStatuses))
3672
3697
  ])
3673
3698
  )
3674
- } : {}
3699
+ } : {},
3700
+ ...quote !== void 0 ? { quote } : {}
3675
3701
  }
3676
3702
  } : {},
3677
3703
  ...mpp !== void 0 ? {
@@ -3752,6 +3778,16 @@ function registerRoutes(options) {
3752
3778
  { onRequest: tokenHook },
3753
3779
  ledgerHandler("events", (list) => options.store.listEvents(list))
3754
3780
  );
3781
+ server.get(
3782
+ "/api/payment-attempts",
3783
+ { onRequest: tokenHook },
3784
+ ledgerHandler(
3785
+ "paymentAttempts",
3786
+ (list, query) => options.store.listPaymentAttempts(
3787
+ parseFlag(query["uncertain"], "uncertain") ? { ...list, uncertain: true } : list
3788
+ )
3789
+ )
3790
+ );
3755
3791
  }
3756
3792
  var bodyDigests = /* @__PURE__ */ new WeakMap();
3757
3793
  function digestingStream(request) {
@@ -10460,6 +10496,7 @@ function clampListLimit(limit) {
10460
10496
  return Math.min(Math.max(Math.trunc(base), 1), MAX_LIST_LIMIT);
10461
10497
  }
10462
10498
  var UNDELIVERED = "backend_status NOT BETWEEN 200 AND 299";
10499
+ var UNCERTAIN = "status IN ('settlement-uncertain', 'failed')";
10463
10500
  var defaultIds = {
10464
10501
  next: (prefix) => prefix !== void 0 ? `${prefix}_${randomUUID()}` : randomUUID()
10465
10502
  };
@@ -10539,6 +10576,15 @@ function createSqliteReceiptStore(options) {
10539
10576
  const listPaymentAttemptsByRequestStmt = db.prepare(
10540
10577
  "SELECT * FROM payment_attempts WHERE request_id = ? ORDER BY created_at DESC, seq DESC LIMIT ?"
10541
10578
  );
10579
+ const listUncertainPaymentAttemptsStmt = db.prepare(
10580
+ `SELECT * FROM payment_attempts WHERE ${UNCERTAIN} ORDER BY created_at DESC, seq DESC LIMIT ?`
10581
+ );
10582
+ const listUncertainPaymentAttemptsByRequestStmt = db.prepare(
10583
+ `SELECT * FROM payment_attempts WHERE request_id = ? AND ${UNCERTAIN} ORDER BY created_at DESC, seq DESC LIMIT ?`
10584
+ );
10585
+ const countUncertainPaymentAttemptsStmt = db.prepare(
10586
+ `SELECT COUNT(*) AS count FROM payment_attempts WHERE ${UNCERTAIN}`
10587
+ );
10542
10588
  const paymentAttemptStatusStmt = db.prepare(
10543
10589
  "SELECT status FROM payment_attempts WHERE replay_key = ?"
10544
10590
  );
@@ -10669,6 +10715,9 @@ function createSqliteReceiptStore(options) {
10669
10715
  async countUndeliveredReceipts() {
10670
10716
  return countUndeliveredReceiptsStmt.get()?.count ?? 0;
10671
10717
  },
10718
+ async countUncertainPaymentAttempts() {
10719
+ return countUncertainPaymentAttemptsStmt.get()?.count ?? 0;
10720
+ },
10672
10721
  async listEvents(listOptions = {}) {
10673
10722
  const limit = clampListLimit(listOptions.limit);
10674
10723
  const rows = listOptions.requestId !== void 0 ? listEventsByRequestStmt.all(listOptions.requestId, limit) : listEventsStmt.all(limit);
@@ -10676,7 +10725,8 @@ function createSqliteReceiptStore(options) {
10676
10725
  },
10677
10726
  async listPaymentAttempts(listOptions = {}) {
10678
10727
  const limit = clampListLimit(listOptions.limit);
10679
- const rows = listOptions.requestId !== void 0 ? listPaymentAttemptsByRequestStmt.all(listOptions.requestId, limit) : listPaymentAttemptsStmt.all(limit);
10728
+ const uncertain = listOptions.uncertain === true;
10729
+ const rows = listOptions.requestId !== void 0 ? (uncertain ? listUncertainPaymentAttemptsByRequestStmt : listPaymentAttemptsByRequestStmt).all(listOptions.requestId, limit) : (uncertain ? listUncertainPaymentAttemptsStmt : listPaymentAttemptsStmt).all(limit);
10680
10730
  return rows.map(rowToPaymentAttempt);
10681
10731
  },
10682
10732
  descriptor,