@devlab.group/agent-commerce 1.4.1 → 1.6.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/README.md +168 -183
- package/dist/ap2.d.ts +21 -24
- package/dist/ap2.js +68 -82
- package/dist/ap2.js.map +1 -1
- package/dist/authorization-BpbWGGrf.d.ts +115 -0
- package/dist/{chunk-NWIQLJNU.js → chunk-74BSEXB5.js} +37 -34
- package/dist/chunk-74BSEXB5.js.map +1 -0
- package/dist/chunk-AFI2CEZS.js +10 -0
- package/dist/chunk-AFI2CEZS.js.map +1 -0
- package/dist/chunk-ATTWSFQP.js +680 -0
- package/dist/chunk-ATTWSFQP.js.map +1 -0
- package/dist/{chunk-ZEGFLRGV.js → chunk-IVJC5YLE.js} +63 -26
- package/dist/chunk-IVJC5YLE.js.map +1 -0
- package/dist/{chunk-GF6KHHKL.js → chunk-RAJGPGJG.js} +5 -8
- package/dist/chunk-RAJGPGJG.js.map +1 -0
- package/dist/chunk-V2V2E7HX.js +27 -0
- package/dist/chunk-V2V2E7HX.js.map +1 -0
- package/dist/cli/index.js +812 -573
- package/dist/cli/index.js.map +1 -1
- package/dist/constants-Bkq04FRZ.d.ts +48 -0
- package/dist/guardrails-71XwtXlT.d.ts +31 -0
- package/dist/index.d.ts +245 -265
- package/dist/index.js +1222 -626
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts +6 -59
- package/dist/mcp.js +64 -53
- package/dist/mcp.js.map +1 -1
- package/dist/mpp.d.ts +50 -0
- package/dist/mpp.js +353 -0
- package/dist/mpp.js.map +1 -0
- 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 +13 -693
- package/dist/x402.js.map +1 -1
- package/package.json +13 -2
- package/dist/authorization-CPDcpJVa.d.ts +0 -123
- package/dist/chunk-GF6KHHKL.js.map +0 -1
- package/dist/chunk-NWIQLJNU.js.map +0 -1
- package/dist/chunk-ZEGFLRGV.js.map +0 -1
- package/dist/guardrails-Dmwi63KB.d.ts +0 -38
- package/dist/protocol-adapter-Bebmggf_.d.ts +0 -273
- package/dist/runtime-CKq3d_3K.d.ts +0 -340
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A JSON Schema document (in practice a draft 2020-12 subset). Deliberately
|
|
3
|
+
* loose: adapters translate it to their own schema representation. Never treat
|
|
4
|
+
* it as trusted input without validation.
|
|
5
|
+
*/
|
|
6
|
+
type JsonSchema = Record<string, unknown>;
|
|
7
|
+
/** Protocol surfaces a resource can be exposed through */
|
|
8
|
+
type ProtocolName = 'http' | 'mcp' | 'a2a' | 'acp';
|
|
9
|
+
/**
|
|
10
|
+
* The same names as a value, for code that checks one at runtime: config
|
|
11
|
+
* validation and the OpenAPI importer's `--expose`
|
|
12
|
+
*/
|
|
13
|
+
declare const PROTOCOL_NAMES: readonly ProtocolName[];
|
|
14
|
+
/**
|
|
15
|
+
* Payment rails a resource can accept.
|
|
16
|
+
*
|
|
17
|
+
* A resource's list is an ordered candidate list, not a buyer-selected menu.
|
|
18
|
+
* The pipeline uses the first method with an enabled provider, and a
|
|
19
|
+
* rejection ends the request instead of trying another rail. Config requires at
|
|
20
|
+
* least one named rail to be enabled and permits others that are not.
|
|
21
|
+
*/
|
|
22
|
+
type PaymentMethodName = 'x402' | 'mpp';
|
|
23
|
+
/** The same names as a value, for config validation */
|
|
24
|
+
declare const PAYMENT_METHOD_NAMES: readonly PaymentMethodName[];
|
|
25
|
+
/**
|
|
26
|
+
* Authorization methods a resource can require. Neither a transport nor a
|
|
27
|
+
* payment rail: it proves the purchase was approved, and sits beside the
|
|
28
|
+
* payment rather than replacing it.
|
|
29
|
+
*/
|
|
30
|
+
type AuthorizationMethodName = 'ap2';
|
|
31
|
+
/** ISO-8601 timestamp string, always UTC with millisecond precision */
|
|
32
|
+
type IsoTimestamp = string;
|
|
33
|
+
/**
|
|
34
|
+
* A decimal amount as a string in the currency's display unit (for example
|
|
35
|
+
* "0.01" USDC), never a float and never base units. Payment providers convert
|
|
36
|
+
* it to on-chain base units.
|
|
37
|
+
*/
|
|
38
|
+
type DecimalAmount = string;
|
|
39
|
+
/** Health of an individual adapter or subsystem */
|
|
40
|
+
interface AdapterHealth {
|
|
41
|
+
readonly status: 'pass' | 'warn' | 'fail';
|
|
42
|
+
readonly detail?: string;
|
|
43
|
+
readonly checkedAt: IsoTimestamp;
|
|
44
|
+
readonly durationMs?: number;
|
|
45
|
+
}
|
|
46
|
+
/** Describes an adapter's supported surface for diagnostics */
|
|
47
|
+
interface AdapterDescriptor {
|
|
48
|
+
readonly name: string;
|
|
49
|
+
readonly kind: 'protocol' | 'payment' | 'storage' | 'authorization';
|
|
50
|
+
/** Version of this adapter implementation, independent of the spec */
|
|
51
|
+
readonly implementationVersion: string;
|
|
52
|
+
/** Exact pinned specification revision this adapter targets */
|
|
53
|
+
readonly supportedSpec: string;
|
|
54
|
+
readonly capabilities: readonly string[];
|
|
55
|
+
readonly status: 'stable' | 'experimental' | 'planned';
|
|
56
|
+
/** Capabilities explicitly not implemented, printed by `doctor` */
|
|
57
|
+
readonly unsupported?: readonly string[];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** HTTP methods a backend handler may use */
|
|
61
|
+
type BackendMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
62
|
+
/**
|
|
63
|
+
* How the gateway calls the merchant's existing backend.
|
|
64
|
+
*
|
|
65
|
+
* Backend URLs come from operator configuration only, never from users or
|
|
66
|
+
* agents (docs/security.md, SSRF). Secret header values belong in `${ENV_VAR}`
|
|
67
|
+
* placeholders resolved by the config loader, not in plaintext configuration.
|
|
68
|
+
*/
|
|
69
|
+
interface BackendHandler {
|
|
70
|
+
readonly type: 'http';
|
|
71
|
+
readonly method: BackendMethod;
|
|
72
|
+
readonly url: string;
|
|
73
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
74
|
+
/** Hard upper bound on the backend call. Defaults to `DEFAULT_BACKEND_TIMEOUT_MS` */
|
|
75
|
+
readonly timeoutMs?: number;
|
|
76
|
+
/**
|
|
77
|
+
* Names the top-level input properties carrying each part of the request.
|
|
78
|
+
*
|
|
79
|
+
* When absent, `{param}` values come from top-level input and everything left
|
|
80
|
+
* over becomes the query string (GET/DELETE) or the whole JSON body
|
|
81
|
+
* (POST/PUT/PATCH). That cannot express an operation with path, query and
|
|
82
|
+
* body at once, such as `POST /users/{userId}/orders?notify=true`.
|
|
83
|
+
*
|
|
84
|
+
* When present, each group comes from its named property, and top-level input
|
|
85
|
+
* that no binding names is not forwarded.
|
|
86
|
+
*/
|
|
87
|
+
readonly inputBindings?: {
|
|
88
|
+
readonly path?: string;
|
|
89
|
+
readonly query?: string;
|
|
90
|
+
readonly body?: string;
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/** Default backend timeout when a resource does not specify one */
|
|
94
|
+
declare const DEFAULT_BACKEND_TIMEOUT_MS = 10000;
|
|
95
|
+
/**
|
|
96
|
+
* Canonical pricing. `dynamic` exists in the type for forward compatibility;
|
|
97
|
+
* config validation rejects it and the pipeline refuses it as defense in depth.
|
|
98
|
+
*/
|
|
99
|
+
type Pricing = {
|
|
100
|
+
readonly type: 'free';
|
|
101
|
+
} | {
|
|
102
|
+
readonly type: 'fixed';
|
|
103
|
+
readonly amount: DecimalAmount;
|
|
104
|
+
readonly currency: string;
|
|
105
|
+
} | {
|
|
106
|
+
readonly type: 'dynamic';
|
|
107
|
+
readonly resolver: string;
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* A merchant capability exposed to agents. Protocol adapters map it outward and
|
|
111
|
+
* never define their own parallel notion of a resource.
|
|
112
|
+
*/
|
|
113
|
+
interface CommerceResource {
|
|
114
|
+
readonly id: string;
|
|
115
|
+
readonly name: string;
|
|
116
|
+
readonly description?: string;
|
|
117
|
+
readonly inputSchema?: JsonSchema;
|
|
118
|
+
readonly outputSchema?: JsonSchema;
|
|
119
|
+
readonly handler: BackendHandler;
|
|
120
|
+
readonly pricing: Pricing;
|
|
121
|
+
readonly exposedVia: readonly ProtocolName[];
|
|
122
|
+
readonly paymentMethods: readonly PaymentMethodName[];
|
|
123
|
+
/**
|
|
124
|
+
* Authorization the buyer must present in addition to payment. Opt-in per
|
|
125
|
+
* resource. It sits beside `paymentMethods`, not inside it, because an
|
|
126
|
+
* authorization method is not a payment rail and must never be selectable as
|
|
127
|
+
* one.
|
|
128
|
+
*/
|
|
129
|
+
readonly authorization?: {
|
|
130
|
+
readonly required: readonly AuthorizationMethodName[];
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/** Read-only view of every configured resource */
|
|
134
|
+
interface ResourceRegistry {
|
|
135
|
+
get(id: string): CommerceResource | undefined;
|
|
136
|
+
list(): readonly CommerceResource[];
|
|
137
|
+
/** Resources exposed through a given protocol surface */
|
|
138
|
+
listExposedVia(protocol: ProtocolName): readonly CommerceResource[];
|
|
139
|
+
has(id: string): boolean;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Canonical payment model. FROZEN CONTRACT.
|
|
144
|
+
*
|
|
145
|
+
* Core decides that a payment is required and for how much. Payment providers
|
|
146
|
+
* decide how the challenge is encoded, verified and settled. No x402- or
|
|
147
|
+
* EVM-specific type may appear in this file.
|
|
148
|
+
*/
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Provider-native payment challenge, opaque to core. For x402 the `accepts`
|
|
152
|
+
* entries are x402 `PaymentRequirements` objects, passed to protocol adapters
|
|
153
|
+
* verbatim.
|
|
154
|
+
*/
|
|
155
|
+
interface PaymentChallenge {
|
|
156
|
+
readonly provider: PaymentMethodName;
|
|
157
|
+
/** Provider protocol version, e.g. the x402 `x402Version` value as a string */
|
|
158
|
+
readonly version: string;
|
|
159
|
+
readonly accepts: readonly Readonly<Record<string, unknown>>[];
|
|
160
|
+
/**
|
|
161
|
+
* The provider's own challenge document, verbatim: for x402 v2 the
|
|
162
|
+
* `PaymentRequired` object a buyer's client consumes, for MPP an object
|
|
163
|
+
* carrying the serialized `WWW-Authenticate` challenge. Opaque to core.
|
|
164
|
+
*
|
|
165
|
+
* `accepts` alone is not that document: x402 v2 carries the resource
|
|
166
|
+
* description and protocol version on the envelope. Adapters with a native
|
|
167
|
+
* channel for it (x402's `PAYMENT-REQUIRED` header, MPP's `WWW-Authenticate`)
|
|
168
|
+
* send it there as is, so every surface offers the same challenge.
|
|
169
|
+
*/
|
|
170
|
+
readonly envelope?: Readonly<Record<string, unknown>>;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* What the buyer must pay, in canonical terms, plus the provider-native
|
|
174
|
+
* challenge the buyer's client needs to construct a payment
|
|
175
|
+
*/
|
|
176
|
+
interface PaymentRequirement {
|
|
177
|
+
readonly id: string;
|
|
178
|
+
readonly requestId: string;
|
|
179
|
+
readonly resourceId: string;
|
|
180
|
+
readonly provider: PaymentMethodName;
|
|
181
|
+
readonly amount: DecimalAmount;
|
|
182
|
+
readonly currency: string;
|
|
183
|
+
/** Merchant-controlled settlement destination, never a gateway-owned wallet */
|
|
184
|
+
readonly destination: string;
|
|
185
|
+
readonly network?: string;
|
|
186
|
+
readonly asset?: string;
|
|
187
|
+
readonly expiresAt?: IsoTimestamp;
|
|
188
|
+
readonly challenge: PaymentChallenge;
|
|
189
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Opaque payment proof supplied by the buyer's client. For x402 over HTTP it is
|
|
193
|
+
* the base64 `PAYMENT-SIGNATURE` header value; over MCP and A2A it is the same
|
|
194
|
+
* string in the reserved `_payment` input field.
|
|
195
|
+
*/
|
|
196
|
+
interface PaymentSubmission {
|
|
197
|
+
readonly method: PaymentMethodName;
|
|
198
|
+
readonly payload: string;
|
|
199
|
+
}
|
|
200
|
+
/** Outcome of verification or settlement */
|
|
201
|
+
interface PaymentResult {
|
|
202
|
+
readonly status: 'verified' | 'settled' | 'rejected';
|
|
203
|
+
readonly provider: PaymentMethodName;
|
|
204
|
+
/** Settlement reference, e.g. an on-chain transaction hash */
|
|
205
|
+
readonly externalReference?: string;
|
|
206
|
+
readonly payer?: string;
|
|
207
|
+
readonly payee?: string;
|
|
208
|
+
readonly amount: DecimalAmount;
|
|
209
|
+
readonly currency: string;
|
|
210
|
+
readonly network?: string;
|
|
211
|
+
readonly asset?: string;
|
|
212
|
+
/**
|
|
213
|
+
* Stable, provider-computed identity of the payment authorization.
|
|
214
|
+
*
|
|
215
|
+
* The pipeline reserves this key before settlement and rejects a second
|
|
216
|
+
* request presenting it with `PAYMENT_REPLAYED`. Providers must derive it
|
|
217
|
+
* only from the authorization (payer, nonce, asset, network), so the same
|
|
218
|
+
* authorization always maps to the same key.
|
|
219
|
+
*/
|
|
220
|
+
readonly replayKey?: string;
|
|
221
|
+
/** Machine-readable rejection reason when status is `rejected` */
|
|
222
|
+
readonly rejectionReason?: string;
|
|
223
|
+
readonly settledAt?: IsoTimestamp;
|
|
224
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
225
|
+
}
|
|
226
|
+
/** Input to {@link PaymentProvider.createRequirement} */
|
|
227
|
+
interface PaymentContext {
|
|
228
|
+
readonly requestId: string;
|
|
229
|
+
readonly resource: CommerceResource;
|
|
230
|
+
readonly amount: DecimalAmount;
|
|
231
|
+
readonly currency: string;
|
|
232
|
+
readonly requestedAt: IsoTimestamp;
|
|
233
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
234
|
+
}
|
|
235
|
+
/** Input to {@link PaymentProvider.verify} */
|
|
236
|
+
interface PaymentVerificationContext {
|
|
237
|
+
readonly requestId: string;
|
|
238
|
+
readonly resource: CommerceResource;
|
|
239
|
+
readonly requirement: PaymentRequirement;
|
|
240
|
+
readonly submission: PaymentSubmission;
|
|
241
|
+
}
|
|
242
|
+
/** Input to {@link PaymentProvider.settle} */
|
|
243
|
+
interface PaymentSettlementContext extends PaymentVerificationContext {
|
|
244
|
+
readonly verification: PaymentResult;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Contract every payment rail implements. Implementations must be
|
|
248
|
+
* non-custodial: they orchestrate an external payment protocol and never hold
|
|
249
|
+
* buyer or merchant production signing keys.
|
|
250
|
+
*/
|
|
251
|
+
interface PaymentProvider {
|
|
252
|
+
readonly name: PaymentMethodName;
|
|
253
|
+
readonly descriptor: AdapterDescriptor;
|
|
254
|
+
/**
|
|
255
|
+
* Build the requirement and its challenge. The pipeline calls it for every
|
|
256
|
+
* paid request, including one that already carries a proof to verify.
|
|
257
|
+
*/
|
|
258
|
+
createRequirement(context: PaymentContext): Promise<PaymentRequirement>;
|
|
259
|
+
/**
|
|
260
|
+
* Validate a submitted proof against the requirement. Must return `rejected`
|
|
261
|
+
* or throw a `CommerceError` rather than an untyped error, and must never
|
|
262
|
+
* move funds.
|
|
263
|
+
*/
|
|
264
|
+
verify(context: PaymentVerificationContext): Promise<PaymentResult>;
|
|
265
|
+
/**
|
|
266
|
+
* Execute settlement. Called only after `verify` returned `verified` and the
|
|
267
|
+
* replay key was reserved. A settlement verdict, including a rejection, is a
|
|
268
|
+
* returned result; the pipeline records any throw as settlement-uncertain.
|
|
269
|
+
*/
|
|
270
|
+
settle(context: PaymentSettlementContext): Promise<PaymentResult>;
|
|
271
|
+
health(): Promise<AdapterHealth>;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Minimal structural logger. Core does not depend on pino; the gateway injects
|
|
276
|
+
* a pino instance that satisfies this shape.
|
|
277
|
+
*
|
|
278
|
+
* Never log secrets: private keys, seed phrases, Authorization headers or
|
|
279
|
+
* payment authorization payloads.
|
|
280
|
+
*/
|
|
281
|
+
interface Logger {
|
|
282
|
+
debug(obj: Record<string, unknown>, msg?: string): void;
|
|
283
|
+
info(obj: Record<string, unknown>, msg?: string): void;
|
|
284
|
+
warn(obj: Record<string, unknown>, msg?: string): void;
|
|
285
|
+
error(obj: Record<string, unknown>, msg?: string): void;
|
|
286
|
+
child(bindings: Record<string, unknown>): Logger;
|
|
287
|
+
}
|
|
288
|
+
/** A logger that discards everything */
|
|
289
|
+
declare const NOOP_LOGGER: Logger;
|
|
290
|
+
|
|
291
|
+
interface Clock {
|
|
292
|
+
now(): Date;
|
|
293
|
+
nowIso(): IsoTimestamp;
|
|
294
|
+
/** Milliseconds since an arbitrary origin; use for durations only */
|
|
295
|
+
monotonicMs(): number;
|
|
296
|
+
}
|
|
297
|
+
interface IdGenerator {
|
|
298
|
+
/** Opaque, collision-resistant identifier */
|
|
299
|
+
next(prefix?: string): string;
|
|
300
|
+
}
|
|
301
|
+
declare const systemClock: Clock;
|
|
302
|
+
|
|
303
|
+
export { type AdapterDescriptor as A, type BackendHandler as B, type Clock as C, type DecimalAmount as D, type IsoTimestamp as I, type JsonSchema as J, type Logger as L, NOOP_LOGGER as N, type PaymentMethodName as P, type ResourceRegistry as R, type CommerceResource as a, type PaymentSubmission as b, type AdapterHealth as c, type PaymentProvider as d, type IdGenerator as e, type AuthorizationMethodName as f, type BackendMethod as g, DEFAULT_BACKEND_TIMEOUT_MS as h, PAYMENT_METHOD_NAMES as i, PROTOCOL_NAMES as j, type PaymentChallenge as k, type PaymentContext as l, type PaymentRequirement as m, type PaymentResult as n, type PaymentSettlementContext as o, type PaymentVerificationContext as p, type Pricing as q, type ProtocolName as r, systemClock as s };
|
|
@@ -7,49 +7,43 @@
|
|
|
7
7
|
*/
|
|
8
8
|
declare const AP2_SPEC_VERSION = "0.2.0";
|
|
9
9
|
/**
|
|
10
|
-
* Autonomous mode needs open mandates, cnf-bound agent keys and
|
|
11
|
-
* evaluation over `checkout.line_items
|
|
12
|
-
*
|
|
10
|
+
* Direct only. Autonomous mode needs open mandates, cnf-bound agent keys and
|
|
11
|
+
* constraint evaluation over `checkout.line_items`, none of which is
|
|
12
|
+
* implemented, so it is refused rather than partly served.
|
|
13
13
|
*/
|
|
14
14
|
declare const AP2_MODES: readonly ["direct"];
|
|
15
15
|
type Ap2Mode = (typeof AP2_MODES)[number];
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
* rather than by a
|
|
17
|
+
* A single algorithm, so `alg=none` and the HMAC family are excluded by
|
|
18
|
+
* construction rather than by a denylist
|
|
19
19
|
*/
|
|
20
20
|
declare const AP2_SIGNING_ALGORITHM = "ES256";
|
|
21
21
|
/**
|
|
22
22
|
* Compared against this literal, never as a prefix. `mandate.checkout.open.1`
|
|
23
|
-
* carries spending constraints
|
|
24
|
-
*
|
|
23
|
+
* carries spending constraints nothing here evaluates, so accepting it would
|
|
24
|
+
* tell a buyer their limits were checked when nothing read them.
|
|
25
25
|
*/
|
|
26
26
|
declare const AP2_CHECKOUT_MANDATE_VCT = "mandate.checkout.1";
|
|
27
27
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* A bare name, matching the gateway's other wire identifiers
|
|
34
|
-
* (`agent-commerce/delivery`, `agent-commerce/v1.0.0`). A profile id is a
|
|
35
|
-
* namespace and is never dereferenced, so a URL would only tie the wire format
|
|
36
|
-
* to a domain. Frozen once released: merchants sign it into every checkout JWT.
|
|
28
|
+
* Merchant checkout JWTs declare this gateway-specific profile; AP2 leaves
|
|
29
|
+
* the checkout payload out of scope. The identifier is a namespace that
|
|
30
|
+
* clients do not dereference. Merchants sign it into each checkout JWT, so
|
|
31
|
+
* changing the expected value would reject previously signed JWTs.
|
|
37
32
|
*/
|
|
38
33
|
declare const AP2_CHECKOUT_PROFILE = "agent-commerce/ap2/checkout/v1";
|
|
39
34
|
/** Seconds of clock skew tolerated on mandate and checkout time claims */
|
|
40
35
|
declare const AP2_DEFAULT_CLOCK_SKEW_SECONDS = 60;
|
|
41
36
|
/**
|
|
42
|
-
* Skew wide
|
|
43
|
-
* anything. An operator
|
|
37
|
+
* Skew as wide as a mandate's validity window would stop `exp` rejecting
|
|
38
|
+
* anything. An operator who needs more than five minutes has a clock to fix.
|
|
44
39
|
*/
|
|
45
40
|
declare const AP2_MAX_CLOCK_SKEW_SECONDS = 300;
|
|
46
41
|
|
|
47
42
|
/**
|
|
48
43
|
* AP2 trust configuration and the shape a successful verification produces.
|
|
49
44
|
*
|
|
50
|
-
*
|
|
51
|
-
* `X402FacilitatorConfig
|
|
52
|
-
* the loader imports it.
|
|
45
|
+
* The subsystem owns its config shape and the config loader imports it, as
|
|
46
|
+
* with `X402FacilitatorConfig`.
|
|
53
47
|
*/
|
|
54
48
|
|
|
55
49
|
/** One inline public verification key, trusted because an operator wrote it here */
|
|
@@ -62,8 +56,8 @@ interface Ap2TrustedKey {
|
|
|
62
56
|
interface Ap2TrustedIssuer {
|
|
63
57
|
readonly issuer: string;
|
|
64
58
|
/**
|
|
65
|
-
* Per issuer, not
|
|
66
|
-
*
|
|
59
|
+
* Per issuer, not gateway-wide: a mandate is addressed to the merchant, while
|
|
60
|
+
* the checkout JWT it binds is addressed to the gateway
|
|
67
61
|
*/
|
|
68
62
|
readonly audience: string;
|
|
69
63
|
readonly keys: readonly Ap2TrustedKey[];
|
package/dist/x402.d.ts
CHANGED
|
@@ -1,25 +1,22 @@
|
|
|
1
|
-
import { X as X402FacilitatorConfig } from './guardrails-
|
|
2
|
-
export { F as FacilitatorAuth } from './guardrails-
|
|
3
|
-
import { L as Logger, C as Clock, e as IdGenerator, d as PaymentProvider } from './runtime-
|
|
1
|
+
import { X as X402FacilitatorConfig } from './guardrails-71XwtXlT.js';
|
|
2
|
+
export { F as FacilitatorAuth } from './guardrails-71XwtXlT.js';
|
|
3
|
+
import { L as Logger, C as Clock, e as IdGenerator, d as PaymentProvider } from './runtime-CiYbgGpi.js';
|
|
4
4
|
|
|
5
5
|
interface NetworkProfile {
|
|
6
|
-
/** CAIP-2 identifier, e.g. `eip155:84532
|
|
6
|
+
/** CAIP-2 identifier, e.g. `eip155:84532` */
|
|
7
7
|
readonly id: string;
|
|
8
|
-
/** Signed into the buyer's EIP-712 domain
|
|
8
|
+
/** Signed into the buyer's EIP-712 domain */
|
|
9
9
|
readonly chainId: number;
|
|
10
10
|
readonly displayName: string;
|
|
11
11
|
readonly kind: 'testnet' | 'mainnet';
|
|
12
12
|
/**
|
|
13
|
-
* The USDC deployment this network
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* point at.
|
|
13
|
+
* The USDC deployment this network settles in, with the EIP-712 domain the
|
|
14
|
+
* token reports. Enforced on mainnet only, since a testnet may use a mock
|
|
15
|
+
* token.
|
|
17
16
|
*
|
|
18
|
-
* `name` is
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* one and every payment is refused `invalid_exact_evm_token_name_mismatch`
|
|
22
|
-
* after the buyer has signed. Read back from the contracts, not assumed.
|
|
17
|
+
* `name` is the signed EIP-712 domain name, not the symbol, and the two
|
|
18
|
+
* deployments differ: `"USDC"` on Base Sepolia, `"USD Coin"` on Base. The
|
|
19
|
+
* values were read back from the contracts.
|
|
23
20
|
*/
|
|
24
21
|
readonly canonicalAsset?: {
|
|
25
22
|
readonly symbol: string;
|
|
@@ -30,42 +27,30 @@ interface NetworkProfile {
|
|
|
30
27
|
}
|
|
31
28
|
declare const SUPPORTED_NETWORK_IDS: readonly string[];
|
|
32
29
|
/**
|
|
33
|
-
* What
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* the CAIP-2 id that node answers to. This distinction is the whole reason
|
|
38
|
-
* diagnostics can say `eip155:84532` without claiming to be on public Base
|
|
39
|
-
* Sepolia.
|
|
30
|
+
* What a deployment is, as opposed to the network it names. `local` comes from
|
|
31
|
+
* the facilitator: the in-process facilitator makes a deployment local whatever
|
|
32
|
+
* CAIP-2 id it is configured with, which lets diagnostics show `eip155:84532`
|
|
33
|
+
* without claiming public Base Sepolia.
|
|
40
34
|
*/
|
|
41
35
|
type DeploymentMode = 'local' | 'testnet' | 'mainnet';
|
|
42
36
|
|
|
43
37
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* payment authorisation, entirely on the buyer's side.
|
|
49
|
-
*
|
|
50
|
-
* The gateway NEVER calls this module and NEVER holds a buyer private key.
|
|
51
|
-
* `buyerPrivateKey` here is always an Anvil well-known
|
|
52
|
-
* development key (LOCAL DEVELOPMENT ONLY — DO NOT FUND) supplied by whoever
|
|
53
|
-
* is driving the demo/test, not something the provider or gateway manages.
|
|
38
|
+
* Client-side payment helper: builds and EIP-712-signs an x402 v2 `exact`/EVM
|
|
39
|
+
* authorization on the buyer's side. The demo buyer agent and the test suites
|
|
40
|
+
* use it, and the `/x402` entry exports it. The gateway never calls it and
|
|
41
|
+
* never holds a buyer key.
|
|
54
42
|
*
|
|
55
|
-
* It signs
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* produce those. Interop with a real SDK client is proved separately, by a
|
|
60
|
-
* test that pays the gateway using `x402Client` itself.
|
|
43
|
+
* It signs directly rather than through the SDK's `x402Client` because of
|
|
44
|
+
* `overrides`: negative tests need deliberately wrong authorizations that a
|
|
45
|
+
* conforming client will not produce. The x402 settlement E2E suite also
|
|
46
|
+
* settles a payment built by `x402Client` itself to cover interoperability.
|
|
61
47
|
*/
|
|
62
48
|
interface CreatePaymentProofOptions {
|
|
63
|
-
/**
|
|
49
|
+
/** The buyer's private key. It signs locally and is never sent anywhere */
|
|
64
50
|
readonly buyerPrivateKey: `0x${string}`;
|
|
65
|
-
|
|
66
|
-
/** One entry from PaymentRequiredEnvelope.payment.accepts, verbatim. */
|
|
51
|
+
/** One entry from PaymentRequiredEnvelope.payment.accepts, verbatim */
|
|
67
52
|
readonly accepts: Readonly<Record<string, unknown>>;
|
|
68
|
-
/**
|
|
53
|
+
/** For negative tests only: a wrong amount, recipient, nonce or validity window */
|
|
69
54
|
readonly overrides?: {
|
|
70
55
|
readonly value?: string;
|
|
71
56
|
readonly payTo?: string;
|
|
@@ -74,26 +59,17 @@ interface CreatePaymentProofOptions {
|
|
|
74
59
|
readonly validAfter?: number;
|
|
75
60
|
};
|
|
76
61
|
}
|
|
77
|
-
/** Returns the base64 `PAYMENT-SIGNATURE` value to send back to the gateway
|
|
62
|
+
/** Returns the base64 `PAYMENT-SIGNATURE` value to send back to the gateway */
|
|
78
63
|
declare function createPaymentProof(options: CreatePaymentProofOptions): Promise<string>;
|
|
79
64
|
|
|
80
65
|
/**
|
|
81
|
-
* x402 payment provider
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
* Implements the frozen `PaymentProvider` interface (src/core/domain/payment.ts).
|
|
85
|
-
* `verify()` never moves funds; only `settle()` does, and only after a
|
|
86
|
-
* successful `verify()` (enforced by the gateway's execution pipeline, not by
|
|
87
|
-
* this file, but this file never calls settle-like RPCs from verify()).
|
|
88
|
-
*
|
|
89
|
-
* Verification and settlement run through the SDK's own `x402Facilitator`
|
|
90
|
-
* with the `exact`/EVM scheme registered against a single CAIP-2 network. The
|
|
91
|
-
* facilitator is in-process — it is the same code a hosted facilitator runs,
|
|
92
|
-
* pointed at the local dev chain — so there is no network hop and no third
|
|
93
|
-
* party in the settlement path.
|
|
66
|
+
* x402 payment provider: protocol v2, `exact` scheme, EVM, EIP-3009
|
|
67
|
+
* `transferWithAuthorization`.
|
|
94
68
|
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
69
|
+
* `verify()` never moves funds. `settle()` does, and throws unless it is handed
|
|
70
|
+
* a successful verification. Both run through a facilitator (see
|
|
71
|
+
* `facilitator.ts`): the SDK's own `x402Facilitator` in this process, or a
|
|
72
|
+
* remote HTTP facilitator.
|
|
97
73
|
*/
|
|
98
74
|
|
|
99
75
|
interface X402ProviderOptions {
|
|
@@ -105,34 +81,26 @@ interface X402ProviderOptions {
|
|
|
105
81
|
readonly network: string;
|
|
106
82
|
/** RPC endpoint. Local chain: http://127.0.0.1:8545 */
|
|
107
83
|
readonly rpcUrl: string;
|
|
108
|
-
/** ERC-20 (EIP-3009) asset address used for settlement
|
|
84
|
+
/** ERC-20 (EIP-3009) asset address used for settlement */
|
|
109
85
|
readonly asset: `0x${string}`;
|
|
110
|
-
/** EIP-712 domain name of the asset, e.g. 'MockUSDC'
|
|
86
|
+
/** EIP-712 domain name of the asset, e.g. 'MockUSDC' */
|
|
111
87
|
readonly assetName: string;
|
|
112
|
-
/** EIP-712 domain version of the asset, e.g. '2'
|
|
88
|
+
/** EIP-712 domain version of the asset, e.g. '2' */
|
|
113
89
|
readonly assetVersion: string;
|
|
114
90
|
readonly assetDecimals: number;
|
|
115
|
-
/** Merchant-controlled settlement destination. Never a gateway-owned wallet
|
|
91
|
+
/** Merchant-controlled settlement destination. Never a gateway-owned wallet */
|
|
116
92
|
readonly payTo: `0x${string}`;
|
|
117
93
|
readonly maxTimeoutSeconds?: number;
|
|
118
94
|
/**
|
|
119
|
-
* Which facilitator verifies and broadcasts.
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
* ONLY — DO NOT FUND. `remote` calls an HTTP facilitator, and this gateway
|
|
124
|
-
* then holds no signing key at all.
|
|
95
|
+
* Which facilitator verifies and broadcasts. `local` runs one in this process
|
|
96
|
+
* against a dev chain, and its `signerPrivateKey` pays gas there, usually
|
|
97
|
+
* an Anvil well-known key (LOCAL DEVELOPMENT ONLY - DO NOT FUND). `remote`
|
|
98
|
+
* calls an HTTP facilitator, and the gateway then holds no signing key.
|
|
125
99
|
*/
|
|
126
100
|
readonly facilitator: X402FacilitatorConfig;
|
|
127
|
-
/**
|
|
128
|
-
* Required to be `true` before anything settles on a mainnet. Never a
|
|
129
|
-
* default — see `guardrails.ts`.
|
|
130
|
-
*/
|
|
101
|
+
/** Must be `true` before anything settles on a mainnet. Never a default */
|
|
131
102
|
readonly allowMainnet?: boolean;
|
|
132
|
-
/**
|
|
133
|
-
* Required to be `true` to settle on a mainnet through a facilitator that
|
|
134
|
-
* takes no credential. Never a default.
|
|
135
|
-
*/
|
|
103
|
+
/** Required on mainnet when facilitator auth is `none` */
|
|
136
104
|
readonly allowUnauthenticatedFacilitator?: boolean;
|
|
137
105
|
readonly logger?: Logger;
|
|
138
106
|
readonly clock?: Clock;
|