@agent-score/commerce 1.3.2 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +75 -29
- package/dist/core.js +1 -1
- package/dist/core.mjs +1 -1
- package/dist/discovery/index.js +4 -3
- package/dist/discovery/index.js.map +1 -1
- package/dist/discovery/index.mjs +4 -3
- package/dist/discovery/index.mjs.map +1 -1
- package/dist/identity/express.js +1 -1
- package/dist/identity/express.mjs +1 -1
- package/dist/identity/fastify.js +1 -1
- package/dist/identity/fastify.mjs +1 -1
- package/dist/identity/hono.js +1 -1
- package/dist/identity/hono.mjs +1 -1
- package/dist/identity/nextjs.js +1 -1
- package/dist/identity/nextjs.mjs +1 -1
- package/dist/identity/web.js +1 -1
- package/dist/identity/web.mjs +1 -1
- package/dist/index.d.mts +333 -84
- package/dist/index.d.ts +333 -84
- package/dist/index.js +394 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +375 -19
- package/dist/index.mjs.map +1 -1
- package/package.json +12 -6
package/dist/index.d.ts
CHANGED
|
@@ -30,6 +30,30 @@ interface A2AAgentCardCapabilities {
|
|
|
30
30
|
/** Free-form skill tags — `["product-purchase", "regulated-commerce", ...]`. */
|
|
31
31
|
skills?: string[];
|
|
32
32
|
}
|
|
33
|
+
/** Per A2A v1.0: an entry in the card's top-level `extensions` array. UCP support
|
|
34
|
+
* is declared this way (UCP §A2A binding requires `https://ucp.dev/2026-04-08/specification/reference`). */
|
|
35
|
+
interface A2AAgentCardExtension {
|
|
36
|
+
/** Canonical extension URI — for UCP, `https://ucp.dev/2026-04-08/specification/reference`. */
|
|
37
|
+
uri: string;
|
|
38
|
+
/** Extension-specific params. UCP places `{ capabilities: { "<reverse-dns>": [{ version: "..." }, ...] } }` here. */
|
|
39
|
+
params?: Record<string, unknown>;
|
|
40
|
+
}
|
|
41
|
+
/** Canonical UCP A2A extension URI — verifiers look for this exact URI in `extensions[]`
|
|
42
|
+
* to detect UCP support on the agent card. Pinned to the 2026-04-08 spec snapshot. */
|
|
43
|
+
declare const UCP_A2A_EXTENSION_URI = "https://ucp.dev/2026-04-08/specification/reference";
|
|
44
|
+
/** Build the canonical UCP entry for an A2A agent card's `extensions[]` array.
|
|
45
|
+
*
|
|
46
|
+
* Per UCP §A2A binding: "Businesses supporting UCP must advertise the extension and
|
|
47
|
+
* any optional capabilities in their A2A Agent Card to allow platforms to activate
|
|
48
|
+
* the extension." Pass the `capabilities` map keyed by reverse-DNS service/capability
|
|
49
|
+
* name (e.g. `dev.ucp.shopping.checkout`), each value a list of `{ version }` records.
|
|
50
|
+
* Pass `{}` (or omit) when you serve UCP at the discovery layer but have no formal
|
|
51
|
+
* capability bindings yet — vendors that haven't implemented checkout/cart/etc. should
|
|
52
|
+
* declare the extension URI without claiming capabilities they don't service.
|
|
53
|
+
*/
|
|
54
|
+
declare function ucpA2AExtension(capabilities?: Record<string, Array<{
|
|
55
|
+
version: string;
|
|
56
|
+
}>>): A2AAgentCardExtension;
|
|
33
57
|
interface A2AAgentCardIdentity {
|
|
34
58
|
/** Issuer of the identity claims — always `"https://agentscore.sh"` for the AgentScore-issued card. */
|
|
35
59
|
issuer: string;
|
|
@@ -61,6 +85,8 @@ interface A2AAgentCard {
|
|
|
61
85
|
url?: string;
|
|
62
86
|
/** Agent capabilities — endpoints + skills. */
|
|
63
87
|
capabilities?: A2AAgentCardCapabilities;
|
|
88
|
+
/** A2A v1.0 extensions array. Use `ucpA2AExtension()` to add the UCP entry. */
|
|
89
|
+
extensions?: A2AAgentCardExtension[];
|
|
64
90
|
/** AgentScore identity claims. Empty `null` when no identity is available (pre-KYC). */
|
|
65
91
|
identity: A2AAgentCardIdentity | null;
|
|
66
92
|
/** Vendor-specific extras merged at the top level. */
|
|
@@ -75,6 +101,9 @@ interface BuildA2AAgentCardInput {
|
|
|
75
101
|
url?: string;
|
|
76
102
|
/** Capabilities — endpoints exposed + skill tags. */
|
|
77
103
|
capabilities?: A2AAgentCardCapabilities;
|
|
104
|
+
/** A2A v1.0 extensions to declare on the card. Build the UCP entry with
|
|
105
|
+
* `ucpA2AExtension()`. Other A2A extensions can be added the same way. */
|
|
106
|
+
extensions?: A2AAgentCardExtension[];
|
|
78
107
|
/** AgentScore assess data — what `getAgentScoreData(c)` returns or what `assess()` returned directly.
|
|
79
108
|
* Pass `null` to emit a card with no identity claims (publishable but unverified). */
|
|
80
109
|
data?: AgentScoreData | null;
|
|
@@ -120,133 +149,353 @@ declare function buildA2AAgentCard(input: BuildA2AAgentCardInput): A2AAgentCard;
|
|
|
120
149
|
/**
|
|
121
150
|
* UCP (Universal Commerce Protocol) profile builder.
|
|
122
151
|
*
|
|
123
|
-
* Compose the JSON payload published at `/.well-known/ucp` per the UCP spec
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
152
|
+
* Compose the JSON payload published at `/.well-known/ucp` per the UCP spec.
|
|
153
|
+
* Output shape matches the spec example: top-level `{ ucp: {...}, signing_keys: [...] }`
|
|
154
|
+
* envelope, with `services` / `capabilities` / `payment_handlers` as MAPs keyed by
|
|
155
|
+
* reverse-DNS service / capability / handler name.
|
|
127
156
|
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
* same surface every other UCP merchant uses.
|
|
157
|
+
* AgentScore identity claims layer over UCP via the `sh.agentscore.identity` capability
|
|
158
|
+
* (vendor-namespaced; UCP doesn't define KYC/sanctions/age/jurisdiction natively). The
|
|
159
|
+
* capability extends `dev.ucp.shopping.checkout` AND `dev.ucp.shopping.cart` (multi-parent,
|
|
160
|
+
* the standard pattern UCP allows for capabilities that compose multiple parents).
|
|
133
161
|
*
|
|
134
|
-
*
|
|
162
|
+
* The unsigned profile body returned here is what merchants publish; pass it through
|
|
163
|
+
* `signUCPProfile` to attach the `agentscore-profile+jws` signature for trust-mode
|
|
164
|
+
* verifiers (vendor extension; UCP itself doesn't mandate profile-body signing).
|
|
135
165
|
*
|
|
136
|
-
*
|
|
137
|
-
* identity in the UCP spec is "who signed this" (JWKS-backed). AgentScore claims layer
|
|
138
|
-
* over UCP via a custom capability so consumers who care about verified-buyer identity
|
|
139
|
-
* can read them; consumers who don't care just see a normal UCP profile.
|
|
166
|
+
* Spec reference: https://ucp.dev/
|
|
140
167
|
*/
|
|
141
168
|
|
|
169
|
+
/**
|
|
170
|
+
* UCP per-element shape note: each binding interface (`UCPServiceBinding`,
|
|
171
|
+
* `UCPCapabilityBinding`, `UCPPaymentHandlerBinding`) carries the canonical UCP fields
|
|
172
|
+
* plus arbitrary vendor extras flat on the same object via `[k: string]: unknown`. The
|
|
173
|
+
* python sibling models these as dataclasses with an explicit `extras: dict` field. Both
|
|
174
|
+
* designs offer equivalent guarantees through different mechanisms.
|
|
175
|
+
*/
|
|
142
176
|
interface UCPSigningKey {
|
|
143
177
|
/** JWK kid (key id). */
|
|
144
178
|
kid: string;
|
|
145
|
-
/** JWK kty (key type) —
|
|
179
|
+
/** JWK kty (key type) — `EC`, `RSA`, or `OKP`. */
|
|
146
180
|
kty: string;
|
|
147
|
-
/** JWK alg (signing algorithm) —
|
|
181
|
+
/** JWK alg (signing algorithm) — `ES256`, `RS256`, or `EdDSA`. */
|
|
148
182
|
alg?: string;
|
|
149
|
-
/** JWK use
|
|
183
|
+
/** JWK use, typically `sig`. */
|
|
150
184
|
use?: string;
|
|
151
185
|
/** JWK crv (curve) for EC / OKP keys. */
|
|
152
186
|
crv?: string;
|
|
153
187
|
/** JWK x / y / n / e / etc. The full key material; passed through verbatim. */
|
|
154
188
|
[k: string]: unknown;
|
|
155
189
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
|
|
169
|
-
/**
|
|
190
|
+
/**
|
|
191
|
+
* Construct a UCPSigningKey from a public JWK dict (e.g. the `publicJWK` returned by
|
|
192
|
+
* `generateUCPSigningKey()`). Validates required fields and rejects symmetric keys that
|
|
193
|
+
* can't publicly verify a JWS in trust-mode UCP. Symmetric to Python's
|
|
194
|
+
* `UCPSigningKey.from_jwk(public_jwk)` classmethod.
|
|
195
|
+
*/
|
|
196
|
+
declare function ucpSigningKeyFromJWK(jwk: Record<string, unknown>): UCPSigningKey;
|
|
197
|
+
/** Transport binding — keyed under a service name (e.g., `dev.ucp.shopping`). */
|
|
198
|
+
interface UCPServiceBinding {
|
|
199
|
+
/** Spec version, YYYY-MM-DD per UCP convention. REQUIRED. */
|
|
200
|
+
version: string;
|
|
201
|
+
/** URL to human-readable specification. REQUIRED. */
|
|
202
|
+
spec: string;
|
|
203
|
+
/** Transport — `rest` / `mcp` / `a2a` / `embedded`. REQUIRED. */
|
|
204
|
+
transport: 'rest' | 'mcp' | 'a2a' | 'embedded';
|
|
205
|
+
/** Endpoint URL — required for rest/mcp; A2A points at the agent-card.json URL. */
|
|
206
|
+
endpoint?: string;
|
|
207
|
+
/** URL to JSON Schema — required for rest/mcp/embedded per spec. */
|
|
170
208
|
schema?: string;
|
|
171
|
-
/**
|
|
172
|
-
|
|
173
|
-
/**
|
|
209
|
+
/** Optional id for entity-instance disambiguation. */
|
|
210
|
+
id?: string;
|
|
211
|
+
/** Entity-specific config. */
|
|
212
|
+
config?: Record<string, unknown>;
|
|
213
|
+
/** Vendor-specific extras. */
|
|
174
214
|
[k: string]: unknown;
|
|
175
215
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
216
|
+
/** Capability binding — keyed under a capability name (e.g., `dev.ucp.shopping.checkout`). */
|
|
217
|
+
interface UCPCapabilityBinding {
|
|
218
|
+
/** Capability version, YYYY-MM-DD. REQUIRED. */
|
|
219
|
+
version: string;
|
|
220
|
+
/** URL to human-readable specification. REQUIRED. */
|
|
221
|
+
spec: string;
|
|
222
|
+
/** URL to JSON Schema. REQUIRED. */
|
|
223
|
+
schema: string;
|
|
224
|
+
/** Optional id for entity-instance disambiguation. */
|
|
225
|
+
id?: string;
|
|
226
|
+
/** Entity-specific config (feature flags, callback URLs, etc). */
|
|
180
227
|
config?: Record<string, unknown>;
|
|
228
|
+
/** Parent capability(ies) extended — single string or array for multi-parent. */
|
|
229
|
+
extends?: string | string[];
|
|
230
|
+
/** Optional version requirements per UCP §6.5. */
|
|
231
|
+
requires?: {
|
|
232
|
+
protocol?: {
|
|
233
|
+
min: string;
|
|
234
|
+
max?: string;
|
|
235
|
+
};
|
|
236
|
+
capabilities?: Record<string, {
|
|
237
|
+
min: string;
|
|
238
|
+
max?: string;
|
|
239
|
+
}>;
|
|
240
|
+
};
|
|
241
|
+
/** Vendor-specific extras (e.g., AgentScore claims block on `sh.agentscore.identity`). */
|
|
242
|
+
[k: string]: unknown;
|
|
181
243
|
}
|
|
182
|
-
|
|
183
|
-
|
|
244
|
+
/** Payment handler binding — keyed under a handler reverse-DNS name (e.g., `com.google.pay`). */
|
|
245
|
+
interface UCPPaymentHandlerBinding {
|
|
246
|
+
/** Handler instance id (short, human-readable, e.g., `gpay`, `tempo`, `x402`). REQUIRED. */
|
|
247
|
+
id: string;
|
|
248
|
+
/** Handler spec version, YYYY-MM-DD. REQUIRED. */
|
|
184
249
|
version: string;
|
|
185
|
-
/** URL
|
|
250
|
+
/** URL to handler spec. REQUIRED. */
|
|
186
251
|
spec: string;
|
|
187
|
-
/** URL
|
|
188
|
-
schema
|
|
189
|
-
/**
|
|
252
|
+
/** URL to handler config schema. REQUIRED. */
|
|
253
|
+
schema: string;
|
|
254
|
+
/** Available instruments — type + per-type constraints (cards, wallets, etc.). */
|
|
255
|
+
available_instruments?: Array<{
|
|
256
|
+
type: string;
|
|
257
|
+
constraints?: Record<string, unknown>;
|
|
258
|
+
[k: string]: unknown;
|
|
259
|
+
}>;
|
|
260
|
+
/** Handler config — gateway IDs, merchant IDs, public keys, etc. */
|
|
261
|
+
config?: Record<string, unknown>;
|
|
262
|
+
/** Vendor-specific extras. */
|
|
263
|
+
[k: string]: unknown;
|
|
264
|
+
}
|
|
265
|
+
/** UCP body — nested under the `ucp` key of the published profile. */
|
|
266
|
+
interface UCPProfileBody {
|
|
267
|
+
/** UCP spec version (YYYY-MM-DD). */
|
|
268
|
+
version: string;
|
|
269
|
+
/** Display name for the merchant / agent surface. */
|
|
190
270
|
name?: string;
|
|
191
|
-
/**
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
|
|
199
|
-
|
|
271
|
+
/** Services — keyed by service name (e.g., `dev.ucp.shopping`). Each value is an
|
|
272
|
+
* array of transport bindings (one merchant typically advertises multiple transports
|
|
273
|
+
* under one service name). */
|
|
274
|
+
services: Record<string, UCPServiceBinding[]>;
|
|
275
|
+
/** Capabilities — keyed by capability name (e.g., `dev.ucp.shopping.checkout`). */
|
|
276
|
+
capabilities: Record<string, UCPCapabilityBinding[]>;
|
|
277
|
+
/** Payment handlers — keyed by handler reverse-DNS name (e.g., `com.google.pay`). */
|
|
278
|
+
payment_handlers: Record<string, UCPPaymentHandlerBinding[]>;
|
|
279
|
+
/** Optional `supported_versions` map linking historical version-specific profile URLs.
|
|
280
|
+
* Pattern: `{ "2026-01-23": "https://merchant/.well-known/ucp/2026-01-23", ... }`. */
|
|
281
|
+
supported_versions?: Record<string, string>;
|
|
282
|
+
/** Vendor-specific extras inside the `ucp` envelope. */
|
|
283
|
+
[k: string]: unknown;
|
|
284
|
+
}
|
|
285
|
+
/** Full UCP profile body as published at `/.well-known/ucp`. Top-level shape:
|
|
286
|
+
* `{ ucp: {...}, signing_keys: [...], signature?: "..." }`. */
|
|
287
|
+
interface UCPProfile {
|
|
288
|
+
/** UCP body. ALL UCP-spec fields nest here per spec. */
|
|
289
|
+
ucp: UCPProfileBody;
|
|
290
|
+
/** JWKS — public keys at the OUTER level per UCP spec. Verifiers fetch this profile,
|
|
291
|
+
* match the kid from a JWS / RFC 9421 signature header against this list, and validate. */
|
|
200
292
|
signing_keys: UCPSigningKey[];
|
|
201
|
-
/**
|
|
293
|
+
/** Set when JWS-signed via `signUCPProfile` — JWS Compact Serialization with detached
|
|
294
|
+
* payload (header..signature; payload is the canonicalized body minus this field). */
|
|
295
|
+
signature?: string;
|
|
296
|
+
/** Top-level vendor-specific extras (outside the `ucp` envelope). */
|
|
202
297
|
[k: string]: unknown;
|
|
203
298
|
}
|
|
204
299
|
interface BuildUCPProfileInput {
|
|
205
|
-
/** UCP spec version. Default `
|
|
300
|
+
/** UCP spec version. Default `'2026-04-17'`. */
|
|
206
301
|
version?: string;
|
|
207
302
|
/** Display name for the merchant / agent surface. */
|
|
208
303
|
name?: string;
|
|
209
|
-
/**
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
/**
|
|
304
|
+
/** Services map, keyed by service name. UCP-shopping merchants typically advertise
|
|
305
|
+
* bindings under `'dev.ucp.shopping'`. */
|
|
306
|
+
services?: Record<string, UCPServiceBinding[]>;
|
|
307
|
+
/** Capabilities map, keyed by capability name. The `sh.agentscore.identity` capability
|
|
308
|
+
* is auto-added when `data` is provided. */
|
|
309
|
+
capabilities?: Record<string, UCPCapabilityBinding[]>;
|
|
310
|
+
/** Payment handlers map, keyed by handler reverse-DNS name. */
|
|
311
|
+
payment_handlers?: Record<string, UCPPaymentHandlerBinding[]>;
|
|
312
|
+
/** JWKS — public keys the merchant signs with. REQUIRED by spec. */
|
|
216
313
|
signing_keys: UCPSigningKey[];
|
|
217
|
-
/** AgentScore assess data — adds an `agentscore
|
|
314
|
+
/** AgentScore assess data — adds an `sh.agentscore.identity` capability + claims
|
|
315
|
+
* block when present. */
|
|
218
316
|
data?: AgentScoreData | null;
|
|
219
|
-
/** Optional override for the AgentScore capability schema URL.
|
|
220
|
-
|
|
221
|
-
|
|
317
|
+
/** Optional override for the AgentScore capability schema URL. Field is snake_cased
|
|
318
|
+
* for cross-language parity with the Python sibling. */
|
|
319
|
+
agentscore_schema_url?: string;
|
|
320
|
+
/** Optional override for the AgentScore capability spec URL. */
|
|
321
|
+
agentscore_spec_url?: string;
|
|
322
|
+
/** `supported_versions` map at the profile root for backwards-compat across
|
|
323
|
+
* spec dates. Pattern: `{ "<date>": "<base>/.well-known/ucp/<date>" }`. */
|
|
324
|
+
supported_versions?: Record<string, string>;
|
|
325
|
+
/** Vendor-specific extras at the OUTER level (alongside `ucp` + `signing_keys`). */
|
|
222
326
|
extras?: Record<string, unknown>;
|
|
327
|
+
/** Vendor-specific extras INSIDE the `ucp` envelope (alongside `version`, `services`, etc.). */
|
|
328
|
+
ucp_extras?: Record<string, unknown>;
|
|
223
329
|
}
|
|
224
330
|
/**
|
|
225
|
-
* Compose a UCP profile body for `/.well-known/ucp` publication.
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
331
|
+
* Compose a UCP profile body for `/.well-known/ucp` publication. Returns the spec-
|
|
332
|
+
* compliant shape: `{ ucp: { version, services, capabilities, payment_handlers, ... },
|
|
333
|
+
* signing_keys: [...] }`. Pass through `signUCPProfile` to attach a JWS signature for
|
|
334
|
+
* trust-mode verifiers.
|
|
335
|
+
*
|
|
336
|
+
* Auto-injects `sh.agentscore.identity` as a vendor capability extending both
|
|
337
|
+
* `dev.ucp.shopping.checkout` and `dev.ucp.shopping.cart` when `data` carries a
|
|
338
|
+
* resolved operator. Verifiers that recognize the AgentScore namespace can parse
|
|
339
|
+
* the `claims` block; vanilla UCP agents see a normal extension capability.
|
|
229
340
|
*
|
|
230
341
|
* Example:
|
|
231
342
|
* ```ts
|
|
232
|
-
* import { buildUCPProfile } from '@agent-score/commerce
|
|
343
|
+
* import { buildUCPProfile } from '@agent-score/commerce';
|
|
233
344
|
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
* { name: 'stripe', config: { profile_id: STRIPE_PROFILE_ID } },
|
|
345
|
+
* const profile = buildUCPProfile({
|
|
346
|
+
* name: 'Example Merchant',
|
|
347
|
+
* services: {
|
|
348
|
+
* 'dev.ucp.shopping': [
|
|
349
|
+
* { version: '2026-04-08', spec: 'https://ucp.dev/2026-04-08/specification/overview',
|
|
350
|
+
* transport: 'mcp', endpoint: 'https://merchant.example/api/ucp/mcp',
|
|
351
|
+
* schema: 'https://ucp.dev/services/shopping/openrpc.json' },
|
|
242
352
|
* ],
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
*
|
|
353
|
+
* },
|
|
354
|
+
* payment_handlers: {
|
|
355
|
+
* 'sh.agentscore.payment.tempo': [{
|
|
356
|
+
* id: 'tempo',
|
|
357
|
+
* version: '2026-04-08',
|
|
358
|
+
* spec: 'https://agentscore.sh/specification/payment-handlers/tempo',
|
|
359
|
+
* schema: 'https://agentscore.sh/schemas/payment-handlers/tempo.json',
|
|
360
|
+
* config: { recipient: TEMPO_ADDR },
|
|
361
|
+
* }],
|
|
362
|
+
* },
|
|
363
|
+
* signing_keys: [signingKey],
|
|
246
364
|
* });
|
|
247
365
|
* ```
|
|
248
366
|
*/
|
|
249
367
|
declare function buildUCPProfile(input: BuildUCPProfileInput): UCPProfile;
|
|
250
|
-
declare const AGENTSCORE_UCP_CAPABILITY = "agentscore
|
|
368
|
+
declare const AGENTSCORE_UCP_CAPABILITY = "sh.agentscore.identity";
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* UCP profile signing helpers (JWKS + JWS).
|
|
372
|
+
*
|
|
373
|
+
* UCP §6 (https://ucp.dev/latest/specification/signatures/) requires that profiles
|
|
374
|
+
* published at `/.well-known/ucp` carry a JWKS-backed signature for trust-mode clients
|
|
375
|
+
* (Google AI Mode, Gemini commerce, future ChatGPT app shells). Without a signature,
|
|
376
|
+
* trust-mode clients reject the profile.
|
|
377
|
+
*
|
|
378
|
+
* This module provides:
|
|
379
|
+
* - `generateUCPSigningKey()` — generate an Ed25519 keypair for signing
|
|
380
|
+
* - `signUCPProfile()` — sign a UCP profile body, returning a JWS-attached envelope
|
|
381
|
+
* - `verifyUCPProfile()` — verify a signed profile against a JWKS
|
|
382
|
+
* - `buildJWKSResponse()` — assemble a JWKS document for `/.well-known/jwks.json`
|
|
383
|
+
*
|
|
384
|
+
* Implementation rides on `jose` (peer-dep, optional). Merchants who don't sign their
|
|
385
|
+
* profile (development) skip this module entirely; the unsigned `buildUCPProfile()`
|
|
386
|
+
* path still works.
|
|
387
|
+
*
|
|
388
|
+
* Why Ed25519: smaller signatures (64 bytes vs 256+ for RSA), faster verification, no
|
|
389
|
+
* curve-parameter ceremony. UCP also accepts ES256 (P-256 ECDSA) — pass `alg: 'ES256'`
|
|
390
|
+
* to `signUCPProfile()` if your existing payment signing key is P-256.
|
|
391
|
+
*/
|
|
392
|
+
|
|
393
|
+
/** Output of `generateUCPSigningKey()`. The private key is what you sign with; the
|
|
394
|
+
* public JWK is what you publish at `/.well-known/jwks.json` and reference in the
|
|
395
|
+
* UCP profile's `signing_keys[]`.
|
|
396
|
+
*/
|
|
397
|
+
interface GeneratedUCPKey {
|
|
398
|
+
/** Private key (KeyLike, opaque) — pass to `signUCPProfile()`. Never publish. */
|
|
399
|
+
privateKey: unknown;
|
|
400
|
+
/** Public key as JWK — publish at `/.well-known/jwks.json` and inline in UCP `signing_keys[]`. */
|
|
401
|
+
publicJWK: UCPSigningKey;
|
|
402
|
+
}
|
|
403
|
+
/** A JWKS document — `{ keys: [...] }` per RFC 7517. Serve at `/.well-known/jwks.json`. */
|
|
404
|
+
interface JWKSResponse {
|
|
405
|
+
keys: UCPSigningKey[];
|
|
406
|
+
}
|
|
407
|
+
/** Options for `signUCPProfile()`. */
|
|
408
|
+
interface SignUCPProfileOptions {
|
|
409
|
+
/** Private signing key — opaque KeyLike from `generateUCPSigningKey()` or `importJWK()`. */
|
|
410
|
+
signingKey: unknown;
|
|
411
|
+
/** Key ID (must match a `kid` in the profile's `signing_keys[]`). */
|
|
412
|
+
kid: string;
|
|
413
|
+
/** Signing algorithm — `EdDSA` (default) or `ES256`. */
|
|
414
|
+
alg?: 'EdDSA' | 'ES256';
|
|
415
|
+
}
|
|
416
|
+
/** A signed UCP profile envelope. Same shape as `UCPProfile` plus the `signature` field
|
|
417
|
+
* carrying the JWS Compact Serialization over the canonicalized profile body. */
|
|
418
|
+
interface SignedUCPProfile extends UCPProfile {
|
|
419
|
+
/** JWS Compact Serialization (`<header>.<payload>.<signature>`) over the profile body
|
|
420
|
+
* with `signature` removed and keys sorted. Verifiers reconstruct the canonical body
|
|
421
|
+
* and validate against the JWK identified by `kid` in the JWS protected header. */
|
|
422
|
+
signature: string;
|
|
423
|
+
}
|
|
424
|
+
/** Discriminated error class so consumers can branch on failure mode without
|
|
425
|
+
* parsing message strings or importing jose internals. */
|
|
426
|
+
declare class UCPVerificationError extends Error {
|
|
427
|
+
readonly code: 'no_signature' | 'missing_kid' | 'kid_not_found' | 'duplicate_kid' | 'unsupported_alg' | 'wrong_typ' | 'signature_invalid' | 'body_mismatch' | 'malformed_jws' | 'malformed_jwks' | 'unrecognized_critical_header' | 'unusable_key';
|
|
428
|
+
constructor(code: 'no_signature' | 'missing_kid' | 'kid_not_found' | 'duplicate_kid' | 'unsupported_alg' | 'wrong_typ' | 'signature_invalid' | 'body_mismatch' | 'malformed_jws' | 'malformed_jwks' | 'unrecognized_critical_header' | 'unusable_key', message: string);
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Generate a fresh Ed25519 (default) or ES256 keypair for signing UCP profiles.
|
|
432
|
+
*
|
|
433
|
+
* The `privateKey` is an opaque KeyLike — store it server-side and pass to
|
|
434
|
+
* `signUCPProfile()`. Never log or transmit the private key.
|
|
435
|
+
*
|
|
436
|
+
* The `publicJWK` is what you publish at `/.well-known/jwks.json` and inline in the
|
|
437
|
+
* UCP profile's `signing_keys[]` array.
|
|
438
|
+
*
|
|
439
|
+
* Example:
|
|
440
|
+
* ```ts
|
|
441
|
+
* import { generateUCPSigningKey } from '@agent-score/commerce';
|
|
442
|
+
*
|
|
443
|
+
* const { privateKey, publicJWK } = await generateUCPSigningKey({ kid: 'merchant-2026-05' });
|
|
444
|
+
* // Persist privateKey securely (env var, KMS, secret manager).
|
|
445
|
+
* // Publish publicJWK at /.well-known/jwks.json and reference it in your UCP profile.
|
|
446
|
+
* ```
|
|
447
|
+
*/
|
|
448
|
+
declare function generateUCPSigningKey(opts: {
|
|
449
|
+
/** Key ID (kid). Must be unique per key; you'll reference this in the UCP profile's `signing_keys[]`. */
|
|
450
|
+
kid: string;
|
|
451
|
+
/** Signing algorithm. Default `EdDSA`. */
|
|
452
|
+
alg?: 'EdDSA' | 'ES256';
|
|
453
|
+
}): Promise<GeneratedUCPKey>;
|
|
454
|
+
/**
|
|
455
|
+
* Sign a UCP profile, returning a new envelope with the JWS attached as `signature`.
|
|
456
|
+
*
|
|
457
|
+
* The signature covers the canonicalized profile body (everything except `signature`
|
|
458
|
+
* itself, with keys sorted at every level). Trust-mode UCP verifiers reconstruct the
|
|
459
|
+
* canonical body, look up the key referenced by the JWS header's `kid`, and validate.
|
|
460
|
+
*
|
|
461
|
+
* The profile's `signing_keys[]` MUST already include a JWK with the matching `kid`
|
|
462
|
+
* — otherwise verifiers can't find the public key. Add the `publicJWK` from
|
|
463
|
+
* `generateUCPSigningKey()` to your `signing_keys[]` before calling this.
|
|
464
|
+
*
|
|
465
|
+
* Example:
|
|
466
|
+
* ```ts
|
|
467
|
+
* const profile = buildUCPProfile({ ..., signing_keys: [publicJWK] });
|
|
468
|
+
* const signed = await signUCPProfile(profile, { signingKey: privateKey, kid: 'merchant-2026-05' });
|
|
469
|
+
* c.json(signed);
|
|
470
|
+
* ```
|
|
471
|
+
*/
|
|
472
|
+
declare function signUCPProfile(profile: UCPProfile, opts: SignUCPProfileOptions): Promise<SignedUCPProfile>;
|
|
473
|
+
/**
|
|
474
|
+
* Verify a signed UCP profile against a JWKS. Returns `true` when the JWS validates
|
|
475
|
+
* against a matching key in `jwks`; throws on signature mismatch, missing key, or
|
|
476
|
+
* canonicalization drift.
|
|
477
|
+
*
|
|
478
|
+
* Round-trip helper for tests and for cross-merchant verification flows. Trust-mode
|
|
479
|
+
* UCP clients use the same algorithm.
|
|
480
|
+
*
|
|
481
|
+
* Example:
|
|
482
|
+
* ```ts
|
|
483
|
+
* const ok = await verifyUCPProfile(signedProfile, { keys: [publicJWK] });
|
|
484
|
+
* ```
|
|
485
|
+
*/
|
|
486
|
+
declare function verifyUCPProfile(profile: SignedUCPProfile, jwks: JWKSResponse): Promise<boolean>;
|
|
487
|
+
/**
|
|
488
|
+
* Build a JWKS document for `/.well-known/jwks.json`.
|
|
489
|
+
*
|
|
490
|
+
* Example:
|
|
491
|
+
* ```ts
|
|
492
|
+
* import { buildJWKSResponse } from '@agent-score/commerce';
|
|
493
|
+
*
|
|
494
|
+
* app.get('/.well-known/jwks.json', (c) =>
|
|
495
|
+
* c.json(buildJWKSResponse([publicJWK]))
|
|
496
|
+
* );
|
|
497
|
+
* ```
|
|
498
|
+
*/
|
|
499
|
+
declare function buildJWKSResponse(keys: UCPSigningKey[]): JWKSResponse;
|
|
251
500
|
|
|
252
|
-
export { type A2AAgentCard, type A2AAgentCardCapabilities, type A2AAgentCardIdentity, AGENTSCORE_UCP_CAPABILITY, AgentScoreData, type BuildA2AAgentCardInput, type BuildUCPProfileInput, type
|
|
501
|
+
export { type A2AAgentCard, type A2AAgentCardCapabilities, type A2AAgentCardExtension, type A2AAgentCardIdentity, AGENTSCORE_UCP_CAPABILITY, AgentScoreData, type BuildA2AAgentCardInput, type BuildUCPProfileInput, type GeneratedUCPKey, type JWKSResponse, type SignUCPProfileOptions, type SignedUCPProfile, type UCPCapabilityBinding, type UCPPaymentHandlerBinding, type UCPProfile, type UCPProfileBody, type UCPServiceBinding, type UCPSigningKey, UCPVerificationError, UCP_A2A_EXTENSION_URI, buildA2AAgentCard, buildJWKSResponse, buildUCPProfile, generateUCPSigningKey, signUCPProfile, ucpA2AExtension, ucpSigningKeyFromJWK, verifyUCPProfile };
|