@devlab.group/agent-commerce 1.5.0 → 1.6.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 +73 -71
- package/dist/ap2.d.ts +20 -23
- package/dist/ap2.js +53 -75
- package/dist/ap2.js.map +1 -1
- package/dist/authorization-BpbWGGrf.d.ts +115 -0
- package/dist/chunk-AFI2CEZS.js +10 -0
- package/dist/chunk-AFI2CEZS.js.map +1 -0
- package/dist/{chunk-PBYN7EK2.js → chunk-CBJIT7QP.js} +10 -9
- package/dist/chunk-CBJIT7QP.js.map +1 -0
- package/dist/{chunk-NKNXVDHN.js → chunk-JKEKKXRJ.js} +45 -66
- package/dist/chunk-JKEKKXRJ.js.map +1 -0
- package/dist/{chunk-5GEWKNIH.js → chunk-N5KRK7YA.js} +63 -27
- package/dist/chunk-N5KRK7YA.js.map +1 -0
- package/dist/{chunk-6D2EZ5ME.js → chunk-V2V2E7HX.js} +2 -2
- package/dist/{chunk-6D2EZ5ME.js.map → chunk-V2V2E7HX.js.map} +1 -1
- package/dist/{chunk-US622BKF.js → chunk-VKDXMXHL.js} +5 -8
- package/dist/chunk-VKDXMXHL.js.map +1 -0
- package/dist/cli/index.js +501 -494
- package/dist/cli/index.js.map +1 -1
- package/dist/{constants-6mypC60h.d.ts → constants-Bkq04FRZ.d.ts} +1 -3
- package/dist/guardrails-71XwtXlT.d.ts +31 -0
- package/dist/index.d.ts +230 -265
- package/dist/index.js +1050 -607
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts +6 -59
- package/dist/mcp.js +61 -53
- package/dist/mcp.js.map +1 -1
- package/dist/mpp.d.ts +4 -4
- package/dist/mpp.js +21 -19
- package/dist/mpp.js.map +1 -1
- package/dist/protocol-adapter-DTkrXTev.d.ts +238 -0
- package/dist/runtime-CiYbgGpi.d.ts +303 -0
- package/dist/{types-CJtwLu1c.d.ts → types-O6lg3Q5V.d.ts} +17 -23
- package/dist/x402.d.ts +43 -75
- package/dist/x402.js +10 -9
- package/dist/x402.js.map +1 -1
- package/package.json +7 -5
- package/dist/authorization-DA7mjy_O.d.ts +0 -123
- package/dist/chunk-5GEWKNIH.js.map +0 -1
- package/dist/chunk-NKNXVDHN.js.map +0 -1
- package/dist/chunk-PBYN7EK2.js.map +0 -1
- package/dist/chunk-US622BKF.js.map +0 -1
- package/dist/guardrails-Dmwi63KB.d.ts +0 -38
- package/dist/protocol-adapter-APRjs1E2.d.ts +0 -273
- package/dist/runtime-DC5XQ9Cc.d.ts +0 -351
package/dist/index.d.ts
CHANGED
|
@@ -1,49 +1,40 @@
|
|
|
1
|
-
import { f as Ap2AuthorizationConfig } from './types-
|
|
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-
|
|
3
|
-
export { f as AuthorizationMethodName, g as BackendMethod, h as DEFAULT_BACKEND_TIMEOUT_MS, J as JsonSchema, N as NOOP_LOGGER, i as PAYMENT_METHOD_NAMES, j as PROTOCOL_NAMES, k as PaymentChallenge, l as PaymentContext, m as PaymentRequirement, n as PaymentResult, o as PaymentSettlementContext, p as PaymentVerificationContext, q as Pricing, r as ProtocolName, s as systemClock } from './runtime-
|
|
4
|
-
import { M as MppNetwork } from './constants-
|
|
5
|
-
import { X as X402FacilitatorConfig } from './guardrails-
|
|
6
|
-
import { a as AuthorizationRequirement, b as AuthorizationSubmission, A as AuthorizationProvider } from './authorization-
|
|
7
|
-
export { c as AuthorizationFinalizeContext, d as AuthorizationRecord, e as AuthorizationVerification, f as AuthorizationVerificationContext } from './authorization-
|
|
8
|
-
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-
|
|
9
|
-
export { e as COMMERCE_EVENT_TYPES, f as CanonicalRequest, g as CommerceEventType, h as EventSink, i as ExecutionOutcome, j as isHttpProtocolAdapter } from './protocol-adapter-
|
|
1
|
+
import { f as Ap2AuthorizationConfig } from './types-O6lg3Q5V.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-CiYbgGpi.js';
|
|
3
|
+
export { f as AuthorizationMethodName, g as BackendMethod, h as DEFAULT_BACKEND_TIMEOUT_MS, J as JsonSchema, N as NOOP_LOGGER, i as PAYMENT_METHOD_NAMES, j as PROTOCOL_NAMES, k as PaymentChallenge, l as PaymentContext, m as PaymentRequirement, n as PaymentResult, o as PaymentSettlementContext, p as PaymentVerificationContext, q as Pricing, r as ProtocolName, s as systemClock } from './runtime-CiYbgGpi.js';
|
|
4
|
+
import { M as MppNetwork } from './constants-Bkq04FRZ.js';
|
|
5
|
+
import { X as X402FacilitatorConfig } from './guardrails-71XwtXlT.js';
|
|
6
|
+
import { a as AuthorizationRequirement, b as AuthorizationSubmission, A as AuthorizationProvider } from './authorization-BpbWGGrf.js';
|
|
7
|
+
export { c as AuthorizationFinalizeContext, d as AuthorizationRecord, e as AuthorizationVerification, f as AuthorizationVerificationContext } from './authorization-BpbWGGrf.js';
|
|
8
|
+
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-DTkrXTev.js';
|
|
9
|
+
export { e as COMMERCE_EVENT_TYPES, f as CanonicalRequest, g as CommerceEventType, h as EventSink, i as ExecutionOutcome, j as isHttpProtocolAdapter } from './protocol-adapter-DTkrXTev.js';
|
|
10
10
|
import { FastifyInstance } from 'fastify';
|
|
11
11
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* Typed domain error codes.
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* format. Never throw a bare string or untyped Error across a package boundary.
|
|
14
|
+
* Typed domain error codes. FROZEN CONTRACT. Protocol adapters map them into
|
|
15
|
+
* their own response format. Never throw a bare string or untyped Error across
|
|
16
|
+
* an area boundary.
|
|
18
17
|
*/
|
|
19
18
|
declare const COMMERCE_ERROR_CODES: readonly ["CONFIG_INVALID", "RESOURCE_NOT_FOUND", "INPUT_INVALID", "PAYMENT_REQUIRED", "PAYMENT_INVALID", "PAYMENT_REPLAYED", "PAYMENT_PROVIDER_UNAVAILABLE", "PAYMENT_SETTLEMENT_FAILED", "AUTHORIZATION_REQUIRED", "AUTHORIZATION_INVALID", "AUTHORIZATION_REPLAYED", "AUTHORIZATION_PROVIDER_UNAVAILABLE", "BACKEND_TIMEOUT", "BACKEND_ERROR", "PROTOCOL_UNSUPPORTED", "GATEWAY_BUSY", "STORAGE_ERROR", "INTERNAL_ERROR"];
|
|
20
19
|
type CommerceErrorCode = (typeof COMMERCE_ERROR_CODES)[number];
|
|
21
20
|
/**
|
|
22
|
-
* Canonical HTTP status for each error code.
|
|
23
|
-
*
|
|
24
|
-
* Paid resources fail closed: every payment failure maps to a 4xx/5xx status
|
|
25
|
-
* and never to a successful delivery.
|
|
21
|
+
* Canonical HTTP status for each error code. Every payment failure maps to a
|
|
22
|
+
* 4xx or 5xx status, never to a delivery.
|
|
26
23
|
*/
|
|
27
24
|
declare const COMMERCE_ERROR_HTTP_STATUS: Readonly<Record<CommerceErrorCode, number>>;
|
|
28
|
-
/** Codes for which a client may reasonably retry the same request
|
|
25
|
+
/** Codes for which a client may reasonably retry the same request */
|
|
29
26
|
declare const RETRYABLE_ERROR_CODES: ReadonlySet<CommerceErrorCode>;
|
|
30
27
|
|
|
31
|
-
/**
|
|
32
|
-
* The single error type crossing package boundaries.
|
|
33
|
-
*
|
|
34
|
-
* FROZEN CONTRACT.
|
|
35
|
-
*/
|
|
36
|
-
|
|
37
28
|
interface CommerceErrorOptions {
|
|
38
|
-
/** Structured, non-secret detail safe to return to a client
|
|
29
|
+
/** Structured, non-secret detail safe to return to a client */
|
|
39
30
|
readonly details?: Readonly<Record<string, unknown>>;
|
|
40
31
|
readonly cause?: unknown;
|
|
41
32
|
readonly requestId?: string;
|
|
42
33
|
readonly resourceId?: string;
|
|
43
|
-
/** Override the default HTTP status for this code
|
|
34
|
+
/** Override the default HTTP status for this code */
|
|
44
35
|
readonly httpStatus?: number;
|
|
45
36
|
}
|
|
46
|
-
/**
|
|
37
|
+
/** Serializable wire form of a CommerceError */
|
|
47
38
|
interface CommerceErrorInfo {
|
|
48
39
|
readonly code: CommerceErrorCode;
|
|
49
40
|
readonly message: string;
|
|
@@ -61,118 +52,93 @@ declare class CommerceError extends Error {
|
|
|
61
52
|
readonly requestId?: string;
|
|
62
53
|
readonly resourceId?: string;
|
|
63
54
|
constructor(code: CommerceErrorCode, message: string, options?: CommerceErrorOptions);
|
|
64
|
-
/** Non-secret, client-safe representation. */
|
|
55
|
+
/** Non-secret, client-safe representation. `cause` is never included */
|
|
65
56
|
toInfo(): CommerceErrorInfo;
|
|
66
57
|
}
|
|
67
58
|
declare function isCommerceError(value: unknown): value is CommerceError;
|
|
68
59
|
/**
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* SECURITY — do not "improve" this by propagating `value.message`.
|
|
74
|
-
* `CommerceError.message` is client-visible: it is serialised by `toInfo()`
|
|
75
|
-
* and `toErrorEnvelope()` and returned over HTTP and MCP. An arbitrary thrown
|
|
76
|
-
* Error's message routinely carries internal detail — database connection
|
|
77
|
-
* strings, internal hostnames, filesystem paths, backend URLs. Copying it into
|
|
78
|
-
* a client-facing field turns every unexpected exception into an information
|
|
79
|
-
* disclosure.
|
|
60
|
+
* Passes an existing CommerceError through. Other thrown values become a
|
|
61
|
+
* CommerceError with a caller-chosen message, for example
|
|
62
|
+
* `toCommerceError(err, 'BACKEND_ERROR', 'Backend call failed')`.
|
|
80
63
|
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* A caller that *wants* a specific client-facing message passes one:
|
|
86
|
-
* toCommerceError(err, 'BACKEND_ERROR', 'Backend call failed')
|
|
64
|
+
* Arbitrary Error messages may contain internal URLs, hostnames or file paths.
|
|
65
|
+
* The original value remains on `cause` for internal logging; `toInfo()` and
|
|
66
|
+
* `toErrorEnvelope()` do not serialize it.
|
|
87
67
|
*/
|
|
88
68
|
declare function toCommerceError(value: unknown, fallbackCode?: CommerceErrorCode, fallbackMessage?: string): CommerceError;
|
|
89
69
|
|
|
90
70
|
/**
|
|
91
|
-
* Gateway-defined wire envelopes.
|
|
71
|
+
* Gateway-defined wire envelopes and carriers. FROZEN CONTRACT.
|
|
92
72
|
*
|
|
93
|
-
*
|
|
94
|
-
* and "error"
|
|
95
|
-
*
|
|
96
|
-
* three can never drift apart.
|
|
73
|
+
* The HTTP routes and the MCP and A2A adapters build their "payment required"
|
|
74
|
+
* and "error" bodies with these helpers, so those surfaces send the same
|
|
75
|
+
* shapes. The ACP adapter maps errors to ACP's own error format instead.
|
|
97
76
|
*/
|
|
98
77
|
|
|
99
78
|
/**
|
|
100
|
-
* Reserved input property carrying a payment proof on protocols
|
|
101
|
-
*
|
|
102
|
-
* used.
|
|
79
|
+
* Reserved input property carrying a payment proof on protocols with no header
|
|
80
|
+
* channel (MCP tool calls, A2A message data). HTTP uses a header instead.
|
|
103
81
|
*/
|
|
104
82
|
declare const PAYMENT_INPUT_FIELD = "_payment";
|
|
105
83
|
/**
|
|
106
|
-
* HTTP request header carrying
|
|
84
|
+
* HTTP request header carrying an x402 payment proof. MPP proofs use
|
|
85
|
+
* `Authorization: Payment ...` instead.
|
|
107
86
|
*
|
|
108
|
-
* x402 v2 header names, lowercased
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
* two verification paths for the same money.
|
|
87
|
+
* The x402 v2 header names, lowercased as Node presents incoming headers. v1's
|
|
88
|
+
* `X-PAYMENT` / `X-PAYMENT-RESPONSE` pair is not accepted: honoring both
|
|
89
|
+
* versions would mean two verification paths for the same money.
|
|
112
90
|
*/
|
|
113
91
|
declare const PAYMENT_HEADER = "payment-signature";
|
|
114
|
-
/** HTTP response header carrying the settlement result
|
|
92
|
+
/** HTTP response header carrying the settlement result */
|
|
115
93
|
declare const PAYMENT_RESPONSE_HEADER = "payment-response";
|
|
116
94
|
/**
|
|
117
|
-
* Reserved input property carrying an authorization proof, the
|
|
118
|
-
*
|
|
95
|
+
* Reserved input property carrying an authorization proof, the counterpart of
|
|
96
|
+
* {@link PAYMENT_INPUT_FIELD}.
|
|
119
97
|
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
* proof cannot lean on that, and guessing the method of a security control is
|
|
124
|
-
* not a thing to do implicitly.
|
|
98
|
+
* `_payment` is a bare string whose method is taken from the resource's first
|
|
99
|
+
* payment method. This field is a `{ method, payload }` object, because the
|
|
100
|
+
* method of a security control should be stated, not inferred.
|
|
125
101
|
*/
|
|
126
102
|
declare const AUTHORIZATION_INPUT_FIELD = "_authorization";
|
|
127
103
|
/**
|
|
128
|
-
* Every input property name the gateway claims for itself.
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* of them), by the protocol adapters that lift them out of client input, and
|
|
132
|
-
* by the pipeline that strips them again as defence in depth. Those three
|
|
133
|
-
* agree by construction instead of by three copies of two strings.
|
|
104
|
+
* Every input property name the gateway claims for itself. The config loader
|
|
105
|
+
* rejects a resource declaring one, protocol adapters lift them out of client
|
|
106
|
+
* input, and the pipeline strips them again as defense in depth.
|
|
134
107
|
*/
|
|
135
108
|
declare const RESERVED_INPUT_FIELDS: readonly string[];
|
|
136
109
|
/**
|
|
137
|
-
* HTTP request header carrying the authorization proof
|
|
138
|
-
*
|
|
139
|
-
* carries.
|
|
110
|
+
* HTTP request header carrying the authorization proof: base64url-encoded JSON
|
|
111
|
+
* of the same `{ method, payload }` object the reserved input field carries.
|
|
140
112
|
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
* routes.
|
|
113
|
+
* An Agent Commerce carrier, not a header from any authorization
|
|
114
|
+
* specification. It is namespaced rather than reusing `Authorization`, which
|
|
115
|
+
* already carries other credentials, including MPP payment proofs.
|
|
145
116
|
*/
|
|
146
117
|
declare const AUTHORIZATION_HEADER = "agent-authorization";
|
|
147
118
|
/**
|
|
148
119
|
* Hard cap on the encoded `Agent-Authorization` header.
|
|
149
120
|
*
|
|
150
|
-
* Node's
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
* below it means an oversized proof gets a deterministic
|
|
154
|
-
* AUTHORIZATION_INVALID naming the limit.
|
|
121
|
+
* Node's default limit is 16 KiB across all request headers, and a request over
|
|
122
|
+
* it is refused before the gateway sees it. Capping well below that gives an
|
|
123
|
+
* oversized proof a deterministic `AUTHORIZATION_INVALID` naming the limit.
|
|
155
124
|
*/
|
|
156
125
|
declare const MAX_AUTHORIZATION_HEADER_BYTES = 8192;
|
|
157
126
|
/**
|
|
158
|
-
* HTTP response header carrying the base64
|
|
127
|
+
* HTTP response header carrying the base64 x402 challenge on a 402.
|
|
159
128
|
*
|
|
160
|
-
* The
|
|
161
|
-
*
|
|
162
|
-
*
|
|
129
|
+
* The body still carries the richer {@link PaymentRequiredEnvelope}, the only
|
|
130
|
+
* channel MCP has, but an x402 v2 client reads the challenge from this header
|
|
131
|
+
* and ignores the body, so both are sent.
|
|
163
132
|
*/
|
|
164
133
|
declare const PAYMENT_REQUIRED_HEADER = "payment-required";
|
|
165
134
|
/**
|
|
166
135
|
* Key under which a protocol adapter attaches a {@link DeliverySummary} to its
|
|
167
|
-
* result metadata
|
|
168
|
-
*
|
|
136
|
+
* result metadata: MCP's `CallToolResult._meta` and the A2A task artifact's
|
|
137
|
+
* metadata.
|
|
169
138
|
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
* consumer both import this constant.
|
|
174
|
-
*
|
|
175
|
-
* Follows MCP's `<namespace>/<name>` convention for `_meta` keys.
|
|
139
|
+
* Part of the frozen contract because producer and consumer must agree on it;
|
|
140
|
+
* both import this constant. Follows MCP's `<namespace>/<name>` convention for
|
|
141
|
+
* `_meta` keys.
|
|
176
142
|
*/
|
|
177
143
|
declare const DELIVERY_SUMMARY_META_KEY = "agent-commerce/delivery";
|
|
178
144
|
interface PaymentRequiredEnvelope {
|
|
@@ -190,24 +156,21 @@ interface PaymentRequiredEnvelope {
|
|
|
190
156
|
readonly network?: string;
|
|
191
157
|
readonly asset?: string;
|
|
192
158
|
readonly expiresAt?: IsoTimestamp;
|
|
193
|
-
/** Provider-native requirement objects, passed through verbatim
|
|
159
|
+
/** Provider-native requirement objects, passed through verbatim */
|
|
194
160
|
readonly accepts: readonly Readonly<Record<string, unknown>>[];
|
|
195
161
|
/**
|
|
196
|
-
* The provider's own challenge document, verbatim
|
|
197
|
-
* {@link PaymentChallenge.envelope}. Present for providers that have one;
|
|
198
|
-
* a buyer's protocol client can hand
|
|
162
|
+
* The provider's own challenge document, verbatim (see
|
|
163
|
+
* {@link PaymentChallenge.envelope}). Present for providers that have one;
|
|
164
|
+
* a buyer's protocol client can hand it straight to its SDK.
|
|
199
165
|
*/
|
|
200
166
|
readonly envelope?: Readonly<Record<string, unknown>>;
|
|
201
167
|
};
|
|
202
168
|
/**
|
|
203
|
-
* Present only when the resource requires an authorization proof
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
* envelope
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
* This advertises a requirement; it does not issue anything. The proof is
|
|
210
|
-
* obtained from the merchant's own approval flow, outside the gateway.
|
|
169
|
+
* Present only when the resource also requires an authorization proof, so a
|
|
170
|
+
* client learns before it spends anything that paying alone will not get the
|
|
171
|
+
* resource delivered. A client that ignores the field sees the plain
|
|
172
|
+
* envelope. The proof comes from the merchant's own approval flow, outside
|
|
173
|
+
* the gateway.
|
|
211
174
|
*/
|
|
212
175
|
readonly authorization?: {
|
|
213
176
|
readonly required: readonly AuthorizationRequirement[];
|
|
@@ -223,17 +186,10 @@ interface ErrorEnvelope {
|
|
|
223
186
|
readonly details?: Readonly<Record<string, unknown>>;
|
|
224
187
|
}
|
|
225
188
|
/**
|
|
226
|
-
* What a buyer learns about their own completed purchase
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
* on-chain. They are NOT entitled to the merchant's ledger, which is why
|
|
231
|
-
* `/api/receipts` is an operator route behind `server.adminToken`.
|
|
232
|
-
*
|
|
233
|
-
* Before this existed the two surfaces disagreed: HTTP callers received a
|
|
234
|
-
* settlement summary in the payment-response header while MCP callers received
|
|
235
|
-
* nothing, so an MCP buyer's only route to their own receipt was the merchant's
|
|
236
|
-
* ledger. Both surfaces now emit this same shape.
|
|
189
|
+
* What a buyer learns about their own completed purchase: the request, whether
|
|
190
|
+
* it settled, and the settlement reference they can check on-chain. The
|
|
191
|
+
* merchant's ledger is not theirs to read, which is why `/api/receipts` is an
|
|
192
|
+
* operator route behind `server.adminToken`.
|
|
237
193
|
*/
|
|
238
194
|
interface DeliverySummary {
|
|
239
195
|
readonly requestId: string;
|
|
@@ -244,45 +200,42 @@ interface DeliverySummary {
|
|
|
244
200
|
readonly status: 'verified' | 'settled' | 'rejected';
|
|
245
201
|
readonly amount: DecimalAmount;
|
|
246
202
|
readonly currency: string;
|
|
247
|
-
/** Settlement reference, e.g. an on-chain transaction hash
|
|
203
|
+
/** Settlement reference, e.g. an on-chain transaction hash */
|
|
248
204
|
readonly externalReference?: string;
|
|
249
205
|
readonly network?: string;
|
|
250
206
|
};
|
|
251
207
|
}
|
|
252
|
-
/** Build the payer-facing summary of a delivered outcome
|
|
208
|
+
/** Build the payer-facing summary of a delivered outcome */
|
|
253
209
|
declare function toDeliverySummary(outcome: DeliveredOutcome): DeliverySummary;
|
|
254
210
|
declare function toPaymentRequiredEnvelope(outcome: PaymentRequiredOutcome): PaymentRequiredEnvelope;
|
|
255
211
|
declare function toErrorEnvelope(error: CommerceError): ErrorEnvelope;
|
|
256
212
|
declare function isPaymentRequiredEnvelope(value: unknown): value is PaymentRequiredEnvelope;
|
|
257
213
|
/**
|
|
258
|
-
* Parses the `{ method, payload }` authorization
|
|
259
|
-
* brought it.
|
|
214
|
+
* Parses the `{ method, payload }` authorization object, whichever carrier
|
|
215
|
+
* brought it. Absent returns `undefined`; malformed throws
|
|
216
|
+
* `AUTHORIZATION_INVALID`.
|
|
260
217
|
*
|
|
261
|
-
*
|
|
262
|
-
* dropped
|
|
263
|
-
*
|
|
264
|
-
* come back as "not authorized" for a proof the client believes it sent, with
|
|
265
|
-
* no way to tell a rejected mandate from a typo in the envelope around it.
|
|
218
|
+
* An unusable `_payment` is dropped, which leaves the buyer a 402 to act on. A
|
|
219
|
+
* dropped authorization would instead come back as "not authorized", with no
|
|
220
|
+
* way to tell a rejected mandate from a typo in the object around it.
|
|
266
221
|
*/
|
|
267
222
|
declare function parseAuthorizationSubmission(value: unknown, requestId?: string): AuthorizationSubmission | undefined;
|
|
268
223
|
/**
|
|
269
|
-
* Decodes the base64url
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
* oversized header costs a length comparison rather than a base64 decode and
|
|
273
|
-
* a JSON parse of whatever a caller chose to send.
|
|
224
|
+
* Decodes the base64url JSON `Agent-Authorization` header. The size check runs
|
|
225
|
+
* on the encoded value, so an oversized header costs a length comparison rather
|
|
226
|
+
* than a decode and a JSON parse.
|
|
274
227
|
*/
|
|
275
228
|
declare function parseAuthorizationHeader(raw: string | readonly string[] | undefined, requestId?: string): AuthorizationSubmission | undefined;
|
|
276
229
|
/**
|
|
277
|
-
* Splits raw client input into resource input plus the reserved fields
|
|
278
|
-
*
|
|
279
|
-
*
|
|
280
|
-
* uses the two parse helpers directly.
|
|
230
|
+
* Splits raw client input into resource input plus the reserved fields, for
|
|
231
|
+
* protocols that carry them in the input object (MCP tool arguments, A2A
|
|
232
|
+
* message data). HTTP carries both in headers.
|
|
281
233
|
*
|
|
282
|
-
* A payment proof is
|
|
283
|
-
* puts provider-backed methods first so the label matches
|
|
284
|
-
* custom
|
|
285
|
-
*
|
|
234
|
+
* A payment proof is labeled with the resource's first payment method.
|
|
235
|
+
* `createGateway` puts provider-backed methods first so the label matches the
|
|
236
|
+
* pipeline's selection; a custom registry must keep that order. A resource with
|
|
237
|
+
* no payment method gets no payment proof, so the request reaches the pipeline
|
|
238
|
+
* unpaid.
|
|
286
239
|
*/
|
|
287
240
|
declare function extractReservedInputFields(rawInput: Record<string, unknown>, resource: CommerceResource | undefined, requestId?: string): {
|
|
288
241
|
input: Record<string, unknown>;
|
|
@@ -291,26 +244,25 @@ declare function extractReservedInputFields(rawInput: Record<string, unknown>, r
|
|
|
291
244
|
};
|
|
292
245
|
|
|
293
246
|
/**
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
*
|
|
297
|
-
* merchant backend. Every call is bounded by a timeout; redirects are not
|
|
298
|
-
* followed (see docs/security.md).
|
|
247
|
+
* The gateway's only boundary for calling a merchant backend. An
|
|
248
|
+
* implementation must bound every call with a timeout and must not follow
|
|
249
|
+
* redirects; the built-in HTTP executor does both (docs/security.md).
|
|
299
250
|
*/
|
|
300
251
|
|
|
301
252
|
interface BackendRequest {
|
|
302
253
|
readonly requestId: string;
|
|
303
254
|
readonly resourceId: string;
|
|
304
|
-
/** Validated resource input
|
|
255
|
+
/** Validated resource input */
|
|
305
256
|
readonly input: unknown;
|
|
306
257
|
/**
|
|
307
|
-
* Names the
|
|
258
|
+
* Names the operation, so the merchant can recognize a repeat of it. Not
|
|
259
|
+
* `requestId`, which is fresh per call and would make every retry look like
|
|
260
|
+
* new work.
|
|
308
261
|
*
|
|
309
|
-
*
|
|
310
|
-
*
|
|
311
|
-
*
|
|
312
|
-
*
|
|
313
|
-
* means the protocol has no such notion, and the merchant sees no header.
|
|
262
|
+
* An adapter sets it only when the value survives a client retry, a
|
|
263
|
+
* reconnect and a gateway restart. The HTTP executor sends it as the
|
|
264
|
+
* `Idempotency-Key` header, replacing one set in `BackendHandler.headers`;
|
|
265
|
+
* when absent, the executor adds none.
|
|
314
266
|
*/
|
|
315
267
|
readonly idempotencyKey?: string;
|
|
316
268
|
}
|
|
@@ -332,17 +284,16 @@ interface BackendExecutor {
|
|
|
332
284
|
}
|
|
333
285
|
|
|
334
286
|
/**
|
|
335
|
-
* Persistence boundary for receipts, events and payment attempts
|
|
336
|
-
*
|
|
337
|
-
*
|
|
338
|
-
* interface, never on SQLite.
|
|
287
|
+
* Persistence boundary for receipts, events and payment attempts, implemented
|
|
288
|
+
* by src/storage/receipts. Core depends only on this interface, never on
|
|
289
|
+
* SQLite.
|
|
339
290
|
*/
|
|
340
291
|
|
|
341
292
|
interface PaymentAttemptReservation {
|
|
342
293
|
readonly requestId: string;
|
|
343
294
|
readonly resourceId: string;
|
|
344
295
|
readonly provider: string;
|
|
345
|
-
/** Must be unique across the store
|
|
296
|
+
/** Must be unique across the store; see `PaymentResult.replayKey` */
|
|
346
297
|
readonly replayKey: string;
|
|
347
298
|
readonly amount: string;
|
|
348
299
|
readonly currency: string;
|
|
@@ -361,14 +312,12 @@ interface ListOptions {
|
|
|
361
312
|
}
|
|
362
313
|
interface ReceiptStore {
|
|
363
314
|
init(): Promise<void>;
|
|
364
|
-
/** Append a canonical event. Must not throw into the caller's flow
|
|
315
|
+
/** Append a canonical event. Must not throw into the caller's flow */
|
|
365
316
|
appendEvent(event: CommerceEvent): Promise<void>;
|
|
366
317
|
/**
|
|
367
|
-
* Atomically claim a payment
|
|
368
|
-
*
|
|
369
|
-
*
|
|
370
|
-
* reserved. This is the gateway's replay defence and is required for every
|
|
371
|
-
* paid request.
|
|
318
|
+
* Atomically claim a payment authorization before settlement: the gateway's
|
|
319
|
+
* replay defense, run for every paid request. Throws
|
|
320
|
+
* `CommerceError('PAYMENT_REPLAYED')` if `replayKey` was already reserved.
|
|
372
321
|
*/
|
|
373
322
|
reservePaymentAttempt(reservation: PaymentAttemptReservation): Promise<PaymentAttempt>;
|
|
374
323
|
updatePaymentAttempt(update: PaymentAttemptUpdate): Promise<void>;
|
|
@@ -376,33 +325,19 @@ interface ReceiptStore {
|
|
|
376
325
|
getReceipt(id: string): Promise<CommerceReceipt | undefined>;
|
|
377
326
|
listReceipts(options?: ListOptions): Promise<readonly CommerceReceipt[]>;
|
|
378
327
|
/**
|
|
379
|
-
* Total receipts held,
|
|
380
|
-
*
|
|
381
|
-
* `listReceipts` clamps to a bounded page (a store-level invariant, so an
|
|
382
|
-
* unbounded `limit` cannot dump the ledger). Counting by measuring the length
|
|
383
|
-
* of a list therefore silently saturates at the clamp — `doctor` reported
|
|
384
|
-
* "receipts=500" forever once 500 was passed. A diagnostic that quietly stops
|
|
385
|
-
* counting is worse than one that admits it cannot.
|
|
328
|
+
* Total receipts held. `listReceipts` clamps every page, so counting a list's
|
|
329
|
+
* length would stop at the clamp.
|
|
386
330
|
*/
|
|
387
331
|
countReceipts(): Promise<number>;
|
|
388
332
|
/**
|
|
389
|
-
* Receipts whose delivery
|
|
390
|
-
*
|
|
391
|
-
*
|
|
392
|
-
* settlement is final and this release has no refunds, so *seeing* it is the only
|
|
393
|
-
* remedy available. Counted rather than listed for the same reason as
|
|
394
|
-
* {@link countReceipts} — `listReceipts` is clamped, so counting by list
|
|
395
|
-
* length silently saturates.
|
|
333
|
+
* Receipts whose delivery failed: `backendStatus` outside 2xx, including 0
|
|
334
|
+
* when no status is known. Counted rather than listed for the same reason as
|
|
335
|
+
* {@link countReceipts}.
|
|
396
336
|
*
|
|
397
|
-
* In practice this is
|
|
398
|
-
*
|
|
399
|
-
*
|
|
400
|
-
*
|
|
401
|
-
* row for `countUndeliveredReceipts` to see. Free-resource failures are
|
|
402
|
-
* therefore *not* counted here, however natural it is to read the name as
|
|
403
|
-
* saying they are. Writing a receipt for a failed free delivery too would be
|
|
404
|
-
* a more complete ledger, but it changes what this count means — that is
|
|
405
|
-
* a product decision for after the alpha, not something to do here.
|
|
337
|
+
* In practice this is "paid but undelivered": the pipeline writes a receipt
|
|
338
|
+
* for a failed delivery only after a settled payment, so a free resource
|
|
339
|
+
* whose backend fails leaves no row here. It is the row a merchant must
|
|
340
|
+
* notice, because settlement is final and the gateway issues no refunds.
|
|
406
341
|
*/
|
|
407
342
|
countUndeliveredReceipts(): Promise<number>;
|
|
408
343
|
listEvents(options?: ListOptions): Promise<readonly CommerceEvent[]>;
|
|
@@ -429,7 +364,7 @@ interface ReceiptStore {
|
|
|
429
364
|
*/
|
|
430
365
|
declare const ACP_SPEC_VERSION = "2026-04-17";
|
|
431
366
|
declare const ACP_API_VERSION = "2026-04-17";
|
|
432
|
-
/** Discovery path fixed by the ACP specification
|
|
367
|
+
/** Discovery path fixed by the ACP specification, never a configurable mount */
|
|
433
368
|
declare const ACP_WELL_KNOWN_PATH = "/.well-known/acp.json";
|
|
434
369
|
/**
|
|
435
370
|
* The stable checkout operations, by ACP operation id. All five are required
|
|
@@ -440,32 +375,25 @@ declare const ACP_CHECKOUT_OPERATIONS: readonly ["createCheckoutSession", "updat
|
|
|
440
375
|
type AcpCheckoutOperation = (typeof ACP_CHECKOUT_OPERATIONS)[number];
|
|
441
376
|
|
|
442
377
|
/**
|
|
443
|
-
* `config.yaml` schema, validation and
|
|
444
|
-
*
|
|
378
|
+
* `config.yaml` schema, validation and normalization into the canonical
|
|
379
|
+
* `GatewayConfig` (docs/contracts.md).
|
|
445
380
|
*
|
|
446
|
-
*
|
|
447
|
-
*
|
|
448
|
-
*
|
|
449
|
-
*
|
|
450
|
-
*
|
|
451
|
-
*
|
|
452
|
-
*
|
|
453
|
-
* 2. A manual business-rule pass validates cross-references that need a
|
|
454
|
-
* specific, actionable message (duplicate ids, disabled protocols/payment
|
|
455
|
-
* methods, dynamic pricing, destination-address plausibility) and
|
|
456
|
-
* performs the numeric/boolean coercion.
|
|
381
|
+
* 1. Zod validates shape: types, required fields, unknown keys. Numeric and
|
|
382
|
+
* boolean leaves accept their native type or a string, because env
|
|
383
|
+
* substitution produces strings. Zod transforms interact badly with
|
|
384
|
+
* `.strict()` inference, so coercion happens in plain TypeScript in step 2.
|
|
385
|
+
* 2. A business-rule pass coerces those leaves and checks what needs a
|
|
386
|
+
* specific message: cross-references, disabled protocols and payment
|
|
387
|
+
* methods, dynamic pricing, addresses, duplicate trust entries.
|
|
457
388
|
*
|
|
458
|
-
* Env substitution (`${VAR}` / `${VAR:-default}`) runs over the raw
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
*
|
|
463
|
-
* environment variables to find out which schema version to expect would be
|
|
464
|
-
* backwards. The order is intended; `version:` is the one exception to the
|
|
465
|
-
* substitution rule, which this sentence exists to record.
|
|
389
|
+
* Env substitution (`${VAR}` / `${VAR:-default}`) runs over the raw value
|
|
390
|
+
* before both steps, so numeric and boolean fields can be templated. The one
|
|
391
|
+
* exception is `version:`, checked before substitution: it decides whether this
|
|
392
|
+
* parser understands the document at all, so it cannot depend on the
|
|
393
|
+
* environment.
|
|
466
394
|
*/
|
|
467
395
|
|
|
468
|
-
/** Optional ACP discovery metadata. Absent fields are omitted from the document
|
|
396
|
+
/** Optional ACP discovery metadata. Absent fields are omitted from the document */
|
|
469
397
|
interface AcpDiscoveryConfig {
|
|
470
398
|
readonly documentationUrl?: string;
|
|
471
399
|
readonly supportedCurrencies?: readonly string[];
|
|
@@ -473,9 +401,8 @@ interface AcpDiscoveryConfig {
|
|
|
473
401
|
readonly interventionTypes?: readonly string[];
|
|
474
402
|
}
|
|
475
403
|
/**
|
|
476
|
-
* Discriminated on `enabled
|
|
477
|
-
* adapter needs
|
|
478
|
-
* half-configured checkout lifecycle is rejected at load instead.
|
|
404
|
+
* Discriminated on `enabled`, so an enabled ACP config carries everything the
|
|
405
|
+
* adapter needs; a half-configured checkout is rejected at load
|
|
479
406
|
*/
|
|
480
407
|
type AcpProtocolConfig = {
|
|
481
408
|
readonly enabled: false;
|
|
@@ -529,7 +456,7 @@ interface GatewayConfig {
|
|
|
529
456
|
};
|
|
530
457
|
readonly acp: AcpProtocolConfig;
|
|
531
458
|
};
|
|
532
|
-
/** Canonical resources, already
|
|
459
|
+
/** Canonical resources, already normalized */
|
|
533
460
|
readonly resources: readonly CommerceResource[];
|
|
534
461
|
readonly payments: {
|
|
535
462
|
readonly x402?: {
|
|
@@ -562,10 +489,7 @@ interface GatewayConfig {
|
|
|
562
489
|
readonly allowUnauthenticatedFacilitator?: boolean;
|
|
563
490
|
};
|
|
564
491
|
};
|
|
565
|
-
/**
|
|
566
|
-
* Absent when no `authorization:` block is configured, which is how every
|
|
567
|
-
* config written before AP2 existed reads.
|
|
568
|
-
*/
|
|
492
|
+
/** Absent when no `authorization:` block is configured */
|
|
569
493
|
readonly authorization?: {
|
|
570
494
|
readonly ap2: Ap2AuthorizationConfig;
|
|
571
495
|
};
|
|
@@ -579,22 +503,17 @@ interface LoadConfigOptions {
|
|
|
579
503
|
}
|
|
580
504
|
declare function loadConfig(options?: LoadConfigOptions): Promise<GatewayConfig>;
|
|
581
505
|
|
|
582
|
-
/**
|
|
583
|
-
* `createGateway()` — the Fastify server. Fully usable (and tested) with
|
|
584
|
-
* fakes, without `main.ts` (docs/contracts.md "Composition root").
|
|
585
|
-
*/
|
|
586
|
-
|
|
587
506
|
interface GatewayOptions {
|
|
588
507
|
readonly config: GatewayConfig;
|
|
589
508
|
readonly store: ReceiptStore;
|
|
590
509
|
readonly paymentProviders: readonly PaymentProvider[];
|
|
591
|
-
/**
|
|
510
|
+
/** Defaults to none; each resource declares the methods it requires */
|
|
592
511
|
readonly authorizationProviders?: readonly AuthorizationProvider[];
|
|
593
512
|
readonly protocolAdapters: readonly ProtocolAdapter[];
|
|
594
513
|
readonly logger?: Logger;
|
|
595
514
|
readonly clock?: Clock;
|
|
596
515
|
readonly ids?: IdGenerator;
|
|
597
|
-
/** Override for tests
|
|
516
|
+
/** Override for tests */
|
|
598
517
|
readonly backend?: BackendExecutor;
|
|
599
518
|
}
|
|
600
519
|
interface GatewayInstance {
|
|
@@ -604,12 +523,79 @@ interface GatewayInstance {
|
|
|
604
523
|
url: string;
|
|
605
524
|
}>;
|
|
606
525
|
close(): Promise<void>;
|
|
607
|
-
/** Fastify instance, for `.inject()` in tests
|
|
526
|
+
/** Fastify instance, for `.inject()` in tests */
|
|
608
527
|
readonly server: FastifyInstance;
|
|
609
528
|
}
|
|
610
529
|
declare function createGateway(options: GatewayOptions): Promise<GatewayInstance>;
|
|
611
530
|
|
|
612
|
-
/**
|
|
531
|
+
/**
|
|
532
|
+
* A2A (Agent2Agent) protocol adapter, experimental.
|
|
533
|
+
*
|
|
534
|
+
* Serves two paths: the configured mount (`/a2a`), where the JSON-RPC endpoint
|
|
535
|
+
* lives, and the specification-fixed `/.well-known/agent-card.json`, declared
|
|
536
|
+
* through `additionalHttpRoutes` so the gateway needs no A2A-specific routing.
|
|
537
|
+
*
|
|
538
|
+
* Only the synchronous `SendMessage` path is in scope; every other A2A method
|
|
539
|
+
* is listed in `descriptor.unsupported` rather than half-served. This file
|
|
540
|
+
* never calls a merchant backend and never inspects a payment object.
|
|
541
|
+
*/
|
|
542
|
+
|
|
543
|
+
interface A2aAdapterOptions {
|
|
544
|
+
readonly mountPath?: string;
|
|
545
|
+
/** Agent name published on the card */
|
|
546
|
+
readonly agentName?: string;
|
|
547
|
+
readonly agentDescription?: string;
|
|
548
|
+
/** Version published on the card. Defaults to this package's version */
|
|
549
|
+
readonly agentVersion?: string;
|
|
550
|
+
}
|
|
551
|
+
declare class A2aProtocolAdapter implements HttpProtocolAdapter {
|
|
552
|
+
readonly name: "a2a";
|
|
553
|
+
readonly mountPath: string;
|
|
554
|
+
readonly descriptor: AdapterDescriptor;
|
|
555
|
+
readonly additionalHttpRoutes: readonly AdapterHttpRoute[];
|
|
556
|
+
private readonly agentName;
|
|
557
|
+
private readonly agentDescription;
|
|
558
|
+
private readonly agentVersion;
|
|
559
|
+
private context;
|
|
560
|
+
private started;
|
|
561
|
+
private skillsById;
|
|
562
|
+
private card;
|
|
563
|
+
constructor(options?: A2aAdapterOptions);
|
|
564
|
+
start(context: ProtocolAdapterContext): Promise<void>;
|
|
565
|
+
/** `GET /.well-known/agent-card.json` */
|
|
566
|
+
handleAgentCard(req: IncomingMessage, res: ServerResponse): Promise<void>;
|
|
567
|
+
/** `POST <mountPath>`: the A2A JSON-RPC endpoint */
|
|
568
|
+
handleHttp(req: IncomingMessage, res: ServerResponse): Promise<void>;
|
|
569
|
+
private dispatch;
|
|
570
|
+
private execute;
|
|
571
|
+
private taskIdentity;
|
|
572
|
+
private taskResult;
|
|
573
|
+
health(): Promise<AdapterHealth>;
|
|
574
|
+
stop(): Promise<void>;
|
|
575
|
+
private writeJson;
|
|
576
|
+
}
|
|
577
|
+
declare function createA2aAdapter(options?: A2aAdapterOptions): A2aProtocolAdapter;
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* A2A pins, kept in one place so nothing infers one version from another.
|
|
581
|
+
*
|
|
582
|
+
* The specification revision and the negotiation version look alike but
|
|
583
|
+
* differ: `1.0.0` names the document this adapter was written against, `1.0`
|
|
584
|
+
* is what a client negotiates on the wire. Neither is this package's version
|
|
585
|
+
* (`PACKAGE_VERSION`).
|
|
586
|
+
*/
|
|
587
|
+
/** A2A specification revision this adapter targets */
|
|
588
|
+
declare const A2A_SPEC_VERSION = "1.0.0";
|
|
589
|
+
/** Protocol negotiation version carried on the wire */
|
|
590
|
+
declare const A2A_PROTOCOL_VERSION = "1.0";
|
|
591
|
+
/**
|
|
592
|
+
* Fixed by the A2A specification: a client fetches the card from this exact
|
|
593
|
+
* path, so it is not configurable. `src/config` reserves it against adapter
|
|
594
|
+
* mounts for the same reason.
|
|
595
|
+
*/
|
|
596
|
+
declare const A2A_AGENT_CARD_PATH = "/.well-known/agent-card.json";
|
|
597
|
+
|
|
598
|
+
/** Discovery metadata an operator may configure. Absent fields are omitted, never guessed */
|
|
613
599
|
interface AcpDiscoveryMetadata {
|
|
614
600
|
readonly documentationUrl?: string;
|
|
615
601
|
readonly supportedCurrencies?: readonly string[];
|
|
@@ -618,29 +604,25 @@ interface AcpDiscoveryMetadata {
|
|
|
618
604
|
}
|
|
619
605
|
|
|
620
606
|
/**
|
|
621
|
-
* ACP (Agentic Commerce Protocol) adapter
|
|
607
|
+
* ACP (Agentic Commerce Protocol) adapter, experimental.
|
|
622
608
|
*
|
|
623
609
|
* Serves two paths: the configured mount (`/acp`), where the five stable
|
|
624
610
|
* checkout routes live, and the specification-fixed `/.well-known/acp.json`,
|
|
625
611
|
* declared through `additionalHttpRoutes` so the gateway needs no ACP-specific
|
|
626
612
|
* routing.
|
|
627
613
|
*
|
|
628
|
-
*
|
|
629
|
-
*
|
|
630
|
-
*
|
|
631
|
-
* honest "not implemented" rather than a fabricated session.
|
|
632
|
-
*
|
|
633
|
-
* This file never calls a merchant backend and never inspects a payment
|
|
634
|
-
* object.
|
|
614
|
+
* A request that passes every protocol guard runs its mapped resource through
|
|
615
|
+
* the pipeline, under an idempotency claim when it carries a key. This file
|
|
616
|
+
* never calls a merchant backend and never inspects a payment object.
|
|
635
617
|
*/
|
|
636
618
|
|
|
637
619
|
interface AcpAdapterOptions {
|
|
638
620
|
readonly mountPath: string;
|
|
639
|
-
/** The configured bearer token. Never logged, never echoed, never published
|
|
621
|
+
/** The configured bearer token. Never logged, never echoed, never published */
|
|
640
622
|
readonly token: string;
|
|
641
|
-
/** Which canonical resource implements each ACP checkout operation
|
|
623
|
+
/** Which canonical resource implements each ACP checkout operation */
|
|
642
624
|
readonly operations: Readonly<Record<AcpCheckoutOperation, string>>;
|
|
643
|
-
/** Where checkout idempotency records live, and how long they are kept
|
|
625
|
+
/** Where checkout idempotency records live, and how long they are kept */
|
|
644
626
|
readonly idempotency: {
|
|
645
627
|
readonly path: string;
|
|
646
628
|
readonly retentionHours: number;
|
|
@@ -652,15 +634,12 @@ declare class AcpProtocolAdapter implements HttpProtocolAdapter {
|
|
|
652
634
|
readonly mountPath: string;
|
|
653
635
|
readonly descriptor: AdapterDescriptor;
|
|
654
636
|
readonly additionalHttpRoutes: readonly AdapterHttpRoute[];
|
|
655
|
-
private readonly
|
|
637
|
+
private readonly isAuthorized;
|
|
656
638
|
private readonly operations;
|
|
657
639
|
private readonly idempotencyOptions;
|
|
658
640
|
/**
|
|
659
|
-
*
|
|
660
|
-
*
|
|
661
|
-
* Not readonly because, unlike the token, it is known only once the adapter
|
|
662
|
-
* starts. Worth that: scoping by the credential meant a rotation freed
|
|
663
|
-
* every outstanding claim.
|
|
641
|
+
* The deployment an idempotency claim is scoped to, `context.publicBaseUrl`.
|
|
642
|
+
* Not readonly because it is known only once the adapter starts.
|
|
664
643
|
*/
|
|
665
644
|
private deployment;
|
|
666
645
|
private readonly discoveryMetadata;
|
|
@@ -671,31 +650,17 @@ declare class AcpProtocolAdapter implements HttpProtocolAdapter {
|
|
|
671
650
|
private discovery;
|
|
672
651
|
constructor(options: AcpAdapterOptions);
|
|
673
652
|
start(context: ProtocolAdapterContext): Promise<void>;
|
|
674
|
-
/** `GET /.well-known/acp.json
|
|
653
|
+
/** `GET /.well-known/acp.json`: public, unauthenticated, cacheable */
|
|
675
654
|
handleDiscovery(req: IncomingMessage, res: ServerResponse): Promise<void>;
|
|
676
|
-
/** `<mountPath>/checkout_sessions
|
|
655
|
+
/** `<mountPath>/checkout_sessions...`: the five stable checkout routes */
|
|
677
656
|
handleHttp(req: IncomingMessage, res: ServerResponse): Promise<void>;
|
|
678
657
|
/**
|
|
679
|
-
* One request, at most one execution.
|
|
680
|
-
*
|
|
681
|
-
*
|
|
682
|
-
* so a retry that arrives while the first one is still running finds the
|
|
683
|
-
* claim instead of starting a second checkout. A route with no key (the GET)
|
|
684
|
-
* is read-only and needs none.
|
|
658
|
+
* One request, at most one execution. A body-bearing route claims its
|
|
659
|
+
* idempotency key before the work starts, so a retry arriving meanwhile finds
|
|
660
|
+
* the claim; the read-only GET carries no key.
|
|
685
661
|
*/
|
|
686
662
|
private dispatch;
|
|
687
|
-
/**
|
|
688
|
-
* One accepted request, one `pipeline.execute()`.
|
|
689
|
-
*
|
|
690
|
-
* Nothing here prices a resource, inspects a payment proof or calls a
|
|
691
|
-
* merchant backend: the adapter builds a canonical request and reads back
|
|
692
|
-
* what the pipeline decided.
|
|
693
|
-
*/
|
|
694
663
|
private runCheckout;
|
|
695
|
-
/**
|
|
696
|
-
* Protocol-owned headers only. A merchant backend's own headers are never
|
|
697
|
-
* proxied onto an ACP response.
|
|
698
|
-
*/
|
|
699
664
|
private responseHeaders;
|
|
700
665
|
private fail;
|
|
701
666
|
health(): Promise<AdapterHealth>;
|
|
@@ -704,7 +669,7 @@ declare class AcpProtocolAdapter implements HttpProtocolAdapter {
|
|
|
704
669
|
declare function createAcpAdapter(options: AcpAdapterOptions): AcpProtocolAdapter;
|
|
705
670
|
|
|
706
671
|
interface SqliteReceiptStoreOptions {
|
|
707
|
-
/** File path, or ':memory:' for tests. Parent directory is created if missing
|
|
672
|
+
/** File path, or ':memory:' for tests. Parent directory is created if missing */
|
|
708
673
|
readonly path: string;
|
|
709
674
|
readonly logger?: Logger;
|
|
710
675
|
readonly clock?: Clock;
|
|
@@ -712,4 +677,4 @@ interface SqliteReceiptStoreOptions {
|
|
|
712
677
|
}
|
|
713
678
|
declare function createSqliteReceiptStore(options: SqliteReceiptStoreOptions): ReceiptStore;
|
|
714
679
|
|
|
715
|
-
export { 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 ReceiptStore, ResourceRegistry, createAcpAdapter, createGateway, createSqliteReceiptStore, extractReservedInputFields, isCommerceError, isPaymentRequiredEnvelope, loadConfig, parseAuthorizationHeader, parseAuthorizationSubmission, parseConfig, createSqliteReceiptStore as receipts, toCommerceError, toDeliverySummary, toErrorEnvelope, toPaymentRequiredEnvelope };
|
|
680
|
+
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 ReceiptStore, ResourceRegistry, createA2aAdapter, createAcpAdapter, createGateway, createSqliteReceiptStore, extractReservedInputFields, isCommerceError, isPaymentRequiredEnvelope, loadConfig, parseAuthorizationHeader, parseAuthorizationSubmission, parseConfig, createSqliteReceiptStore as receipts, toCommerceError, toDeliverySummary, toErrorEnvelope, toPaymentRequiredEnvelope };
|